* parser/gapi2xml.pl (parseInitFunc, addPropElem): handle

GtkContainer child properties

	* generator/Property.cs:
	* generator/ChildProperty.cs: make Property subclassable and add a
	"ChildProperty" subclass.

	* generator/Makefile.am (sources): add ChildProperty.cs

	* generator/ClassBase.cs: handle "childprop" nodes by creating
	ChildProperty objects.

	* glib/Value.cs (explicit operator EnumWrapper): use
	g_value_get_flags() rather than g_value_get_enum() when
	appropriate.

	* glib/glue/value.c (glibsharp_value_holds_flags): glue for that

	* gtk/gtk-api.raw: regen to pick up child properties

	* gtk/Gtk.metadata:
	* gtk/Container.custom: hide the auto-generated
	Gtk.Container.ChildGetProperty and implement a nicer one by hand.

	* gtk/glue/container.c (gtksharp_container_child_get_property):
	utility function to set up an appropriate GValue for us

svn path=/trunk/gtk-sharp/; revision=35702
This commit is contained in:
Dan Winship 2004-11-05 16:47:15 +00:00
parent 2a3d6563db
commit df41dcc177
12 changed files with 229 additions and 27 deletions

View file

@ -1,3 +1,32 @@
2004-11-05 Dan Winship <danw@novell.com>
* parser/gapi2xml.pl (parseInitFunc, addPropElem): handle
GtkContainer child properties
* generator/Property.cs:
* generator/ChildProperty.cs: make Property subclassable and add a
"ChildProperty" subclass.
* generator/Makefile.am (sources): add ChildProperty.cs
* generator/ClassBase.cs: handle "childprop" nodes by creating
ChildProperty objects.
* glib/Value.cs (explicit operator EnumWrapper): use
g_value_get_flags() rather than g_value_get_enum() when
appropriate.
* glib/glue/value.c (glibsharp_value_holds_flags): glue for that
* gtk/gtk-api.raw: regen to pick up child properties
* gtk/Gtk.metadata:
* gtk/Container.custom: hide the auto-generated
Gtk.Container.ChildGetProperty and implement a nicer one by hand.
* gtk/glue/container.c (gtksharp_container_child_get_property):
utility function to set up an appropriate GValue for us
2004-11-05 Tambet Ingo <tambet@ximian.com>
* generator/OpaqueGen.cs: Add optional "parent" attribute to Opaque

View file

@ -0,0 +1,57 @@
// GtkSharp.Generation.ChildProperty.cs - GtkContainer child properties
//
// Copyright (c) 2004 Novell, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
namespace GtkSharp.Generation {
using System;
using System.Collections;
using System.IO;
using System.Xml;
public class ChildProperty : Property {
public ChildProperty (XmlElement elem, ClassBase container_type) : base (elem, container_type) {}
protected override string PropertyHeader (ref string indent, string modifiers, string cs_type, string name) {
return "";
}
protected override string GetterHeader (string modifiers, string cs_type, string name) {
return "public " + modifiers + cs_type + " Get" + name + " (Widget w)";
}
protected override string RawGetter (string cname) {
return "ChildGetProperty (w, " + cname + ")";
}
protected override string SetterHeader (string modifiers, string cs_type, string name) {
return "public " + modifiers + "void Set" + name + " (Widget w, " + cs_type + " value)";
}
protected override string RawSetter (string cname) {
return "ChildSetProperty(w, " + cname + ", val)";
}
protected override string PropertyFooter (string indent) {
return "";
}
}
}

View file

