2004-12-23 Mike Kestner <mkestner@novell.com>

* glib/ClassInitializerAttribute.cs : new attr for identifying type.
	inialization methods to be run by RegisterGType.
	* glib/Makefile.am : add file.
	* glib/Object.cs : add private method to invoke ClassInitializers.
	* gtk/glue/widget.c : some new glue for binding registration.
	* gtk/BindingAttribute.cs : new attr for registering key bindings.
	* gtk/Makefile.am : add file.
	* gtk/Widget.custom : add ClassInitializer method to scan types
	for [Binding] and register key bindings.

svn path=/trunk/gtk-sharp/; revision=38074
This commit is contained in:
Mike Kestner 2004-12-23 22:59:59 +00:00
parent 7cc3f74b9c
commit adef5f7bbd
12 changed files with 369 additions and 4 deletions

View file

@ -1,3 +1,15 @@
2004-12-23 Mike Kestner <mkestner@novell.com>
* glib/ClassInitializerAttribute.cs : new attr for identifying type.
inialization methods to be run by RegisterGType.
* glib/Makefile.am : add file.
* glib/Object.cs : add private method to invoke ClassInitializers.
* gtk/glue/widget.c : some new glue for binding registration.
* gtk/BindingAttribute.cs : new attr for registering key bindings.
* gtk/Makefile.am : add file.
* gtk/Widget.custom : add ClassInitializer method to scan types
for [Binding] and register key bindings.
2004-12-22 Dan Winship <danw@novell.com> 2004-12-22 Dan Winship <danw@novell.com>
* generator/Signal.cs: fix some WriteLine()s that should have been * generator/Signal.cs: fix some WriteLine()s that should have been

View file

@ -1,3 +1,8 @@
2004-12-23 Mike Kestner <mkestner@novell.com>
* en/GLib/ClassInitializerAttribute.xml : doc new attr.
* en/Gtk/BindingAttribute.xml : doc new attr.
2004-12-22 Dan Winship <danw@novell.com> 2004-12-22 Dan Winship <danw@novell.com>
* en/Gtk/Decorated.xml: * en/Gtk/Decorated.xml:

View file

@ -0,0 +1,33 @@
<Type Name="ClassInitializerAttribute" FullName="GLib.ClassInitializerAttribute">
<TypeSignature Language="C#" Value="public sealed class ClassInitializerAttribute : System.Attribute" Maintainer="auto" />
<AssemblyInfo>
<AssemblyName>glib-sharp</AssemblyName>
<AssemblyPublicKey>[00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 71 EB 6C 55 75 52 9C BF 72 44 F7 A6 EA 05 62 84 F9 EA E0 3B CF F2 CC 13 2C 9C 49 0A B3 09 EA B0 B5 6B CE 44 9D F5 03 D9 C0 A8 1E 52 05 85 CD BE 70 E2 FB 90 43 4B AC 04 FA 62 22 A8 00 98 B7 A1 A7 B3 AF 99 1A 41 23 24 BB 43 25 F6 B8 65 BB 64 EB F6 D1 C2 06 D5 73 2D DF BC 70 A7 38 9E E5 3E 0C 24 6E 32 79 74 1A D0 05 03 E4 98 42 E1 9B F3 7B 19 8B 40 21 26 CB 36 89 C2 EA 64 96 A4 7C B4]</AssemblyPublicKey>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyCulture>neutral</AssemblyCulture>
<Attributes />
</AssemblyInfo>
<ThreadSafetyStatement>Gtk# is thread aware, but not thread safe; See the <link location="node:gtk-sharp/programming/threads">Gtk# Thread Programming</link> for details.</ThreadSafetyStatement>
<Docs>
<summary>Identifies a class initialization method to call when GTypes are registered.</summary>
<remarks />
</Docs>
<Base>
<BaseTypeName>System.Attribute</BaseTypeName>
</Base>
<Interfaces />
<Attributes />
<Members>
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public ClassInitializerAttribute ();" />
<MemberType>Constructor</MemberType>
<ReturnValue />
<Parameters />
<Docs>
<summary>Constructs an attribute.</summary>
<returns>a <see cref="T:GLib.ClassInitializerAttribute" /></returns>
<remarks />
</Docs>
</Member>
</Members>
</Type>

View file

