2004-05-07 Mike Kestner <mkestner@ximian.com>
[Derived from a patch by Ben Maurer] * generator/Ctor.cs : generate code to detect subclassing and handle GType registration and native object creation properly. * generator/Parameters.cs : add PropertyName accessor for param attr. * generator/Property.cs : use a new GLib.Value ctor. * glib/ObjectManager.cs : redo hash access. * glib/Object.cs : CreateNativeObject method to invoke g_object_newv and some refactoring of RegisterGType and LookupGType. * glib/Value.cs : make gtype field an IntPtr. * glib/glue/object.c : glue for g_object_newv use. * glib/glue/value.c : new glue for value creation. * gtk/Dialog.custom : fix a ctor declaration for auto-reg. * gtk/Gtk.metadata : mark a couple property_name attrs as examples. * sample/Subclass.cs : use auto-GType-registration now. svn path=/trunk/gtk-sharp/; revision=26916
This commit is contained in:
parent
e301835e99
commit
c9f1eadc11
12 changed files with 163 additions and 40 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2004-05-07 Mike Kestner <mkestner@ximian.com>
|
||||
|
||||
[Derived from a patch by Ben Maurer]
|
||||
* generator/Ctor.cs : generate code to detect subclassing and handle
|
||||
GType registration and native object creation properly.
|
||||
* generator/Parameters.cs : add PropertyName accessor for param attr.
|
||||
* generator/Property.cs : use a new GLib.Value ctor.
|
||||
* glib/ObjectManager.cs : redo hash access.
|
||||
* glib/Object.cs : CreateNativeObject method to invoke g_object_newv
|
||||
and some refactoring of RegisterGType and LookupGType.
|
||||
* glib/Value.cs : make gtype field an IntPtr.
|
||||
* glib/glue/object.c : glue for g_object_newv use.
|
||||
* glib/glue/value.c : new glue for value creation.
|
||||
* gtk/Dialog.custom : fix a ctor declaration for auto-reg.
|
||||
* gtk/Gtk.metadata : mark a couple property_name attrs as examples.
|
||||
* sample/Subclass.cs : use auto-GType-registration now.
|
||||
|
||||
2004-05-06 Mike Kestner <mkestner@ximian.com>
|
||||
|
||||
* gdk/Gdk.metadata : some out and array magic for Property.Get.
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace GtkSharp.Generation {
|
|||
private string clashName = null;
|
||||
private ClassBase container_type;
|
||||
private bool force_static;
|
||||
private bool needs_chaining = false;
|
||||
|
||||
public bool Preferred {
|
||||
get { return preferred; }
|
||||
|
@ -47,6 +48,8 @@ namespace GtkSharp.Generation {
|
|||
parms = new Parameters (parms_elem, container_type.NS);
|
||||
if (elem.HasAttribute ("preferred"))
|
||||
preferred = true;
|
||||
if (container_type is ObjectGen)
|
||||
needs_chaining = true;
|
||||
}
|
||||
|
||||
public bool Validate ()
|
||||
|
@ -102,6 +105,8 @@ namespace GtkSharp.Generation {
|
|||
else
|
||||
safety = "";
|
||||
|
||||
SymbolTable table = SymbolTable.Table;
|
||||
|
||||
sw.WriteLine("\t\t[DllImport(\"" + libname + "\")]");
|
||||
sw.WriteLine("\t\tstatic extern " + safety + "IntPtr " + cname + "(" + isig.ToString () + ");");
|
||||
sw.WriteLine();
|
||||
|
@ -133,9 +138,60 @@ namespace GtkSharp.Generation {
|
|||
sw.Write ("new {0} (", name);
|
||||
sw.WriteLine (cname + "(" + body.GetCallString (false) + "));");
|
||||
} else {
|
||||
sw.WriteLine("\t\tpublic " + safety + name + "(" + sig.ToString() + ") : base (IntPtr.Zero)");
|
||||
sw.WriteLine("\t\tpublic {0}{1} ({2}) {3}", safety, name, sig.ToString(), needs_chaining ? ": base (IntPtr.Zero)" : "");
|
||||
sw.WriteLine("\t\t{");
|
||||
|
||||
if (needs_chaining) {
|
||||
sw.WriteLine ("\t\t\tif (GetType () != typeof (" + name + ")) {");
|
||||
|
||||
if (Params == null || Params.Count == 0) {
|
||||
sw.WriteLine ("\t\t\t\tCreateNativeObject (new string [0], new GLib.Value[0]);");
|
||||
sw.WriteLine ("\t\t\t\treturn;");
|
||||
} else {
|
||||
ArrayList names = new ArrayList ();
|
||||
ArrayList values = new ArrayList ();
|
||||
for (int i = 0; i < Params.Count; i++) {
|
||||
Parameter p = Params[i];
|
||||
if (container_type.GetPropertyRecursively (p.StudlyName) != null) {
|
||||
names.Add (p.Name);
|
||||
values.Add (p.Name);
|
||||
} else if (p.PropertyName != String.Empty) {
|
||||
names.Add (p.PropertyName);
|
||||
values.Add (p.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (names.Count == Params.Count) {
|
||||
sw.WriteLine ("\t\t\t\tArrayList vals = new ArrayList();");
|
||||
sw.WriteLine ("\t\t\t\tArrayList names = new ArrayList();");
|
||||
for (int i = 0; i < names.Count; i++) {
|
||||
Parameter p = Params [i];
|
||||
string indent = "\t\t\t\t";
|
||||
if (p.NullOk && p.Generatable is ObjectGen) {
|
||||
sw.WriteLine (indent + "if (" + p.Name + " != null) {");
|
||||
indent += "\t";
|
||||
}
|
||||
sw.WriteLine (indent + "names.Add (\"" + names [i] + "\");");
|
||||
sw.Write (indent + "vals.Add (");
|
||||
|
||||
if (table.IsEnum (p.CType))
|
||||
sw.WriteLine ("new GLib.Value (this, \"" + names[i] + "\", new GLib.EnumWrapper ((int)" + values[i] + ", " + (table.IsEnumFlags (p.CType) ? "true" : "false") + ")));");
|
||||
else
|
||||
sw.WriteLine ("new GLib.Value (" + values[i] + "));");
|
||||
|
||||
if (p.NullOk && p.Generatable is ObjectGen)
|
||||
sw.WriteLine ("\t\t\t\t}");
|
||||
}
|
||||
|
||||
sw.WriteLine ("\t\t\t\tCreateNativeObject ((string[])names.ToArray (typeof (string)), (GLib.Value[])vals.ToArray (typeof (GLib.Value)));");
|
||||
sw.WriteLine ("\t\t\t\treturn;");
|
||||
} else
|
||||
sw.WriteLine ("\t\t\t\tthrow new InvalidOperationException (\"Can't override this constructor.\");");
|
||||
}
|
||||
|
||||
sw.WriteLine ("\t\t\t}");
|
||||
}
|
||||
|
||||
body.Initialize(gen_info, false, false, "");
|
||||
sw.WriteLine("\t\t\t{0} = {1}({2});", container_type.AssignToName, cname, body.GetCallString (false));
|
||||
body.HandleException (sw, "");
|
||||
|
|
|
@ -145,6 +145,12 @@ namespace GtkSharp.Generation {
|
|||
}
|
||||
}
|
||||
|
||||
public string PropertyName {
|
||||
get {
|
||||
return elem.GetAttribute("property_name");
|
||||
}
|
||||
}
|
||||
|
||||
public string PassAs {
|
||||
get {
|
||||
if (elem.HasAttribute ("pass_as"))
|
||||
|
@ -195,7 +201,6 @@ namespace GtkSharp.Generation {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Parameters {
|
||||
|
|
|
@ -162,7 +162,7 @@ namespace GtkSharp.Generation {
|
|||
sw.WriteLine("\t\t\tset {");
|
||||
sw.Write("\t\t\t\tGLib.Value val = ");
|
||||
if (table.IsEnum(c_type)) {
|
||||
sw.WriteLine("new GLib.Value(Handle, " + cname + ", new GLib.EnumWrapper ((int) value, {0}));", table.IsEnumFlags (c_type) ? "true" : "false");
|
||||
sw.WriteLine("new GLib.Value(this, " + cname + ", new GLib.EnumWrapper ((int) value, {0}));", table.IsEnumFlags (c_type) ? "true" : "false");
|
||||
} else if (table.IsBoxed (c_type)) {
|
||||
sw.WriteLine("(GLib.Value) value;");
|
||||
} else if (table.IsOpaque (c_type)) {
|
||||
|
|
|
@ -127,15 +127,9 @@ namespace GLib {
|
|||
|
||||
public static GType RegisterGType (System.Type t)
|
||||
{
|
||||
System.Type parent = t.BaseType;
|
||||
PropertyInfo pi = parent.GetProperty ("GType", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public);
|
||||
if (pi == null) {
|
||||
Console.WriteLine ("null PropertyInfo");
|
||||
return GType.Invalid;
|
||||
}
|
||||
GType parent_gtype = (GType) pi.GetValue (null, null);
|
||||
string name = t.Namespace.Replace(".", "_") + t.Name;
|
||||
GtkSharp.ObjectManager.RegisterType (name, t.Namespace + t.Name, t.Assembly.GetName().Name);
|
||||
GType parent_gtype = LookupGType (t.BaseType);
|
||||
string name = t.FullName.Replace(".", "_");
|
||||
GtkSharp.ObjectManager.RegisterType (name, t.FullName, t.Assembly.GetName().Name);
|
||||
GType gtype = new GType (gtksharp_register_type (name, parent_gtype.Val));
|
||||
ConnectDefaultHandlers (gtype, t);
|
||||
g_types[t] = gtype;
|
||||
|
@ -144,9 +138,15 @@ namespace GLib {
|
|||
|
||||
|
||||
static Hashtable g_types = new Hashtable ();
|
||||
public static GType GetGType (System.Type t)
|
||||
|
||||
public GType LookupGType ()
|
||||
{
|
||||
if (g_types.ContainsKey (t))
|
||||
return LookupGType (GetType ());
|
||||
}
|
||||
|
||||
private static GType LookupGType (System.Type t)
|
||||
{
|
||||
if (g_types.Contains (t))
|
||||
return (GType) g_types [t];
|
||||
|
||||
PropertyInfo pi = t.GetProperty ("GType", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public);
|
||||
|
@ -169,6 +169,14 @@ namespace GLib {
|
|||
Raw = g_object_new (gtype.Val, IntPtr.Zero);
|
||||
}
|
||||
|
||||
[DllImport("glibsharpglue")]
|
||||
static extern IntPtr gtksharp_object_newv (IntPtr gtype, int n_params, string[] names, GLib.Value[] vals);
|
||||
|
||||
protected void CreateNativeObject (string[] names, GLib.Value[] vals)
|
||||
{
|
||||
Raw = gtksharp_object_newv (LookupGType ().Val, names.Length, names, vals);
|
||||
}
|
||||
|
||||
protected virtual IntPtr Raw {
|
||||
get {
|
||||
return _obj;
|
||||
|
|
|
@ -45,12 +45,12 @@ namespace GtkSharp {
|
|||
|
||||
public static void RegisterType (string native_name, string managed_name, string assembly)
|
||||
{
|
||||
types.Add(native_name, managed_name + "," + assembly);
|
||||
RegisterType (native_name, managed_name + "," + assembly);
|
||||
}
|
||||
|
||||
public static void RegisterType (string native_name, string mangled)
|
||||
{
|
||||
types.Add(native_name, mangled);
|
||||
types [native_name] = mangled;
|
||||
}
|
||||
|
||||
static string GetExpected (string cname)
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace GLib {
|
|||
[StructLayout (LayoutKind.Sequential)]
|
||||
public struct Value : IDisposable {
|
||||
|
||||
GType type;
|
||||
IntPtr type;
|
||||
long pad_1;
|
||||
long pad_2;
|
||||
|
||||
|
@ -30,6 +30,9 @@ namespace GLib {
|
|||
[DllImport("glibsharpglue")]
|
||||
static extern IntPtr gtksharp_value_create_from_property(ref GLib.Value val, IntPtr obj, string name);
|
||||
|
||||
[DllImport("glibsharpglue")]
|
||||
static extern IntPtr gtksharp_value_create_from_type_and_property(ref GLib.Value val, IntPtr gtype, string name);
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
g_value_unset (ref this);
|
||||
|
@ -42,14 +45,14 @@ namespace GLib {
|
|||
|
||||
public Value (GLib.GType gtype)
|
||||
{
|
||||
type = GType.Invalid;
|
||||
type = IntPtr.Zero;
|
||||
pad_1 = pad_2 = 0;
|
||||
g_value_init (ref this, gtype.Val);
|
||||
}
|
||||
|
||||
public Value (GLib.Object obj, string prop_name)
|
||||
{
|
||||
type = GType.Invalid;
|
||||
type = IntPtr.Zero;
|
||||
pad_1 = pad_2 = 0;
|
||||
gtksharp_value_create_from_property (ref this, obj.Handle, prop_name);
|
||||
}
|
||||
|
@ -81,7 +84,7 @@ namespace GLib {
|
|||
|
||||
public Value (IntPtr obj, string prop_name, Opaque val)
|
||||
{
|
||||
type = GType.Invalid;
|
||||
type = IntPtr.Zero;
|
||||
pad_1 = pad_2 = 0;
|
||||
gtksharp_value_create_from_property (ref this, obj, prop_name);
|
||||
g_value_set_boxed (ref this, val.Handle);
|
||||
|
@ -155,11 +158,11 @@ namespace GLib {
|
|||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern void g_value_set_char (ref Value val, char data);
|
||||
|
||||
public Value (IntPtr obj, string prop_name, EnumWrapper wrap)
|
||||
public Value (GLib.Object obj, string prop_name, EnumWrapper wrap)
|
||||
{
|
||||
type = GType.Invalid;
|
||||
type = IntPtr.Zero;
|
||||
pad_1 = pad_2 = 0;
|
||||
gtksharp_value_create_from_property (ref this, obj, prop_name);
|
||||
gtksharp_value_create_from_type_and_property (ref this, obj.LookupGType ().Val, prop_name);
|
||||
if (wrap.flags)
|
||||
g_value_set_flags (ref this, (uint) (int) wrap);
|
||||
else
|
||||
|
@ -168,7 +171,7 @@ namespace GLib {
|
|||
|
||||
public Value (object obj)
|
||||
{
|
||||
type = GType.Invalid;
|
||||
type = IntPtr.Zero;
|
||||
pad_1 = pad_2 = 0;
|
||||
|
||||
GType gtype = TypeConverter.LookupType (obj.GetType ());
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
/* Forward declarations */
|
||||
int gtksharp_object_get_ref_count (GObject *obj);
|
||||
GObject *gtksharp_object_newv (GType type, gint cnt, gchar **names, GValue *vals);
|
||||
/* */
|
||||
|
||||
int
|
||||
|
@ -16,3 +17,25 @@ gtksharp_object_get_ref_count (GObject *obj)
|
|||
{
|
||||
return obj->ref_count;
|
||||
}
|
||||
|
||||
GObject *
|
||||
gtksharp_object_newv (GType type, gint cnt, gchar **names, GValue *vals)
|
||||
{
|
||||
int i;
|
||||
GParameter *parms = NULL;
|
||||
GObject *result;
|
||||
|
||||
if (cnt > 0)
|
||||
parms = g_new0 (GParameter, cnt);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
parms[i].name = names[i];
|
||||
parms[i].value = vals[i];
|
||||
}
|
||||
|
||||
result = g_object_newv (type, cnt, parms);
|
||||
|
||||
g_free (parms);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
/* Forward declarations */
|
||||
void gtksharp_value_create_from_property (GValue *value, GObject *obj, const gchar* name);
|
||||
void gtksharp_value_create_from_type_and_property (GValue *value, GType gtype, const gchar* name);
|
||||
GType gtksharp_value_get_value_type (GValue *value);
|
||||
gpointer glibsharp_value_get_boxed (GValue *value);
|
||||
void glibsharp_value_set_boxed (GValue *value, gpointer boxed);
|
||||
|
@ -21,6 +22,13 @@ gtksharp_value_create_from_property (GValue *value, GObject *obj, const gchar* n
|
|||
g_value_init (value, spec->value_type);
|
||||
}
|
||||
|
||||
void
|
||||
gtksharp_value_create_from_type_and_property (GValue *value, GType gtype, const gchar* name)
|
||||
{
|
||||
GParamSpec *spec = g_object_class_find_property (g_type_class_ref (gtype), name);
|
||||
g_value_init (value, spec->value_type);
|
||||
}
|
||||
|
||||
GType
|
||||
gtksharp_value_get_value_type (GValue *value)
|
||||
{
|
||||
|
|
|
@ -14,8 +14,22 @@
|
|||
static extern IntPtr gtk_dialog_new_with_buttons (string title, IntPtr i, int flags, IntPtr dummy);
|
||||
public Dialog (string title, Gtk.Window parent, Gtk.DialogFlags flags) : base(IntPtr.Zero)
|
||||
{
|
||||
if (GetType() != typeof (Dialog))
|
||||
throw new InvalidOperationException ("Can't chain to this constructor from subclasses.");
|
||||
if (GetType() != typeof (Dialog)) {
|
||||
GLib.Value[] vals = new GLib.Value [1];
|
||||
string[] names = new string [1];
|
||||
names [0] = "title";
|
||||
vals [0] = new GLib.Value (title);
|
||||
CreateNativeObject (names, vals);
|
||||
TransientFor = parent;
|
||||
if ((flags & DialogFlags.Modal) > 0)
|
||||
Modal = true;
|
||||
if ((flags & DialogFlags.DestroyWithParent) > 0)
|
||||
DestroyWithParent = true;
|
||||
if ((flags & DialogFlags.NoSeparator) > 0)
|
||||
HasSeparator = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Raw = gtk_dialog_new_with_buttons (title, parent.Handle, (int) flags, IntPtr.Zero);
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
<attr path="/api/namespace/object[@cname='GtkBox']/method[@name='PackEndDefaults']" name="name">PackEnd</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkBox']/method[@name='PackStartDefaults']" name="name">PackStart</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkButton']/constructor[@cname='gtk_button_new_from_stock']" name="preferred">1</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkButton']/constructor[@cname='gtk_button_new_from_stock']/*/*[@name='stock_id']" name="property_name">label</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkButton']/method[@name='Clicked']" name="name">Click</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkButton']/method[@name='Pressed']" name="name">Press</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkButton']/method[@name='Released']" name="name">Release</attr>
|
||||
|
@ -116,6 +117,7 @@
|
|||
<attr path="/api/namespace/object[@cname='GtkItem']/signal[@name='Select']" name="name">Selected</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkItem']/signal[@name='Toggle']" name="name">Toggled</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkLabel']/constructor[@cname='gtk_label_new_with_mnemonic']" name="preferred">1</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkLabel']/constructor[@cname='gtk_label_new_with_mnemonic']/*/*[@name='str']" name="property_name">label</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkLayout']/constructor[@cname='gtk_layout_new']/*/*[@type='GtkAdjustment*']" name="null_ok">1</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkLayout']/method[@name='SetHadjustment']/*/*[@type='GtkAdjustment*']" name="null_ok">1</attr>
|
||||
<attr path="/api/namespace/object[@cname='GtkLayout']/method[@name='SetVadjustment']/*/*[@type='GtkAdjustment*']" name="null_ok">1</attr>
|
||||
|
|
|
@ -31,20 +31,7 @@ namespace GtkSamples {
|
|||
|
||||
public class MyButton : Gtk.Button {
|
||||
|
||||
static GLib.GType gtype = GLib.GType.Invalid;
|
||||
|
||||
public MyButton () : base (GType)
|
||||
{
|
||||
Label = "I'm a subclassed button";
|
||||
}
|
||||
|
||||
public static new GLib.GType GType {
|
||||
get {
|
||||
if (gtype == GLib.GType.Invalid)
|
||||
gtype = RegisterGType (typeof (MyButton));
|
||||
return gtype;
|
||||
}
|
||||
}
|
||||
public MyButton () : base ("I'm a subclassed button") {}
|
||||
|
||||
protected override void OnClicked ()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue