[hyena/canvas: 4/5] [Hyena.Gui.Canvas] Modify to be usable by ListView



commit 7af9ec50d3480d6916885f68cd031e9a77378ff3
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Thu Oct 21 18:53:00 2010 -0500

    [Hyena.Gui.Canvas] Modify to be usable by ListView

 Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs    |   49 +++-----------
 Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs    |   99 +++++++++++++++++++++++---
 Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs |    2 +-
 Hyena.Gui/Hyena.Gui.Canvas/FpsCalculator.cs |   67 ++++++++++++++++++
 Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs   |   39 +++++++++++
 Hyena.Gui/Hyena.Gui.Canvas/ImageBrush.cs    |    4 +-
 Hyena.Gui/Hyena.Gui.Canvas/Panel.cs         |   55 +++++++--------
 Hyena.Gui/Hyena.Gui.Canvas/Slider.cs        |   26 ++++----
 Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs     |   47 ++++++++++++-
 9 files changed, 291 insertions(+), 97 deletions(-)
---
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs b/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs
index db20cf5..6eb7e1e 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/CanvasHost.cs
@@ -32,40 +32,7 @@ using Hyena.Gui.Theming;
 
 namespace Hyena.Gui.Canvas
 {
-    public class FpsCalculator
-    {
-        private DateTime last_update;
-        private TimeSpan update_interval;
-        private int frame_count;
-        private double fps;
-
-        public FpsCalculator ()
-        {
-            update_interval = TimeSpan.FromSeconds (0.5);
-        }
-
-        public bool Update ()
-        {
-            bool updated = false;
-            DateTime current_time = DateTime.Now;
-            frame_count++;
-
-            if (current_time - last_update >= update_interval) {
-                fps = (double)frame_count / (current_time - last_update).TotalSeconds;
-                frame_count = 0;
-                updated = true;
-                last_update = current_time;
-            }
-
-            return updated;
-        }
-
-        public double FramesPerSecond {
-            get { return fps; }
-        }
-    }
-
-    public class CanvasHost : Widget
+    public class CanvasHost : Widget, ICanvasHost
     {
         private Gdk.Window event_window;
         private CanvasItem canvas_child;
@@ -73,6 +40,7 @@ namespace Hyena.Gui.Canvas
         private CanvasManager manager;
         private bool debug = false;
         private FpsCalculator fps = new FpsCalculator ();
+        private Hyena.Data.Gui.CellContext context = new Hyena.Data.Gui.CellContext ();
 
         public CanvasHost ()
         {
@@ -170,13 +138,14 @@ namespace Hyena.Gui.Canvas
             }
 
             Cairo.Context cr = Gdk.CairoHelper.Create (evnt.Window);
+            context.Context = cr;
 
             foreach (Gdk.Rectangle damage in evnt.Region.GetRectangles ()) {
                 cr.Rectangle (damage.X, damage.Y, damage.Width, damage.Height);
                 cr.Clip ();
 
                 cr.Translate (Allocation.X, Allocation.Y);
-                canvas_child.Render (cr);
+                canvas_child.Render (context);
                 cr.Translate (-Allocation.X, -Allocation.Y);
 
                 if (Debug) {
@@ -258,18 +227,18 @@ namespace Hyena.Gui.Canvas
             base.OnStyleSet (old_style);
         }
 
-        protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
+        protected override bool OnButtonPressEvent (Gdk.EventButton press)
         {
             if (canvas_child != null) {
-                canvas_child.ButtonPress (evnt.X, evnt.Y, evnt.Button);
+                canvas_child.ButtonEvent (new Point (press.X, press.Y), true, press.Button);
             }
             return true;
         }
 
-        protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt)
+        protected override bool OnButtonReleaseEvent (Gdk.EventButton press)
         {
             if (canvas_child != null) {
-                canvas_child.ButtonRelease ();
+                canvas_child.ButtonEvent (new Point (press.X, press.Y), false, press.Button);
             }
             return true;
         }
@@ -277,7 +246,7 @@ namespace Hyena.Gui.Canvas
         protected override bool OnMotionNotifyEvent (EventMotion evnt)
         {
             if (canvas_child != null) {
-                canvas_child.PointerMotion (evnt.X, evnt.Y);
+                canvas_child.CursorMotionEvent (new Point (evnt.X, evnt.Y));
             }
             return true;
         }
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs b/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs
index cd4121e..30f09f9 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs
@@ -44,12 +44,23 @@ namespace Hyena.Gui.Canvas
         public event EventHandler<EventArgs> SizeChanged;
         public event EventHandler<EventArgs> LayoutUpdated;
 
+        private class MemoryDataBinder : Hyena.Data.IDataBinder
+        {
+            public void Bind (object o)
+            {
+                BoundObject = o;
+            }
+
+            public object BoundObject { get; set; }
+        }
+
         public CanvasItem ()
         {
             InstallProperty<double> ("Opacity", 1.0);
             InstallProperty<double> ("Width", Double.NaN);
             InstallProperty<double> ("Height", Double.NaN);
             InstallProperty<Thickness> ("Margin", new Thickness (0));
+            InstallProperty<Thickness> ("Padding", new Thickness (0));
             InstallProperty<Brush> ("Foreground", Brush.Black);
             InstallProperty<Brush> ("Background", Brush.White);
             InstallProperty<MarginStyle> ("MarginStyle", MarginStyle.None);
@@ -76,12 +87,48 @@ namespace Hyena.Gui.Canvas
             InvalidateRender (InvalidationRect);
         }
 
+        public void Invalidate (Rect area)
+        {
+            InvalidateRender (area);
+        }
+
         protected void InvalidateRender (Rect area)
         {
+            if (Parent == null) {
+                OnInvalidate (area);
+            } else {
+                var alloc = Parent.ContentAllocation;
+                area.Offset (alloc.X, alloc.Y);
+                Parent.Invalidate (area);
+            }
+        }
+
+        private void OnInvalidate (Rect area)
+        {
             CanvasItem root = RootAncestor;
             if (root != null && root.Manager != null) {
                 root.Manager.QueueRender (this, area);
+            } else {
+                Hyena.Log.WarningFormat ("Asked to invalidate {0} for {1} but no CanvasManager!", area, this);
+            }
+        }
+
+        private Hyena.Data.IDataBinder binder;
+        public Hyena.Data.IDataBinder Binder {
+            get {
+                return binder ?? (binder = new MemoryDataBinder ());
             }
+            set { binder = value; }
+        }
+
+        public virtual void Bind (object o)
+        {
+            Binder.Bind (o);
+        }
+
+        protected object BoundObject {
+            get { return Binder.BoundObject; }
+            set { Binder.BoundObject = value; }
         }
 
         public virtual void Arrange ()
@@ -102,8 +149,9 @@ namespace Hyena.Gui.Canvas
             );
         }
 
