[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--