@ -0,0 +1,116 @@
<Type Name="BindingAttribute" FullName="Gtk.BindingAttribute">
<TypeSignature Language="C#" Value="public sealed class BindingAttribute : System.Attribute" Maintainer="auto" />
<AssemblyInfo>
<AssemblyName>gtk-sharp</AssemblyName>
<AssemblyPublicKey>[00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 71 EB 6C 55 75 52 9C BF 72 44 F7 A6 EA 05 62 84 F9 EA E0 3B CF F2 CC 13 2C 9C 49 0A B3 09 EA B0 B5 6B CE 44 9D F5 03 D9 C0 A8 1E 52 05 85 CD BE 70 E2 FB 90 43 4B AC 04 FA 62 22 A8 00 98 B7 A1 A7 B3 AF 99 1A 41 23 24 BB 43 25 F6 B8 65 BB 64 EB F6 D1 C2 06 D5 73 2D DF BC 70 A7 38 9E E5 3E 0C 24 6E 32 79 74 1A D0 05 03 E4 98 42 E1 9B F3 7B 19 8B 40 21 26 CB 36 89 C2 EA 64 96 A4 7C B4]</AssemblyPublicKey>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyCulture>neutral</AssemblyCulture>
<Attributes />
</AssemblyInfo>
<ThreadSafetyStatement>Gtk# is thread aware, but not thread safe; See the <link location="node:gtk-sharp/programming/threads">Gtk# Thread Programming</link> for details.</ThreadSafetyStatement>
<Docs>
<summary>Registers a key binding for a class.</summary>
<remarks />
</Docs>
<Base>
<BaseTypeName>System.Attribute</BaseTypeName>
</Base>
<Interfaces />
<Attributes>
<Attribute>
<AttributeName>System.AttributeUsageAttribute</AttributeName>
</Attribute>
</Attributes>
<Members>
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public BindingAttribute (Gdk.Key key, string handler, object [] parms);" />
<MemberType>Constructor</MemberType>
<ReturnValue />
<Parameters>
<Parameter Name="key" Type="Gdk.Key" />
<Parameter Name="handler" Type="System.String" />
<Parameter Name="parms" Type="System.Object[]" />
</Parameters>
<Docs>
<summary>Constructs a Binding attribute with no key modifier.</summary>
<param name="key">a key value</param>
<param name="handler">name of the instance method to call.</param>
<param name="parms">an array containing the parameters to pass to the handler.</param>
<returns>a <see cref="T:Gtk.BindingAttribute" /></returns>
<remarks />
</Docs>
</Member>
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public BindingAttribute (Gdk.Key key, Gdk.ModifierType mod, string handler, object [] parms);" />
<MemberType>Constructor</MemberType>
<ReturnValue />
<Parameters>
<Parameter Name="key" Type="Gdk.Key" />
<Parameter Name="mod" Type="Gdk.ModifierType" />
<Parameter Name="handler" Type="System.String" />
<Parameter Name="parms" Type="System.Object[]" />
</Parameters>
<Docs>
<summary>Constructs a Binding attribute for a key and modifier.</summary>
<param name="key">a key value</param>
<param name="mod">a modifier type, like ctrl or shift</param>
<param name="handler">name of the instance method to call.</param>
<param name="parms">an array containing the parameters to pass to the handler.</param>
<returns>a <see cref="T:Gtk.BindingAttribute" /></returns>
<remarks />
</Docs>
</Member>
<Member MemberName="Key">
<MemberSignature Language="C#" Value="public Gdk.Key Key { get; };" />
<MemberType>Property</MemberType>
<ReturnValue>
<ReturnType>Gdk.Key</ReturnType>
</ReturnValue>
<Parameters />
<Docs>
<summary>The key value</summary>
<returns>a <see cref="T:Gdk.Key" /></returns>
<remarks />
</Docs>
</Member>
<Member MemberName="Mod">
<MemberSignature Language="C#" Value="public Gdk.ModifierType Mod { get; };" />
<MemberType>Property</MemberType>
<ReturnValue>
<ReturnType>Gdk.ModifierType</ReturnType>
</ReturnValue>
<Parameters />
<Docs>
<summary>The key modifier, such as ctrl or shift.</summary>
<returns>a <see cref="T:Gdk.ModifierType" /></returns>
<remarks />
</Docs>
</Member>
<Member MemberName="Handler">
<MemberSignature Language="C#" Value="public string Handler { get; };" />
<MemberType>Property</MemberType>
<ReturnValue>
<ReturnType>System.String</ReturnType>
</ReturnValue>
<Parameters />
<Docs>
<summary>The name of the instance method to call on activation.</summary>
<returns>a <see cref="T:System.String" /></returns>
<remarks />
</Docs>
</Member>
<Member MemberName="Parms">
<MemberSignature Language="C#" Value="public object [] Parms { get; };" />
<MemberType>Property</MemberType>
<ReturnValue>
<ReturnType>System.Object[]</ReturnType>
</ReturnValue>
<Parameters />
<Docs>
<summary>An Array of parameters to pass to the Handler.</summary>
<returns>a <see cref="T:System.Object[]" /></returns>
<remarks />
</Docs>
</Member>
</Members>
</Type>

View file

@ -0,0 +1,30 @@
// ClassInitializerAttribute.cs
//
// Author: Mike Kestner <mkestner@novell.com>
//
// 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 Lesser 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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 GLib {
using System;
public sealed class ClassInitializerAttribute : Attribute
{
public ClassInitializerAttribute () {}
}
}