-        public virtual void Render (Cairo.Context cr)
+        public void Render (Hyena.Data.Gui.CellContext context)
         {
+            var cr = context.Context;
             double opacity = Opacity;
 
             if (ContentAllocation.Width <= 0 || ContentAllocation.Height <= 0 || opacity <= 0) {
@@ -128,7 +176,8 @@ namespace Hyena.Gui.Canvas
             }
 
             cr.Antialias = Cairo.Antialias.Default;
-            ClippedRender (cr);
+
+            ClippedRender (context);
 
             if (opacity < 1.0) {
                 cr.PopGroupToSource ();
@@ -142,6 +191,11 @@ namespace Hyena.Gui.Canvas
         {
         }
 
+        protected virtual void ClippedRender (Hyena.Data.Gui.CellContext context)
+        {
+            ClippedRender (context.Context);
+        }
+
         protected virtual void OnSizeChanged ()
         {
             EventHandler<EventArgs> handler = SizeChanged;
@@ -165,8 +219,8 @@ namespace Hyena.Gui.Canvas
 
         public CanvasItem RootAncestor {
             get {
-                CanvasItem root = Parent ?? this;
-                while (root != null && root.Parent != null) {
+                CanvasItem root = this;
+                while (root.Parent != null) {
                     root = root.Parent;
                 }
                 return root;
@@ -188,6 +242,11 @@ namespace Hyena.Gui.Canvas
             protected set { desired_size = value; }
         }
 
+        public Thickness Padding {
+            get { return GetValue<Thickness> ("Padding"); }
+            set { SetValue<Thickness> ("Padding", value); }
+        }
+
         public Thickness Margin {
             get { return GetValue<Thickness> ("Margin"); }
             set { SetValue<Thickness> ("Margin", value); }
@@ -239,8 +298,12 @@ namespace Hyena.Gui.Canvas
             }
         }
 
+        // FIXME need this?
+        public Rect VirtualAllocation { get; set; }
+
         protected virtual Rect InvalidationRect {
-            get { return Rect.Empty; }
+            //get { return Rect.Empty; }
+            get { return Allocation; }
         }
 
         public Size ContentSize {
@@ -359,7 +422,7 @@ namespace Hyena.Gui.Canvas
 
 #region Input Events
 
-        public event EventHandler<EventArgs> Clicked;
+        //public event EventHandler<EventArgs> Clicked;
 
         private bool pointer_grabbed;
         public virtual bool IsPointerGrabbed {
@@ -376,28 +439,40 @@ namespace Hyena.Gui.Canvas
             pointer_grabbed = false;
         }
 
-        public virtual void ButtonPress (double x, double y, uint button)
+        public virtual bool ButtonEvent (Point press, bool pressed, uint button)
         {
-            GrabPointer ();
+            //GrabPointer ();
+            return false;
         }
 
-        public virtual void ButtonRelease ()
+        /*public virtual void ButtonRelease ()
         {
             ReleasePointer ();
             OnClicked ();
+        }*/
+
+        public virtual bool CursorMotionEvent (Point cursor)
+        {
+            return false;
+        }
+
+        public virtual bool CursorEnterEvent ()
+        {
+            return false;
         }
 
-        public virtual void PointerMotion (double x, double y)
+        public virtual bool CursorLeaveEvent ()
         {
+            return false;
         }
 
-        protected virtual void OnClicked ()
+        /*protected virtual void OnClicked ()
         {
             var handler = Clicked;
             if (handler != null) {
                 handler (this, EventArgs.Empty);
             }
-        }
+        }*/
 
 #endregion
 
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs b/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs
index ca5badb..eac25e5 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/CanvasManager.cs
@@ -49,7 +49,7 @@ namespace Hyena.Gui.Canvas
 
         public void QueueRender (CanvasItem item, Rect rect)
         {
-            CanvasHost host = Host as CanvasHost;
+            ICanvasHost host = Host as ICanvasHost;
             if (host == null) {
                 return;
             }
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/FpsCalculator.cs b/Hyena.Gui/Hyena.Gui.Canvas/FpsCalculator.cs
new file mode 100644
index 0000000..1d4b367
--- /dev/null
+++ b/Hyena.Gui/Hyena.Gui.Canvas/FpsCalculator.cs
@@ -0,0 +1,67 @@
+//
+// FpsCalculator.cs
+//
+// Author:
+//       Aaron Bockover <abockover novell com>
+//
+// Copyright 2009 Aaron Bockover
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using Gtk;
+using Gdk;
+
+using Hyena.Gui.Theming;
+
+namespace Hyena.Gui.Canvas
+{
+    public class FpsCalculator
+    {
+        private DateTime last_update;
+        private TimeSpan update_interval;
+        private int frame_count;
+        private double fps;
+
+        public FpsCalculator ()
+        {
+            update_interval = TimeSpan.FromSeconds (0.5);
+        }
+
+        public bool Update ()
+        {
+            bool updated = false;
+            DateTime current_time = DateTime.Now;
+            frame_count++;
+
+            if (current_time - last_update >= update_interval) {
+                fps = (double)frame_count / (current_time - last_update).TotalSeconds;
+                frame_count = 0;
+                updated = true;
+                last_update = current_time;
+            }
+
+            return updated;
+        }
+
+        public double FramesPerSecond {
+            get { return fps; }
+        }
+    }
+}
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs b/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs
new file mode 100644
index 0000000..9abc395
--- /dev/null
+++ b/Hyena.Gui/Hyena.Gui.Canvas/ICanvasHost.cs
@@ -0,0 +1,39 @@
+//
+// ICanvasHost.cs
+//
+// Author:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright 2010 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using Gtk;
+using Gdk;
+
+using Hyena.Gui.Theming;
+
+namespace Hyena.Gui.Canvas
+{
+    public interface ICanvasHost
+    {
+        void QueueRender (CanvasItem item, Rect rect);
+    }
+}
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/ImageBrush.cs b/Hyena.Gui/Hyena.Gui.Canvas/ImageBrush.cs
index e30405a..4ff7053 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/ImageBrush.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/ImageBrush.cs
@@ -34,7 +34,7 @@ namespace Hyena.Gui.Canvas
     public class ImageBrush : Brush
     {
         private ImageSurface surface;
-        private bool surface_owner;
+        //private bool surface_owner;
 
         public ImageBrush ()
         {
@@ -52,7 +52,7 @@ namespace Hyena.Gui.Canvas
         public ImageBrush (ImageSurface surface, bool disposeSurface)
         {
             this.surface = surface;
-            this.surface_owner = disposeSurface;
+            //this.surface_owner = disposeSurface;
         }
 
         protected ImageSurface Surface {
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs b/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs
index f2effc8..2200bea 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs
@@ -25,6 +25,7 @@
 // THE SOFTWARE.
 
 using System;
+using System.Linq;
 
 namespace Hyena.Gui.Canvas
 {
@@ -80,61 +81,59 @@ namespace Hyena.Gui.Canvas
             }
         }
 
-        protected override void ClippedRender (Cairo.Context cr)
+        protected override void ClippedRender (Hyena.Data.Gui.CellContext context)
         {
             foreach (var child in Children) {
                 if (child.Visible) {
-                    child.Render (cr);
+                    child.Render (context);
                 }
             }
         }
 
-        protected CanvasItem FindChildAt (double x, double y, bool grabHasPriority)
+        public override void Bind (object o)
         {
             foreach (var child in Children) {
-                if (child.IsPointerGrabbed || (child.Visible && child.Allocation.Contains (x, y))) {
-                    return child;
-                }
+                child.Bind (o);
             }
-
-            return null;
         }
 
-        protected delegate void CanvasItemHandler (CanvasItem item);
-
-        protected void WithPointerGrabChild (CanvasItemHandler handler)
+        protected CanvasItem FindChildAt (Point pt, bool grabHasPriority)
         {
-            WithChildAt (-1, -1, true, handler);
+            return FindChildAt (pt.X, pt.Y, grabHasPriority);
         }
 
-        protected void WithChildAt (double x, double y, CanvasItemHandler handler)
+        protected CanvasItem FindChildAt (double x, double y, bool grabHasPriority)
         {
-            WithChildAt (x, y, true, handler);
-        }
+            if (grabHasPriority) {
+                var child = Children.FirstOrDefault (c => c.IsPointerGrabbed);
+                if (child != null)
+                    return child;
+            }
 
-        protected void WithChildAt (double x, double y, bool grabHasPriority, CanvasItemHandler handler)
-        {
-            CanvasItem child = FindChildAt (x, y, grabHasPriority);
-            if (child != null) {
-                handler (child);
+            foreach (var child in Children) {
+                if (child.IsPointerGrabbed || (child.Visible && child.Allocation.Contains (x, y))) {
+                    return child;
+                }
             }
+
+            return null;
         }
 
-        public override void ButtonPress (double x, double y, uint button)
+        public override bool ButtonEvent (Point cursor, bool pressed, uint button)
         {
-            WithChildAt (x, y, (item) => item.ButtonPress (
-                x - item.Allocation.X, y - item.Allocation.Y, button));
+            var child = FindChildAt (cursor, true);
+            return child == null ? false : child.ButtonEvent (ChildCoord (child, cursor), pressed, button);
         }
 
-        public override void ButtonRelease ()
+        public override bool CursorMotionEvent (Point cursor)
         {
-            WithPointerGrabChild ((item) => item.ButtonRelease ());
+            var child = FindChildAt (cursor, true);
+            return child == null ? false : child.CursorMotionEvent (ChildCoord (child, cursor));
         }
 
-        public override void PointerMotion (double x, double y)
+        private Point ChildCoord (CanvasItem item, Point pt)
         {
-            WithChildAt (x, y, (item) => item.PointerMotion (
-                x - item.Allocation.X, y - item.Allocation.Y));
+            return new Point (pt.X - item.Allocation.X, pt.Y - item.Allocation.Y);
         }
 
         public override bool IsPointerGrabbed {
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs b/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs
index 82dd6c1..2a58049 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs
@@ -84,28 +84,28 @@ namespace Hyena.Gui.Canvas
             PendingValue = Math.Max (0, Math.Min ((x - ThrobberSize / 2) / RenderSize.Width, 1));
         }
 
-        public override void ButtonPress (double x, double y, uint button)
+        public override bool ButtonEvent (Point cursor, bool pressed, uint button)
         {
-            if (button == 1) {
+            if (pressed && button == 1) {
                 GrabPointer ();
-                SetPendingValueFromX (x);
-            }
-        }
-
-        public override void ButtonRelease ()
-        {
-            if (IsPointerGrabbed) {
+                SetPendingValueFromX (cursor.X);
+                return true;
+            } else if (!pressed && IsPointerGrabbed) {
                 ReleasePointer ();
                 Value = PendingValue;
                 IsValueUpdatePending = false;
+                return true;
             }
+            return false;
         }
 
-        public override void PointerMotion (double x, double y)
+        public override bool CursorMotionEvent (Point cursor)
         {
             if (IsPointerGrabbed) {
-                SetPendingValueFromX (x);
+                SetPendingValueFromX (cursor.X);
+                return true;
             }
+            return false;
         }
 
         private double last_invalidate_value = -1;
@@ -137,14 +137,14 @@ namespace Hyena.Gui.Canvas
             InvalidateRender (region);
         }
 
-        protected override Rect InvalidationRect {
+        /*protected override Rect InvalidationRect {
             get { return new Rect (
                 -Margin.Left - ThrobberSize / 2,
                 -Margin.Top,
                 Allocation.Width + ThrobberSize,
                 Allocation.Height);
             }
-        }
+        }*/
 
         protected override void ClippedRender (Cairo.Context cr)
         {
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs b/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
index 3569bd6..7988ead 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
@@ -78,7 +78,8 @@ namespace Hyena.Gui.Canvas
             layout.Width = wrap == TextWrap.None ? -1 : (int)(Pango.Scale.PangoScale * available.Width);
             layout.Wrap = GetPangoWrapMode (wrap);
             layout.FontDescription.Weight = GetPangoFontWeight (FontWeight);
-            layout.SetText (Text);
+            layout.SingleParagraphMode = wrap == TextWrap.None;
+            UpdateLayout (layout, Text);
             layout.GetPixelSize (out text_w, out text_h);
 
             double width = text_w;
@@ -101,6 +102,29 @@ namespace Hyena.Gui.Canvas
             return DesiredSize;
         }
 
+        private static char[] lfcr = new char[] {'\n', '\r'};
+        private void UpdateLayout (Pango.Layout layout, string text)
+        {
+            string final_text = GetFormattedText (text);
+            if (TextWrap == TextWrap.None && final_text.IndexOfAny (lfcr) >= 0) {
+                final_text = final_text.Replace ("\r\n", "\x20").Replace ('\n', '\x20').Replace ('\r', '\x20');
+            }
+
+            if (UseMarkup) {
+                layout.SetMarkup (final_text);
+            } else {
+                layout.SetText (final_text);
+            }
+        }
+
+        private string GetFormattedText (string text)
+        {
+            if (TextFormat == null) {
+                return text;
+            }
+            return String.Format (TextFormat, UseMarkup ? GLib.Markup.EscapeText (text) : text);
+        }
+
         public override void Arrange ()
         {
             if (!EnsureLayout ()) {
@@ -227,11 +251,23 @@ namespace Hyena.Gui.Canvas
             get { return invalidation_rect; }
         }
 
+        public override void Bind (object o)
+        {
+            base.Bind (o);
+            var so = BoundObject;
+            Text = so == null ? "" : so.ToString ();
+        }
+
         public string Text {
             get { return GetValue<string> ("Text"); }
             set { SetValue<string> ("Text", value); }
         }
 
+        public string TextFormat {
+            get { return GetValue<string> ("TextFormat"); }
+            set { SetValue<string> ("TextFormat", value); }
+        }
+
         public FontWeight FontWeight {
             get { return GetValue<FontWeight> ("FontWeight"); }
             set { SetValue<FontWeight> ("FontWeight", value); }
@@ -247,6 +283,15 @@ namespace Hyena.Gui.Canvas
             set { SetValue<bool> ("ForceSize", value); }
         }
 
+        public virtual Pango.EllipsizeMode EllipsizeMode { get; set; }
+
+        public Func<object, string> TextGenerator { get; set; }
+
+        public bool UseMarkup {
+            get { return GetValue<bool> ("UseMarkup"); }
+            set { SetValue<bool> ("UseMarkup", value); }
+        }
+
         public double HorizontalAlignment {
             get { return GetValue<double> ("HorizontalAlignment", 0.5); }
             set { SetValue<double> ("HorizontalAlignment", value); }



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