[california/wip/725783-time] Time units adjusted separately (disengaged)



commit d9e6c0093bcfc2d2c863f9091178ad557a9d7cbe
Author: Jim Nelson <jim yorba org>
Date:   Tue Aug 5 16:08:11 2014 -0700

    Time units adjusted separately (disengaged)

 src/calendar/calendar-wall-time.vala |   32 ++++++++++++++++++++++++++++++++
 src/host/host-date-time-widget.vala  |   30 +++++++++++++++++-------------
 2 files changed, 49 insertions(+), 13 deletions(-)
---
diff --git a/src/calendar/calendar-wall-time.vala b/src/calendar/calendar-wall-time.vala
index 57d6d8e..c68d5c2 100644
--- a/src/calendar/calendar-wall-time.vala
+++ b/src/calendar/calendar-wall-time.vala
@@ -450,6 +450,38 @@ public class WallTime : BaseObject, Gee.Comparable<WallTime>, Gee.Hashable<WallT
     }
     
     /**
+     * Adjust the time by the specified amount without affecting other units.
+     *
+     * "Free adjust" is designed to work like adjusting a clock's time where each unit is disengaged
+     * from the others.  That is, if the minutes setting is adjusted from 59 to 0, the hour remains
+     * unchanged.
+     *
+     * An amount of zero returns the current { link WallTime}.
+     *
+     * @see adjust
+     */
+    public WallTime free_adjust(int amount, TimeUnit time_unit) {
+        if (amount == 0)
+            return this;
+        
+        // piggyback on adjust() to do the heavy lifting, then rearrange its results
+        WallTime adjusted = adjust(amount, time_unit, null);
+        switch (time_unit) {
+            case TimeUnit.HOUR:
+                return new WallTime(adjusted.hour, minute, second);
+            
+            case TimeUnit.MINUTE:
+                return new WallTime(hour, adjusted.minute, second);
+            
+            case TimeUnit.SECOND:
+                return new WallTime(hour, minute, adjusted.second);
+            
+            default:
+                assert_not_reached();
+        }
+    }
+    
+    /**
      * Returns a prettified, localized user-visible string.
      *
      * The string respects { link System.is_24hr}.
diff --git a/src/host/host-date-time-widget.vala b/src/host/host-date-time-widget.vala
index 3753ace..d715964 100644
--- a/src/host/host-date-time-widget.vala
+++ b/src/host/host-date-time-widget.vala
@@ -156,9 +156,13 @@ public class DateTimeWidget : Gtk.Box {
         if (!adjust_time_controls(details, out amount, out time_unit))
             return Toolkit.PROPAGATE;
         
-        // adjust wall time and ensure it's clamped
-        // this will update the entry fields, so don't disconnect widget signals
-        wall_time = get_clamped(date, wall_time.adjust(amount, time_unit, null)).to_wall_time();
+        // use free_adjust() to adjust each unit individually without affecting others
+        Calendar.WallTime new_wall_time = wall_time.free_adjust(amount, time_unit);
+        
+        // ensure it's clamped ... this assignment will update the entry fields, so don't
+        // disconnect widget signals
+        if (is_valid_date_time(date, new_wall_time))
+            wall_time = new_wall_time;
         
         return Toolkit.STOP;
     }
@@ -192,11 +196,11 @@ public class DateTimeWidget : Gtk.Box {
         return true;
     }
     
-    private Calendar.ExactTime get_clamped(Calendar.Date proposed_date, Calendar.WallTime proposed_time) {
+    private bool is_valid_date_time(Calendar.Date proposed_date, Calendar.WallTime proposed_time) {
         Calendar.ExactTime exact_time = new Calendar.ExactTime(Calendar.Timezone.local, proposed_date,
             proposed_time);
         
-        return exact_time.clamp(floor, ceiling);
+        return exact_time.clamp(floor, ceiling).equal_to(exact_time);
     }
     
     private Calendar.Date? get_selected_date() {
@@ -220,13 +224,11 @@ public class DateTimeWidget : Gtk.Box {
         disconnect_property_signals();
         
         Calendar.Date? selected = get_selected_date();
-        if (selected != null) {
-            // clamp selected date; if not the same as selected, select it (in effect, prevents the
-            // user from selecting a date on the GtkCalendar outside of range)
-            date = new Calendar.Date.from_exact_time(get_clamped(selected, wall_time));
-            if (!date.equal_to(selected))
-                on_date_changed();
-        }
+        if (selected != null && is_valid_date_time(selected, wall_time) && !selected.equal_to(date))
+            date = selected;
+        
+        // even if user picked invalid date, this resets selection to valid one
+        on_date_changed();
         
         connect_property_signals();
     }
@@ -274,8 +276,10 @@ public class DateTimeWidget : Gtk.Box {
         
         disconnect_property_signals();
         
-        wall_time = new_wall_time;
+        freeze_notify();
         out_of_range = !valid;
+        wall_time = new_wall_time;
+        thaw_notify();
         
         connect_property_signals();
     }


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