[gnome-clocks/wip/analogstopwatchtimer: 3/6] Add an AnalogFrame widget



commit f6beb97925bb51d8bca825e398610f67b21be740
Author: Paolo Borelli <pborelli gnome org>
Date:   Thu Aug 15 10:42:07 2013 +0200

    Add an AnalogFrame widget
    
    This is GtkFrame subclass that allocates enough space for a
    circumscribed circle around its child and draws it.
    It will be used as a base class for drawing analog progress in stopwatch
    and timer.

 data/css/gnome-clocks.css |    4 ++
 src/widgets.vala          |   86 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)
---
diff --git a/data/css/gnome-clocks.css b/data/css/gnome-clocks.css
index b53ea12..17c2b71 100644
--- a/data/css/gnome-clocks.css
+++ b/data/css/gnome-clocks.css
@@ -185,6 +185,10 @@
     padding: 2px 16px;
 }
 
+.clocks-analog-frame.trough {
+    color: #d3d7cf;
+}
+
 .view.clocks-laps {
     font-size: larger;
     background-color: @theme_bg_color;
diff --git a/src/widgets.vala b/src/widgets.vala
index aabbcd1..541154b 100644
--- a/src/widgets.vala
+++ b/src/widgets.vala
@@ -618,4 +618,90 @@ public class AmPmToggleButton : Gtk.Button {
     }
 }
 
+public class AnalogFrame : Gtk.Frame {
+    protected const int LINE_WIDTH = 10;
+    protected const int RADIUS_PAD = 64;
+
+    private int calculate_diameter () {
+        int ret = 2 * RADIUS_PAD;
+        var child = get_child ();
+        if (child != null && child.visible) {
+            int w, h;
+            child.get_preferred_width (out w, null);
+            child.get_preferred_height (out h, null);
+            ret += (int) Math.sqrt (w * w + h * h);
+        }
+
+        return ret;
+    }
+
+    public override void get_preferred_width (out int min_w, out int natural_w) {
+        var d = calculate_diameter ();
+        min_w = d;
+        natural_w = d;
+    }
+
+    public override void get_preferred_height (out int min_h, out int natural_h) {
+        var d = calculate_diameter ();
+        min_h = d;
+        natural_h = d;
+    }
+
+    public override void size_allocate (Gtk.Allocation allocation) {
+        set_allocation (allocation);
+        var child = get_child ();
+        if (child != null && child.visible) {
+            int w, h;
+            child.get_preferred_width (out w, null);
+            child.get_preferred_height (out h, null);
+
+            Gtk.Allocation child_allocation = {};
+            child_allocation.x = allocation.x + (allocation.width - w) / 2;
+            child_allocation.y = allocation.y + (allocation.height - h) / 2;
+            child_allocation.width = w;
+            child_allocation.height =  h;
+            child.size_allocate (child_allocation);
+        }
+    }
+
+    public override bool draw (Cairo.Context cr) {
+        var context = get_style_context ();
+
+        Gtk.Allocation allocation;
+        get_allocation (out allocation);
+        var center_x = allocation.width / 2;
+        var center_y = allocation.height / 2;
+
+        var radius = calculate_diameter () / 2;
+
+        cr.save ();
+        cr.move_to (center_x + radius, center_y);
+
+        context.save ();
+        context.add_class ("clocks-analog-frame");
+
+        context.save ();
+        context.add_class (Gtk.STYLE_CLASS_TROUGH);
+
+        var color = context.get_color (Gtk.StateFlags.NORMAL);
+
+        cr.set_line_width (LINE_WIDTH);
+        Gdk.cairo_set_source_rgba (cr, color);
+        cr.arc (center_x, center_y, radius - LINE_WIDTH / 2, 0, 2 * Math.PI);
+        cr.stroke ();
+
+        context.restore ();
+
+        draw_progress (cr, center_x, center_y, radius);
+
+        context.restore ();
+        cr.restore ();
+
+        return base.draw(cr);
+    }
+
+    public virtual void draw_progress (Cairo.Context cr, int center_x, int center_y, int radius) {
+    }
+}
+
 } // namespace Clocks


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