[f-spot: 27/41] wow, the managed Layout works



commit 905e4e12f0e249438ebfc643d6d4b55d94fda06c
Author: Stephane Delcroix <stephane delcroix org>
Date:   Thu Jun 11 10:44:10 2009 +0200

    wow, the managed Layout works

 src/Makefile.am          |    1 +
 src/Widgets/ImageView.cs |   11 +--
 src/Widgets/Layout.cs    |  285 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 289 insertions(+), 8 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7f08e71..cb92663 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,6 +83,7 @@ WIDGETS_CSDISTFILES =				\
 	$(srcdir)/Widgets/DateEditFlags.cs	\
 	$(srcdir)/Widgets/HighlightedBox.cs	\
 	$(srcdir)/Widgets/ImageView.cs		\
+	$(srcdir)/Widgets/Layout.cs		\
 	$(srcdir)/Widgets/MenuButton.cs		\
 	$(srcdir)/Widgets/OpenWithMenu.cs	\
 	$(srcdir)/Widgets/PointerMode.cs	\
diff --git a/src/Widgets/ImageView.cs b/src/Widgets/ImageView.cs
index 0f38825..59da448 100644
--- a/src/Widgets/ImageView.cs
+++ b/src/Widgets/ImageView.cs
@@ -155,16 +155,13 @@ Console.WriteLine ("DoZoom");
 			x_anchor = (double)(Hadjustment.Value + x) / (double)Width;
 			y_anchor = (double)(Vadjustment.Value + y) / (double)Height;
 
-//			BinWindow.Clear ();
-frozen = true;
-			UpdateScaledSize ();
+      			UpdateScaledSize ();
 			Hadjustment.Value = x_anchor * Width - x;
 			Vadjustment.Value = y_anchor * Height - y;
 
 			EventHandler eh = ZoomChanged;
 			if (eh != null)
 				eh (this, EventArgs.Empty);
-frozen = false;
 			QueueDraw ();
 		}
 
@@ -226,15 +223,11 @@ frozen = false;
 		{
 		}
 
