Merge pull request #26 from dufoli/master
ginterface properties support
This commit is contained in:
commit
9d319c8033
7 changed files with 356 additions and 27 deletions
|
@ -316,7 +316,16 @@ namespace GtkSharp.Generation {
|
||||||
p = (Property) klass.GetProperty (name);
|
p = (Property) klass.GetProperty (name);
|
||||||
klass = klass.Parent;
|
klass = klass.Parent;
|
||||||
}
|
}
|
||||||
|
if (p == null) {
|
||||||
|
foreach (string iface in interfaces) {
|
||||||
|
ClassBase igen = SymbolTable.Table.GetClassGen (iface);
|
||||||
|
if (igen == null)
|
||||||
|
continue;
|
||||||
|
p = igen.GetPropertyRecursively (name);
|
||||||
|
if (p != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,13 +107,20 @@ namespace GtkSharp.Generation {
|
||||||
sw.WriteLine ();
|
sw.WriteLine ();
|
||||||
sw.WriteLine ("\t\tstatic void Initialize (IntPtr ptr, IntPtr data)");
|
sw.WriteLine ("\t\tstatic void Initialize (IntPtr ptr, IntPtr data)");
|
||||||
sw.WriteLine ("\t\t{");
|
sw.WriteLine ("\t\t{");
|
||||||
|
if (interface_vms.Count > 0) {
|
||||||
sw.WriteLine ("\t\t\tIntPtr ifaceptr = new IntPtr (ptr.ToInt64 () + class_offset);");
|
sw.WriteLine ("\t\t\tIntPtr ifaceptr = new IntPtr (ptr.ToInt64 () + class_offset);");
|
||||||
sw.WriteLine ("\t\t\t{0} native_iface = ({0}) Marshal.PtrToStructure (ifaceptr, typeof ({0}));", class_struct_name);
|
sw.WriteLine ("\t\t\t{0} native_iface = ({0}) Marshal.PtrToStructure (ifaceptr, typeof ({0}));", class_struct_name);
|
||||||
foreach (InterfaceVM vm in interface_vms)
|
foreach (InterfaceVM vm in interface_vms) {
|
||||||
sw.WriteLine ("\t\t\tnative_iface." + vm.Name + " = iface." + vm.Name + ";");
|
sw.WriteLine ("\t\t\tnative_iface." + vm.Name + " = iface." + vm.Name + ";");
|
||||||
|
}
|
||||||
sw.WriteLine ("\t\t\tMarshal.StructureToPtr (native_iface, ifaceptr, false);");
|
sw.WriteLine ("\t\t\tMarshal.StructureToPtr (native_iface, ifaceptr, false);");
|
||||||
sw.WriteLine ("\t\t\tGCHandle gch = (GCHandle) data;");
|
sw.WriteLine ("\t\t\tGCHandle gch = (GCHandle) data;");
|
||||||
sw.WriteLine ("\t\t\tgch.Free ();");
|
sw.WriteLine ("\t\t\tgch.Free ();");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Property prop in props.Values) {
|
||||||
|
sw.WriteLine ("\t\t\tGLib.Object.OverrideProperty (data, \"" + prop.CName + "\");");
|
||||||
|
}
|
||||||
sw.WriteLine ("\t\t}");
|
sw.WriteLine ("\t\t}");
|
||||||
sw.WriteLine ();
|
sw.WriteLine ();
|
||||||
}
|
}
|
||||||
|
@ -309,7 +316,10 @@ namespace GtkSharp.Generation {
|
||||||
vm_table.Remove (vm.Name);
|
vm_table.Remove (vm.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach (Property prop in props.Values) {
|
||||||
|
sw.WriteLine ("\t\t[GLib.Property (\"" + prop.CName + "\")]");
|
||||||
|
prop.GenerateDecl (sw, "\t\t");
|
||||||
|
}
|
||||||
AppendCustom (sw, gen_info.CustomDir, Name + "Implementor");
|
AppendCustom (sw, gen_info.CustomDir, Name + "Implementor");
|
||||||
|
|
||||||
sw.WriteLine ("\t}");
|
sw.WriteLine ("\t}");
|
||||||
|
|
|
@ -296,6 +296,14 @@ namespace GLib {
|
||||||
return klass;
|
return klass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IntPtr GetDefaultInterfacePtr ()
|
||||||
|
{
|
||||||
|
IntPtr klass = g_type_default_interface_peek (val);
|
||||||
|
if (klass == IntPtr.Zero)
|
||||||
|
klass = g_type_default_interface_ref (val);
|
||||||
|
return klass;
|
||||||
|
}
|
||||||
|
|
||||||
public GType GetBaseType ()
|
public GType GetBaseType ()
|
||||||
{
|
{
|
||||||
IntPtr parent = g_type_parent (this.Val);
|
IntPtr parent = g_type_parent (this.Val);
|
||||||
|
@ -405,6 +413,12 @@ namespace GLib {
|
||||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern IntPtr g_type_class_ref (IntPtr gtype);
|
static extern IntPtr g_type_class_ref (IntPtr gtype);
|
||||||
|
|
||||||
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern IntPtr g_type_default_interface_peek (IntPtr gtype);
|
||||||
|
|
||||||
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern IntPtr g_type_default_interface_ref (IntPtr gtype);
|
||||||
|
|
||||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern IntPtr g_type_from_name (string name);
|
static extern IntPtr g_type_from_name (string name);
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace GLib {
|
||||||
IntPtr handle;
|
IntPtr handle;
|
||||||
ToggleRef tref;
|
ToggleRef tref;
|
||||||
bool disposed = false;
|
bool disposed = false;
|
||||||
|
static uint idx = 1;
|
||||||
static Dictionary<IntPtr, ToggleRef> Objects = new Dictionary<IntPtr, ToggleRef>();
|
static Dictionary<IntPtr, ToggleRef> Objects = new Dictionary<IntPtr, ToggleRef>();
|
||||||
|
|
||||||
~Object ()
|
~Object ()
|
||||||
|
@ -161,6 +162,15 @@ namespace GLib {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Dictionary<IntPtr, Dictionary<Type, PropertyInfo>> interface_properties;
|
||||||
|
static Dictionary<IntPtr, Dictionary<Type, PropertyInfo>> IProperties {
|
||||||
|
get {
|
||||||
|
if (interface_properties == null)
|
||||||
|
interface_properties = new Dictionary<IntPtr, Dictionary<Type, PropertyInfo>> ();
|
||||||
|
return interface_properties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct GTypeClass {
|
struct GTypeClass {
|
||||||
public IntPtr gtype;
|
public IntPtr gtype;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +240,36 @@ namespace GLib {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern void g_object_class_override_property (IntPtr klass, uint prop_id, IntPtr name);
|
||||||
|
|
||||||
|
public static void OverrideProperty (IntPtr declaring_class, string name)
|
||||||
|
{
|
||||||
|
IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
|
||||||
|
g_object_class_override_property (declaring_class, idx, native_name);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern IntPtr g_object_class_find_property (IntPtr klass, IntPtr name);
|
||||||
|
|
||||||
|
static IntPtr FindClassProperty (GType type, string name)
|
||||||
|
{
|
||||||
|
IntPtr g_iface = type.GetDefaultInterfacePtr ();
|
||||||
|
IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
|
||||||
|
return g_object_class_find_property (g_iface, native_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern IntPtr g_object_interface_find_property (IntPtr klass, IntPtr name);
|
||||||
|
|
||||||
|
static IntPtr FindInterfaceProperty (GType type, string name)
|
||||||
|
{
|
||||||
|
IntPtr g_iface = type.GetDefaultInterfacePtr ();
|
||||||
|
IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
|
||||||
|
return g_object_interface_find_property (g_iface, native_name);
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern void g_object_class_install_property (IntPtr klass, uint prop_id, IntPtr param_spec);
|
static extern void g_object_class_install_property (IntPtr klass, uint prop_id, IntPtr param_spec);
|
||||||
|
|
||||||
|
@ -242,10 +282,8 @@ namespace GLib {
|
||||||
return pspec.Handle;
|
return pspec.Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddProperties (GType gtype, System.Type t, bool register_instance_prop)
|
static void AddProperties (GType gtype, System.Type t, bool register_instance_prop, ref bool handlers_overridden)
|
||||||
{
|
{
|
||||||
uint idx = 1;
|
|
||||||
|
|
||||||
if (register_instance_prop) {
|
if (register_instance_prop) {
|
||||||
IntPtr declaring_class = gtype.GetClassPtr ();
|
IntPtr declaring_class = gtype.GetClassPtr ();
|
||||||
ParamSpec pspec = new ParamSpec ("gtk-sharp-managed-instance", "", "", GType.Pointer, ParamFlags.Writable | ParamFlags.ConstructOnly);
|
ParamSpec pspec = new ParamSpec ("gtk-sharp-managed-instance", "", "", GType.Pointer, ParamFlags.Writable | ParamFlags.ConstructOnly);
|
||||||
|
@ -253,7 +291,6 @@ namespace GLib {
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handlers_overridden = register_instance_prop;
|
|
||||||
foreach (PropertyInfo pinfo in t.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) {
|
foreach (PropertyInfo pinfo in t.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) {
|
||||||
foreach (object attr in pinfo.GetCustomAttributes (typeof (PropertyAttribute), false)) {
|
foreach (object attr in pinfo.GetCustomAttributes (typeof (PropertyAttribute), false)) {
|
||||||
if(pinfo.GetIndexParameters().Length > 0)
|
if(pinfo.GetIndexParameters().Length > 0)
|
||||||
|
@ -305,6 +342,16 @@ namespace GLib {
|
||||||
|
|
||||||
static void SetPropertyCallback(IntPtr handle, uint property_id, ref GLib.Value value, IntPtr param_spec)
|
static void SetPropertyCallback(IntPtr handle, uint property_id, ref GLib.Value value, IntPtr param_spec)
|
||||||
{
|
{
|
||||||
|
// FIXME: Here is a big quick hack to avoid race condition when trying to set up adjustment with contructor
|
||||||
|
// Because Raw is set too late
|
||||||
|
if (param_spec != IntPtr.Zero) {
|
||||||
|
ParamSpec foo = new ParamSpec(param_spec);
|
||||||
|
if (foo.Name == "gtk-sharp-managed-instance") {
|
||||||
|
GCHandle gch = (GCHandle) (IntPtr) value.Val;
|
||||||
|
Object o = (GLib.Object) gch.Target;
|
||||||
|
o.Raw = handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!Properties.ContainsKey (param_spec))
|
if (!Properties.ContainsKey (param_spec))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -324,24 +371,51 @@ namespace GLib {
|
||||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern void g_type_add_interface_static (IntPtr gtype, IntPtr iface_type, ref GInterfaceInfo info);
|
static extern void g_type_add_interface_static (IntPtr gtype, IntPtr iface_type, ref GInterfaceInfo info);
|
||||||
|
|
||||||
static void AddInterfaces (GType gtype, Type t)
|
static void AddInterfaces (GType gtype, Type t, ref bool handlers_overridden)
|
||||||
{
|
{
|
||||||
foreach (Type iface in t.GetInterfaces ()) {
|
foreach (Type iface in t.GetInterfaces ()) {
|
||||||
if (!iface.IsDefined (typeof (GInterfaceAttribute), true) || iface.IsAssignableFrom (t.BaseType))
|
if (!iface.IsDefined (typeof (GInterfaceAttribute), true))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GInterfaceAttribute attr = iface.GetCustomAttributes (typeof (GInterfaceAttribute), false) [0] as GInterfaceAttribute;
|
GInterfaceAttribute attr = iface.GetCustomAttributes (typeof (GInterfaceAttribute), false) [0] as GInterfaceAttribute;
|
||||||
GInterfaceAdapter adapter = Activator.CreateInstance (attr.AdapterType, null) as GInterfaceAdapter;
|
GInterfaceAdapter adapter = Activator.CreateInstance (attr.AdapterType, null) as GInterfaceAdapter;
|
||||||
|
if (!handlers_overridden) {
|
||||||
|
IntPtr class_ptr = gtype.GetClassPtr ();
|
||||||
|
GObjectClass gobject_class = (GObjectClass) Marshal.PtrToStructure (class_ptr, typeof (GObjectClass));
|
||||||
|
gobject_class.get_prop_cb = GetPropertyHandler;
|
||||||
|
gobject_class.set_prop_cb = SetPropertyHandler;
|
||||||
|
Marshal.StructureToPtr (gobject_class, class_ptr, false);
|
||||||
|
handlers_overridden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iface.IsAssignableFrom (t.BaseType)) {
|
||||||
GInterfaceInfo info = adapter.Info;
|
GInterfaceInfo info = adapter.Info;
|
||||||
|
info.Data = gtype.GetClassPtr ();
|
||||||
|
//FIXME: overiding prop is done inside the init of interface adapter
|
||||||
|
// not sure that it is the good solution but
|
||||||
|
// it is the only one I found without exception or loop
|
||||||
g_type_add_interface_static (gtype.Val, adapter.GType.Val, ref info);
|
g_type_add_interface_static (gtype.Val, adapter.GType.Val, ref info);
|
||||||
}
|
}
|
||||||
|
foreach (PropertyInfo p in iface.GetProperties ()) {
|
||||||
|
PropertyAttribute[] attrs = p.GetCustomAttributes (typeof (PropertyAttribute), true) as PropertyAttribute [];
|
||||||
|
if (attrs.Length == 0)
|
||||||
|
continue;
|
||||||
|
PropertyAttribute property_attr = attrs [0];
|
||||||
|
PropertyInfo declared_prop = t.GetProperty (p.Name, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
if (declared_prop == null)
|
||||||
|
continue;
|
||||||
|
IntPtr param_spec = FindInterfaceProperty (adapter.GType, property_attr.Name);
|
||||||
|
|
||||||
|
Properties [param_spec] = declared_prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected internal static GType RegisterGType (System.Type t)
|
protected internal static GType RegisterGType (System.Type t)
|
||||||
{
|
{
|
||||||
GType gtype = GType.RegisterGObjectType (t);
|
GType gtype = GType.RegisterGObjectType (t);
|
||||||
bool is_first_subclass = gtype.GetBaseType () == gtype.GetThresholdType ();
|
bool is_first_subclass = gtype.GetBaseType () == gtype.GetThresholdType ();
|
||||||
|
|
||||||
if (is_first_subclass) {
|
if (is_first_subclass) {
|
||||||
IntPtr class_ptr = gtype.GetClassPtr ();
|
IntPtr class_ptr = gtype.GetClassPtr ();
|
||||||
GObjectClass gobject_class = (GObjectClass) Marshal.PtrToStructure (class_ptr, typeof (GObjectClass));
|
GObjectClass gobject_class = (GObjectClass) Marshal.PtrToStructure (class_ptr, typeof (GObjectClass));
|
||||||
|
@ -350,10 +424,12 @@ namespace GLib {
|
||||||
gobject_class.set_prop_cb = SetPropertyHandler;
|
gobject_class.set_prop_cb = SetPropertyHandler;
|
||||||
Marshal.StructureToPtr (gobject_class, class_ptr, false);
|
Marshal.StructureToPtr (gobject_class, class_ptr, false);
|
||||||
}
|
}
|
||||||
AddProperties (gtype, t, is_first_subclass);
|
idx = 1;
|
||||||
|
bool handlers_overridden = is_first_subclass;
|
||||||
|
AddProperties (gtype, t, is_first_subclass, ref handlers_overridden);
|
||||||
ConnectDefaultHandlers (gtype, t);
|
ConnectDefaultHandlers (gtype, t);
|
||||||
InvokeTypeInitializers (gtype, t);
|
InvokeTypeInitializers (gtype, t);
|
||||||
AddInterfaces (gtype, t);
|
AddInterfaces (gtype, t, ref handlers_overridden);
|
||||||
return gtype;
|
return gtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,10 @@ namespace GLib {
|
||||||
handle = g_param_spec_int64 (p_name, p_nick, p_blurb, Int64.MinValue, Int64.MaxValue, 0, flags);
|
handle = g_param_spec_int64 (p_name, p_nick, p_blurb, Int64.MinValue, Int64.MaxValue, 0, flags);
|
||||||
else if (type == GType.UInt64)
|
else if (type == GType.UInt64)
|
||||||
handle = g_param_spec_uint64 (p_name, p_nick, p_blurb, 0, UInt64.MaxValue, 0, flags);
|
handle = g_param_spec_uint64 (p_name, p_nick, p_blurb, 0, UInt64.MaxValue, 0, flags);
|
||||||
/*
|
else if (type.GetBaseType () == GType.Enum)
|
||||||
else if (type == GType.Enum)
|
handle = g_param_spec_enum (p_name, p_nick, p_blurb, type.Val, (int) (Enum.GetValues((Type)type).GetValue (0)), flags);
|
||||||
else if (type == GType.Flags)
|
/*else if (type == GType.Flags)
|
||||||
|
* g_param_spec_flags (p_name, p_nick, p_blurb, type.Val, Enum.GetValues((Type)type) [0], flags);
|
||||||
* TODO:
|
* TODO:
|
||||||
* Both g_param_spec_enum and g_param_spec_flags expect default property values and the members of the enum seemingly cannot be enumerated
|
* Both g_param_spec_enum and g_param_spec_flags expect default property values and the members of the enum seemingly cannot be enumerated
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +86,7 @@ namespace GLib {
|
||||||
else if (g_type_is_a (type.Val, GType.Object.Val))
|
else if (g_type_is_a (type.Val, GType.Object.Val))
|
||||||
handle = g_param_spec_object (p_name, p_nick, p_blurb, type.Val, flags);
|
handle = g_param_spec_object (p_name, p_nick, p_blurb, type.Val, flags);
|
||||||
else
|
else
|
||||||
throw new ArgumentException ("type");
|
throw new ArgumentException ("type:" + type.ToString ());
|
||||||
|
|
||||||
GLib.Marshaller.Free (p_name);
|
GLib.Marshaller.Free (p_name);
|
||||||
GLib.Marshaller.Free (p_nick);
|
GLib.Marshaller.Free (p_nick);
|
||||||
|
@ -108,6 +109,21 @@ namespace GLib {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Name {
|
||||||
|
get {
|
||||||
|
GParamSpec spec = (GParamSpec) Marshal.PtrToStructure (Handle, typeof (GParamSpec));
|
||||||
|
return Marshaller.Utf8PtrToString (spec.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToString ()
|
||||||
|
{
|
||||||
|
GParamSpec spec = (GParamSpec) Marshal.PtrToStructure (Handle, typeof (GParamSpec));
|
||||||
|
GType valtype= new GType (spec.value_type);
|
||||||
|
GType ownertype= new GType (spec.owner_type);
|
||||||
|
return "ParamSpec: name=" + Marshaller.Utf8PtrToString (spec.name) + " value_type=" + valtype.ToString() + " owner_type=" + ownertype.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
struct GTypeInstance {
|
struct GTypeInstance {
|
||||||
public IntPtr g_class;
|
public IntPtr g_class;
|
||||||
}
|
}
|
||||||
|
@ -136,6 +152,9 @@ namespace GLib {
|
||||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern IntPtr g_param_spec_boolean (IntPtr name, IntPtr nick, IntPtr blurb, bool dval, int flags);
|
static extern IntPtr g_param_spec_boolean (IntPtr name, IntPtr nick, IntPtr blurb, bool dval, int flags);
|
||||||
|
|
||||||
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
static extern IntPtr g_param_spec_enum (IntPtr name, IntPtr nick, IntPtr blurb, IntPtr enum_type, int dval, int flags);
|
||||||
|
|
||||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
static extern IntPtr g_param_spec_int (IntPtr name, IntPtr nick, IntPtr blurb, int min, int max, int dval, int flags);
|
static extern IntPtr g_param_spec_int (IntPtr name, IntPtr nick, IntPtr blurb, int min, int max, int dval, int flags);
|
||||||
|
|
||||||
|
|
197
sample/CustomScrollableWidget.cs
Normal file
197
sample/CustomScrollableWidget.cs
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
using GLib;
|
||||||
|
using Gtk;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
class CustomScrollableWidgetTest {
|
||||||
|
public static int Main (string[] args)
|
||||||
|
{
|
||||||
|
Gtk.Application.Init ();
|
||||||
|
Window win = new Window ("Custom Scrollable Widget Test");
|
||||||
|
win.DeleteEvent += new DeleteEventHandler (OnQuit);
|
||||||
|
|
||||||
|
ScrolledWindow scroll = new ScrolledWindow ();
|
||||||
|
scroll.HscrollbarPolicy = PolicyType.Automatic;
|
||||||
|
scroll.VscrollbarPolicy = PolicyType.Automatic;
|
||||||
|
|
||||||
|
CustomScrollableWidget cw = new CustomScrollableWidget ("This one label that is repeated");
|
||||||
|
scroll.Add (cw);
|
||||||
|
|
||||||
|
win.Add (scroll);
|
||||||
|
win.DefaultWidth = 200;
|
||||||
|
win.DefaultHeight = 200;
|
||||||
|
win.ShowAll ();
|
||||||
|
Gtk.Application.Run ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnQuit (object sender, DeleteEventArgs args)
|
||||||
|
{
|
||||||
|
Gtk.Application.Quit ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CustomBase : Widget
|
||||||
|
{
|
||||||
|
public CustomBase () : base ()
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomScrollableWidget : CustomBase, ScrollableImplementor {
|
||||||
|
private int num_rows = 20;
|
||||||
|
private string label;
|
||||||
|
private Pango.Layout layout;
|
||||||
|
|
||||||
|
public CustomScrollableWidget (string custom_label) : base ()
|
||||||
|
{
|
||||||
|
label = custom_label;
|
||||||
|
layout = null;
|
||||||
|
|
||||||
|
HasWindow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pango.Layout Layout {
|
||||||
|
get {
|
||||||
|
if (layout == null)
|
||||||
|
layout = CreatePangoLayout (label);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Gdk.Rectangle ContentArea {
|
||||||
|
get {
|
||||||
|
Gdk.Rectangle area;
|
||||||
|
area.X = Allocation.X;
|
||||||
|
area.Y = Allocation.Y;
|
||||||
|
|
||||||
|
int layoutWidth, layoutHeight;
|
||||||
|
Layout.GetPixelSize (out layoutWidth, out layoutHeight);
|
||||||
|
area.Width = layoutWidth;
|
||||||
|
area.Height = layoutHeight * num_rows;
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnDrawn (Cairo.Context cr)
|
||||||
|
{
|
||||||
|
int layout_x = - HadjustmentValue;
|
||||||
|
int layout_y = - VadjustmentValue;
|
||||||
|
|
||||||
|
int layoutWidth, layoutHeight;
|
||||||
|
Layout.GetPixelSize (out layoutWidth, out layoutHeight);
|
||||||
|
|
||||||
|
for (int i = 0; i < num_rows; i++) {
|
||||||
|
Layout.SetText (String.Format ("{0} {1}", label, i));
|
||||||
|
StyleContext.RenderLayout (cr, layout_x, layout_y, Layout);
|
||||||
|
layout_y += layoutHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnDrawn (cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSizeAllocated (Gdk.Rectangle allocation)
|
||||||
|
{
|
||||||
|
base.OnSizeAllocated (allocation);
|
||||||
|
|
||||||
|
if (hadjustment != null) {
|
||||||
|
hadjustment.PageSize = allocation.Width;
|
||||||
|
hadjustment.PageIncrement = allocation.Width;
|
||||||
|
UpdateAdjustments ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vadjustment != null) {
|
||||||
|
vadjustment.PageSize = allocation.Height;
|
||||||
|
vadjustment.PageIncrement = allocation.Height;
|
||||||
|
UpdateAdjustments ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Adjustment hadjustment;
|
||||||
|
public Adjustment Hadjustment {
|
||||||
|
get { return hadjustment; }
|
||||||
|
set {
|
||||||
|
if (value == hadjustment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hadjustment = value;
|
||||||
|
if (hadjustment == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hadjustment.ValueChanged += OnHadjustmentChanged;
|
||||||
|
UpdateAdjustments ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Adjustment vadjustment;
|
||||||
|
public Adjustment Vadjustment {
|
||||||
|
get { return vadjustment; }
|
||||||
|
set {
|
||||||
|
if (value == vadjustment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vadjustment = value;
|
||||||
|
if (vadjustment == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vadjustment.ValueChanged += OnVadjustmentChanged;
|
||||||
|
UpdateAdjustments ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int HadjustmentValue {
|
||||||
|
get { return hadjustment == null ? 0 : (int)hadjustment.Value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int VadjustmentValue {
|
||||||
|
get { return vadjustment == null ? 0 : (int)vadjustment.Value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gtk.ScrollablePolicy HscrollPolicy {
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gtk.ScrollablePolicy VscrollPolicy {
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateAdjustments ()
|
||||||
|
{
|
||||||
|
int layoutWidth, layoutHeight;
|
||||||
|
Layout.GetPixelSize (out layoutWidth, out layoutHeight);
|
||||||
|
|
||||||
|
if (hadjustment != null) {
|
||||||
|
hadjustment.Upper = ContentArea.Width;
|
||||||
|
hadjustment.StepIncrement = 10.0;
|
||||||
|
if (hadjustment.Value + hadjustment.PageSize > hadjustment.Upper) {
|
||||||
|
hadjustment.Value = hadjustment.Upper - hadjustment.PageSize;
|
||||||
|
}
|
||||||
|
Console.WriteLine (String.Format ("H adj={0} upper={1} PageSize={2} PageInc={3}",
|
||||||
|
HadjustmentValue, hadjustment.Upper, hadjustment.PageSize, hadjustment.PageIncrement));
|
||||||
|
hadjustment.Change ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vadjustment != null) {
|
||||||
|
vadjustment.Upper = ContentArea.Height;
|
||||||
|
vadjustment.StepIncrement = layoutHeight;
|
||||||
|
if (vadjustment.Value + vadjustment.PageSize > vadjustment.Upper) {
|
||||||
|
vadjustment.Value = vadjustment.Upper - vadjustment.PageSize;
|
||||||
|
}
|
||||||
|
Console.WriteLine (String.Format ("V adj={0} upper={1} PageSize={2} PageInc={3}",
|
||||||
|
VadjustmentValue, vadjustment.Upper, vadjustment.PageSize, vadjustment.PageIncrement));
|
||||||
|
vadjustment.Change ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnHadjustmentChanged (object o, EventArgs args)
|
||||||
|
{
|
||||||
|
UpdateAdjustments ();
|
||||||
|
QueueDraw ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnVadjustmentChanged (object o, EventArgs args)
|
||||||
|
{
|
||||||
|
UpdateAdjustments ();
|
||||||
|
QueueDraw ();
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ DOTNET_TARGETS=
|
||||||
DOTNET_ASSEMBLY=
|
DOTNET_ASSEMBLY=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
TARGETS = gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe treemodeldemo.exe actions.exe spawn.exe assistant.exe registerprop.exe gexceptiontest.exe native-instantiation.exe polarfixed.exe cairo-sample.exe scribble.exe testdnd.exe custom-cellrenderer.exe custom-widget.exe #scribble-xinput.exe $(DOTNET_TARGETS)
|
TARGETS = gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe treemodeldemo.exe actions.exe spawn.exe assistant.exe registerprop.exe gexceptiontest.exe native-instantiation.exe polarfixed.exe cairo-sample.exe scribble.exe testdnd.exe custom-cellrenderer.exe custom-widget.exe custom-scrollable.exe #scribble-xinput.exe $(DOTNET_TARGETS)
|
||||||
|
|
||||||
DEBUGS = $(addsuffix .mdb, $(TARGETS))
|
DEBUGS = $(addsuffix .mdb, $(TARGETS))
|
||||||
|
|
||||||
|
@ -79,6 +79,9 @@ drawing-sample.exe: $(srcdir)/DrawingSample.cs $(assemblies) $(DOTNET_ASSEMBLIES
|
||||||
custom-widget.exe: $(srcdir)/CustomWidget.cs $(assemblies)
|
custom-widget.exe: $(srcdir)/CustomWidget.cs $(assemblies)
|
||||||
$(CSC) $(CSFLAGS) -out:custom-widget.exe $(references) $(srcdir)/CustomWidget.cs
|
$(CSC) $(CSFLAGS) -out:custom-widget.exe $(references) $(srcdir)/CustomWidget.cs
|
||||||
|
|
||||||
|
custom-scrollable.exe: $(srcdir)/CustomScrollableWidget.cs $(assemblies)
|
||||||
|
$(CSC) $(CSFLAGS) -out:custom-scrollable.exe $(references) $(srcdir)/CustomScrollableWidget.cs
|
||||||
|
|
||||||
actions.exe: $(srcdir)/Actions.cs
|
actions.exe: $(srcdir)/Actions.cs
|
||||||
$(CSC) $(CSFLAGS) -unsafe -out:actions.exe $(references) $(srcdir)/Actions.cs
|
$(CSC) $(CSFLAGS) -unsafe -out:actions.exe $(references) $(srcdir)/Actions.cs
|
||||||
|
|
||||||
|
@ -118,6 +121,7 @@ EXTRA_DIST = \
|
||||||
CustomCellRenderer.cs \
|
CustomCellRenderer.cs \
|
||||||
DrawingSample.cs \
|
DrawingSample.cs \
|
||||||
CustomWidget.cs \
|
CustomWidget.cs \
|
||||||
|
CustomScrollableWidget.cs \
|
||||||
Actions.cs \
|
Actions.cs \
|
||||||
PropertyRegistration.cs \
|
PropertyRegistration.cs \
|
||||||
PolarFixed.cs
|
PolarFixed.cs
|
||||||
|
|
Loading…
Add table
Reference in a new issue