Deal with pango or model changes
authorEnrico Zini <enrico@enricozini.org>
Wed, 9 Dec 2009 21:01:08 +0000 (21:01 +0000)
committerEnrico Zini <enrico@enricozini.org>
Wed, 9 Dec 2009 21:01:08 +0000 (21:01 +0000)
src/fisheye.vala

index 0e71ebbeece4b89a420406628db7681486bb8196..9b281f6b9865ef722d9e9cc64d06c8acc6e671bc 100644 (file)
@@ -26,10 +26,7 @@ public class FisheyeList : Gtk.DrawingArea
        protected Gdk.Pixmap backing_store;
 
        // Pango layouts cached for speed
-       // TODO: If you create and keep a PangoLayout using this context, you
-       // must deal with changes to the context by calling
-       // pango_layout_context_changed() on the layout in response to the
-       // "style-set" and "direction-changed" signals for the widget.
+       protected const int max_font_size = 30;
        protected Pango.Layout[] pango_cache;
 
        // Labels to show, extracted from the model
@@ -67,21 +64,31 @@ public class FisheyeList : Gtk.DrawingArea
                }
        }
 
+       protected int _label_column;
+       public int label_column {
+               get { return _label_column; }
+               set {
+                       _label_column = value;
+                       build_label_cache_needed = true;
+                       queue_draw();
+               }
+       }
+
        public FisheyeList()
        {
                model = null;
                backing_store = null;
 
                label_cache = null;
-               build_label_cache_needed = true;
 
-               pango_cache = new Pango.Layout[30];
-               for (int i = 0; i < 30; ++i)
+               pango_cache = new Pango.Layout[max_font_size];
+               for (int i = 0; i < pango_cache.length; ++i)
                        pango_cache[i] = null;
 
                // Defaults for properties
                focus_size = 20;
                distortion_factor = 30;
+               label_column = 0;
 
                cur_el = 0;
                focus_centre = 0;
@@ -96,6 +103,11 @@ public class FisheyeList : Gtk.DrawingArea
        public void set_model (Gtk.TreeModel? model)
        {
                this.model = model;
+               this.model.row_changed += (a, b) => { build_label_cache_needed = true; };
+               this.model.row_deleted += (a) => { build_label_cache_needed = true; };
+               this.model.row_has_child_toggled += (a, b) => { build_label_cache_needed = true; };
+               this.model.row_inserted += (a, b) => { build_label_cache_needed = true; };
+               this.model.rows_reordered += (a, b, c) => { build_label_cache_needed = true; };
                build_label_cache_needed = true;
                queue_draw();
        }
@@ -174,12 +186,25 @@ public class FisheyeList : Gtk.DrawingArea
                return false;
        }
 
+       public override void style_set(Gtk.Style? previous_style)
+       {
+               // Reset the pango cache if the pango context changes
+               for (int i = 0; i < pango_cache.length; ++i)
+                       pango_cache[i] = null;
+       }
+       public override void direction_changed(Gtk.TextDirection previous_direction)
+       {
+               // Reset the pango cache if the pango context changes
+               for (int i = 0; i < pango_cache.length; ++i)
+                       pango_cache[i] = null;
+       }
+
        protected int el_y(int idx)
        {
                // Undistorted Y
                int undy = idx * allocation.height / label_cache.length;
                // Distorted position
-               int pos = fisheye(undy, focus_centre, distortion_factor, 0, allocation.height);
+               int pos = fisheye(undy, focus_centre, _distortion_factor, 0, allocation.height);
                //stderr.printf("%d %f %f\n", idx, undy, pos);
                return pos;
        }
@@ -203,7 +228,7 @@ public class FisheyeList : Gtk.DrawingArea
                                int i = 0;
                                do {
                                        string val;
-                                       model.get(iter, 0, out val, -1);
+                                       model.get(iter, _label_column, out val, -1);
                                        label_cache[i] = val;
                                        ++i;
                                } while (model.iter_next(ref iter));
@@ -226,8 +251,8 @@ public class FisheyeList : Gtk.DrawingArea
                        // Anchor point
                        focus_centre = cur_el*allocation.height/label_cache.length;
 
-                       focus_first = cur_el > focus_size/2 ? cur_el-focus_size/2 : 0;
-                       focus_end = focus_first + focus_size;
+                       focus_first = cur_el > _focus_size/2 ? cur_el-_focus_size/2 : 0;
+                       focus_end = focus_first + _focus_size;
                        if (focus_end >= label_cache.length) focus_end = label_cache.length;
 
                        // Compute starting positions for all items in focus