[hyena/canvas] [Hyena.Gui] Add tooltip support to Hyena.Gui.Canvas



commit 4535f30c4176d6dd102b66761a33082a9fe6303d
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Mon Oct 25 21:20:50 2010 -0500

    [Hyena.Gui] Add tooltip support to Hyena.Gui.Canvas

 .../Accessibility/ListViewAccessible.cs            |    2 +-
 Hyena.Gui/Hyena.Data.Gui/ColumnCell.cs             |    5 --
 Hyena.Gui/Hyena.Data.Gui/ListView/ListView.cs      |   74 +++++++++++++------
 .../ListView/ListView_Interaction.cs               |    2 +-
 .../Hyena.Data.Gui/ListView/ListView_Rendering.cs  |    2 +-
 Hyena.Gui/Hyena.Gui.Canvas/AnimationManager.cs     |    1 +
 Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs           |   25 +++++--
 Hyena.Gui/Hyena.Gui.Canvas/Panel.cs                |   11 +++
 Hyena.Gui/Hyena.Gui.Canvas/Rect.cs                 |    4 +
 Hyena.Gui/Hyena.Gui.Canvas/Slider.cs               |    6 +-
 Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs            |   42 +++++++----
 11 files changed, 118 insertions(+), 56 deletions(-)
---
diff --git a/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible.cs b/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible.cs
index 0ebc6de..48220e2 100644
--- a/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/Accessibility/ListViewAccessible.cs
@@ -110,7 +110,7 @@ namespace Hyena.Data.Gui.Accessibility
                 int column = (index - n_columns) % n_columns;
                 int row = (index - n_columns) / n_columns;
                 var cell = columns.ElementAtOrDefault (column).GetCell (0);
-                cell.BindListItem (list_view.Model[row]);
+                cell.Bind (list_view.Model[row]);
                 child = (ColumnCellAccessible) cell.GetAccessible (this);
             }
 
diff --git a/Hyena.Gui/Hyena.Data.Gui/ColumnCell.cs b/Hyena.Gui/Hyena.Data.Gui/ColumnCell.cs
index 7a491ff..e342864 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ColumnCell.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ColumnCell.cs
@@ -65,11 +65,6 @@ namespace Hyena.Data.Gui
             set { ObjectBinder.Property = value; }
         }
 
-        public void BindListItem (object item)
-        {
-            Bind (item);
-        }
-
         public virtual void NotifyThemeChange ()
         {
         }
diff --git a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView.cs b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView.cs
index d1340fe..1f35928 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView.cs
@@ -28,6 +28,8 @@
 
 using System;
 
