[Gtk-sharp-list] Design for Indexer for GLib.List to allow [] based addressing.

Daniel Kornhauser dkor@media.mit.edu
Thu, 23 Oct 2003 14:49:11 -0400


--=-0shUEHZdqxKCrxfmwzoT
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

HI,

Finally, Duncan helped me create the patch for:

ListBase.cs
List.cs
SList.cs
and the test the modified Arrow.cs example : ListIndexerTest.cs

Note that I only did the pach for the get accesor for the List.cs and
SList.cs . Does it make sense to make the set accesor ?
If it makes sense should it be made with g_list_insert and
g_slist_insert

			Daniel



On Wed, 2003-10-22 at 11:19, Mike Kestner wrote:
> Hi Daniel,
> 
> Nice summary.  :)
> 
> On Tue, 2003-10-21 at 15:39, Daniel Kornhauser wrote:
> 
> > The code :
> > ==========
> > 
> > In ListBase.cs
> 
> You'll need an:
> 
> abstract internal IntPtr NthData (uint index);
> 
> declaration here to implement in the subclasses.
> 
> > 
> > public object this[int index] { 
> >     get {  
> > 	IntPtr data = list.NthData (index);
> 
> IntPtr data = NthData (index);
> 
> > 	object ret = null;
> > 	if (list.element_type != null)
> > 	    {
> <snip>
> > 
> > In List.cs
> > 
> >         [DllImport("libglib-2.0-0.dll")]
> >         static extern IntPtr g_list_nth_data (IntPtr l, uint n);
> > 
> >         internal override IntPtr g_list_nth_data NthData (IntPtr list, uint n)
> 
> internal override IntPtr NthData (uint n)
> 
> >         {
> >                 return g_list_nth_data ();
> 
> return g_list_nth_data (Handle, n);
> 
> >         }
> 
> And of course, the above change needs to be added to SList.cs as well.
> 
> So the approach looks right.  Can you work up a patch to add it?
> 
> Thanks,

--=-0shUEHZdqxKCrxfmwzoT
Content-Disposition: inline; filename=ListBase.patch
Content-Type: text/x-patch; name=ListBase.patch; charset=
Content-Transfer-Encoding: 7bit

Index: ListBase.cs
===================================================================
RCS file: /mono/gtk-sharp/glib/ListBase.cs,v
retrieving revision 1.9
diff -u -r1.9 ListBase.cs
--- ListBase.cs	7 Oct 2003 18:08:32 -0000	1.9
+++ ListBase.cs	23 Oct 2003 18:09:26 -0000
@@ -24,7 +24,8 @@
 		private int length = -1;
 		private bool managed = false;
 		protected System.Type element_type = null;
-
+	 
+                abstract internal IntPtr NthData (uint index);
 		abstract internal IntPtr GetData (IntPtr current);
 		abstract internal IntPtr Next (IntPtr current);
 		abstract internal int Length (IntPtr list);
@@ -106,6 +107,15 @@
 			}
 		}
 
+		public object this [int index] { 
+			get { 
+				IntPtr data = NthData ((uint) index);
+				object ret = null;
+				ret = DataMarshal (data);
+				return ret;
+			}
+		}
+
 		// Synchronization could be tricky here. Hmm.
 		public bool IsSynchronized {
 			get { return false; }
@@ -125,6 +135,25 @@
 			orig.CopyTo (array, index); 
 		}
 
+		internal object DataMarshal (IntPtr data) {
+			object ret = null;
+			if (element_type != null) {
+				if (element_type == typeof (string))
+					ret = Marshal.PtrToStringAnsi (data);
+				else if (element_type == typeof (int))
+					ret = (int) data;
+				else if (element_type.IsValueType)
+					ret = Marshal.PtrToStructure (data, element_type);
+				else
+					ret = Activator.CreateInstance (element_type, new object[] {data});
+
+			} else if (Object.IsObject (data))
+				ret = GLib.Object.GetObject (data, false);
+
+			return ret;
+		}
+
+
 		private class ListEnumerator : IEnumerator
 		{
 			private IntPtr current = IntPtr.Zero;
@@ -135,24 +164,11 @@
 				this.list = list;
 			}
 
-			public object Current {
+			public object  Current {
 				get {
 					IntPtr data = list.GetData (current);
 					object ret = null;
-					if (list.element_type != null)
-					{
-						if (list.element_type == typeof (string))
-							ret = Marshal.PtrToStringAnsi (data);
-						else if (list.element_type == typeof (int))
-							ret = (int) data;
-						else if (list.element_type.IsValueType)
-							ret = Marshal.PtrToStructure (data, list.element_type);
-						else
-							ret = Activator.CreateInstance (list.element_type, new object[] {data});
-					}
-					else if (Object.IsObject (data))
-						ret = GLib.Object.GetObject (data, false);
-
+					ret = list.DataMarshal (data);
 					return ret;
 				}
 			}

--=-0shUEHZdqxKCrxfmwzoT
Content-Disposition: inline; filename=List.patch
Content-Type: text/x-patch; name=List.patch; charset=
Content-Transfer-Encoding: 7bit

Index: List.cs
===================================================================
RCS file: /mono/gtk-sharp/glib/List.cs,v
retrieving revision 1.4
diff -u -r1.4 List.cs
--- List.cs	24 Feb 2003 06:39:29 -0000	1.4
+++ List.cs	23 Oct 2003 18:09:50 -0000
@@ -76,6 +76,15 @@
 			return g_list_prepend (list, raw);
 		}
 
+		[DllImport("libglib-2.0-0.dll")]
+	        static extern IntPtr g_list_nth_data (IntPtr l, uint n);
+
+		internal override IntPtr NthData (uint n)
+		{
+			return g_list_nth_data (Handle, n);
+		}
+
+
 		public List (IntPtr raw) : base (raw)
 		{
 		}

--=-0shUEHZdqxKCrxfmwzoT
Content-Disposition: inline; filename=SList.patch
Content-Type: text/x-patch; name=SList.patch; charset=
Content-Transfer-Encoding: 7bit

Index: SList.cs
===================================================================
RCS file: /mono/gtk-sharp/glib/SList.cs,v
retrieving revision 1.12
diff -u -r1.12 SList.cs
--- SList.cs	24 Feb 2003 06:39:30 -0000	1.12
+++ SList.cs	23 Oct 2003 18:09:57 -0000
@@ -76,6 +76,15 @@
 			return g_slist_prepend (list, raw);
 		}
 