-bool frozen = false;
 		void PaintRectangle (Rectangle area, InterpType interpolation)
 		{
-if (frozen)
-	return;
 Console.WriteLine ("PaintRectangle {0}", area);
 			int x_offset = (int)Width < Allocation.Width ? (Allocation.Width - (int)Width) / 2 : -XOffset;
 			int y_offset = (int)Height < Allocation.Height ? (Allocation.Height - (int)Height) / 2 : -YOffset;
-
 			//Draw background
 			if (y_offset > 0) 	//Top
 				PaintBackground (new Rectangle (0, 0, Allocation.Width, y_offset), area);
@@ -289,6 +282,7 @@ Console.WriteLine ("PaintRectangle {0}", area);
 
 		protected override void OnSizeAllocated (Rectangle allocation)
 		{
+Console.WriteLine ("ImageView.OnSizeAllocated");
 			if (Pixbuf == null)
 				min_zoom = 0.1;
 			else {
@@ -310,6 +304,7 @@ Console.WriteLine ("PaintRectangle {0}", area);
 
 		protected override bool OnExposeEvent (EventExpose evnt)
 		{
+Console.WriteLine ("ImageView.OnExposeEvent");
 			if (evnt == null)
 				return true;
 
diff --git a/src/Widgets/Layout.cs b/src/Widgets/Layout.cs
new file mode 100644
index 0000000..de9ef68
--- /dev/null
+++ b/src/Widgets/Layout.cs
@@ -0,0 +1,285 @@
+//
+// FSpot.Widgets.Layout.cs
+//
+// Author(s):
+//	Stephane Delcroix  <stephane delcroix org>
+//
+// Port GtkLayout to managed, to have a finer control over the drawing process
+//
+// This is free software. See COPYING for details.
+//
+
+using System;
+using System.Collections.Generic;
+
+namespace FSpot.Widgets
+{
+	public class Layout : Gtk.Container
+	{
+		public Layout () : this (null, null)
+		{
+		}
+
+		public Layout (Gtk.Adjustment hadjustment, Gtk.Adjustment vadjustment) : base ()
+		{
+			OnSetScrollAdjustments (hadjustment, vadjustment);
+			children = new List<LayoutChild> ();
+		}
+
+		Gdk.Window bin_window = null;
+		public Gdk.Window BinWindow {
+			get { return bin_window; }
+		}
+
+		Gtk.Adjustment hadjustment;
+		public Gtk.Adjustment Hadjustment {
+			get { return hadjustment; }
+			set { OnSetScrollAdjustments (hadjustment, Vadjustment); }
+		}
+
+		Gtk.Adjustment vadjustment;
+		public Gtk.Adjustment Vadjustment {
+			get { return vadjustment; }
+			set { OnSetScrollAdjustments (Hadjustment, vadjustment); }
+		}
+
+		uint width = 100;
+		public uint Width {
+			get { return width; }
+		}
+
+		uint height = 100;
+		public uint Height {
+			get { return height; }
+		}
+
+		class LayoutChild {
+			Gtk.Widget widget;
+			public Gtk.Widget Widget {
+				get { return widget; }
+			}
+
+			int x;
+			public int X {
+				get { return x; } 
+				set { x = value; }
+			}
+
+			int y;
+			public int Y {
+				get { return y; }
+				set { y = value; }
+			}
+
+			public LayoutChild (Gtk.Widget widget, int x, int y)
+			{
+				this.widget = widget;
+				this.x = x;
+				this.y = y;
+			}
+		}
+
+		List<LayoutChild> children;
+		public void Put (Gtk.Widget widget, int x, int y)
+		{
+			children.Add (new LayoutChild (widget, x, y));
+			if (IsRealized)
+				widget.ParentWindow = bin_window;
+			widget.Parent = this;
+		}
+
+		public void Move (Gtk.Widget widget, int x, int y)
+		{
+			LayoutChild child = GetChild (widget);
+			if (child == null)
+				return;
+
+			child.X = x;
+			child.Y = y;
+			if (Visible && widget.Visible)
+				QueueResize ();
+		}
+
+		public void SetSize (uint width, uint height)
+		{
+			Hadjustment.Upper = this.width = width;
+			Vadjustment.Upper = this.height = height;
+			
+			if (IsRealized) {
+				bin_window.Resize ((int)Math.Max (width, Allocation.Width), (int)Math.Max (height, Allocation.Height));
+			}
+		}
+
+		LayoutChild GetChild (Gtk.Widget widget)
+		{
+			foreach (var child in children)
+				if (child.Widget == widget)
+					return child;
+			return null;
+		}
+		
+#region widgetry
+		protected override void OnRealized ()
+		{
+			SetFlag (Gtk.WidgetFlags.Realized);
+
+			Gdk.WindowAttr attributes = new Gdk.WindowAttr {
+							     WindowType = Gdk.WindowType.Child,
+							     X = Allocation.X,
+							     Y = Allocation.Y,
+							     Width = Allocation.Width,
+							     Height = Allocation.Height,
+							     Wclass = Gdk.WindowClass.InputOutput,
+							     Visual = this.Visual,
+							     Colormap = this.Colormap,
+							     Mask = Gdk.EventMask.VisibilityNotifyMask };
+			GdkWindow = new Gdk.Window (ParentWindow, attributes, 
+						    Gdk.WindowAttributesType.X | Gdk.WindowAttributesType.Y | Gdk.WindowAttributesType.Visual | Gdk.WindowAttributesType.Colormap);
+
+			GdkWindow.SetBackPixmap (null, false);
+			GdkWindow.UserData = Handle;
+
+			attributes = new Gdk.WindowAttr {
+							     WindowType = Gdk.WindowType.Child, 
+							     X = (int)-Hadjustment.Value,
+							     Y = (int)-Vadjustment.Value,
+							     Width = (int)Math.Max (width, Allocation.Width),
+							     Height = (int)Math.Max (height, Allocation.Height),
+							     Wclass = Gdk.WindowClass.InputOutput,
+							     Visual = this.Visual,
+							     Colormap = this.Colormap,
+							     Mask = Gdk.EventMask.ExposureMask | Gdk.EventMask.ScrollMask | this.Events };
+			bin_window = new Gdk.Window (GdkWindow, attributes, 
+						     Gdk.WindowAttributesType.X | Gdk.WindowAttributesType.Y | Gdk.WindowAttributesType.Visual | Gdk.WindowAttributesType.Colormap);
+			bin_window.UserData = Handle;
+
+			Style.Attach (GdkWindow);
+			Style.SetBackground (bin_window, Gtk.StateType.Normal);
+
+			foreach (var child in children) {
+				child.Widget.ParentWindow = bin_window;
+			}
+
+		}
+
+		protected override void OnUnrealized ()
+		{
+			bin_window.Destroy ();
+			bin_window = null;
+
+			base.OnUnrealized ();
+		}
+
+		protected override void OnStyleSet (Gtk.Style old_style)
+		{
+			base.OnStyleSet (old_style);
+			if (IsRealized)
+				Style.SetBackground (bin_window, Gtk.StateType.Normal);
+		}
+
+		protected override void OnMapped ()
+		{
+			SetFlag (Gtk.WidgetFlags.Mapped);
+
+			foreach (var child in children) {
+				if (child.Widget.Visible && !child.Widget.IsMapped)
+					child.Widget.Map ();
+			}
+			bin_window.Show ();
+			GdkWindow.Show ();
+		}
+
+		protected override void OnSizeRequested (ref Gtk.Requisition requisition)
+		{
+			requisition.Width = requisition.Height = 0;
+
+			foreach (var child in children) {
+				child.Widget.SizeRequest ();
+			}
+		}
+
+		protected override void OnSizeAllocated (Gdk.Rectangle allocation)
+		{
+			foreach (var child in children) {
+				Gtk.Requisition req = child.Widget.ChildRequisition;
+				child.Widget.SizeAllocate (new Gdk.Rectangle (child.X, child.Y, req.Width, req.Height));
+			}
+
+			if (IsRealized) {
+				GdkWindow.MoveResize (allocation.X, allocation.Y, allocation.Width, allocation.Height);
+				bin_window.Resize ((int)Math.Max (width, allocation.Width), (int)Math.Max (height, allocation.Height));
+			}
+
+			Hadjustment.PageSize = allocation.Width;
+			Hadjustment.PageIncrement = Width * .9;
+			Hadjustment.Lower = 0;
+			Hadjustment.Upper = Math.Max (width, allocation.Width);
+
+			Vadjustment.PageSize = allocation.Height;
+			Vadjustment.PageIncrement = Height * .9;
+			Vadjustment.Lower = 0;
+			Vadjustment.Upper = Math.Max (height, allocation.Height);
+			base.OnSizeAllocated (allocation);
+		}
+
+		protected override bool OnExposeEvent (Gdk.EventExpose evnt)
+		{
+			if (evnt.Window != bin_window)
+				return false;
+
+			return base.OnExposeEvent (evnt);
+		}
+
+		protected override void OnSetScrollAdjustments (Gtk.Adjustment hadjustment, Gtk.Adjustment vadjustment)
+		{
+Console.WriteLine ("\n\nLayout.OnSetScrollAdjustments");
+			if (hadjustment == null)
+				hadjustment = new Gtk.Adjustment (0, 0, 0, 0, 0, 0);
+			if (vadjustment == null)
+				vadjustment = new Gtk.Adjustment (0, 0, 0, 0, 0, 0);
+			if (Hadjustment != hadjustment) {
+				this.hadjustment = hadjustment;
+				this.hadjustment.Upper = Width;
+				this.hadjustment.ValueChanged += delegate {Console.WriteLine ("Hadjustment.ValueChanged");};
+			}
+			if (Vadjustment != vadjustment) {
+				this.vadjustment = vadjustment;
+				this.vadjustment.Upper = Width;
+				this.vadjustment.ValueChanged += delegate {Console.WriteLine ("Vadjustment.ValueChanged");};
+			}
+
+			//FIXME: trigger the AdjustmentChanged
+		}
+#endregion widgetry
+
+#region container stuffs
+		protected override void OnAdded (Gtk.Widget widget)
+		{
+			Put (widget, 0, 0);
+		}
+
+		protected override void OnRemoved (Gtk.Widget widget)
+		{
+			LayoutChild child = null;
+			foreach (var c in children) {
+				if (child.Widget == widget) {
+					child = c;
+					break;
+				}
+			}
+
+			if (child != null) {
+				widget.Unparent ();
+				children.Remove (child);
+			}
+		}
+
+		protected override void ForAll (bool include_internals, Gtk.Callback callback)
+		{
+			foreach (var child in children) {
+				callback (child.Widget);
+			}
+		}
+#endregion
+	}
+}



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