[ease/bindings] Working on transformations.



commit 59ee4506ca6dc0ad3a0f52c986b24ac2b76ee454
Author: Nate Stedman <natesm gmail com>
Date:   Sat Aug 21 04:06:20 2010 -0400

     Working on transformations.

 ease-bindings/bindings-test.vala |   15 +++++-
 ease-bindings/bindings.vala      |  105 ++++++++++++++++++++++++++------------
 2 files changed, 86 insertions(+), 34 deletions(-)
---
diff --git a/ease-bindings/bindings-test.vala b/ease-bindings/bindings-test.vala
index 3daa811..35bbf8a 100644
--- a/ease-bindings/bindings-test.vala
+++ b/ease-bindings/bindings-test.vala
@@ -22,9 +22,19 @@ public int main(string[] args)
 	// create bound GTK widgets
 	var scale = new Gtk.HScale.with_range(0, 10, 0.1);
 	var spin = new Gtk.SpinButton.with_range(0, 10, 0.1);
+	var entry = new Gtk.Entry();
 	
 	// bind the scale and spin buttons together
 	Binding.connect(spin, "value", scale.adjustment, "value");
+	Binding.transformed(spin, "value", (val) => {
+		var number = GLib.Value(typeof(string));
+		//number.set_string(val.get_double().to_string());
+		return number;
+	},                  entry, "text", (val) => {
+		var number = GLib.Value(typeof(double));
+		//number.set_double(val.get_string().to_double());
+		return number;
+	});
 	
 	// create a button to drop the binding
 	var button = new Gtk.Button.with_label("Drop Binding");
@@ -39,7 +49,10 @@ public int main(string[] args)
 	hbox.pack_start(spin, false, false, 0);
 	hbox.pack_start(scale, true, true, 0);
 	hbox.pack_start(button, false, false, 0);
-	window.add(hbox);
+	var vbox = new Gtk.VBox(false, 5);
+	vbox.pack_start(hbox, false, false, 0);
+	vbox.pack_start(entry, false, false, 0);
+	window.add(vbox);
 	
 	// show the window
 	window.show_all();
diff --git a/ease-bindings/bindings.vala b/ease-bindings/bindings.vala
index d9ac815..02176da 100644
--- a/ease-bindings/bindings.vala
+++ b/ease-bindings/bindings.vala
@@ -50,6 +50,17 @@ namespace Binding
 		bindings().add(new Binding(object1, property1, object2, property2));
 	}
 	
+	public void transformed(GLib.Object object1, string property1,
+	                        TransformFunction transform_function1,
+	                        GLib.Object object2, string property2,
+	                        TransformFunction transform_function2)
+	{
+		bindings().add(new Binding.transformed(object1, property1,
+		                                       transform_function1,
+		                                       object2, property2,
+		                                       transform_function2));
+	}
+	
 	/**
 	 * Drops a binding. Order does not need to match the order in which
 	 * 
@@ -149,43 +160,14 @@ namespace Binding
 		foreach (var binding in bindings())
 		{
 			if (binding.silence) continue;
-			if (object == binding.obj1 && pspec.name == binding.prop1)
-			{
-				// don't loop on this binding
-				binding.silence = true;
-				
-				// perform the set
-				set_binding(object, pspec.name, binding.obj2, binding.prop2);
-				
-				// start acting on this binding again
-				binding.silence = false;
-			}
-			else if (object == binding.obj2 && pspec.name == binding.prop2)
+			if ((object == binding.obj1 && pspec.name == binding.prop1) ||
+			    (object == binding.obj2 && pspec.name == binding.prop2))
 			{
-				// don't loop on this binding
-				binding.silence = true;
-				
-				// perform the set
-				set_binding(object, pspec.name, binding.obj1, binding.prop1);
-				
-				// start acting on this binding again
-				binding.silence = false;
+				binding.apply(object);
 			}
 		}
 	}
 	
-	private void set_binding(GLib.Object from, string from_prop,
-	                         GLib.Object to, string to_prop)
-	{
-		// get the value from the sender
-		var type = from.get_class().find_property(from_prop).value_type;
-		var storage = GLib.Value(type);
-		from.get_property(from_prop, ref storage);
-		
-		// set the value on the bound object
-		to.set_property(to_prop, storage);
-	}
-	
 	private void connect_signals(GLib.Object obj1, string prop1,
 	                             GLib.Object obj2, string prop2)
 	{
@@ -217,6 +199,11 @@ namespace Binding
 	public delegate bool DropFunction(GLib.Object object1, string property1,
 	                                  GLib.Object object2, string property2);
 	
+	/**
+	 * Transforms one type into another.
+	 */
+	public delegate GLib.Value TransformFunction(GLib.Value value_in);
+	
 	private class Binding : GLib.Object
 	{
 		public weak GLib.Object obj1;
@@ -224,6 +211,8 @@ namespace Binding
 		public string prop1;
 		public string prop2;
 		public bool silence = false;
+		private TransformFunction func1;
+		private TransformFunction func2;
 		
 		public Binding(GLib.Object o1, string p1, GLib.Object o2, string p2)
 		{
@@ -234,7 +223,7 @@ namespace Binding
 			prop2 = p2;
 			
 			// perform initial synchronization
-			set_binding(o1, p1, o2, p2);
+			apply(o1);
 			
 			// connect signal handlers
 			connect_signals(o1, p1, o2, p2);
@@ -243,6 +232,56 @@ namespace Binding
 			o1.weak_ref(drop_object);
 			o2.weak_ref(drop_object);
 		}
+		
+		public Binding.transformed(GLib.Object o1, string p1,
+		                           TransformFunction f1,
+		                           GLib.Object o2, string p2,
+		                           TransformFunction f2)
+		{
+			func1 = f1;
+			func2 = f2;
+			this(o1, p1, o2, p2);
+		}
+		
+		public void apply(GLib.Object from)
+		{
+			// don't apply a silenced binding
+			if (silence) return;
+			
+			// don't loop on this binding
+			silence = true;
+			
+			GLib.Object to;
+			string from_prop, to_prop;
+			TransformFunction func = null;
+				
+			if (from == obj1)
+			{
+				from_prop = prop1;
+				to_prop = prop2;
+				to = obj2;
+				func = func1;
+			}
+			else if (from == obj2)
+			{
+				from_prop = prop2;
+				to_prop = prop1;
+				to = obj1;
+				func = func2;
+			}
+			else return; // this binding doesn't have that object
+		
+			// get the value from the sender
+			var type = from.get_class().find_property(from_prop).value_type;
+			var storage = GLib.Value(type);
+			from.get_property(from_prop, ref storage);
+		
+			// set the value on the bound object
+			to.set_property(to_prop, func == null ? storage : func(storage));
+			
+			// start acting on this binding again
+			silence = false;
+		}
 	}
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]