+
+		[DllImport("libglib-2.0-0.dll")]
+	        static extern IntPtr g_slist_nth_data (IntPtr l, uint n);
+
+		internal override IntPtr NthData (uint n)
+		{
+			return g_slist_nth_data (Handle, n);
+		}
+
 		public SList (IntPtr raw) : base (raw)
 		{
 		}

--=-0shUEHZdqxKCrxfmwzoT
Content-Disposition: attachment; filename=ListIndexerTest.cs
Content-Type: text/plain; name=ListIndexerTest.cs; charset=
Content-Transfer-Encoding: 7bit

//
// Arrow.cs, port of arrow.c from gtk examples
//
// Author: Daniel Kornhauser <dkor@alum.mit.edu>
//
// Copyright (C) 2003, Ximian Inc.
//

using System;
using Gdk;
using Gtk;
using GtkSharp;
using GLib;

public class Arrow
{
	static void Main (string [] args)
	{
		/* Initialize the toolkit */
		Application.Init ();

		/* Declaration of widget type & 
		   Create a new window */
		Gtk.Window window = new Gtk.Window ("arrow");

		/* Catches window destroy signal for closing the application */
		window.DeleteEvent += new DeleteEventHandler (WindowDelete);

		/* Sets the border width of window. */
		window.BorderWidth = 10;

		/* Create a box to hold the arrows/buttons */
		HBox hbox = new HBox (false,0);
		hbox.BorderWidth = 2;
		window.Add(hbox);
		hbox.Show ();

		GLib.List l = new GLib.List ((IntPtr) 0, typeof (Gtk.Widget));
		GLib.SList sl = new GLib.SList ((IntPtr) 0, typeof (Gtk.Widget));

		/*Pack and show all our widgets */

		Button button = CreateArrowButton(ArrowType.Up, ShadowType.In);
		l.Append(button.Handle);
		button = CreateArrowButton(ArrowType.Down, ShadowType.Out);
		l.Append(button.Handle);
		button = CreateArrowButton(ArrowType.Left, ShadowType.In);
		sl.Append(button.Handle);
		button = CreateArrowButton(ArrowType.Right,ShadowType.Out);
		sl.Append(button.Handle);

		hbox.PackStart((Widget) l[0],false,false,3);
		hbox.PackStart((Widget) l[1],false,false,3);
		hbox.PackStart((Widget) sl[0],false,false,3);
		hbox.PackStart((Widget) sl[1],false,false,3);


		window.Show ();

		/* Run the application and wait for the fun to begin!*/

		Application.Run ();

	}

        /* Create an Arrow widget with the specified parameters
         * and pack it into a button */
	static Gtk.Button CreateArrowButton(ArrowType arrowType, 
			ShadowType shadowType)
	{
		Gtk.Button button = new Gtk.Button ();
		Gtk.Arrow arrow = new Gtk.Arrow(arrowType, shadowType);
		
		button.Add(arrow);
		
		button.Show();
		arrow.Show();
		
		return button;

	}

	static void WindowDelete (object obj, DeleteEventArgs args)
	{
		Application.Quit ();
		args.RetVal = true;
	}
}

--=-0shUEHZdqxKCrxfmwzoT--