[Gtk-sharp-list] Gtk.Idle support

Luciano martorella@sssup.it
Fri, 19 Dec 2003 21:09:04 +0100


This is a multi-part message in MIME format.
--------------060206090602060206040908
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit


  Hi!

  I want to start a brief discussion on "Idle" support on gtk.
  The class "Gtk.Idle" autogenerated from the API work well, but the 
class is removed (hidden) from the metadata. I think for style reasons.

  I have improved myself for testing around in C#, and i have wroted a 
small piece of code what implements Idle events from Gtk.Application. 
This is more "c sharp" and more aligned with glib signals schema, i think.
  To reflect the priority associated with every idle callback (like in 
GTK+), i wrote an attribute to associate with the target of delegate. I 
explain myself with an example:


   [IdlePriority (IdlePriorityEnum.High)]
   void OnIdle (object o, EventArgs args)
   {
      .. some code ..
   }

     ..
     Application.Idle += new EventHandler (OnIdle);


  The piece of code included with this mail work fine, but i don't 
succeed to read the attribute from the target of delegate.

  Everyone interested to complete the work? For typical OpenGL apps with 
animation, the idle loop is very useful...

  Thanks a lot!

  P.S. After vacancies my lab offer english course to researcher... i 
want to partecipate... :)

------------------------
-| Luciano Martorella  \-
---------------------------------
http://net.supereva.it/noinetcorp
---------------------------------

--------------060206090602060206040908
Content-Type: text/plain;
 name="Application.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Application.diff"

Index: Application.cs
===================================================================
RCS file: /mono/gtk-sharp/gtk/Application.cs,v
retrieving revision 1.11
diff -u -p -r1.11 Application.cs
--- Application.cs	25 Mar 2003 16:57:05 -0000	1.11
+++ Application.cs	19 Dec 2003 19:47:50 -0000
@@ -9,6 +9,7 @@ namespace Gtk {
 	using System;
 	using System.Runtime.InteropServices;
 	using Gdk;
+	using GtkSharp;
 
 	public class Application {
 
@@ -173,5 +174,77 @@ namespace Gtk {
 				return null;
 			}
 		}
+		
+
+
+
+
+
+
+
+
+
+		[DllImport("libgtk-win32-2.0-0.dll")]
+		static extern void gtk_idle_remove (uint idle_handler_id);
+		[DllImport("libgtk-win32-2.0-0.dll")]
+		static extern uint gtk_idle_add_priority (int priority, GtkSharp.FunctionNative function, IntPtr data);
+
+		class _IdleCallback 
+		{
+			public uint			id;
+			public Delegate 	handler;
+		}			
+		
+		// Hashtable of callbacks (grouped by priority)
+		static Collections.Hashtable 	_IdleInstances = new Collections.Hashtable ();
+	
+		// The low level callback 
+		private static bool 		IdleCallback (IntPtr context)
+		{
+			int priority = (int)context;
+			_IdleCallback cb = _IdleInstances[priority] as _IdleCallback;
+			if (cb == null)
+				throw new Exception ("wrong context in IdleCallback");
+			EventHandler handler = (EventHandler) cb.handler;
+			handler (null, new EventArgs ());
+			return true;
+		}
+
+		static private int GetIdlePriority (Delegate f)
+		{
+			IdlePriorityAttribute attr = Attribute.GetCustomAttribute (f.Method.GetType(), typeof (IdlePriorityAttribute)) as IdlePriorityAttribute;
+			if (attr != null)
+				return attr.Priority;
+			return (int)IdlePriorityEnum.Redraw;
+		}
+	
+		static public event EventHandler Idle {
+			add {
+				int priority = GetIdlePriority (value);					
+				Console.WriteLine ("Add: Priority {0}", priority);
+				_IdleCallback cb = _IdleInstances [priority] as _IdleCallback;
+				if (cb == null) {
+					cb = new _IdleCallback ();
+					cb.id = gtk_idle_add_priority (priority, 
+												   new GtkSharp.FunctionNative (IdleCallback), 
+												   (IntPtr)priority);
+					cb.handler = value;
+					_IdleInstances[priority] = cb; 
+				}
+				else
+					cb.handler = Delegate.Combine (cb.handler, value);
+			}
+			remove {
+				int priority = GetIdlePriority (value);					
+				Console.WriteLine ("Remove: Priority {0}", priority);
+				_IdleCallback cb = _IdleInstances [priority] as _IdleCallback;
+				cb.handler = Delegate.Remove (cb.handler, value);
+				if (cb.handler == null) {
+					gtk_idle_remove (cb.id);
+					_IdleInstances.Remove (priority);
+				}
+			}
+		}
 	}
 }
+

--------------060206090602060206040908
Content-Type: text/plain;
 name="IdlePriority.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="IdlePriority.cs"


// GTK.IdlePriority.cs - GTK Priority attribute of Idle callback implementation
//
// Author: Luciano Martorella <mad_lux_it@users.sourceforge.net>
//
// (c) 2003 Luciano Martorella


using System;

namespace GtkSharp {

	public enum IdlePriorityEnum
	{
		High = -100,
		Default = 0,
		HighIdle = 100,
		Resize = 110,
		Redraw = 120,
		DefaultIdle = 200,
		Low = 300
	}

	[AttributeUsage (AttributeTargets.Method)]
	public class IdlePriorityAttribute : Attribute 
	{
		private int priority;
		
		public IdlePriorityAttribute (IdlePriorityEnum e, int modifier)
		{
			priority = (int)e + modifier;
		} 
		public IdlePriorityAttribute (IdlePriorityEnum e)
		{
			priority = (int)e;
		} 
		public int Priority
		{
			get { return priority; }
		}
	} 

}

--------------060206090602060206040908--