[gnome-break-timer] Add a custom countdown widget to the status dialog



commit afd3d832fd978adf5e43452d22d9e752519b4317
Author: Dylan McCall <dylanmccall ubuntu com>
Date:   Thu Sep 12 12:34:23 2013 -0700

    Add a custom countdown widget to the status dialog
    
    This new widget gives a little more information about the countdown to a break starting. It is 
reminiscent of the new countdown and timer in gnome-clocks.

 settings/CircleCounter.vala  |  103 ++++++++++++++++++++++++++++++++++++++++++
 settings/TimerBreakType.vala |   21 ++++-----
 settings/settings.am         |    1 +
 3 files changed, 114 insertions(+), 11 deletions(-)
---
diff --git a/settings/CircleCounter.vala b/settings/CircleCounter.vala
new file mode 100644
index 0000000..4fb3963
--- /dev/null
+++ b/settings/CircleCounter.vala
@@ -0,0 +1,103 @@
+/*
+ * This file is part of GNOME Break Timer.
+ * 
+ * GNOME Break Timer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * GNOME Break Timer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNOME Break Timer.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class CircleCounter : Gtk.Widget {
+       protected const double LINE_WIDTH = 5.0;
+       protected const int DEFAULT_RADIUS = 48;
+
+       public enum Direction {
+               COUNT_DOWN,
+               COUNT_UP
+       }
+
+       public Direction direction {get; set;}
+       public double progress {get; set;}
+
+       public CircleCounter () {
+               Object ();
+               this.set_has_window (false);
+
+               this.notify["progress"].connect((s, p) => {
+                       this.queue_draw ();
+               });
+       }
+
+       public override bool draw (Cairo.Context cr) {
+               Gtk.StyleContext style_context = this.get_style_context ();
+               Gtk.StateFlags state = this.get_state_flags ();
+               Gtk.Allocation allocation;
+               this.get_allocation (out allocation);
+
+               int center_x = allocation.width / 2;
+               int center_y = allocation.height / 2;
+               int radius = int.min(center_x, center_y);
+               double arc_radius = radius - LINE_WIDTH / 2;
+
+               // FIXME: Get some nicer colours from CSS?
+               Gdk.RGBA trough_color = style_context.get_color (state);
+               trough_color.alpha = trough_color.alpha / 5;
+               Gdk.RGBA base_color = style_context.get_color (state);
+
+               Gdk.cairo_set_source_rgba (cr, trough_color);
+               cr.arc (center_x, center_y, arc_radius, 0, Math.PI * 2.0);
+               cr.set_line_width (LINE_WIDTH);
+               cr.stroke ();
+
+               double start_angle = 1.5 * Math.PI;
+               double progress_angle = this.progress * Math.PI * 2.0;
+               if (this.direction == Direction.COUNT_DOWN) {
+                       if (progress_angle > 0) {
+                               cr.arc (center_x, center_y, arc_radius, start_angle, start_angle - 
progress_angle);
+                       } else {
+                               // No progress: Draw a full circle (to be gradually emptied)
+                               cr.arc (center_x, center_y, arc_radius, start_angle, start_angle + Math.PI * 
2.0);
+                       }
+               } else {
+                       if (progress_angle > 0) {
+                               cr.arc_negative (center_x, center_y, arc_radius, start_angle, start_angle - 
progress_angle);
+                       }
+                       // No progress: Draw nothing (arc will gradually appear)
+               }
+
+               Gdk.cairo_set_source_rgba (cr, base_color);
+               cr.set_line_width (LINE_WIDTH);
+               cr.set_line_cap  (Cairo.LineCap.ROUND);
+               cr.stroke ();
+
+               return true;
+       }
+
+       public override void get_preferred_width (out int minimum_width, out int natural_width) {
+               var diameter = calculate_diameter ();
+               minimum_width = diameter;
+               natural_width = diameter;
+       }
+
+       public override void get_preferred_height (out int minimum_height, out int natural_height) {
+               var diameter = calculate_diameter ();
+               minimum_height = diameter;
+               natural_height = diameter;
+       }
+
+       public override void size_allocate (Gtk.Allocation allocation) {
+               base.size_allocate (allocation);
+       }
+
+       private int calculate_diameter () {
+               return 2 * DEFAULT_RADIUS;
+       }
+}
\ No newline at end of file
diff --git a/settings/TimerBreakType.vala b/settings/TimerBreakType.vala
index ebe8c27..24794ea 100644
--- a/settings/TimerBreakType.vala
+++ b/settings/TimerBreakType.vala
@@ -103,7 +103,7 @@ public abstract class TimerBreakStatusPanel : BreakStatusPanel {
        private string upcoming_text;
        private string ongoing_text;
 
-       private Gtk.Image time_icon;
+       private CircleCounter circle_counter;
        private Gtk.Label status_label;
        private Gtk.Label time_label;
 
@@ -115,13 +115,9 @@ public abstract class TimerBreakStatusPanel : BreakStatusPanel {
                this.set_column_spacing (12);
 
                // FIXME: This is an application icon. It doesn't make sense here.
-               this.time_icon = new Gtk.Image.from_icon_name (
-                       "preferences-system-time-symbolic",
-                       Gtk.IconSize.DIALOG
-               );
-               this.attach (this.time_icon, 0, 0, 1, 1);
-               this.time_icon.set_pixel_size (90);
-               this.time_icon.get_style_context ().add_class ("_break-status-icon");
+               this.circle_counter = new CircleCounter ();
+               this.attach (this.circle_counter, 0, 0, 1, 1);
+               this.circle_counter.get_style_context ().add_class ("_break-status-icon");
 
                var labels_grid = new Gtk.Grid ();
                this.attach (labels_grid, 1, 0, 1, 1);
@@ -146,19 +142,22 @@ public abstract class TimerBreakStatusPanel : BreakStatusPanel {
 
        private void timer_status_changed_cb (TimerBreakStatus? status) {
                if (status == null) return;
+
+               TimerBreakType timer_break = (TimerBreakType) this.break_type;
                
                if (status.is_active) {
-                       // TODO: Instead of this, explain the current break. Implement
-                       // the "What should I do?" button from the mockup, seen at
-                       // 
https://raw.github.com/gnome-design-team/gnome-mockups/master/break-timer/wires-notifications.png
                        this.status_label.set_label (this.ongoing_text);
                        string time_text = NaturalTime.instance.get_countdown_for_seconds_with_start (
                                status.time_remaining, status.current_duration);
                        this.time_label.set_label (time_text);
+                       this.circle_counter.direction = CircleCounter.Direction.COUNT_DOWN;
+                       this.circle_counter.progress = (status.current_duration - status.time_remaining) / 
(double)status.current_duration;
                } else {
                        this.status_label.set_label (this.upcoming_text);
                        string time_text = NaturalTime.instance.get_countdown_for_seconds (status.starts_in);
                        this.time_label.set_label (time_text);
+                       this.circle_counter.direction = CircleCounter.Direction.COUNT_UP;
+                       this.circle_counter.progress = (timer_break.interval - status.starts_in) / 
(double)timer_break.interval;
                }
        }
 }
diff --git a/settings/settings.am b/settings/settings.am
index 9490756..dcea801 100644
--- a/settings/settings.am
+++ b/settings/settings.am
@@ -4,6 +4,7 @@ SETTINGS_SOURCES = \
        BreakManager.vala \
        BreakSettingsDialog.vala \
        BreakType.vala \
+       CircleCounter.vala \
        MainWindow.vala \
        MicroBreakType.vala \
        OverlayArrow.vala \


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