Fixed containers child properties

* Fixed marshaling for reading child properties.
* Enabled child properties for Box, Grid, Stack in api xml.
* Added sample/test for using child properties (ChildPropertiesSection).
This commit is contained in:
dmg 2022-01-16 17:38:30 +03:00 committed by Harry
parent 7ff80bcc8f
commit afc7ab450b
3 changed files with 188 additions and 36 deletions

View file

@ -28,16 +28,12 @@ namespace Gtk
public partial class Container : IEnumerable
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate IntPtr d_gtk_container_class_find_child_property(IntPtr cclass, string property_name);
delegate IntPtr d_gtk_container_class_find_child_property(IntPtr cclass, IntPtr property_name);
static d_gtk_container_class_find_child_property gtk_container_class_find_child_property = FuncLoader.LoadFunction<d_gtk_container_class_find_child_property>(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_container_class_find_child_property"));
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void d_gtk_container_child_get_property(IntPtr container, IntPtr child, string property_name, ref GLib.Value value);
static d_gtk_container_child_get_property gtk_container_child_get_property = FuncLoader.LoadFunction<d_gtk_container_child_get_property>(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_container_child_get_property"));
struct GTypeInstance
{
public IntPtr GTypeClass;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
unsafe delegate void d_gtk_container_child_get_property(IntPtr container, IntPtr child, IntPtr property_name, GLib.Value* value);
static d_gtk_container_child_get_property gtk_container_child_get_property = FuncLoader.LoadFunction<d_gtk_container_child_get_property>(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_container_child_get_property"));
struct GParamSpec
{
@ -48,25 +44,34 @@ namespace Gtk
public GLib.GType value_type;
public GLib.GType owner_type;
IntPtr _nick;
IntPtr _blurb;
IntPtr qdata;
uint ref_count;
uint param_id;
public IntPtr _nick;
public IntPtr _blurb;
public IntPtr qdata;
public uint ref_count;
public uint param_id;
};
public GLib.Value ChildGetProperty(Gtk.Widget child, string property_name)
{
var value = new GLib.Value();
var cclass = ((GTypeInstance)Marshal.PtrToStructure(Handle, typeof(GTypeInstance))).GTypeClass;
var propPtr = gtk_container_class_find_child_property(cclass, property_name);
IntPtr native_property_name = GLib.Marshaller.StringToPtrGStrdup(property_name);
try
{
var cclass = ((GTypeInstance)Marshal.PtrToStructure(Handle, typeof(GTypeInstance))).g_class;
var propPtr = gtk_container_class_find_child_property(cclass, native_property_name);
var prop = (GParamSpec)Marshal.PtrToStructure(propPtr, typeof(GParamSpec));
var value = new GLib.Value();
value.Init(prop.value_type);
gtk_container_child_get_property(Handle, child.Handle, property_name, ref value);
unsafe
{
gtk_container_child_get_property(Handle, child.Handle, native_property_name, &value);
}
return value;
}
finally
{
GLib.Marshaller.Free(native_property_name);
}
}
public IEnumerator GetEnumerator()
{

View file

@ -6114,11 +6114,11 @@
<property name="Spacing" cname="spacing" type="gint" readable="true" writeable="true" />
<property name="Homogeneous" cname="homogeneous" type="gboolean" readable="true" writeable="true" />
<property name="BaselinePosition" cname="baseline-position" type="GtkBaselinePosition" readable="true" writeable="true" />
<property name="Expand" cname="expand" type="gboolean" readable="true" writeable="true" />
<property name="Fill" cname="fill" type="gboolean" readable="true" writeable="true" />
<property name="Padding" cname="padding" type="guint" readable="true" writeable="true" />
<property name="PackType" cname="pack-type" type="GtkPackType" readable="true" writeable="true" />
<property name="Position" cname="position" type="gint" readable="true" writeable="true" />
<childprop name="Expand" cname="expand" type="gboolean" readable="true" writeable="true" />
<childprop name="Fill" cname="fill" type="gboolean" readable="true" writeable="true" />
<childprop name="Padding" cname="padding" type="guint" readable="true" writeable="true" />
<childprop name="PackType" cname="pack-type" type="GtkPackType" readable="true" writeable="true" />
<childprop name="Position" cname="position" type="gint" readable="true" writeable="true" />
<virtual_method name="GtkReserved1" cname="_gtk_reserved1" shared="true" padding="true">
<return-type type="void" />
</virtual_method>
@ -12709,10 +12709,10 @@
<property name="RowHomogeneous" cname="row-homogeneous" type="gboolean" readable="true" writeable="true" />
<property name="ColumnHomogeneous" cname="column-homogeneous" type="gboolean" readable="true" writeable="true" />
<property name="BaselineRow" cname="baseline-row" type="gint" readable="true" writeable="true" />
<property name="LeftAttach" cname="left-attach" type="gint" readable="true" writeable="true" />
<property name="TopAttach" cname="top-attach" type="gint" readable="true" writeable="true" />
<property name="Width" cname="width" type="gint" readable="true" writeable="true" />
<property name="Height" cname="height" type="gint" readable="true" writeable="true" />
<childprop name="LeftAttach" cname="left-attach" type="gint" readable="true" writeable="true" />
<childprop name="TopAttach" cname="top-attach" type="gint" readable="true" writeable="true" />
<childprop name="Width" cname="width" type="gint" readable="true" writeable="true" />
<childprop name="Height" cname="height" type="gint" readable="true" writeable="true" />
<virtual_method name="GtkReserved1" cname="_gtk_reserved1" shared="true" padding="true">
<return-type type="void" />
</virtual_method>
@ -21794,11 +21794,11 @@
<property name="TransitionType" cname="transition-type" type="GtkStackTransitionType" readable="true" writeable="true" />
<property name="TransitionRunning" cname="transition-running" type="gboolean" readable="true" />
<property name="InterpolateSize" cname="interpolate-size" type="gboolean" readable="true" writeable="true" />
<property name="Name" cname="name" type="gchar*" readable="true" writeable="true" />
<property name="Title" cname="title" type="gchar*" readable="true" writeable="true" />
<property name="IconName" cname="icon-name" type="gchar*" readable="true" writeable="true" />
<property name="Position" cname="position" type="gint" readable="true" writeable="true" />
<property name="NeedsAttention" cname="needs-attention" type="gboolean" readable="true" writeable="true" />
<childprop name="Name" cname="name" type="gchar*" readable="true" writeable="true" />
<childprop name="Title" cname="title" type="gchar*" readable="true" writeable="true" />
<childprop name="IconName" cname="icon-name" type="gchar*" readable="true" writeable="true" />
<childprop name="Position" cname="position" type="gint" readable="true" writeable="true" />
<childprop name="NeedsAttention" cname="needs-attention" type="gboolean" readable="true" writeable="true" />
<method name="AddNamed" cname="gtk_stack_add_named">
<return-type type="void" />
<parameters>

View file

@ -0,0 +1,147 @@
using System;
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(ContainerChildProperties), Category = Category.Miscellaneous)]
class ContainerChildPropertiesSection : Box
{
public ContainerChildPropertiesSection() : base(Orientation.Vertical, 3)
{
ContainerChildProperties.CreateBoxProperties(this);
ContainerChildProperties.CreateGridProperties(this);
ContainerChildProperties.CreateStackProperties(this);
}
}
static class ContainerChildProperties
{
public static void CreateBoxProperties(Box parent)
{
var title = new Label { Text = "Box child properties" };
parent.PackStart(title, false, true, 0);
var box1 = new Box(Orientation.Horizontal, 3);
var btn1 = new Button() { Label = "Expand" };
btn1.Clicked += delegate
{
var child = (Box.BoxChild)box1[btn1];
child.Expand = !child.Expand;
ApplicationOutput.WriteLine(child, "Expand changed to " + child.Expand);
};
box1.PackStart(btn1, true, true, 0);
parent.PackStart(box1, false, true, 0);
var box2 = new Box(Orientation.Horizontal, 3);
var btn2 = new Button() { Label = "PackType" };
btn2.Clicked += delegate
{
var child = (Box.BoxChild)box2[btn2];
child.PackType = child.PackType == PackType.Start ? PackType.End : PackType.Start;
ApplicationOutput.WriteLine(child, "PackType changed to " + child.PackType);
};
box2.PackStart(btn2, false, false, 0);
parent.PackStart(box2, false, true, 0);
var box3 = new Box(Orientation.Horizontal, 3);
var btn3 = new Button() { Label = "Position" };
btn3.Clicked += delegate
{
var child = (Box.BoxChild)box3[btn3];
child.Position = child.Position == 0 ? 1 : 0;
ApplicationOutput.WriteLine(child, "Position changed to " + child.Position);
};
box3.PackStart(btn3, false, false, 0);
box3.PackStart(new Label { Text = "Neighbor" }, false, false, 0);
parent.PackStart(box3, false, true, 0);
}
public static void CreateGridProperties(Box parent)
{
var title = new Label { Text = "Grid child properties" };
parent.PackStart(title, false, true, 0);
var grid = new Grid { ColumnSpacing = 3, RowSpacing = 3 };
var btn1 = new Button { Label = "LeftAttach" };
var lbl = new Label { Text = "Neighbor" };
btn1.Clicked += delegate
{
var child1 = (Grid.GridChild)grid[btn1];
var child2 = (Grid.GridChild)grid[lbl];
if (child1.LeftAttach == 0)
{
child1.LeftAttach = 1;
child2.LeftAttach = 0;
}
else
{
child1.LeftAttach = 0;
child2.LeftAttach = 1;
}
ApplicationOutput.WriteLine(child1, "Child 1 LeftAttach changed to " + child1.LeftAttach);
ApplicationOutput.WriteLine(child1, "Child 2 LeftAttach changed to " + child2.LeftAttach);
};
var btn2 = new Button { Label = "Width (column span)", Hexpand = true };
btn2.Clicked += delegate
{
var child = (Grid.GridChild)grid[btn2];
child.Width = child.Width == 1 ? 2 : 1;
ApplicationOutput.WriteLine(child, "Width changed to " + child.Width);
};
grid.Attach(btn1, 0, 0, 1, 1);
grid.Attach(lbl, 1, 0, 1, 1);
grid.Attach(btn2, 0, 1, 1, 1);
parent.PackStart(grid, false, true, 0);
}
public static void CreateStackProperties(Box parent)
{
var title = new Label { Text = "Stack child properties" };
parent.PackStart(title, false, true, 0);
var stack = new Stack();
var box = new Box(Orientation.Horizontal, 3);
var btn1 = new Button { Label = "Title" };
btn1.Clicked += delegate
{
var child = (Stack.StackChild)stack[box];
child.Title = child.Title == "Page 1" ? "Page 1 abc" : "Page 1";
ApplicationOutput.WriteLine(child, "Title changed to " + child.Title);
};
box.PackStart(btn1, false, false, 0);
var btn2 = new Button { Label = "Position" };
var lbl = new Label { Text = "Page 2 label", Halign = Align.Start };
btn2.Clicked += delegate
{
var child1 = (Stack.StackChild)stack[box];
var child2 = (Stack.StackChild)stack[lbl];
if (child1.Position == 0)
{
child1.Position = 1;
child2.Position = 0;
}
else
{
child1.Position = 0;
child2.Position = 1;
}
ApplicationOutput.WriteLine(child1, "Child 1 Position changed to " + child1.Position);
ApplicationOutput.WriteLine(child1, "Child 2 Position changed to " + child2.Position);
};
box.PackStart(btn2, false, false, 0);
stack.AddTitled(box, "1", "Page 1");
stack.AddTitled(lbl, "2", "Page 2");
var switcher = new StackSwitcher();
switcher.Stack = stack;
parent.PackStart(switcher, false, true, 0);
parent.PackStart(stack, false, true, 0);
}
}
}