[california/wip/725767-week] Double-clicking on week view pane creates event for time at click



commit c8bcb89530fd3a1746b0713648a9e5730555e594
Author: Jim Nelson <jim yorba org>
Date:   Thu May 22 12:45:40 2014 -0700

    Double-clicking on week view pane creates event for time at click

 src/Makefile.am                         |    1 +
 src/calendar/calendar-wall-time.vala    |   59 +++++++++++++++++++++++++
 src/tests/tests-calendar-wall-time.vala |   71 +++++++++++++++++++++++++++++++
 src/tests/tests.vala                    |    1 +
 src/view/week/week-grid.vala            |   10 ++++-
 src/view/week/week-pane.vala            |    2 +-
 6 files changed, 142 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 6f66f9f..6f176ea 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -104,6 +104,7 @@ california_VALASOURCES = \
        tests/tests-calendar-date.vala \
        tests/tests-calendar-month-of-year.vala \
        tests/tests-calendar-month-span.vala \
+       tests/tests-calendar-wall-time.vala \
        tests/tests-quick-add.vala \
        \
        toolkit/toolkit.vala \
diff --git a/src/calendar/calendar-wall-time.vala b/src/calendar/calendar-wall-time.vala
index b8806be..efa8d34 100644
--- a/src/calendar/calendar-wall-time.vala
+++ b/src/calendar/calendar-wall-time.vala
@@ -337,6 +337,65 @@ public class WallTime : BaseObject, Gee.Comparable<WallTime>, Gee.Hashable<WallT
     }
     
     /**
+     * Round a unit of the { link WallTime} to a multiple of a supplied value.
+     *
+     * By rounding wall-clock time, not only is the unit in question rounded down to a multiple of
+     * the supplied value, but the lesser units are truncated to zero.  Thus, 17:23:54 rounded down
+     * to a multiple of 10 minutes returns 17:20:00.
+     *
+     * If the { link TimeUnit} is already a multiple of the value, no change is made (although
+     * there's no guarantee that the same WallTime instance will be returned, especially if the
+     * lesser units are truncated).
+     *
+     * A multiple of zero or a negative value is always rounded to the current WallTime.
+     *
+     * TODO: An interface to round up (which will need to deal with overflow).
+     */
+    public WallTime round_down(int multiple, TimeUnit time_unit) {
+        if (multiple <= 0)
+            return this;
+        
+        // get value being manipulated
+        int current;
+        switch (time_unit) {
+            case TimeUnit.HOUR:
+                current = hour;
+            break;
+            
+            case TimeUnit.MINUTE:
+                current = minute;
+            break;
+            
+            case TimeUnit.SECOND:
+                current = second;
+            break;
+            
+            default:
+                assert_not_reached();
+        }
+        
+        // round down and watch for underflow (which shouldn't happen)
+        int rounded = current - (current % multiple.abs());
+        if (rounded < 0)
+            rounded = 0;
+        
+        // return new value
+        switch (time_unit) {
+            case TimeUnit.HOUR:
+                return new WallTime(rounded, 0, 0);
+            
+            case TimeUnit.MINUTE:
+                return new WallTime(hour, rounded, 0);
+            
+            case TimeUnit.SECOND:
+                return new WallTime(hour, minute, rounded);
+            
+            default:
+                assert_not_reached();
+        }
+    }
+    
+    /**
      * Returns a prettified, localized user-visible string.
      *
      * The string respects { link System.is_24hr}.
diff --git a/src/tests/tests-calendar-wall-time.vala b/src/tests/tests-calendar-wall-time.vala
new file mode 100644
index 0000000..ef974de
--- /dev/null
+++ b/src/tests/tests-calendar-wall-time.vala
@@ -0,0 +1,71 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+namespace California.Tests {
+
+internal class CalendarWallTime : UnitTest.Harness {
+    public CalendarWallTime() {
+        add_case("round-down-perverse", round_down_perverse);
+        add_case("round-down-zero", round_down_zero);
+        add_case("round-down-hour-no-change", round_down_hour_no_change);
+        add_case("round-down-hour-change", round_down_hour_change);
+        add_case("round-down-minute", round_down_minute);
+        add_case("round-down-second", round_down_second);
+    }
+    
+    protected override void setup() throws Error {
+        Calendar.init();
+    }
+    
+    protected override void teardown() {
+        Calendar.terminate();
+    }
+    
+    private bool round_down_perverse() throws Error {
+        Calendar.WallTime wall_time = new Calendar.WallTime(10, 12, 14);
+        Calendar.WallTime round_down = wall_time.round_down(-1, Calendar.TimeUnit.MINUTE);
+        
+        return wall_time.equal_to(round_down);
+    }
+    
+    private bool round_down_zero() throws Error {
+        Calendar.WallTime wall_time = new Calendar.WallTime(10, 12, 14);
+        Calendar.WallTime round_down = wall_time.round_down(0, Calendar.TimeUnit.HOUR);
+        
+        return wall_time.equal_to(round_down);
+    }
+    
+    private bool round_down_hour_no_change() throws Error {
+        Calendar.WallTime wall_time = new Calendar.WallTime(10, 12, 14);
+        Calendar.WallTime round_down = wall_time.round_down(2, Calendar.TimeUnit.HOUR);
+        
+        return round_down.hour == 10 && round_down.minute == 0 && round_down.second == 0;
+    }
+    
+    private bool round_down_hour_change() throws Error {
+        Calendar.WallTime wall_time = new Calendar.WallTime(9, 12, 14);
+        Calendar.WallTime round_down = wall_time.round_down(2, Calendar.TimeUnit.HOUR);
+        
+        return round_down.hour == 8 && round_down.minute == 0 && round_down.second == 0;
+    }
+    
+    private bool round_down_minute() throws Error {
+        Calendar.WallTime wall_time = new Calendar.WallTime(10, 12, 14);
+        Calendar.WallTime round_down = wall_time.round_down(10, Calendar.TimeUnit.MINUTE);
+        
+        return round_down.hour == 10 && round_down.minute == 10 && round_down.second == 0;
+    }
+    
+    private bool round_down_second() throws Error {
+        Calendar.WallTime wall_time = new Calendar.WallTime(10, 12, 16);
+        Calendar.WallTime round_down = wall_time.round_down(15, Calendar.TimeUnit.SECOND);
+        
+        return round_down.hour == 10 && round_down.minute == 12 && round_down.second == 15;
+    }
+}
+
+}
+
diff --git a/src/tests/tests.vala b/src/tests/tests.vala
index 20b6638..1d484b0 100644
--- a/src/tests/tests.vala
+++ b/src/tests/tests.vala
@@ -11,6 +11,7 @@ public int run(string[] args) {
     UnitTest.Harness.register(new CalendarDate());
     UnitTest.Harness.register(new CalendarMonthSpan());
     UnitTest.Harness.register(new CalendarMonthOfYear());
+    UnitTest.Harness.register(new CalendarWallTime());
     
     return UnitTest.Harness.exec_all();
 }
diff --git a/src/view/week/week-grid.vala b/src/view/week/week-grid.vala
index b55a7d0..29ee9b5 100644
--- a/src/view/week/week-grid.vala
+++ b/src/view/week/week-grid.vala
@@ -256,7 +256,15 @@ internal class Grid : Gtk.Box {
         
         DayPane day_pane = (DayPane) details.widget;
         
-        owner.request_create_all_day_event(new Calendar.DateSpan.from_span(day_pane.date),
+        // convert click into starting time on the day pane rounded down to the nearest half-hour
+        Calendar.WallTime wall_time = day_pane.get_wall_time(details.press_point.y).round_down(
+            30, Calendar.TimeUnit.MINUTE);
+        
+        Calendar.ExactTime start_time = new Calendar.ExactTime(Calendar.Timezone.local,
+            day_pane.date, wall_time);
+        
+        owner.request_create_timed_event(
+            new Calendar.ExactTimeSpan(start_time, start_time.adjust_time(1, Calendar.TimeUnit.HOUR)),
             day_pane, details.press_point);
     }
 }
diff --git a/src/view/week/week-pane.vala b/src/view/week/week-pane.vala
index 728b7b5..96292fc 100644
--- a/src/view/week/week-pane.vala
+++ b/src/view/week/week-pane.vala
@@ -119,7 +119,7 @@ internal abstract class Pane : Gtk.EventBox {
     /**
      * Returns the { link Calendar.WallTime} for a y-coordinate down to the minute;
      */
-    protected Calendar.WallTime get_wall_time(int y) {
+    public Calendar.WallTime get_wall_time(int y) {
         // every hour gets two "lines" of text
         int one_hour = line_height_px * 2;
         


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