@ -93,6 +93,13 @@ namespace GtkSharp.Generation {
props.Add (name, new Property (member, this));
break;
case "childprop":
name = member.GetAttribute("name");
while (props.ContainsKey(name))
name += "mangled";
props.Add (name, new ChildProperty (member, this));
break;
case "signal":
name = member.GetAttribute("name");
while (sigs.ContainsKey(name))
@ -131,6 +138,7 @@ namespace GtkSharp.Generation {
switch (name) {
case "method":
case "property":
case "childprop":
case "signal":
case "implements":
case "constructor":

View file

@ -11,6 +11,7 @@ sources = \
BoxedGen.cs \
ByRefGen.cs \
CallbackGen.cs \
ChildProperty.cs \
ClassBase.cs \
ClassGen.cs \
CodeGenerator.cs \

View file

@ -29,8 +29,8 @@ namespace GtkSharp.Generation {
public class Property {
private XmlElement elem;
private ClassBase container_type;
protected XmlElement elem;
protected ClassBase container_type;
public string Name {
get {
@ -66,6 +66,34 @@ namespace GtkSharp.Generation {
return true;
}
protected virtual string PropertyHeader (ref string indent, string modifiers, string cs_type, string name) {
string header;
header = indent + "public " + modifiers + cs_type + " " + name + " {\n";
indent += "\t";
return header;
}
protected virtual string GetterHeader (string modifiers, string cs_type, string name) {
return "get";
}
protected virtual string RawGetter (string cname) {
return "GetProperty (" + cname + ")";
}
protected virtual string SetterHeader (string modifiers, string cs_type, string name) {
return "set";
}
protected virtual string RawSetter (string cname) {
return "SetProperty(" + cname + ", val)";
}
protected virtual string PropertyFooter (string indent) {
return indent.Substring (1) + "}\n";
}
public void Generate (GenerationInfo gen_info)
{
SymbolTable table = SymbolTable.Table;
@ -141,23 +169,24 @@ namespace GtkSharp.Generation {
sw.WriteLine();
sw.WriteLine("\t\tpublic " + modifiers + cs_type + " " + name + " {");
string indent = "\t\t";
sw.Write(PropertyHeader (ref indent, modifiers, cs_type, name));
if (has_getter) {
sw.Write("\t\t\tget ");
sw.Write(indent + GetterHeader (modifiers, cs_type, name));
getter.GenerateBody(gen_info, "\t");
sw.WriteLine();
} else if (elem.HasAttribute("readable")) {
sw.WriteLine("\t\t\tget {");
sw.WriteLine("\t\t\t\tGLib.Value val = GetProperty (" + cname + ");");
sw.WriteLine(indent + GetterHeader (modifiers, cs_type, name) + " {");
sw.WriteLine(indent + "\tGLib.Value val = " + RawGetter (cname) + ";");
if (table.IsObject (c_type)) {
sw.WriteLine("\t\t\t\tSystem.IntPtr raw_ret = (System.IntPtr) {0} val;", v_type);
sw.WriteLine("\t\t\t\t" + cs_type + " ret = " + table.FromNativeReturn(c_type, "raw_ret") + ";");
sw.WriteLine(indent + "\tSystem.IntPtr raw_ret = (System.IntPtr) {0} val;", v_type);
sw.WriteLine(indent + "\t" + cs_type + " ret = " + table.FromNativeReturn(c_type, "raw_ret") + ";");
if (!table.IsBoxed (c_type) && !table.IsObject (c_type))
sw.WriteLine("\t\t\t\tif (ret == null) ret = new " + cs_type + "(raw_ret);");
sw.WriteLine(indent + "\tif (ret == null) ret = new " + cs_type + "(raw_ret);");
} else if (table.IsOpaque (c_type) || table.IsBoxed (c_type)) {
sw.WriteLine("\t\t\t\t" + cs_type + " ret = (" + cs_type + ") val;");
sw.WriteLine(indent + "\t" + cs_type + " ret = (" + cs_type + ") val;");
} else {
sw.Write("\t\t\t\t" + cs_type + " ret = ");
sw.Write(indent + "\t" + cs_type + " ret = ");
sw.Write ("(" + cs_type + ") ");
if (v_type != "") {
sw.Write(v_type + " ");
@ -165,18 +194,18 @@ namespace GtkSharp.Generation {
sw.WriteLine("val;");
}
sw.WriteLine("\t\t\t\tval.Dispose ();");
sw.WriteLine("\t\t\t\treturn ret;");
sw.WriteLine("\t\t\t}");
sw.WriteLine(indent + "\tval.Dispose ();");
sw.WriteLine(indent + "\treturn ret;");
sw.WriteLine(indent + "}");
}
if (has_setter) {
sw.Write("\t\t\tset ");
sw.Write(indent + SetterHeader (modifiers, cs_type, name));
setter.GenerateBody(gen_info, "\t");
sw.WriteLine();
} else if (elem.HasAttribute("writeable") && !elem.HasAttribute("construct-only")) {
sw.WriteLine("\t\t\tset {");
sw.Write("\t\t\t\tGLib.Value val = ");
sw.WriteLine(indent + SetterHeader (modifiers, cs_type, name) + " {");
sw.Write(indent + "\tGLib.Value val = ");
if (table.IsEnum(c_type)) {
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)) {
@ -190,12 +219,12 @@ namespace GtkSharp.Generation {
}
sw.WriteLine("value);");
}
sw.WriteLine("\t\t\t\tSetProperty(" + cname + ", val);");
sw.WriteLine("\t\t\t\tval.Dispose ();");
sw.WriteLine("\t\t\t}");
sw.WriteLine(indent + "\t" + RawSetter (cname) + ";");
sw.WriteLine(indent + "\tval.Dispose ();");
sw.WriteLine(indent + "}");
}
sw.WriteLine("\t\t}");
sw.Write(PropertyFooter (indent));
sw.WriteLine();
Statistics.PropCount++;

View file

@ -290,11 +290,15 @@ namespace GLib {
static extern int g_value_get_enum (ref Value val);
[DllImport("libgobject-2.0-0.dll")]
static extern uint g_value_get_flags (ref Value val);
[DllImport("glibsharpglue-2.0")]
static extern bool glibsharp_value_holds_flags (ref Value val);
public static explicit operator EnumWrapper (Value val)
{
// FIXME: handle flags
return new EnumWrapper (g_value_get_enum (ref val), false);
if (glibsharp_value_holds_flags (ref val))
return new EnumWrapper ((int)g_value_get_flags (ref val), true);
else
return new EnumWrapper (g_value_get_enum (ref val), false);
}
[DllImport("glibsharpglue-2.0")]

View file

@ -25,6 +25,7 @@
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);
gboolean glibsharp_value_holds_flags (GValue *value);
/* */
void
@ -49,3 +50,8 @@ gtksharp_value_get_value_type (GValue *value)
return G_VALUE_TYPE (value);
}
gboolean
glibsharp_value_holds_flags (GValue *value)
{
return G_VALUE_HOLDS_FLAGS (value);
}

View file

@ -19,6 +19,16 @@
// Boston, MA 02111-1307, USA.
[DllImport("gtksharpglue-2.0")]
static extern void gtksharp_container_child_get_property (IntPtr container, IntPtr child, string property, ref GLib.Value value);
public GLib.Value ChildGetProperty (Gtk.Widget child, string property_name) {
GLib.Value value = new GLib.Value ();
gtksharp_container_child_get_property (Handle, child.Handle, property_name, ref value);
return value;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern IntPtr gtk_container_get_children (IntPtr raw);

View file

@ -127,6 +127,7 @@
<attr path="/api/namespace/object[@cname='GtkColorSelection']/method[@name='SetPreviousColor']" name="hidden">1</attr>
<attr path="/api/namespace/object[@cname='GtkCombo']/method[@name='SetPopdownStrings']" name="hidden">1</attr>
<attr path="/api/namespace/object[@cname='GtkComboBox']/method[@cname='gtk_combo_box_get_active_iter']/*/*[@type='GtkTreeIter*']" name="pass_as">out</attr>
<attr path="/api/namespace/object[@cname='GtkContainer']/method[@name='ChildGetProperty']" name="hidden">1</attr>
<attr path="/api/namespace/object[@cname='GtkContainer']/method[@name='GetChildren']" name="hidden">1</attr>
<attr path="/api/namespace/object[@cname='GtkContainer']/method[@name='GetFocusChain']" name="hidden">1</attr>
<attr path="/api/namespace/object[@cname='GtkContainer']/method[@name='SetFocusChain']" name="hidden">1</attr>

View file

@ -64,6 +64,8 @@ gtksharp_container_base_child_type (GtkContainer *container)
return slot;
}
void gtksharp_container_override_child_type (GType gtype, gpointer cb);
void
gtksharp_container_override_child_type (GType gtype, gpointer cb)
{
@ -72,3 +74,16 @@ gtksharp_container_override_child_type (GType gtype, gpointer cb)
klass = g_type_class_ref (gtype);
((GtkContainerClass *) klass)->child_type = cb;
}
void gtksharp_container_child_get_property (GtkContainer *container, GtkWidget *child,
const gchar* property, GValue *value);
void
gtksharp_container_child_get_property (GtkContainer *container, GtkWidget *child,
const gchar* property, GValue *value)
{
GParamSpec *spec = gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (container), property);
g_value_init (value, spec->value_type);
gtk_container_child_get_property (container, child, property, value);
}

View file

@ -2669,6 +2669,11 @@
<field cname="homogeneous" bits="1" type="guint"/>
<property name="Spacing" cname="spacing" type="gint" readable="true" writeable="true"/>
<property name="Homogeneous" cname="homogeneous" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildExpand" cname="child_expand" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildFill" cname="child_fill" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildPadding" cname="child_padding" type="guint" readable="true" writeable="true"/>
<childprop name="ChildPackType" cname="child_pack_type" type="GtkPackType" readable="true" writeable="true"/>
<childprop name="ChildPosition" cname="child_position" type="gint" readable="true" writeable="true"/>
<method name="GetHomogeneous" cname="gtk_box_get_homogeneous">
<return-type type="gboolean"/>
</method>
@ -2908,6 +2913,7 @@
<field cname="child_ipad_y" type="gint"/>
<field cname="layout_style" type="GtkButtonBoxStyle"/>
<property name="LayoutStyle" cname="layout_style" type="GtkButtonBoxStyle" readable="true" writeable="true"/>
<childprop name="ChildSecondary" cname="child_secondary" type="gboolean" readable="true" writeable="true"/>
<method name="GetChildIpadding" cname="gtk_button_box_get_child_ipadding" deprecated="1">
<return-type type="void"/>
<parameters>
@ -5106,6 +5112,8 @@
</object>
<object name="Fixed" cname="GtkFixed" parent="GtkContainer">
<field cname="children" type="GList*"/>
<childprop name="ChildX" cname="child_x" type="gint" readable="true" writeable="true"/>
<childprop name="ChildY" cname="child_y" type="gint" readable="true" writeable="true"/>
<method name="GetHasWindow" cname="gtk_fixed_get_has_window">
<return-type type="gboolean"/>
</method>
@ -6572,6 +6580,8 @@
<field cname="scroll_x" type="gint"/>
<field cname="scroll_y" type="gint"/>
<field cname="freeze_count" type="guint"/>
<childprop name="ChildX" cname="child_x" type="gint" readable="true" writeable="true"/>
<childprop name="ChildY" cname="child_y" type="gint" readable="true" writeable="true"/>
<property name="Hadjustment" cname="hadjustment" type="GtkAdjustment" readable="true" writeable="true"/>
<property name="Vadjustment" cname="vadjustment" type="GtkAdjustment" readable="true" writeable="true"/>
<property name="Width" cname="width" type="guint" readable="true" writeable="true"/>
@ -6818,6 +6828,10 @@
<field cname="upper_arrow_prelight" bits="1" type="guint"/>
<field cname="lower_arrow_prelight" bits="1" type="guint"/>
<property name="TearoffTitle" cname="tearoff-title" type="gchar*" readable="true" writeable="true"/>
<childprop name="ChildLeftAttach" cname="child_left_attach" type="gint" readable="true" writeable="true"/>
<childprop name="ChildRightAttach" cname="child_right_attach" type="gint" readable="true" writeable="true"/>
<childprop name="ChildTopAttach" cname="child_top_attach" type="gint" readable="true" writeable="true"/>
<childprop name="ChildBottomAttach" cname="child_bottom_attach" type="gint" readable="true" writeable="true"/>
<method name="Attach" cname="gtk_menu_attach">
<return-type type="void"/>
<parameters>
@ -7253,6 +7267,12 @@
<property name="Scrollable" cname="scrollable" type="gboolean" readable="true" writeable="true"/>
<property name="EnablePopup" cname="enable_popup" type="gboolean" readable="true" writeable="true"/>
<property name="Homogeneous" cname="homogeneous" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildTabLabel" cname="child_tab_label" type="gchar*" readable="true" writeable="true"/>
<childprop name="ChildMenuLabel" cname="child_menu_label" type="gchar*" readable="true" writeable="true"/>
<childprop name="ChildPosition" cname="child_position" type="gint" readable="true" writeable="true"/>
<childprop name="ChildTabExpand" cname="child_tab_expand" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildTabFill" cname="child_tab_fill" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildTabPack" cname="child_tab_pack" type="GtkPackType" readable="true" writeable="true"/>
<signal name="SwitchPage" cname="switch_page" when="LAST">
<return-type type="void"/>
<parameters>
@ -7733,6 +7753,8 @@
<property name="PositionSet" cname="position_set" type="gboolean" readable="true" writeable="true"/>
<property name="MinPosition" cname="min_position" type="gint" readable="true"/>
<property name="MaxPosition" cname="max_position" type="gint" readable="true"/>
<childprop name="ChildResize" cname="child_resize" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildShrink" cname="child_shrink" type="gboolean" readable="true" writeable="true"/>
<signal name="CycleChildFocus" cname="cycle_child_focus" when="LAST">
<return-type type="gboolean"/>
<parameters>
@ -9292,6 +9314,14 @@
<property name="RowSpacing" cname="row_spacing" type="guint" readable="true" writeable="true"/>
<property name="ColumnSpacing" cname="column_spacing" type="guint" readable="true" writeable="true"/>
<property name="Homogeneous" cname="homogeneous" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildLeftAttach" cname="child_left_attach" type="guint" readable="true" writeable="true"/>
<childprop name="ChildRightAttach" cname="child_right_attach" type="guint" readable="true" writeable="true"/>
<childprop name="ChildTopAttach" cname="child_top_attach" type="guint" readable="true" writeable="true"/>
<childprop name="ChildBottomAttach" cname="child_bottom_attach" type="guint" readable="true" writeable="true"/>
<childprop name="ChildXOptions" cname="child_x_options" type="GtkAttachOptions" readable="true" writeable="true"/>
<childprop name="ChildYOptions" cname="child_y_options" type="GtkAttachOptions" readable="true" writeable="true"/>
<childprop name="ChildXPadding" cname="child_x_padding" type="guint" readable="true" writeable="true"/>
<childprop name="ChildYPadding" cname="child_y_padding" type="guint" readable="true" writeable="true"/>
<method name="Attach" cname="gtk_table_attach">
<return-type type="void"/>
<parameters>
@ -10710,6 +10740,8 @@
<property name="Orientation" cname="orientation" type="GtkOrientation" readable="true" writeable="true"/>
<property name="ToolbarStyle" cname="toolbar_style" type="GtkToolbarStyle" readable="true" writeable="true"/>
<property name="ShowArrow" cname="show_arrow" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildExpand" cname="child_expand" type="gboolean" readable="true" writeable="true"/>
<childprop name="ChildHomogeneous" cname="child_homogeneous" type="gboolean" readable="true" writeable="true"/>
<method name="AppendElement" cname="gtk_toolbar_append_element" deprecated="1">
<return-type type="GtkWidget*"/>
<parameters>

View file

@ -465,7 +465,7 @@ if ($ARGV[1]) {
$scnt = keys(%sdefs); $fcnt = keys(%fdefs); $tcnt = keys(%types);
print "structs: $scnt enums: $ecnt callbacks: $cbcnt\n";
print "funcs: $fcnt types: $tcnt classes: $classcnt\n";
print "props: $propcnt signals: $sigcnt\n\n";
print "props: $propcnt childprops: $childpropcnt signals: $sigcnt\n\n";
sub addFieldElems
{
@ -776,7 +776,7 @@ sub addReturnElem
sub addPropElem
{
my ($spec, $node) = @_;
my ($spec, $node, $is_child) = @_;
my ($name, $mode, $docs);
$spec =~ /g_param_spec_(\w+)\s*\((.*)\s*\)\s*\)/;
my $type = $1;
@ -788,6 +788,9 @@ sub addPropElem
} else {
$name =~ s/\s*\"//g;
}
if ($is_child) {
$name = "child_$name";
}
$mode = $params[$#params];
@ -807,7 +810,7 @@ sub addPropElem
$type = StudlyCaps(lc($type));
}
$prop_elem = $doc->createElement('property');
$prop_elem = $doc->createElement($is_child ? "childprop" : "property");
$node->appendChild($prop_elem);
$prop_elem->setAttribute('name', StudlyCaps($name));
$prop_elem->setAttribute('cname', $name);
@ -952,8 +955,15 @@ sub parseInitFunc
do {
$prop .= $init_lines[++$linenum];
} until ($init_lines[$linenum] =~ /\)\s*;/);
addPropElem ($prop, $obj_el);
addPropElem ($prop, $obj_el, 0);
$propcnt++;
} elsif ($line =~ /gtk_container_class_install_child_property/) {
my $prop = $line;
do {
$prop .= $init_lines[++$linenum];
} until ($init_lines[$linenum] =~ /\)\s*;/);
addPropElem ($prop, $obj_el, 1);
$childpropcnt++;
} elsif ($line =~ /\bg.*_signal_new/) {
my $sig = $line;
do {