View file

@ -12,6 +12,7 @@ references =
sources = \ sources = \
Argv.cs \ Argv.cs \
Boxed.cs \ Boxed.cs \
ClassInitializerAttribute.cs \
ConnectBeforeAttribute.cs \ ConnectBeforeAttribute.cs \
DefaultSignalHandlerAttribute.cs \ DefaultSignalHandlerAttribute.cs \
DelegateWrapper.cs \ DelegateWrapper.cs \

View file

@ -122,10 +122,7 @@ namespace GLib {
if (baseinfo == minfo) if (baseinfo == minfo)
continue; continue;
foreach (object attr in baseinfo.GetCustomAttributes (true)) { foreach (object attr in baseinfo.GetCustomAttributes (typeof (DefaultSignalHandlerAttribute), true)) {
if (attr.ToString () != "GLib.DefaultSignalHandlerAttribute")
continue;
DefaultSignalHandlerAttribute sigattr = attr as DefaultSignalHandlerAttribute; DefaultSignalHandlerAttribute sigattr = attr as DefaultSignalHandlerAttribute;
MethodInfo connector = sigattr.Type.GetMethod (sigattr.ConnectionMethod, BindingFlags.Static | BindingFlags.NonPublic); MethodInfo connector = sigattr.Type.GetMethod (sigattr.ConnectionMethod, BindingFlags.Static | BindingFlags.NonPublic);
object[] parms = new object [1]; object[] parms = new object [1];
@ -137,6 +134,15 @@ namespace GLib {
} }
private static void InvokeClassInitializers (GType gtype, System.Type t)
{
object[] parms = {gtype, t};
BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
foreach (MethodInfo minfo in t.GetMethods(flags))
foreach (object attr in minfo.GetCustomAttributes (typeof (ClassInitializerAttribute), true))
minfo.Invoke (null, parms);
}
[DllImport("glibsharpglue-2")] [DllImport("glibsharpglue-2")]
static extern IntPtr gtksharp_register_type (string name, IntPtr parent_type); static extern IntPtr gtksharp_register_type (string name, IntPtr parent_type);
@ -147,6 +153,7 @@ namespace GLib {
GLib.ObjectManager.RegisterType (name, t.FullName, t.Assembly.GetName().Name); GLib.ObjectManager.RegisterType (name, t.FullName, t.Assembly.GetName().Name);
GType gtype = new GType (gtksharp_register_type (name, parent_gtype.Val)); GType gtype = new GType (gtksharp_register_type (name, parent_gtype.Val));
ConnectDefaultHandlers (gtype, t); ConnectDefaultHandlers (gtype, t);
InvokeClassInitializers (gtype, t);
g_types[t] = gtype; g_types[t] = gtype;
return gtype; return gtype;
} }

68
gtk/BindingAttribute.cs Normal file
View file

@ -0,0 +1,68 @@
// BindingAttribute.cs - Attribute to specify key bindings
//
// Author: Mike Kestner <mkestner@ximian.com>
//
// 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 Lesser 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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 Gtk {
using System;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class BindingAttribute : Attribute {
Gdk.Key key;
Gdk.ModifierType mod;
string handler;
object[] parms;
public BindingAttribute (Gdk.Key key, string handler, params object[] parms) : this (key, 0, handler, parms) {}
public BindingAttribute (Gdk.Key key, Gdk.ModifierType mod, string handler, params object[] parms)
{
this.key = key;
this.mod = mod;
this.handler = handler;
this.parms = parms;
}
public Gdk.Key Key {
get {
return key;
}
}
public Gdk.ModifierType Mod {
get {
return mod;
}
}
public string Handler {
get {
return handler;
}
}
public object[] Parms {
get {
return parms;
}
}
}
}

View file

@ -19,6 +19,7 @@ DISTCLEANFILES = $(ASSEMBLY).config AssemblyInfo.cs
sources = \ sources = \
ActionEntry.cs \ ActionEntry.cs \
Application.cs \ Application.cs \
BindingAttribute.cs \
ChildPropertyAttribute.cs \ ChildPropertyAttribute.cs \
ITreeNode.cs \ ITreeNode.cs \
NodeCellDataFunc.cs \ NodeCellDataFunc.cs \

View file

