diff --git a/ChangeLog b/ChangeLog index 2345bab32..e80a1e61c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-12-17 Mike Kestner + + * gtk/Makefile.am : add new file. + * gtk/glue/makefile.win32 : add missing file. + * gtk/NodeCellDataFunc.cs : new callback delegate type and marshaler + for NodeStore tree views using GtkTreeCellDataFuncs. + * gtk/NodeStore.cs : add internal GetNode overload by TreeIter. + * gtk/NodeView.cs : add AppendColumn overload that uses data funcs. + * gtk/TreeViewColumn.custom : manual implementation for SetCellDataFunc + to support both TreeIter and ITreeNode models. We need to hold a ref + to a delegate for each cell renderer on a column. [Fixes #63062] + * sample/NodeViewDemo.cs : use a NodeCellDataFunc for one of the + cell renderers in the tree. + 2004-12-17 Dan Winship * generator/Field.cs (StudlyName): Fall back to using "cname" if diff --git a/doc/en/Gtk/NodeView.xml b/doc/en/Gtk/NodeView.xml index 83ea52949..5bc62c1ca 100644 --- a/doc/en/Gtk/NodeView.xml +++ b/doc/en/Gtk/NodeView.xml @@ -68,5 +68,25 @@ + + + Method + + Gtk.TreeViewColumn + + + + + + + + Adds a column to the view using a data callback delegate. + a + a + a + a + + + diff --git a/doc/en/Gtk/TreeViewColumn.xml b/doc/en/Gtk/TreeViewColumn.xml index daeb8f566..71a360b1e 100644 --- a/doc/en/Gtk/TreeViewColumn.xml +++ b/doc/en/Gtk/TreeViewColumn.xml @@ -701,5 +701,22 @@ To be added + + + Method + + System.Void + + + + + + + Set the data func used to set cell renderer attributes. + a + a + + + - \ No newline at end of file + diff --git a/gtk/Makefile.am b/gtk/Makefile.am index ceb136f09..7fc1f59e7 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -21,6 +21,7 @@ sources = \ Application.cs \ ChildPropertyAttribute.cs \ ITreeNode.cs \ + NodeCellDataFunc.cs \ NodeSelection.cs \ NodeStore.cs \ NodeView.cs \ diff --git a/gtk/NodeCellDataFunc.cs b/gtk/NodeCellDataFunc.cs new file mode 100644 index 000000000..eea01c9e9 --- /dev/null +++ b/gtk/NodeCellDataFunc.cs @@ -0,0 +1,48 @@ +// NodeCellDataFunc.cs - a TreeCellDataFunc marshaler for ITreeNodes +// +// 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 Gtk { + + using System; + + public delegate void NodeCellDataFunc (TreeViewColumn tree_column, CellRenderer cell, ITreeNode node); + + + internal class NodeCellDataFuncWrapper : GLib.DelegateWrapper { + + public void NativeCallback (IntPtr tree_column, IntPtr cell, IntPtr tree_model, ref Gtk.TreeIter iter, IntPtr data) + { + TreeViewColumn col = (Gtk.TreeViewColumn) GLib.Object.GetObject(tree_column); + CellRenderer renderer = (Gtk.CellRenderer) GLib.Object.GetObject(cell); + NodeStore store = (NodeStore) GLib.Object.GetObject(tree_model); + managed (col, renderer, store.GetNode (iter)); + } + + internal GtkSharp.TreeCellDataFuncNative NativeDelegate; + protected NodeCellDataFunc managed; + + public NodeCellDataFuncWrapper (NodeCellDataFunc managed, object o) : base (o) + { + NativeDelegate = new GtkSharp.TreeCellDataFuncNative (NativeCallback); + this.managed = managed; + } + } +} diff --git a/gtk/NodeStore.cs b/gtk/NodeStore.cs index dcaee0ba1..fd343729c 100644 --- a/gtk/NodeStore.cs +++ b/gtk/NodeStore.cs @@ -399,13 +399,19 @@ namespace Gtk { return node; } - public ITreeNode GetNode (TreePath path) { + public ITreeNode GetNode (TreePath path) + { if (path == null) throw new ArgumentNullException (); return GetNodeAtPath (path); } + internal ITreeNode GetNode (TreeIter iter) + { + return node_hash [(int) iter.UserData] as ITreeNode; + } + internal TreePath GetPath (ITreeNode node) { TreePath path = new TreePath (); diff --git a/gtk/NodeView.cs b/gtk/NodeView.cs index 0550cd960..29a355021 100644 --- a/gtk/NodeView.cs +++ b/gtk/NodeView.cs @@ -60,5 +60,17 @@ namespace Gtk { return new NodeSelection (Selection); } } + + public Gtk.TreeViewColumn AppendColumn (string title, Gtk.CellRenderer cell, Gtk.NodeCellDataFunc cell_data) + { + Gtk.TreeViewColumn col = new Gtk.TreeViewColumn (); + col.Title = title; + col.PackStart (cell, true); + col.SetCellDataFunc (cell, cell_data); + + AppendColumn (col); + return col; + } } } + diff --git a/gtk/TreeViewColumn.custom b/gtk/TreeViewColumn.custom index 538146bb3..713c99f8e 100644 --- a/gtk/TreeViewColumn.custom +++ b/gtk/TreeViewColumn.custom @@ -22,12 +22,6 @@ - public void SetCellDataFunc(Gtk.CellRenderer cell_renderer, Gtk.TreeCellDataFunc func) { - GtkSharp.TreeCellDataFuncWrapper func_wrapper = null; - func_wrapper = new GtkSharp.TreeCellDataFuncWrapper (func, this); - gtk_tree_view_column_set_cell_data_func(Handle, cell_renderer.Handle, func_wrapper.NativeDelegate, IntPtr.Zero, null); - } - private void _NewWithAttributes (string title, Gtk.CellRenderer cell, Array attrs) { Title = title; PackStart (cell, true); @@ -62,3 +56,49 @@ } } + Hashtable cell_data_funcs; + + Hashtable CellDataFuncs { + get { + if (cell_data_funcs == null) + cell_data_funcs = new Hashtable (); + return cell_data_funcs; + } + } + + [DllImport("libgtk-win32-2.0-0.dll")] + static extern void gtk_tree_view_column_set_cell_data_func(IntPtr raw, IntPtr cell_renderer, IntPtr func, IntPtr func_data, IntPtr destroy); + + private void ReleaseDataFunc (CellRenderer cell) + { + CellDataFuncs [cell.Handle] = null; + gtk_tree_view_column_set_cell_data_func(Handle, cell.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + } + + [DllImport("libgtk-win32-2.0-0.dll")] + static extern void gtk_tree_view_column_set_cell_data_func(IntPtr raw, IntPtr cell_renderer, GtkSharp.TreeCellDataFuncNative func, IntPtr func_data, IntPtr destroy); + + public void SetCellDataFunc (CellRenderer cell_renderer, TreeCellDataFunc func) + { + if (func == null) { + ReleaseDataFunc (cell_renderer); + return; + } +; + GtkSharp.TreeCellDataFuncWrapper wrapper = new GtkSharp.TreeCellDataFuncWrapper (func, this); + CellDataFuncs [cell_renderer.Handle] = wrapper; + gtk_tree_view_column_set_cell_data_func(Handle, cell_renderer.Handle, wrapper.NativeDelegate, IntPtr.Zero, IntPtr.Zero); + } + + public void SetCellDataFunc (CellRenderer cell_renderer, NodeCellDataFunc func) + { + if (func == null) { + ReleaseDataFunc (cell_renderer); + return; + } +; + NodeCellDataFuncWrapper wrapper = new NodeCellDataFuncWrapper (func, this); + CellDataFuncs [cell_renderer.Handle] = wrapper; + gtk_tree_view_column_set_cell_data_func(Handle, cell_renderer.Handle, wrapper.NativeDelegate, IntPtr.Zero, IntPtr.Zero); + } + diff --git a/gtk/glue/makefile.win32 b/gtk/glue/makefile.win32 index 3edf7cdac..f88d1dc91 100755 --- a/gtk/glue/makefile.win32 +++ b/gtk/glue/makefile.win32 @@ -6,6 +6,7 @@ DLLWRAP=dllwrap -mno-cygwin -mms-bitfields --target i386-mingw32 --export-all-sy GLUE_OBJS = \ adjustment.o \ button.o \ + cellrenderer.o \ clipboard.o \ colorseldialog.o \ combo.o \ diff --git a/sample/NodeViewDemo.cs b/sample/NodeViewDemo.cs index b44cd2d21..c3aa8c40f 100644 --- a/sample/NodeViewDemo.cs +++ b/sample/NodeViewDemo.cs @@ -57,7 +57,7 @@ namespace GtkSamples { NodeView view = new NodeView (Store); view.HeadersVisible = true; view.AppendColumn ("Name", new CellRendererText (), "text", 0); - view.AppendColumn ("Type", new CellRendererText (), "text", 1); + view.AppendColumn ("Type", new CellRendererText (), new NodeCellDataFunc (DataCallback)); sw.Add (view); @@ -65,6 +65,11 @@ namespace GtkSamples { dialog = null; } + private void DataCallback (TreeViewColumn col, CellRenderer cell, ITreeNode node) + { + (cell as CellRendererText).Text = (node as DemoTreeNode).Description; + } + StatusDialog Dialog { get { if (dialog == null)