[gnome-clocks/wip/stopwatchlistbox: 3/3] wip analog stopwatch



commit 8b976cb4ddc3827544414902d74af733c9b139cd
Author: Paolo Borelli <pborelli gnome org>
Date:   Wed Aug 7 16:45:50 2013 +0200

    wip analog stopwatch

 data/ui/stopwatch.ui |   10 ++++
 src/stopwatch.vala   |  138 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 146 insertions(+), 2 deletions(-)
---
diff --git a/data/ui/stopwatch.ui b/data/ui/stopwatch.ui
index 6e13a50..60672d6 100644
--- a/data/ui/stopwatch.ui
+++ b/data/ui/stopwatch.ui
@@ -6,6 +6,12 @@
     <property name="can_focus">False</property>
     <property name="hexpand">True</property>
     <child>
+
+  <object class="ClocksStopwatchAnalogFrame" id="analog_frame">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <child>
+
       <object class="GtkGrid" id="top_grid">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
@@ -70,6 +76,10 @@
           </packing>
         </child>
       </object>
+
+        </child>
+      </object>
+
       <packing>
         <property name="left_attach">0</property>
         <property name="top_attach">0</property>
diff --git a/src/stopwatch.vala b/src/stopwatch.vala
index eafb986..eed927d 100644
--- a/src/stopwatch.vala
+++ b/src/stopwatch.vala
@@ -19,6 +19,134 @@
 namespace Clocks {
 namespace Stopwatch {
 
+public class AnalogFrame : Gtk.Frame {
+    private const int RADIUS_PAD = 128;
+
+    private int seconds;
+    private double millisecs;
+    private Cairo.Pattern cursor_pattern;
+
+    private int calculate_diameter () {
+        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);
+            return RADIUS_PAD + (int) Math.sqrt (w * w + h * h);
+        } else {
+            return RADIUS_PAD;
+        }
+    }
+
+    public void update (int s, double ms) {
+        seconds = s;
+        millisecs = ms;
+    }
+
+    public void reset () {
+        update (0, 0);
+    }
+
+    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-timer-inner");
+        var color = context.get_background_color (Gtk.StateFlags.NORMAL);
+        Gdk.cairo_set_source_rgba (cr, color);
+        cr.arc (center_x, center_y, radius, 0, 2 * Math.PI);
+        cr.fill ();
+        context.restore ();
+
+        cr.set_line_width (1);
+        color = context.get_border_color (Gtk.StateFlags.SELECTED);
+        Gdk.cairo_set_source_rgba (cr, color);
+        cr.arc (center_x, center_y, radius, 0, 2 * Math.PI);
+        cr.stroke ();
+
+        if (seconds > 0) {
+            var progress = (seconds + millisecs) / 60;
+            if (progress > 0) {
+                cr.set_line_width (10);
+                color = context.get_background_color (Gtk.StateFlags.SELECTED);
+                cr.arc (center_x, center_y, radius, 1.5  * Math.PI, (1.5 + progress * 2 ) * Math.PI);
+                Gdk.cairo_set_source_rgba (cr, color);
+                cr.stroke ();
+            }
+        }
+
+        if (millisecs > 0) {
+            var progress = millisecs;
+            if (progress > 0) {
+                cr.set_line_width (2);
+                color = context.get_background_color (Gtk.StateFlags.SELECTED);
+                cr.arc (center_x, center_y, radius, 1.5  * Math.PI, (1.5 + progress * 2 ) * Math.PI);
+                Gdk.cairo_set_source_rgba (cr, color);
+                cr.stroke ();
+
+                if (progress < 1) {
+                    if (cursor_pattern == null) {
+                        cursor_pattern = new Cairo.Pattern.radial (0, 0, 3, 0, 0, 9);
+                        cursor_pattern.add_color_stop_rgba (0, color.red, color.green, color.blue, 1);
+                        cursor_pattern.add_color_stop_rgba (0.5, color.red, color.green, color.blue, 0);
+                    }
+
+                    var x = center_x + (radius) * Math.cos((1.5 + progress * 2) * Math.PI);
+                    var y = center_y + (radius) * Math.sin((1.5 + progress * 2) * Math.PI);
+
+                    var cursor_radius = 9;
+                    cr.arc (x, y, cursor_radius, 0, 2 * Math.PI);
+                    cr.translate (x, y);
+                    cr.set_source (cursor_pattern);
+                    cr.fill ();
+                }
+            }
+        }
+
+        cr.restore ();
+
+        return base.draw(cr);
+    }
+}
+
 [GtkTemplate (ui = "/org/gnome/clocks/ui/stopwatchlapsrow.ui")]
 private class LapsRow : Gtk.ListBoxRow {
     [GtkChild]
@@ -63,6 +191,7 @@ public class MainPanel : Gtk.Box, Clocks.Clock {
     private uint timeout_id;
     private int current_lap;
     private double last_lap_time;
+    private AnalogFrame analog_frame;
     private Gtk.Label time_label;
     private Gtk.Button left_button;
     private Gtk.Button right_button;
@@ -78,6 +207,7 @@ public class MainPanel : Gtk.Box, Clocks.Clock {
         var builder = Utils.load_ui ("stopwatch.ui");
 
         var stopwatch_panel = builder.get_object ("stopwatch_panel") as Gtk.Widget;
+        analog_frame = builder.get_object ("analog_frame") as AnalogFrame;
         time_label = builder.get_object ("time_label") as Gtk.Label;
         left_button = builder.get_object ("left_button") as Gtk.Button;
         right_button = builder.get_object ("right_button") as Gtk.Button;
@@ -218,13 +348,15 @@ public class MainPanel : Gtk.Box, Clocks.Clock {
 
     private void add_timeout () {
         if (timeout_id == 0) {
-            timeout_id = Timeout.add (100, update_time_label);
+            timeout_id = add_tick_callback ((c) => {
+                return update_time_label ();
+            });
         }
     }
 
     private void remove_timeout () {
         if (timeout_id != 0) {
-            Source.remove (timeout_id);
+            remove_tick_callback (timeout_id);
             timeout_id = 0;
         }
     }
@@ -247,6 +379,8 @@ public class MainPanel : Gtk.Box, Clocks.Clock {
             time_label.set_text ("%02i∶%02i.%i".printf (m, s, ds));
         }
 
+        analog_frame.update (s, r);
+
         return true;
     }
 


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