0998fd871a
* glade/XML.custom: Added a constructor to read the glade file from a stream and to read it from a resource in an assembly. * sample/Makefile.in * sample/GladeTest.cs: Embed the glade file as a resource and use the new constructor. svn path=/trunk/gtk-sharp/; revision=7482
232 lines
7.2 KiB
Text
232 lines
7.2 KiB
Text
// XML.custom
|
||
//
|
||
// Author: Ricardo Fern<72>ndez Pascual <ric@users.sourceforge.net>
|
||
//
|
||
// (c) 2002 Ricardo Fern<72>ndez Pascual
|
||
//
|
||
// This code is inserted after the automatically generated code.
|
||
|
||
|
||
[DllImport("gtksharpglue")]
|
||
static extern string gtksharp_glade_xml_get_filename (IntPtr raw);
|
||
|
||
/// <summary>Filename Property</summary>
|
||
/// <remarks>Gets the filename used to create this GladeXML object
|
||
/// </remarks>
|
||
public string Filename {
|
||
get {
|
||
string ret = gtksharp_glade_xml_get_filename (Handle);
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
/// <summary>Indexer of widgets</summary>
|
||
/// <remarks>Acts like GetWidget</remarks>
|
||
public Gtk.Widget this [string name] {
|
||
get {
|
||
return GetWidget (name);
|
||
}
|
||
}
|
||
|
||
[DllImport("glade-2.0")]
|
||
static extern string glade_get_widget_name (IntPtr widget);
|
||
|
||
static public string GetWidgetName (Gtk.Widget w) {
|
||
string ret = glade_get_widget_name (w.Handle);
|
||
return ret;
|
||
}
|
||
|
||
[DllImport("glade-2.0")]
|
||
static extern IntPtr glade_get_widget_tree (IntPtr widget);
|
||
|
||
static public Glade.XML GetWidgetTree (Gtk.Widget w) {
|
||
IntPtr ret_raw = glade_get_widget_tree (w.Handle);
|
||
Glade.XML ret = GLib.Object.GetObject (ret_raw) as Glade.XML;
|
||
return ret;
|
||
}
|
||
|
||
/* a constructor that reads the XML from a Stream */
|
||
|
||
[DllImport("glade-2.0")]
|
||
static extern IntPtr glade_xml_new_from_buffer(byte[] buffer, int size, string root, string domain);
|
||
|
||
/// <summary>Creates a Glade.XML object from a Stream</sumary>
|
||
/// <remarks>Reads the contents of the stream and parses it. It must be in
|
||
/// correct Glade format</remarks>
|
||
public XML (System.IO.Stream s, string root, string domain)
|
||
{
|
||
int size = (int) s.Length;
|
||
byte[] buffer = new byte[size];
|
||
s.Read (buffer, 0, size);
|
||
Raw = glade_xml_new_from_buffer(buffer, size, root, domain);
|
||
}
|
||
|
||
/// <summary>Creates a Glade.XML object from a resource</sumary>
|
||
/// <remarks>Reads the contents of the resource in the
|
||
/// given assembly and parses it. If the assembly is null,
|
||
/// the current assembly will be used. It must be in
|
||
/// correct Glade format</remarks>
|
||
public XML (System.Reflection.Assembly assembly, string resource_name, string root, string domain)
|
||
{
|
||
if (assembly == null)
|
||
{
|
||
assembly = System.Reflection.Assembly.GetCallingAssembly ();
|
||
}
|
||
System.IO.Stream s = assembly.GetManifestResourceStream (resource_name);
|
||
int size = (int) s.Length;
|
||
byte[] buffer = new byte[size];
|
||
s.Read (buffer, 0, size);
|
||
s.Close ();
|
||
Raw = glade_xml_new_from_buffer(buffer, size, root, domain);
|
||
}
|
||
|
||
/* signal autoconnection using reflection */
|
||
|
||
/// <summary>Automatically connect signals</summary>
|
||
/// <remarks>Connects the signals defined in the glade file with handler methods
|
||
/// provided by the given object.</remarks>
|
||
public void Autoconnect (object handler)
|
||
{
|
||
SignalConnector sc = new SignalConnector (this, handler);
|
||
sc.Autoconnect ();
|
||
}
|
||
|
||
/// <summary>Automatically connect signals</summary>
|
||
/// <remarks>Connects the signals defined in the glade file with static handler
|
||
/// methods provided by the given type.</remarks>
|
||
public void Autoconnect (Type handler_class)
|
||
{
|
||
SignalConnector sc = new SignalConnector (this, handler_class);
|
||
sc.Autoconnect ();
|
||
}
|
||
|
||
class SignalConnector
|
||
{
|
||
/* the Glade.XML object whose signals we want to connect */
|
||
XML gxml;
|
||
|
||
/* the object to look for handlers */
|
||
object handler_object;
|
||
|
||
/* the type to look for handlers if no object has been specified */
|
||
Type handler_type;
|
||
|
||
public SignalConnector (XML gxml, object handler)
|
||
{
|
||
this.gxml = gxml;
|
||
this.handler_object = handler;
|
||
this.handler_type = handler.GetType ();
|
||
}
|
||
|
||
public SignalConnector (XML gxml, Type type)
|
||
{
|
||
this.gxml = gxml;
|
||
this.handler_object = null;
|
||
this.handler_type = type;
|
||
}
|
||
|
||
delegate void RawXMLConnectFunc (string handler_name, IntPtr objekt,
|
||
string signal_name, string signal_data,
|
||
IntPtr connect_object, int after, IntPtr user_data);
|
||
|
||
[DllImport("glade-2.0")]
|
||
static extern void glade_xml_signal_autoconnect_full (IntPtr raw, RawXMLConnectFunc func,
|
||
IntPtr user_data);
|
||
|
||
public void Autoconnect () {
|
||
RawXMLConnectFunc cf = new RawXMLConnectFunc (ConnectFunc);
|
||
glade_xml_signal_autoconnect_full (gxml.Handle, cf, IntPtr.Zero);
|
||
}
|
||
|
||
void ConnectFunc (string handler_name, IntPtr objekt_ptr,
|
||
string signal_name, string signal_data,
|
||
IntPtr connect_object_ptr, int after, IntPtr user_data) {
|
||
|
||
GLib.Object objekt = GLib.Object.GetObject (objekt_ptr);
|
||
|
||
/* if an connect_object_ptr is provided, use that as handler */
|
||
object connect_object =
|
||
connect_object_ptr == IntPtr.Zero
|
||
? handler_object
|
||
: GLib.Object.GetObject (connect_object_ptr);
|
||
|
||
/* search for the event to connect */
|
||
System.Reflection.MemberInfo[] evnts = objekt.GetType ().
|
||
FindMembers (System.Reflection.MemberTypes.Event,
|
||
System.Reflection.BindingFlags.Instance
|
||
| System.Reflection.BindingFlags.Static
|
||
| System.Reflection.BindingFlags.Public
|
||
| System.Reflection.BindingFlags.NonPublic,
|
||
signalFilter, signal_name);
|
||
foreach (System.Reflection.EventInfo ei in evnts)
|
||
{
|
||
bool connected = false;
|
||
System.Reflection.MethodInfo add = ei.GetAddMethod ();
|
||
System.Reflection.ParameterInfo[] addpi = add.GetParameters ();
|
||
if (addpi.Length == 1)
|
||
{ /* this should be always true, unless there's something broken */
|
||
Type delegate_type = addpi[0].ParameterType;
|
||
|
||
/* look for an instance method */
|
||
if (connect_object != null) try
|
||
{
|
||
Delegate d = Delegate.CreateDelegate
|
||
(delegate_type, connect_object, handler_name);
|
||
add.Invoke (objekt, new object[] { d } );
|
||
connected = true;
|
||
}
|
||
catch (ArgumentException)
|
||
{
|
||
/* ignore if there is not such instance method */
|
||
}
|
||
|
||
/* look for a static method if no instance method has been found */
|
||
if (!connected && handler_type != null) try
|
||
{
|
||
Delegate d = Delegate.CreateDelegate
|
||
(delegate_type, handler_type, handler_name);
|
||
add.Invoke (objekt, new object[] { d } );
|
||
connected = true;
|
||
}
|
||
catch (ArgumentException)
|
||
{
|
||
/* ignore if there is not such static method */
|
||
}
|
||
|
||
if (!connected)
|
||
{
|
||
throw new HandlerNotFoundException (handler_name, signal_name, ei, delegate_type);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
System.Reflection.MemberFilter signalFilter = new System.Reflection.MemberFilter (SignalFilter);
|
||
|
||
/* matches events to GLib signal names */
|
||
static bool SignalFilter (System.Reflection.MemberInfo m, object filterCriteria)
|
||
{
|
||
string signame = (filterCriteria as string);
|
||
object[] attrs = m.GetCustomAttributes (typeof (GLib.SignalAttribute), true);
|
||
if (attrs.Length > 0)
|
||
{
|
||
foreach (GLib.SignalAttribute a in attrs)
|
||
{
|
||
if (signame == a.CName)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
/* this tries to match the names when no attibutes are present.
|
||
It is only a fallback. */
|
||
signame = signame.ToLower ().Replace ("_", "");
|
||
string evname = m.Name.ToLower ();
|
||
return signame == evname;
|
||
}
|
||
}
|
||
}
|