+using Hyena.Gui.Canvas;
+
 namespace Hyena.Data.Gui
 {
     public partial class ListView<T> : ListViewBase, IListView<T>
@@ -49,38 +51,62 @@ namespace Hyena.Data.Gui
 
         private void OnQueryTooltip (object o, Gtk.QueryTooltipArgs args)
         {
-            if (cell_context != null && cell_context.Layout != null && !args.KeyboardTooltip) {
-                ITooltipCell cell;
-                Column column;
-                int row_index;
+            if (!args.KeyboardTooltip) {
+                if (ViewLayout != null) {
+                    var pt = new Point (args.X - list_interaction_alloc.X, args.Y - list_interaction_alloc.Y);
+                    var child = ViewLayout.FindChildAtPoint (pt);
+                    if (child != null) {
+                        string markup;
+                        Rect area;
+                        pt.Offset (ViewLayout.ActualAllocation.Point);
+                        if (child.GetTooltipMarkupAt (pt, out markup, out area)) {
+                            area.Offset (-ViewLayout.ActualAllocation.X, -ViewLayout.ActualAllocation.Y);
+                            area.Offset (list_interaction_alloc.X, list_interaction_alloc.Y);
+                            args.Tooltip.Markup = markup;
+                            args.Tooltip.TipArea = (Gdk.Rectangle)area;
+                            /*if (!area.Contains (args.X, args.Y)) {
+                                Log.WarningFormat ("Tooltip rect {0} does not contain tooltip point {1},{2} -- this will cause excessive requerying", area, args.X, args.Y);
+                            }*/
+                            args.RetVal = true;
+                        }
+                    }
+                } else if (cell_context != null && cell_context.Layout != null) {
+                    ITooltipCell cell;
+                    Column column;
+                    int row_index;
+
+                    if (GetEventCell<ITooltipCell> (args.X, args.Y, out cell, out column, out row_index)) {
+                        CachedColumn cached_column = GetCachedColumnForColumn (column);
 
-                if (GetEventCell<ITooltipCell> (args.X, args.Y, out cell, out column, out row_index)) {
-                    CachedColumn cached_column = GetCachedColumnForColumn (column);
+                        string markup = cell.GetTooltipMarkup (cell_context, cached_column.Width);
+                        if (!String.IsNullOrEmpty (markup)) {
+                            Gdk.Rectangle rect = new Gdk.Rectangle ();
+                            rect.X = list_interaction_alloc.X + cached_column.X1;
 
-                    string markup = cell.GetTooltipMarkup (cell_context, cached_column.Width);
-                    if (!String.IsNullOrEmpty (markup)) {
-                        Gdk.Rectangle rect = new Gdk.Rectangle ();
-                        rect.X = list_interaction_alloc.X + cached_column.X1;
+                            // get the y of the event in list coords
+                            rect.Y = args.Y - list_interaction_alloc.Y;
 
-                        // get the y of the event in list coords
-                        rect.Y = args.Y - list_interaction_alloc.Y;
+                            // get the top of the cell pointed to by list_y
+                            rect.Y -= VadjustmentValue % ChildSize.Height;
+                            rect.Y -= rect.Y % ChildSize.Height;
 
-                        // get the top of the cell pointed to by list_y
-                        rect.Y -= VadjustmentValue % ChildSize.Height;
-                        rect.Y -= rect.Y % ChildSize.Height;
+                            // convert back to widget coords
+                            rect.Y += list_interaction_alloc.Y;
 
-                        // convert back to widget coords
-                        rect.Y += list_interaction_alloc.Y;
+                            // TODO is this right even if the list is wide enough to scroll horizontally?
+                            rect.Width = cached_column.Width;
 
-                        // TODO is this right even if the list is wide enough to scroll horizontally?
-                        rect.Width = cached_column.Width;
+                            // TODO not right - could be smaller if at the top/bottom and only partially showing
+                            rect.Height = ChildSize.Height;
 
-                        // TODO not right - could be smaller if at the top/bottom and only partially showing
-                        rect.Height = ChildSize.Height;
+                            /*if (!rect.Contains (args.X, args.Y)) {
+                                Log.WarningFormat ("ListView tooltip rect {0} does not contain tooltip point {1},{2} -- this will cause excessive requerying", rect, args.X, args.Y);
+                            }*/
 
-                        args.Tooltip.Markup = markup;
-                        args.Tooltip.TipArea = rect;
-                        args.RetVal = true;
+                            args.Tooltip.Markup = markup;
+                            args.Tooltip.TipArea = rect;
+                            args.RetVal = true;
+                        }
                     }
                 }
             }
diff --git a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Interaction.cs b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Interaction.cs
index 6d6890c..f1d1841 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Interaction.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Interaction.cs
@@ -495,7 +495,7 @@ namespace Hyena.Data.Gui
             }
 
             // Bind the row to the cell
-            cell.BindListItem (model[row_index]);
+            cell.Bind (model[row_index]);
             return true;
         }
 
diff --git a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
index 006911c..8918e43 100644
--- a/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
+++ b/Hyena.Gui/Hyena.Data.Gui/ListView/ListView_Rendering.cs
@@ -425,7 +425,7 @@ namespace Hyena.Data.Gui
             StateType state, bool dragging)
         {
             ColumnCell cell = column_cache[column_index].Column.GetCell (0);
-            cell.BindListItem (item);
+            cell.Bind (item);
             ColumnCellDataProvider (cell, item);
 
             ITextCell text_cell = cell as ITextCell;
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/AnimationManager.cs b/Hyena.Gui/Hyena.Gui.Canvas/AnimationManager.cs
index 123fd4d..371ab38 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/AnimationManager.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/AnimationManager.cs
@@ -89,6 +89,7 @@ namespace Hyena.Gui.Canvas
 
             if (Item != null) {
                 Item.InvalidateRender ();
+                //Item.Invalidate ();
             }
 
             return !is_expired;
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs b/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs
index 55781cb..beaf0ff 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/CanvasItem.cs
@@ -143,8 +143,8 @@ namespace Hyena.Gui.Canvas
 
             cr.Antialias = Cairo.Antialias.Default;
 
-            cr.Rectangle (0, 0, alloc.Width, alloc.Height);
-            cr.Clip ();
+            //cr.Rectangle (0, 0, alloc.Width, alloc.Height);
+            //cr.Clip ();
 
             ClippedRender (context);
 
@@ -152,7 +152,7 @@ namespace Hyena.Gui.Canvas
                 PrelightRenderer (context.Context, context.Theme, new Rect (0, 0, ContentAllocation.Width, ContentAllocation.Height), prelight_opacity);
             }
 
-            cr.ResetClip ();
+            //cr.ResetClip ();
 
             if (opacity < 1.0) {
                 cr.PopGroupToSource ();
@@ -179,6 +179,14 @@ namespace Hyena.Gui.Canvas
             set { theme = value; }
         }
 
+        public virtual bool GetTooltipMarkupAt (Point pt, out string markup, out Rect area)
+        {
+            markup = TooltipMarkup;
+            area = TopLevelAllocation;
+            return markup != null;
+        }
+
+        protected string TooltipMarkup { get; set; }
         public bool Visible { get; set; }
         public double Opacity { get; set; }
         public Brush Foreground { get; set; }
@@ -243,6 +251,13 @@ namespace Hyena.Gui.Canvas
 
         #endregion
 
+        public void Invalidate ()
+        {
+            InvalidateMeasure ();
+            InvalidateArrange ();
+            InvalidateRender ();
+        }
+
         protected void InvalidateRender (Rect area)
         {
             if (Parent == null) {
@@ -269,7 +284,7 @@ namespace Hyena.Gui.Canvas
             set { Binder.BoundObject = value; }
         }
 
-        /*protected Rect TopLevelAllocation {
+        private Rect TopLevelAllocation {
             get {
                 var alloc = ContentAllocation;
                 var top = this;
@@ -280,7 +295,7 @@ namespace Hyena.Gui.Canvas
 
                 return alloc;
             }
-        }*/
+        }
 
         protected virtual void ClippedRender (Cairo.Context cr)
         {
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs b/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs
index 2200bea..58df9c2 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/Panel.cs
@@ -119,6 +119,17 @@ namespace Hyena.Gui.Canvas
             return null;
         }
 
+        public override bool GetTooltipMarkupAt (Point pt, out string markup, out Rect area)
+        {
+            if (base.GetTooltipMarkupAt (pt, out markup, out area)) {
+                return true;
+            }
+
+            pt = ChildCoord (this, pt);
+            CanvasItem child = FindChildAt (pt, false);
+            return child == null ? false : child.GetTooltipMarkupAt (ChildCoord (child, pt), out markup, out area);
+        }
+
         public override bool ButtonEvent (Point cursor, bool pressed, uint button)
         {
             var child = FindChildAt (cursor, true);
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/Rect.cs b/Hyena.Gui/Hyena.Gui.Canvas/Rect.cs
index f25e2ce..3dc568b 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/Rect.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/Rect.cs
@@ -149,6 +149,10 @@ namespace Hyena.Gui.Canvas
             get { return new Size (Width, Height); }
         }
 
+        public Point Point {
+            get { return new Point (X, Y); }
+        }
+
         public void Intersect (Rect rect)
         {
             if (IsEmpty || rect.IsEmpty) {
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs b/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs
index 2a58049..0cef220 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/Slider.cs
@@ -108,9 +108,9 @@ namespace Hyena.Gui.Canvas
             return false;
         }
 
-        private double last_invalidate_value = -1;
+        //private double last_invalidate_value = -1;
 
-        private void Invalidate ()
+        /*private void Invalidate ()
         {
             double current_value = (IsValueUpdatePending ? PendingValue : Value);
 
@@ -135,7 +135,7 @@ namespace Hyena.Gui.Canvas
 
             last_invalidate_value = current_value;
             InvalidateRender (region);
-        }
+        }*/
 
         /*protected override Rect InvalidationRect {
             get { return new Rect (
diff --git a/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs b/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
index 41464ca..db72054 100644
--- a/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
+++ b/Hyena.Gui/Hyena.Gui.Canvas/TextBlock.cs
@@ -79,7 +79,18 @@ namespace Hyena.Gui.Canvas
             layout.FontDescription.Weight = GetPangoFontWeight (FontWeight);
             layout.SingleParagraphMode = wrap == TextWrap.None;
             layout.Ellipsize = EllipsizeMode;
-            UpdateLayout (layout, GetText ());
+            
+            last_text = GetFormattedText (GetText ()) ?? "";
+            if (TextWrap == TextWrap.None && last_text.IndexOfAny (lfcr) >= 0) {
+                last_text = last_text.Replace ("\r\n", "\x20").Replace ('\n', '\x20').Replace ('\r', '\x20');
+            }
+
+            if (UseMarkup) {
+                layout.SetMarkup (last_text);
+            } else {
+                layout.SetText (last_text);
+            }
+
             layout.GetPixelSize (out text_w, out text_h);
 
             double width = text_w;
@@ -111,21 +122,6 @@ namespace Hyena.Gui.Canvas
             }
         }
 
-        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 (String.IsNullOrEmpty (TextFormat)) {
@@ -151,6 +147,12 @@ namespace Hyena.Gui.Canvas
             layout.SetHeight ((int)(Pango.Scale.PangoScale * RenderSize.Height));
             layout.GetPixelSize (out text_width, out text_height);
 
+            if (layout.IsEllipsized || text_width > RenderSize.Width || text_height > RenderSize.Height) {
+                TooltipMarkup = last_text;
+            } else {
+                TooltipMarkup = null;
+            }
+
             Rect new_alloc = new Rect (
                 Math.Round ((RenderSize.Width - text_width) * HorizontalAlignment),
                 Math.Round ((RenderSize.Height - text_height) * VerticalAlignment),
@@ -238,6 +240,11 @@ namespace Hyena.Gui.Canvas
             get { return invalidation_rect; }
         }
 
+        public override string ToString ()
+        {
+            return String.Format ("<TextBlock Text='{0}' Allocation={1}>", last_text, Allocation);
+        }
+
         public string Text { get; set; }
         public string TextFormat { get; set; }
         public FontWeight FontWeight { get; set; }
@@ -250,5 +257,8 @@ namespace Hyena.Gui.Canvas
 
         public double HorizontalAlignment { get; set; }
         public double VerticalAlignment { get; set; }
+
+        private static char[] lfcr = new char[] {'\n', '\r'};
+        private string last_text;
     }
 }



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