Use a pixmap as background storage
authorEnrico Zini <enrico@enricozini.org>
Thu, 10 Dec 2009 08:46:10 +0000 (08:46 +0000)
committerEnrico Zini <enrico@enricozini.org>
Thu, 10 Dec 2009 08:46:10 +0000 (08:46 +0000)
src/fisheye.vala

index 1a35918c33a232101e301183834cac504ed67b0f..489ca9bddf72f744351611aa6d09b6dfaa439345 100644 (file)
@@ -23,6 +23,7 @@ using GLib;
 public class FisheyeList : Gtk.DrawingArea
 {
        protected Gtk.TreeModel model;
+       protected Gdk.Pixmap background;
        protected Gdk.Pixmap backing_store;
 
        // Pango layouts cached for speed
@@ -31,7 +32,7 @@ public class FisheyeList : Gtk.DrawingArea
 
        // Labels to show, extracted from the model
        protected string[] label_cache;
-       protected bool build_label_cache_needed;
+       protected bool base_layout_needed;
 
        protected int cur_el;
 
@@ -58,7 +59,7 @@ public class FisheyeList : Gtk.DrawingArea
                get { return _label_column; }
                set {
                        _label_column = value;
-                       build_label_cache_needed = true;
+                       base_layout_needed = true;
                        queue_draw();
                }
        }
@@ -106,15 +107,15 @@ public class FisheyeList : Gtk.DrawingArea
                this.model.row_has_child_toggled += on_row_has_child_toggled;
                this.model.row_inserted += on_row_inserted;
                this.model.rows_reordered += on_rows_reordered;
-               build_label_cache_needed = true;
+               base_layout_needed = true;
                queue_draw();
        }
 
-       private void on_row_changed(Gtk.TreePath path, Gtk.TreeIter iter) { build_label_cache_needed = true; }
-       private void on_row_deleted(Gtk.TreePath path) { build_label_cache_needed = true; }
-       private void on_row_has_child_toggled(Gtk.TreePath path, Gtk.TreeIter iter) { build_label_cache_needed = true; }
-       private void on_row_inserted(Gtk.TreePath path, Gtk.TreeIter iter) { build_label_cache_needed = true; }
-       private void on_rows_reordered(Gtk.TreePath path, Gtk.TreeIter iter, void* new_order) { build_label_cache_needed = true; }
+       private void on_row_changed(Gtk.TreePath path, Gtk.TreeIter iter) { base_layout_needed = true; }
+       private void on_row_deleted(Gtk.TreePath path) { base_layout_needed = true; }
+       private void on_row_has_child_toggled(Gtk.TreePath path, Gtk.TreeIter iter) { base_layout_needed = true; }
+       private void on_row_inserted(Gtk.TreePath path, Gtk.TreeIter iter) { base_layout_needed = true; }
+       private void on_rows_reordered(Gtk.TreePath path, Gtk.TreeIter iter, void* new_order) { base_layout_needed = true; }
 
        /* Mouse button got pressed over widget */
        /*
@@ -178,8 +179,7 @@ public class FisheyeList : Gtk.DrawingArea
 
        public override bool configure_event (Gdk.EventConfigure event)
        {
-               backing_store = new Gdk.Pixmap(window, allocation.width, allocation.height, -1);
-               focus_layout_needed = true;
+               base_layout_needed = true;
                queue_draw();
                return false;
        }
@@ -187,10 +187,7 @@ public class FisheyeList : Gtk.DrawingArea
        /* Widget is asked to draw itself */
        public override bool expose_event (Gdk.EventExpose event)
        {
-               if (backing_store == null)
-                       return false;
-
-               draw(backing_store);
+               draw();
 
                window.draw_drawable(
                        get_style().fg_gc[Gtk.StateType.NORMAL],
@@ -223,8 +220,18 @@ public class FisheyeList : Gtk.DrawingArea
                return pos;
        }
 
-       protected void build_label_cache()
+       protected void base_layout()
        {
+               background = new Gdk.Pixmap(window, allocation.width, allocation.height, -1);
+               draw_background(background);
+
+               backing_store = new Gdk.Pixmap(window, allocation.width, allocation.height, -1);
+
+                Gtk.Style style = get_style();
+               //int max_font_size = style.font_desc.get_size();
+
+               //int min_size = max_font_size * 3 + FIXME;
+
                if (model == null)
                {
                        label_cache = new string[0];
@@ -249,7 +256,7 @@ public class FisheyeList : Gtk.DrawingArea
                        }
                }
 
-               build_label_cache_needed = false;
+               base_layout_needed = false;
                focus_layout_needed = true;
        }
 
@@ -284,13 +291,8 @@ public class FisheyeList : Gtk.DrawingArea
                focus_layout_needed = false;
        }
 
-       protected void draw(Gdk.Drawable drawable)
+       protected void draw_background(Gdk.Drawable drawable)
        {
-               if (build_label_cache_needed)
-                       build_label_cache();
-               if (focus_layout_needed)
-                       focus_layout();
-
                 Gtk.Style style = get_style();
 
                // Background
@@ -299,6 +301,24 @@ public class FisheyeList : Gtk.DrawingArea
                // Focus lock area
                drawable.draw_rectangle(style.bg_gc[Gtk.StateType.ACTIVE], true,
                        0, focus_starts[0], allocation.width/2, focus_starts[focus_end - focus_first]-focus_starts[0]);
+       }
+
+       protected void draw()
+       {
+               if (base_layout_needed)
+                       base_layout();
+               if (focus_layout_needed)
+                       focus_layout();
+
+               var drawable = backing_store;
+                Gtk.Style style = get_style();
+
+               // Background
+               drawable.draw_drawable(
+                       get_style().fg_gc[Gtk.StateType.NORMAL],
+                       background,
+                       0, 0, 0, 0,
+                       allocation.width, allocation.height);
 
                // Focus movement area
                drawable.draw_rectangle(style.bg_gc[Gtk.StateType.INSENSITIVE], true,