@ -231,3 +231,65 @@ protected virtual void OnSetScrollAdjustments (Gtk.Adjustment hadj, Gtk.Adjustme
{ {
} }
private class BindingInvoker {
System.Reflection.MethodInfo mi;
object[] parms;
public BindingInvoker (System.Reflection.MethodInfo mi, object[] parms)
{
this.mi = mi;
this.parms = parms;
}
public void Invoke (Widget w)
{
mi.Invoke (w, parms);
}
}
private delegate void BindingHandler (IntPtr handle, IntPtr user_data);
private static void BindingCallback (IntPtr handle, IntPtr user_data)
{
Widget w = GLib.Object.GetObject (handle, false) as Widget;
BindingInvoker invoker = ((GCHandle) user_data).Target as BindingInvoker;
invoker.Invoke (w);
}
static BindingHandler binding_delegate;
static BindingHandler BindingDelegate {
get {
if (binding_delegate == null)
binding_delegate = new BindingHandler (BindingCallback);
return binding_delegate;
}
}
[DllImport ("gtksharpglue-2")]
static extern void gtksharp_widget_add_binding_signal (IntPtr gvalue, string name, BindingHandler handler);
[DllImport ("gtksharpglue-2")]
static extern void gtksharp_widget_register_binding (IntPtr gvalue, string name, uint key, int mod, IntPtr data);
[GLib.ClassInitializer]
static void ClassInit (GLib.GType gtype, Type t)
{
object[] attrs = t.GetCustomAttributes (typeof (BindingAttribute), true);
if (attrs.Length == 0)
return;
string signame = t.Name.Replace (".", "_") + "_bindings";
gtksharp_widget_add_binding_signal (gtype.Val, signame, BindingDelegate);
foreach (BindingAttribute attr in attrs) {
System.Reflection.MethodInfo mi = t.GetMethod (attr.Handler, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
if (mi == null)
throw new Exception ("Instance method " + attr.Handler + " not found in " + t);
BindingInvoker inv = new BindingInvoker (mi, attr.Parms);
gtksharp_widget_register_binding (gtype.Val, signame, (uint) attr.Key, (int) attr.Mod, (IntPtr) GCHandle.Alloc (inv));
}
}

View file

@ -19,6 +19,7 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#include <gtk/gtkbindings.h>
#include <gtk/gtkwidget.h> #include <gtk/gtkwidget.h>
/* Forward declarations */ /* Forward declarations */
@ -35,6 +36,8 @@ void _gtksharp_marshal_VOID__OBJECT_OBJECT (GClosure *closure, GValue *return_va
int gtksharp_gtk_widget_get_flags (GtkWidget *widget); int gtksharp_gtk_widget_get_flags (GtkWidget *widget);
void gtksharp_gtk_widget_set_flags (GtkWidget *widget, int flags); void gtksharp_gtk_widget_set_flags (GtkWidget *widget, int flags);
int gtksharp_gtk_widget_style_get_int (GtkWidget *widget, const char *name); int gtksharp_gtk_widget_style_get_int (GtkWidget *widget, const char *name);
void gtksharp_widget_add_binding_signal (GType gtype, const char *sig_name, GCallback cb);
void gtksharp_widget_register_binding (GType gtype, const char *sig_name, guint key, int mod, gpointer data);
/* */ /* */
GdkRectangle* GdkRectangle*
@ -140,3 +143,20 @@ gtksharp_widget_connect_set_scroll_adjustments_signal (GType gtype, gpointer cb)
G_TYPE_NONE, 2, parm_types); G_TYPE_NONE, 2, parm_types);
} }
void
gtksharp_widget_add_binding_signal (GType gtype, const gchar *sig_name, GCallback cb)
{
GType parm_types[] = {G_TYPE_LONG};
g_signal_newv (sig_name, gtype, G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, g_cclosure_new (cb, NULL, NULL), NULL, NULL, g_cclosure_marshal_VOID__LONG, G_TYPE_NONE, 1, parm_types);
}
void
gtksharp_widget_register_binding (GType gtype, const gchar *signame, guint key, int mod, gpointer data)
{
GObjectClass *klass = g_type_class_peek (gtype);
if (klass == NULL)
klass = g_type_class_ref (gtype);
GtkBindingSet *set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (set, key, mod, signame, 1, G_TYPE_LONG, data);
}

View file

@ -29,6 +29,11 @@ namespace GtkSamples {
} }
} }
[Binding (Gdk.Key.Escape, "HandleBinding", "Escape")]
[Binding (Gdk.Key.Left, "HandleBinding", "Left")]
[Binding (Gdk.Key.Right, "HandleBinding", "Right")]
[Binding (Gdk.Key.Up, "HandleBinding", "Up")]
[Binding (Gdk.Key.Down, "HandleBinding", "Down")]
public class MyButton : Gtk.Button { public class MyButton : Gtk.Button {
public MyButton () : base ("I'm a subclassed button") {} public MyButton () : base ("I'm a subclassed button") {}
@ -37,5 +42,10 @@ namespace GtkSamples {
{ {
Console.WriteLine ("Button::Clicked default handler fired."); Console.WriteLine ("Button::Clicked default handler fired.");
} }
private void HandleBinding (string text)
{
Console.WriteLine ("Got a bound keypress: " + text);
}
} }
} }