2007-10-02 Mike Kestner <mkestner@novell.com>

* generator/*.cs: implement the interfaces on the adapters too.
	Generate an Implementor interface for users which exposes the 
	methods to implement.  Register based on the Implementor sub-iface.
	* gtk/*Adapter.custom: custom implementations for the custom
	interface members.
	* gtk/TreeIter.custom: make UserData public.
	* sample/TreeModelDemo.cs: sample for implementing a TreeModel
	interface.

svn path=/trunk/gtk-sharp/; revision=86753
This commit is contained in:
Mike Kestner 2007-10-02 15:57:45 +00:00
parent 70f976e020
commit b2db2cda9e
15 changed files with 869 additions and 133 deletions

View File

@ -1,3 +1,14 @@
2007-10-02 Mike Kestner <mkestner@novell.com>
* generator/*.cs: implement the interfaces on the adapters too.
Generate an Implementor interface for users which exposes the
methods to implement. Register based on the Implementor sub-iface.
* gtk/*Adapter.custom: custom implementations for the custom
interface members.
* gtk/TreeIter.custom: make UserData public.
* sample/TreeModelDemo.cs: sample for implementing a TreeModel
interface.
2007-10-01 Mike Kestner <mkestner@novell.com>
* generator/OpaqueGen.cs: disable Copy generation fix until I can

View File

@ -42,7 +42,10 @@ namespace GtkSharp.Generation {
members.Add (vm);
break;
case "signal":
members.Add ((node as XmlElement).GetAttribute ("cname").Replace ('-', '_'));
object sig = sigs [(node as XmlElement).GetAttribute ("name")];
if (sig == null)
sig = new Signal (node as XmlElement, this);
members.Add (sig);
break;
default:
if (!IsNodeNameHandled (node.Name))
@ -52,6 +55,11 @@ namespace GtkSharp.Generation {
}
}
public override string FromNative (string var, bool owned)
{
return QualifiedName + "Adapter.GetObject (" + var + ", " + (owned ? "true" : "false") + ")";
}
public override bool ValidateForSubclass ()
{
ArrayList invalids = new ArrayList ();
@ -85,14 +93,15 @@ namespace GtkSharp.Generation {
sw.WriteLine ();
foreach (object member in members) {
if (member is System.String)
sw.WriteLine ("\t\t\tpublic IntPtr " + member + ";");
else if (member is VirtualMethod) {
if (member is Signal) {
Signal sig = member as Signal;
sw.WriteLine ("\t\t\tpublic IntPtr {0};", sig.ClassFieldName);
} else if (member is VirtualMethod) {
VirtualMethod vm = member as VirtualMethod;
bool has_method = methods [vm.Name] != null;
if (!has_method)
bool has_target = methods [vm.Name] != null;
if (!has_target)
Console.WriteLine ("Interface " + QualifiedName + " virtual method " + vm.Name + " has no matching method to invoke.");
string type = has_method && vm.IsValid ? vm.Name + "Delegate" : "IntPtr";
string type = has_target && vm.IsValid ? vm.Name + "Delegate" : "IntPtr";
sw.WriteLine ("\t\t\tpublic " + type + " " + vm.CName + ";");
}
}
@ -106,8 +115,8 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t\tstatic " + Name + "Adapter ()");
sw.WriteLine ("\t\t{");
foreach (VirtualMethod vm in vms) {
bool has_method = methods [vm.Name] != null;
if (has_method && vm.IsValid)
bool has_target = methods [vm.Name] != null;
if (has_target && vm.IsValid)
sw.WriteLine ("\t\t\tiface.{0} = new {1}Delegate ({1}Callback);", vm.CName, vm.Name);
}
sw.WriteLine ("\t\t}");
@ -131,20 +140,27 @@ namespace GtkSharp.Generation {
void GenerateCallbacks (StreamWriter sw)
{
foreach (VirtualMethod vm in vms) {
if (methods [vm.Name] == null)
continue;
sw.WriteLine ();
vm.GenerateCallback (sw);
if (methods [vm.Name] != null) {
sw.WriteLine ();
vm.GenerateCallback (sw);
}
}
}
void GenerateCtor (StreamWriter sw)
void GenerateCtors (StreamWriter sw)
{
sw.WriteLine ("\t\tpublic " + Name + "Adapter ()");
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\tInitHandler = new GLib.GInterfaceInitHandler (Initialize);");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
sw.WriteLine ("\t\t{0}Implementor implementor;", Name);
sw.WriteLine ();
sw.WriteLine ("\t\tpublic {0}Adapter ({0}Implementor implementor)", Name);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\tthis.implementor = implementor;");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
void GenerateGType (StreamWriter sw)
@ -159,6 +175,43 @@ namespace GtkSharp.Generation {
sw.WriteLine ();
}
void GenerateHandleProp (StreamWriter sw)
{
sw.WriteLine ("\t\tpublic IntPtr Handle {");
sw.WriteLine ("\t\t\tget {");
sw.WriteLine ("\t\t\t\treturn implementor == null ? IntPtr.Zero : implementor.Handle;");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
void GenerateGetObject (StreamWriter sw)
{
sw.WriteLine ("\t\tpublic static " + Name + " GetObject (IntPtr handle, bool owned)");
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\tGLib.Object obj = GLib.Object.GetObject (handle, owned);");
sw.WriteLine ("\t\t\tif (obj is " + Name + "Implementor)");
sw.WriteLine ("\t\t\t\treturn new {0}Adapter (obj as {0}Implementor);", Name);
sw.WriteLine ("\t\t\telse");
sw.WriteLine ("\t\t\t\treturn obj as {0};", Name);
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
void GenerateCastOperators (StreamWriter sw)
{
sw.WriteLine ("\t\tpublic static implicit operator {0}Adapter ({0}Implementor implementor)", Name);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\treturn new {0}Adapter (implementor);", Name);
sw.WriteLine ("\t\t}");
sw.WriteLine ();
sw.WriteLine ("\t\tpublic static implicit operator {0}Implementor ({0}Adapter adapter)", Name);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\treturn adapter.implementor;");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
void GenerateAdapter (GenerationInfo gen_info)
{
StreamWriter sw = gen_info.Writer = gen_info.OpenStream (Name + "Adapter");
@ -169,74 +222,50 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\tusing System.Runtime.InteropServices;");
sw.WriteLine ();
sw.WriteLine ("#region Autogenerated code");
sw.WriteLine ("\tinternal class " + Name + "Adapter : GLib.GInterfaceAdapter {");
sw.WriteLine ("\tpublic class " + Name + "Adapter : GLib.GInterfaceAdapter, " + QualifiedName + " {");
sw.WriteLine ();
GenerateIfaceStruct (sw);
GenerateStaticCtor (sw);
GenerateCallbacks (sw);
GenerateInitialize (sw);
GenerateCtor (sw);
GenerateCtors (sw);
GenerateGType (sw);
GenerateHandleProp (sw);
GenerateGetObject (sw);
GenProperties (gen_info, null);
foreach (Signal sig in sigs.Values) {
sig.GenCallback (sw);
sig.GenEvent (sw, null, "GLib.Object.GetObject (Handle)");
}
Method temp = methods ["GetType"] as Method;
if (temp != null)
methods.Remove ("GetType");
GenMethods (gen_info, new Hashtable (), this);
if (temp != null)
methods ["GetType"] = temp;
sw.WriteLine ("#endregion");
string custom = Path.Combine (gen_info.CustomDir, Name + "Adapter.custom");
if (File.Exists (custom)) {
sw.WriteLine ("#region Customized extensions");
sw.WriteLine ("#line 1 \"" + Name + "Adapter.custom\"");
using (StreamReader sr = new StreamReader(new FileStream (custom, FileMode.Open, FileAccess.Read)))
sw.WriteLine (sr.ReadToEnd ());
sw.WriteLine ("#endregion");
}
sw.WriteLine ("\t}");
sw.WriteLine ("#endregion");
sw.WriteLine ("}");
sw.Close ();
gen_info.Writer = null;
}
void GenSignals (GenerationInfo gen_info)
{
if (sigs.Count == 0)
return;
StreamWriter sw = gen_info.Writer;
sw.WriteLine ();
sw.WriteLine ("\t\t// signals");
foreach (Signal sig in sigs.Values) {
sig.GenerateDecl (sw);
sig.GenEventHandler (gen_info);
}
}
Hashtable GenVMDecls (StreamWriter sw)
{
if (vms.Count == 0)
return new Hashtable ();
sw.WriteLine ();
sw.WriteLine ("\t\t// virtual methods");
Hashtable vm_decls = new Hashtable ();
foreach (VirtualMethod vm in vms) {
sw.WriteLine ("\t\t" + vm.Declaration);
vm_decls [vm.Declaration] = vm;
}
return vm_decls;
}
void GenMethodDecls (StreamWriter sw, Hashtable vm_decls)
{
if (methods.Count == 0)
return;
bool need_comment = true;
foreach (Method method in methods.Values) {
//if (IgnoreMethod (method))
//continue;
if (!vm_decls.Contains (method.Declaration) && method.Name != "GetGType") {
if (need_comment) {
sw.WriteLine ();
sw.WriteLine ("\t\t// non-virtual methods");
need_comment = false;
}
method.GenerateDecl (sw);
}
}
}
public override void Generate (GenerationInfo gen_info)
{
GenerateAdapter (gen_info);
@ -247,7 +276,6 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\tusing System;");
sw.WriteLine ();
sw.WriteLine ("#region Autogenerated code");
sw.WriteLine ("\t[GLib.GInterface (typeof (" + Name + "Adapter))]");
sw.WriteLine ("\tpublic interface " + Name + " : GLib.IWrapper {");
sw.WriteLine ();
@ -267,6 +295,37 @@ namespace GtkSharp.Generation {
AppendCustom (sw, gen_info.CustomDir);
sw.WriteLine ("\t}");
sw.WriteLine ();
sw.WriteLine ("\t[GLib.GInterface (typeof (" + Name + "Adapter))]");
sw.WriteLine ("\tpublic interface " + Name + "Implementor : GLib.IWrapper {");
sw.WriteLine ();
Hashtable vm_table = new Hashtable ();
foreach (VirtualMethod vm in vms)
vm_table [vm.Name] = vm;
foreach (VirtualMethod vm in vms) {
if (vm_table [vm.Name] == null)
continue;
else if (!vm.IsValid) {
vm_table.Remove (vm.Name);
continue;
} else if (vm.IsGetter || vm.IsSetter) {
string cmp_name = (vm.IsGetter ? "Set" : "Get") + vm.Name.Substring (3);
VirtualMethod cmp = vm_table [cmp_name] as VirtualMethod;
if (cmp != null && (cmp.IsGetter || cmp.IsSetter)) {
if (vm.IsSetter)
cmp.GenerateDeclaration (sw, vm);
else
vm.GenerateDeclaration (sw, cmp);
vm_table.Remove (cmp.Name);
} else
vm.GenerateDeclaration (sw, null);
vm_table.Remove (vm.Name);
} else {
vm.GenerateDeclaration (sw, null);
vm_table.Remove (vm.Name);
}
}
sw.WriteLine ("\t}");
sw.WriteLine ("#endregion");
sw.WriteLine ("}");

View File

@ -552,6 +552,15 @@ namespace GtkSharp.Generation {
set { has_cb = value; }
}
public bool HasOutParam {
get {
foreach (Parameter p in this)
if (p.PassAs == "out")
return true;
return false;
}
}
bool hide_data;
public bool HideData {
get { return hide_data; }

View File

@ -52,6 +52,14 @@ namespace GtkSharp.Generation {
}
}
public string DefaultValue {
get {
if (IGen == null)
return String.Empty;
return IGen.DefaultValue;
}
}
string ElementCType {
get {
if (elem != null && elem.HasAttribute ("element_type"))

View File

@ -103,7 +103,6 @@ namespace GtkSharp.Generation {
result += p.PassAs + " ";
result += (p.MarshalType + " arg" + i);
}
result += ", IntPtr gch";
return result;
}
@ -153,6 +152,12 @@ namespace GtkSharp.Generation {
}
}
public string ClassFieldName {
get {
return elem.GetAttribute("cname").Replace ("-", "_");
}
}
private bool HasOutParams {
get {
foreach (Parameter p in parms) {
@ -199,21 +204,8 @@ namespace GtkSharp.Generation {
}
}
public void GenCallback (StreamWriter sw)
public string GenArgsInitialization (StreamWriter sw)
{
SymbolTable table = SymbolTable.Table;
sw.WriteLine ("\t\t[GLib.CDeclCallback]");
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + DelegateName + " (" + CallbackSig + ");");
sw.WriteLine ();
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + CallbackName + " (" + CallbackSig + ")");
sw.WriteLine("\t\t{");
sw.WriteLine("\t\t\t{0} args = new {0} ();", EventArgsQualifiedName);
sw.WriteLine("\t\t\ttry {");
sw.WriteLine("\t\t\t\tGLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;");
sw.WriteLine("\t\t\t\tif (sig == null)");
sw.WriteLine("\t\t\t\t\tthrow new Exception(\"Unknown signal GC handle received \" + gch);");
sw.WriteLine();
if (parms.Count > 1)
sw.WriteLine("\t\t\t\targs.Args = new object[" + (parms.Count - 1) + "];");
string finish = "";
@ -235,16 +227,13 @@ namespace GtkSharp.Generation {
else if (p.PassAs != "")
finish += "\t\t\t\targ" + idx + " = " + igen.ToNativeReturn ("((" + p.CSType + ")args.Args[" + (idx - 1) + "])") + ";\n";
}
sw.WriteLine("\t\t\t\t{0} handler = ({0}) sig.Handler;", EventHandlerQualifiedName);
sw.WriteLine("\t\t\t\thandler (GLib.Object.GetObject (arg0), args);");
sw.WriteLine("\t\t\t} catch (Exception e) {");
sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, false);");
sw.WriteLine("\t\t\t}");
return finish;
}
if (IsVoid && finish.Length == 0) {
sw.WriteLine("\t\t}\n");
public void GenArgsCleanup (StreamWriter sw, string finish)
{
if (IsVoid && finish.Length == 0)
return;
}
sw.WriteLine("\n\t\t\ttry {");
sw.Write (finish);
@ -253,7 +242,7 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t\t\t\tif (args.RetVal == null)");
sw.WriteLine ("\t\t\t\t\treturn false;");
}
sw.WriteLine("\t\t\t\treturn " + table.ToNativeReturn (retval.CType, "((" + retval.CSType + ")args.RetVal)") + ";");
sw.WriteLine("\t\t\t\treturn " + SymbolTable.Table.ToNativeReturn (retval.CType, "((" + retval.CSType + ")args.RetVal)") + ";");
}
sw.WriteLine("\t\t\t} catch (Exception) {");
sw.WriteLine ("\t\t\t\tException ex = new Exception (\"args.RetVal or 'out' property unset or set to incorrect type in " + EventHandlerQualifiedName + " callback\");");
@ -262,6 +251,31 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t\t\t\t// NOTREACHED: above call doesn't return.");
sw.WriteLine ("\t\t\t\tthrow ex;");
sw.WriteLine("\t\t\t}");
}
public void GenCallback (StreamWriter sw)
{
if (IsEventHandler)
return;
sw.WriteLine ("\t\t[GLib.CDeclCallback]");
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + DelegateName + " (" + CallbackSig + ", IntPtr gch);");
sw.WriteLine ();
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + CallbackName + " (" + CallbackSig + ", IntPtr gch)");
sw.WriteLine("\t\t{");
sw.WriteLine("\t\t\t{0} args = new {0} ();", EventArgsQualifiedName);
sw.WriteLine("\t\t\ttry {");
sw.WriteLine("\t\t\t\tGLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;");
sw.WriteLine("\t\t\t\tif (sig == null)");
sw.WriteLine("\t\t\t\t\tthrow new Exception(\"Unknown signal GC handle received \" + gch);");
sw.WriteLine();
string finish = GenArgsInitialization (sw);
sw.WriteLine("\t\t\t\t{0} handler = ({0}) sig.Handler;", EventHandlerQualifiedName);
sw.WriteLine("\t\t\t\thandler (GLib.Object.GetObject (arg0), args);");
sw.WriteLine("\t\t\t} catch (Exception e) {");
sw.WriteLine("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, false);");
sw.WriteLine("\t\t\t}");
GenArgsCleanup (sw, finish);
sw.WriteLine("\t\t}");
sw.WriteLine();
}
@ -403,17 +417,8 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\t\t}\n");
}
public void Generate (GenerationInfo gen_info, ClassBase implementor)
public void GenEvent (StreamWriter sw, ClassBase implementor, string target)
{
StreamWriter sw = gen_info.Writer;
if (implementor == null)
GenEventHandler (gen_info);
if (!IsEventHandler)
GenCallback (sw);
GenDefaultHandlerDelegate (sw, implementor);
GenVirtualMethod (sw, implementor);
string marsh = IsEventHandler ? "" : ", new " + DelegateName + "(" + CallbackName + ")";
sw.WriteLine("\t\t[GLib.Signal("+ CName + ")]");
@ -422,15 +427,28 @@ namespace GtkSharp.Generation {
sw.Write("new ");
sw.WriteLine("event " + EventHandlerQualifiedName + " " + Name + " {");
sw.WriteLine("\t\t\tadd {");
sw.WriteLine("\t\t\t\tGLib.Signal sig = GLib.Signal.Lookup (this, " + CName + marsh + ");");
sw.WriteLine("\t\t\t\tGLib.Signal sig = GLib.Signal.Lookup (" + target + ", " + CName + marsh + ");");
sw.WriteLine("\t\t\t\tsig.AddDelegate (value);");
sw.WriteLine("\t\t\t}");
sw.WriteLine("\t\t\tremove {");
sw.WriteLine("\t\t\t\tGLib.Signal sig = GLib.Signal.Lookup (this, " + CName + marsh + ");");
sw.WriteLine("\t\t\t\tGLib.Signal sig = GLib.Signal.Lookup (" + target + ", " + CName + marsh + ");");
sw.WriteLine("\t\t\t\tsig.RemoveDelegate (value);");
sw.WriteLine("\t\t\t}");
sw.WriteLine("\t\t}");
sw.WriteLine();
}
public void Generate (GenerationInfo gen_info, ClassBase implementor)
{
StreamWriter sw = gen_info.Writer;
if (implementor == null)
GenEventHandler (gen_info);
GenCallback (sw);
GenDefaultHandlerDelegate (sw, implementor);
GenVirtualMethod (sw, implementor);
GenEvent (sw, implementor, "this");
Statistics.SignalCount++;
}

View File

@ -48,6 +48,9 @@ namespace GtkSharp.Generation {
if (p.CType == "GError**")
continue;
if (p.Scope == "notified")
i += 2;
this.parms.Add (p);
}
}

View File

@ -27,39 +27,26 @@ namespace GtkSharp.Generation {
using System.Xml;
// FIXME: handle static VMs
public class VirtualMethod {
public class VirtualMethod : MethodBase {
XmlElement elem;
ReturnValue retval;
Parameters parms;
public VirtualMethod (XmlElement elem, ClassBase container_type)
public VirtualMethod (XmlElement elem, ClassBase container_type) : base (elem, container_type)
{
this.elem = elem;
retval = new ReturnValue (elem ["return-type"]);
parms = new Parameters (elem["parameters"]);
}
public string CName {
get {
return elem.GetAttribute("cname");
}
}
public string Declaration {
get {
VMSignature vmsig = new VMSignature (parms);
return retval.CSType + " " + Name + " (" + vmsig + ");";
}
}
bool IsGetter {
public bool IsGetter {
get {
return (Name.StartsWith ("Get") || Name.StartsWith ("Has")) && ((!retval.IsVoid && parms.Count == 1) || (retval.IsVoid && parms.Count == 2 && parms [1].PassAs == "out"));
}
}
bool IsSetter {
public bool IsSetter {
get {
if (!Name.StartsWith ("Set") || !retval.IsVoid)
return false;
@ -89,7 +76,7 @@ namespace GtkSharp.Generation {
return;
ManagedCallString call = new ManagedCallString (parms);
string type = parms [0].CSType;
string type = parms [0].CSType + "Implementor";
string name = parms [0].Name;
string call_string = "__obj." + Name + " (" + call + ")";
if (IsGetter)
@ -102,25 +89,55 @@ namespace GtkSharp.Generation {
sw.WriteLine ();
sw.WriteLine ("\t\tstatic " + MarshalReturnType + " " + Name + "Callback (" + parms.ImportSignature + ")");
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\t" + type + " __obj = GLib.Object.GetObject (" + name + ", false) as " + type + ";");
sw.Write (call.Setup ("\t\t\t"));
sw.WriteLine ("\t\t\ttry {");
sw.WriteLine ("\t\t\t\t" + type + " __obj = GLib.Object.GetObject (" + name + ", false) as " + type + ";");
sw.Write (call.Setup ("\t\t\t\t"));
if (retval.IsVoid) {
if (IsGetter) {
Parameter p = parms [1];
string out_name = p.Name;
if (p.MarshalType != p.CSType)
out_name = "my" + out_name;
sw.WriteLine ("\t\t\t" + out_name + " = " + call_string + ";");
sw.WriteLine ("\t\t\t\t" + out_name + " = " + call_string + ";");
} else
sw.WriteLine ("\t\t\t" + call_string + ";");
sw.WriteLine ("\t\t\t\t" + call_string + ";");
} else
sw.WriteLine ("\t\t\t" + retval.ToNativeType + " result = " + retval.ToNative (call_string) + ";");
sw.Write (call.Finish ("\t\t\t"));
sw.WriteLine ("\t\t\t\t" + retval.ToNativeType + " result = " + retval.ToNative (call_string) + ";");
string finish = call.Finish ("\t\t\t\t");
bool fatal = parms.HasOutParam || !retval.IsVoid;
sw.Write (call.Finish ("\t\t\t\t"));
if (!retval.IsVoid)
sw.WriteLine ("\t\t\treturn result;");
sw.WriteLine ("\t\t\t\treturn result;");
sw.WriteLine ("\t\t\t} catch (Exception e) {");
sw.WriteLine ("\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, " + (fatal ? "true" : "false") + ");");
if (fatal) {
sw.WriteLine ("\t\t\t\t// NOTREACHED: above call does not return.");
sw.WriteLine ("\t\t\t\tthrow e;");
}
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
}
public void GenerateDeclaration (StreamWriter sw, VirtualMethod complement)
{
VMSignature vmsig = new VMSignature (parms);
if (IsGetter) {
string name = Name.StartsWith ("Get") ? Name.Substring (3) : Name;
string type = retval.IsVoid ? parms [1].CSType : retval.CSType;
if (complement != null && complement.parms [1].CSType == type)
sw.WriteLine ("\t\t" + type + " " + name + " { get; set; }");
else {
sw.WriteLine ("\t\t" + type + " " + name + " { get; }");
if (complement != null)
sw.WriteLine ("\t\t" + complement.retval.CSType + " " + complement.Name + " (" + (new VMSignature (complement.parms)) + ");");
}
} else if (IsSetter)
sw.WriteLine ("\t\t" + parms[1].CSType + " " + Name.Substring (3) + " { set; }");
else
sw.WriteLine ("\t\t" + retval.CSType + " " + Name + " (" + vmsig + ");");
}
enum ValidState {
Unvalidated,
Invalid,
@ -138,7 +155,7 @@ namespace GtkSharp.Generation {
}
}
bool Validate ()
public override bool Validate ()
{
if (!parms.Validate () || !retval.Validate ()) {
Console.Write ("in virtual method " + Name + " ");

View File

@ -0,0 +1,31 @@
// Gtk.CellLayoutAdaptor.custom - Gtk CellLayoutAdaptor customizations
//
// Authors: Mike Kestner <mkestner@novell.com>
//
// Copyright (c) 2007 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.
public void SetAttributes (CellRenderer cell, params object[] attrs)
{
if (attrs.Length % 2 != 0)
throw new ArgumentException ("attrs should contain pairs of attribute/col");
ClearAttributes (cell);
for (int i = 0; i < attrs.Length - 1; i += 2) {
AddAttribute (cell, (string) attrs [i], (int) attrs [i + 1]);
}
}

View File

@ -0,0 +1,43 @@
// Gtk.FileChooserAdapter.custom - Gtk FileChooserAdapter customizations
//
// Authors: Mike Kestner <mkestner@novell.com>
//
// Copyright (c) 2007 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.
[DllImport ("libgtk-win32-2.0-0.dll")]
static extern IntPtr gtk_file_chooser_get_filenames (IntPtr raw);
public string[] Filenames {
get {
IntPtr raw_ret = gtk_file_chooser_get_filenames (Handle);
GLib.SList list = new GLib.SList (raw_ret, typeof (GLib.ListBase.FilenameString), true, true);
return (string[]) GLib.Marshaller.ListToArray (list, typeof (string));
}
}
[DllImport ("libgtk-win32-2.0-0.dll")]
static extern IntPtr gtk_file_chooser_list_shortcut_folders (IntPtr raw);
public string[] ShortcutFolders {
get {
IntPtr raw_ret = gtk_file_chooser_list_shortcut_folders (Handle);
GLib.SList list = new GLib.SList (raw_ret, typeof (GLib.ListBase.FilenameString), true, true);
return (string[]) GLib.Marshaller.ListToArray (list, typeof (string));
}
}

View File

@ -49,6 +49,7 @@ customs = \
CellRendererText.custom \
CellRendererToggle.custom \
CellLayout.custom \
CellLayoutAdapter.custom \
CellView.custom \
CheckMenuItem.custom \
Clipboard.custom \
@ -63,6 +64,7 @@ customs = \
Entry.custom \
EntryCompletion.custom \
FileChooser.custom \
FileChooserAdapter.custom \
FileChooserButton.custom \
FileChooserDialog.custom \
FileChooserWidget.custom \
@ -115,11 +117,13 @@ customs = \
TooltipsData.custom \
TreeIter.custom \
TreeModel.custom \
TreeModelAdapter.custom \
TreeModelFilter.custom \
TreeModelSort.custom \
TreePath.custom \
TreeSelection.custom \
TreeSortable.custom \
TreeSortableAdapter.custom \
TreeStore.custom \
TreeViewColumn.custom \
TreeView.custom \

View File

@ -35,7 +35,7 @@
ti._user_data3 == _user_data3;
}
internal IntPtr UserData {
public IntPtr UserData {
get {
return _user_data;
}

181
gtk/TreeModelAdapter.custom Normal file
View File

@ -0,0 +1,181 @@
// Gtk.TreeModelAdapter.custom - Gtk TreeModelAdapter customizations
//
// Author: Mike Kestner <mkestner@novell.com>
//
// Copyright (c) 2007 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.
[DllImport("libgtk-win32-2.0-0.dll")]
static extern bool gtk_tree_model_iter_children (IntPtr raw, out Gtk.TreeIter iter, IntPtr parent);
public bool IterChildren (out Gtk.TreeIter iter) {
bool raw_ret = gtk_tree_model_iter_children (Handle, out iter, IntPtr.Zero);
bool ret = raw_ret;
return ret;
}
public int IterNChildren () {
int raw_ret = gtk_tree_model_iter_n_children (Handle, IntPtr.Zero);
int ret = raw_ret;
return ret;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern bool gtk_tree_model_iter_nth_child (IntPtr raw, out Gtk.TreeIter iter, IntPtr parent, int n);
public bool IterNthChild (out Gtk.TreeIter iter, int n) {
bool raw_ret = gtk_tree_model_iter_nth_child (Handle, out iter, IntPtr.Zero, n);
bool ret = raw_ret;
return ret;
}
public void SetValue (Gtk.TreeIter iter, int column, bool value) {
SetValue (iter, column, new GLib.Value (value));
}
public void SetValue (Gtk.TreeIter iter, int column, double value) {
SetValue (iter, column, new GLib.Value (value));
}
public void SetValue (Gtk.TreeIter iter, int column, int value) {
SetValue (iter, column, new GLib.Value (value));
}
public void SetValue (Gtk.TreeIter iter, int column, string value) {
SetValue (iter, column, new GLib.Value (value));
}
public void SetValue (Gtk.TreeIter iter, int column, float value) {
SetValue (iter, column, new GLib.Value (value));
}
public void SetValue (Gtk.TreeIter iter, int column, uint value) {
SetValue (iter, column, new GLib.Value (value));
}
public void SetValue (Gtk.TreeIter iter, int column, object value) {
SetValue (iter, column, new GLib.Value (value));
}
public object GetValue (Gtk.TreeIter iter, int column) {
GLib.Value val = GLib.Value.Empty;
GetValue (iter, column, ref val);
object ret = val.Val;
val.Dispose ();
return ret;
}
[GLib.CDeclCallback]
delegate void RowsReorderedSignalDelegate (IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr gch);
static void RowsReorderedSignalCallback (IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr gch)
{
Gtk.RowsReorderedArgs args = new Gtk.RowsReorderedArgs ();
try {
GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;
if (sig == null)
throw new Exception("Unknown signal GC handle received " + gch);
TreeModelFilter sender = GLib.Object.GetObject (arg0) as TreeModelFilter;
args.Args = new object[3];
args.Args[0] = arg1 == IntPtr.Zero ? null : (Gtk.TreePath) GLib.Opaque.GetOpaque (arg1, typeof (Gtk.TreePath), false);
args.Args[1] = Gtk.TreeIter.New (arg2);
int child_cnt = sender.IterNChildren ((TreeIter)args.Args[1]);
int[] new_order = new int [child_cnt];
Marshal.Copy (arg3, new_order, 0, child_cnt);
args.Args[2] = new_order;
Gtk.RowsReorderedHandler handler = (Gtk.RowsReorderedHandler) sig.Handler;
handler (sender, args);
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, false);
}
}
#if false
[GLib.CDeclCallback]
delegate void RowsReorderedVMDelegate (IntPtr tree_model, IntPtr path, IntPtr iter, IntPtr new_order);
static RowsReorderedVMDelegate RowsReorderedVMCallback;
static void rowsreordered_cb (IntPtr tree_model, IntPtr path_ptr, IntPtr iter_ptr, IntPtr new_order)
{
try {
TreeModelFilter store = GLib.Object.GetObject (tree_model, false) as TreeModelFilter;
TreePath path = GLib.Opaque.GetOpaque (path_ptr, typeof (TreePath), false) as TreePath;
TreeIter iter = TreeIter.New (iter_ptr);
int child_cnt = store.IterNChildren (iter);
int[] child_order = new int [child_cnt];
Marshal.Copy (new_order, child_order, 0, child_cnt);
store.OnRowsReordered (path, iter, child_order);
} catch (Exception e) {
GLib.ExceptionManager.RaiseUnhandledException (e, true);
// NOTREACHED: above call doesn't return
throw e;
}
}
private static void OverrideRowsReordered (GLib.GType gtype)
{
if (RowsReorderedVMCallback == null)
RowsReorderedVMCallback = new RowsReorderedVMDelegate (rowsreordered_cb);
OverrideVirtualMethod (gtype, "rows_reordered", RowsReorderedVMCallback);
}
[Obsolete ("Replaced by int[] new_order overload.")]
[GLib.DefaultSignalHandler(Type=typeof(Gtk.TreeModelFilter), ConnectionMethod="OverrideRowsReordered")]
protected virtual void OnRowsReordered (Gtk.TreePath path, Gtk.TreeIter iter, out int new_order)
{
new_order = -1;
}
[GLib.DefaultSignalHandler(Type=typeof(Gtk.TreeModelFilter), ConnectionMethod="OverrideRowsReordered")]
protected virtual void OnRowsReordered (Gtk.TreePath path, Gtk.TreeIter iter, int[] new_order)
{
int dummy;
OnRowsReordered (path, iter, out dummy);
GLib.Value ret = GLib.Value.Empty;
GLib.ValueArray inst_and_params = new GLib.ValueArray (4);
GLib.Value[] vals = new GLib.Value [4];
vals [0] = new GLib.Value (this);
inst_and_params.Append (vals [0]);
vals [1] = new GLib.Value (path);
inst_and_params.Append (vals [1]);
vals [2] = new GLib.Value (iter);
inst_and_params.Append (vals [2]);
int cnt = IterNChildren (iter);
IntPtr new_order_ptr = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (int)) * cnt);
Marshal.Copy (new_order, 0, new_order_ptr, cnt);
vals [3] = new GLib.Value (new_order_ptr);
inst_and_params.Append (vals [3]);
g_signal_chain_from_overridden (inst_and_params.ArrayPtr, ref ret);
Marshal.FreeHGlobal (new_order_ptr);
foreach (GLib.Value v in vals)
v.Dispose ();
}
#endif
[GLib.Signal("rows_reordered")]
public event Gtk.RowsReorderedHandler RowsReordered {
add {
GLib.Signal sig = GLib.Signal.Lookup (GLib.Object.GetObject (Handle), "rows_reordered", new RowsReorderedSignalDelegate(RowsReorderedSignalCallback));
sig.AddDelegate (value);
}
remove {
GLib.Signal sig = GLib.Signal.Lookup (GLib.Object.GetObject (Handle), "rows_reordered", new RowsReorderedSignalDelegate(RowsReorderedSignalCallback));
sig.RemoveDelegate (value);
}
}

View File

@ -0,0 +1,36 @@
// Gtk.TreeSortableAdapter.Custom - Gtk TreeSortableAdapter class customizations
//
// Author: Mike Kestner <mkestner@novell.com>
//
// Copyright (c) 2007 Novell, Inc.
//
// This code is inserted after the automatically generated code.
//
// 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.
[Obsolete ("Replaced by SetSortFunc (int, TreeIterCompareFunc) overload.")]
public void SetSortFunc (int sort_column_id, TreeIterCompareFunc sort_func, IntPtr user_data, Gtk.DestroyNotify destroy)
{
SetSortFunc (sort_column_id, sort_func);
}
[Obsolete ("Replaced by DefaultSortFunc property.")]
public void SetDefaultSortFunc (TreeIterCompareFunc sort_func, IntPtr user_data, Gtk.DestroyNotify destroy)
{
DefaultSortFunc = sort_func;
}

View File

@ -16,7 +16,7 @@ DOTNET_TARGETS=
DOTNET_ASSEMBLY=
endif
TARGETS = polarfixed.exe custom-widget.exe custom-cellrenderer.exe gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe size.exe scribble.exe scribble-xinput.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe testdnd.exe actions.exe $(GLADE_TARGETS) $(DOTNET_TARGETS)
TARGETS = polarfixed.exe custom-widget.exe custom-cellrenderer.exe gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe size.exe scribble.exe scribble-xinput.exe treeviewdemo.exe managedtreeviewdemo.exe nodeviewdemo.exe treemodeldemo.exe testdnd.exe actions.exe $(GLADE_TARGETS) $(DOTNET_TARGETS)
DEBUGS = $(addsuffix .mdb, $(TARGETS))
@ -59,6 +59,9 @@ managedtreeviewdemo.exe: $(srcdir)/ManagedTreeViewDemo.cs $(assemblies)
nodeviewdemo.exe: $(srcdir)/NodeViewDemo.cs $(assemblies)
$(CSC) /out:nodeviewdemo.exe $(references) $(srcdir)/NodeViewDemo.cs
treemodeldemo.exe: $(srcdir)/TreeModelDemo.cs $(assemblies)
$(CSC) /out:treemodeldemo.exe $(references) $(srcdir)/TreeModelDemo.cs
glade-viewer.exe: $(srcdir)/GladeViewer.cs $(assemblies)
$(CSC) /out:glade-viewer.exe $(references) $(srcdir)/GladeViewer.cs

313
sample/TreeModelDemo.cs Normal file
View File

@ -0,0 +1,313 @@
// TreeModelSample.cs - TreeModelSample application.
//
// Author: Mike Kestner <mkestner@novell.com>
//
// Copyright (c) 2007 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 GtkSamples {
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using Gtk;
public class TreeModelDemo : Gtk.Window {
public TreeModelDemo () : base ("TreeModel demo")
{
DefaultSize = new Gdk.Size (640,480);
ScrolledWindow sw = new ScrolledWindow ();
TreeView view = new TreeView (new TreeModelAdapter (new MyTreeModel ()));
view.HeadersVisible = true;
view.AppendColumn ("Name", new CellRendererText (), "text", 0);
view.AppendColumn ("Type", new CellRendererText (), "text", 1);
sw.Add (view);
sw.ShowAll ();
Add (sw);
}
protected override bool OnDeleteEvent (Gdk.Event ev)
{
Application.Quit ();
return true;
}
public static void Main (string[] args)
{
Application.Init ();
Gtk.Window win = new TreeModelDemo ();
win.Show ();
Application.Run ();
}
}
public class MyTreeModel : GLib.Object, TreeModelImplementor {
Assembly[] assemblies;
public MyTreeModel ()
{
assemblies = AppDomain.CurrentDomain.GetAssemblies ();
}
object GetNodeAtPath (TreePath path)
{
if (path.Indices.Length > 0) {
Assembly assm = assemblies [path.Indices [0]];
if (path.Indices.Length > 1) {
Type t = assm.GetTypes ()[path.Indices [1]];
if (path.Indices.Length < 2)
return t.GetMembers () [path.Indices [2]];
else
return t;
} else
return assm;
} else
return null;
}
Hashtable node_hash = new Hashtable ();
public TreeModelFlags Flags {
get {
return TreeModelFlags.ItersPersist;
}
}
public int NColumns {
get {
return 2;
}
}
public GLib.GType GetColumnType (int col)
{
GLib.GType result = GLib.GType.String;
return result;
}
TreeIter IterFromNode (object node)
{
GCHandle gch;
if (node_hash [node] != null)
gch = (GCHandle) node_hash [node];
else
gch = GCHandle.Alloc (node);
TreeIter result = TreeIter.Zero;
result.UserData = (IntPtr) gch;
return result;
}
object NodeFromIter (TreeIter iter)
{
GCHandle gch = (GCHandle) iter.UserData;
return gch.Target;
}
TreePath PathFromNode (object node)
{
if (node == null)
return new TreePath ();
object work = node;
TreePath path = new TreePath ();
if (work is MemberInfo) {
Type parent = (work as MemberInfo).ReflectedType;
path.PrependIndex (Array.IndexOf (parent.GetMembers (), work));
work = parent;
}
if (work is Type) {
Assembly assm = (work as Type).Assembly;
path.PrependIndex (Array.IndexOf (assm.GetTypes (), work));
work = assm;
}
if (work is Assembly)
path.PrependIndex (Array.IndexOf (assemblies, node));
return path;
}
public bool GetIter (out TreeIter iter, TreePath path)
{
if (path == null)
throw new ArgumentNullException ("path");
iter = TreeIter.Zero;
object node = GetNodeAtPath (path);
if (node == null)
return false;
iter = IterFromNode (node);
return true;
}
public TreePath GetPath (TreeIter iter)
{
object node = NodeFromIter (iter);
if (node == null)
throw new ArgumentException ("iter");
return PathFromNode (node);
}
public void GetValue (TreeIter iter, int col, ref GLib.Value val)
{
object node = NodeFromIter (iter);
if (node == null)
return;
if (node is Assembly)
val = new GLib.Value (col == 0 ? (node as Assembly).GetName ().Name : "Assembly");
else if (node is Type)
val = new GLib.Value (col == 0 ? (node as Type).Name : "Type");
else
val = new GLib.Value (col == 0 ? (node as MemberInfo).Name : "Member");
}
public bool IterNext (ref TreeIter iter)
{
object node = NodeFromIter (iter);
if (node == null)
return false;
int idx;
if (node is Assembly) {
idx = Array.IndexOf (assemblies, node) + 1;
if (idx < assemblies.Length) {
iter = IterFromNode (assemblies [idx]);
return true;
}
} else if (node is Type) {
Type[] siblings = (node as Type).Assembly.GetTypes ();
idx = Array.IndexOf (siblings, node) + 1;
if (idx < siblings.Length) {
iter = IterFromNode (siblings [idx]);
return true;
}
} else {
MemberInfo[] siblings = (node as MemberInfo).ReflectedType.GetMembers ();
idx = Array.IndexOf (siblings, node) + 1;
if (idx < siblings.Length) {
iter = IterFromNode (siblings [idx]);
return true;
}
}
return false;
}
int ChildCount (object node)
{
if (node is Assembly)
return (node as Assembly).GetTypes ().Length;
else if (node is Type)
return (node as Type).GetMembers ().Length;
else
return 0;
}
public bool IterChildren (out TreeIter child, TreeIter parent)
{
child = TreeIter.Zero;
if (parent.UserData == IntPtr.Zero) {
child = IterFromNode (assemblies [0]);
return true;
}
object node = NodeFromIter (parent);
if (node == null || ChildCount (node) <= 0)
return false;
if (node is Assembly)
child = IterFromNode ((node as Assembly).GetTypes () [0]);
else if (node is Type)
child = IterFromNode ((node as Type).GetMembers () [0]);
return true;
}
public bool IterHasChild (TreeIter iter)
{
object node = NodeFromIter (iter);
if (node == null || ChildCount (node) <= 0)
return false;
return true;
}
public int IterNChildren (TreeIter iter)
{
if (iter.UserData == IntPtr.Zero)
return assemblies.Length;
object node = NodeFromIter (iter);
if (node == null)
return 0;
return ChildCount (node);
}
public bool IterNthChild (out TreeIter child, TreeIter parent, int n)
{
child = TreeIter.Zero;
if (parent.UserData == IntPtr.Zero) {
if (assemblies.Length <= n)
return false;
child = IterFromNode (assemblies [n]);
return true;
}
object node = NodeFromIter (parent);
if (node == null || ChildCount (node) <= n)
return false;
if (node is Assembly)
child = IterFromNode ((node as Assembly).GetTypes () [n]);
else if (node is Type)
child = IterFromNode ((node as Type).GetMembers () [n]);
return true;
}
public bool IterParent (out TreeIter parent, TreeIter child)
{
parent = TreeIter.Zero;
object node = NodeFromIter (child);
if (node == null || node is Assembly)
return false;
if (node is Type)
parent = IterFromNode ((node as Type).Assembly);
else if (node is MemberInfo)
parent = IterFromNode ((node as MemberInfo).ReflectedType);
return true;
}
public void RefNode (TreeIter iter)
{
}
public void UnrefNode (TreeIter iter)
{
}
}
}