[california/wip/725778-allday] First stab at spanning bars for all-day events



commit b454cd1af2aa0a20474aee63a11f2b7351dadca6
Author: Jim Nelson <jim yorba org>
Date:   Fri Apr 4 18:14:46 2014 -0700

    First stab at spanning bars for all-day events
    
    Pretty close, but currently doesn't deal well with spans that
    overlap but have differing start and end dates.  Also would like to
    make the bars a little prettier, perhaps rounded corners.

 src/view/month/month-cell.vala |   63 +++++++++++++++++++++++++++++++++------
 1 files changed, 53 insertions(+), 10 deletions(-)
---
diff --git a/src/view/month/month-cell.vala b/src/view/month/month-cell.vala
index dd1ee0f..4b9a52c 100644
--- a/src/view/month/month-cell.vala
+++ b/src/view/month/month-cell.vala
@@ -59,7 +59,7 @@ public class Cell : Gtk.EventBox {
         }
     }
     
-    private Gee.TreeSet<Component.Event> days_events = new Gee.TreeSet<Component.Event>();
+    private Gee.TreeSet<Component.Event> days_events = new Gee.TreeSet<Component.Event>(all_day_comparator);
     private Gee.HashMap<int, Component.Event> line_to_event = new Gee.HashMap<int, Component.Event>();
     
     // TODO: We may need to get these colors from the theme
@@ -101,10 +101,32 @@ public class Cell : Gtk.EventBox {
         Calendar.System.instance.today_changed.disconnect(on_today_changed);
     }
     
+    // this comparator uses the standard Event comparator with one exception: if both Events are
+    // all-day, it sorts the one(s) with the furthest out end dates to the top, to ensure they are
+    // at the top of the drawn lines and prevent gaps and skips in the connected bars
+    private static int all_day_comparator(Component.Event a, Component.Event b) {
+        if (a == b)
+            return 0;
+        
+        if (!a.is_all_day || !b.is_all_day)
+            return a.compare_to(b);
+        
+        int compare = a.date_span.start_date.compare_to(b.date_span.start_date);
+        if (compare != 0)
+            return compare;
+        
+        compare = b.date_span.end_date.compare_to(a.date_span.end_date);
+        if (compare != 0)
+            return compare;
+        
+        // to stabilize
+        return a.compare_to(b);
+    }
+    
     internal static void init() {
         top_line_font = new Pango.FontDescription();
         top_line_font.set_size(TOP_LINE_FONT_SIZE_PT * Pango.SCALE);
-    
+        
         line_font = new Pango.FontDescription();
         line_font.set_size(LINE_FONT_SIZE_PT * Pango.SCALE);
         
@@ -241,7 +263,7 @@ public class Cell : Gtk.EventBox {
         // draw day of month as the top line
         if (date != null) {
             Gdk.RGBA color = (date in owner.month_of_year) ? RGBA_DAY_OF_MONTH : RGBA_DAY_OUTSIDE_MONTH;
-            draw_line_of_text(ctx, -1, color, date.day_of_month.informal_number);
+            draw_line_of_text(ctx, -1, color, date.day_of_month.informal_number, false);
         }
         
         // represents the line number being drawn (zero-based for remaining lines)
@@ -254,19 +276,26 @@ public class Cell : Gtk.EventBox {
             if (!event.calendar_source.visible)
                 continue;
             
-            string text;
+            string text, tooltip_text;
             if (event.is_all_day) {
-                text = event.summary;
+                // only show the title if (a) the first day of an all-day event or (b) this is the
+                // first day of a new week of a multi-day even.  (b) handles the contingency of a
+                // multi-day event starting in a previous week prior to the top of the current view
+                bool display_text = event.date_span.start_date.equal_to(date)
+                    || owner.first_of_week.as_day_of_week().equal_to(date.day_of_week);
+                text = display_text ? event.summary : "";
+                tooltip_text = event.summary;
             } else {
                 Calendar.ExactTime local_start = event.exact_time_span.start_exact_time.to_timezone(
                     Calendar.Timezone.local);
                 text = "%s %s".printf(local_start.to_pretty_time_string(PRETTY_TIME_FLAGS), event.summary);
+                tooltip_text = text;
             }
             
             Pango.Layout layout = draw_line_of_text(ctx, line_number, event.calendar_source.color_as_rgba(),
-                text);
+                text, event.is_all_day);
             line_to_event.set(line_number++, event);
-            event.set_data<string?>(KEY_TOOLTIP, layout.is_ellipsized() ? text : null);
+            event.set_data<string?>(KEY_TOOLTIP, layout.is_ellipsized() ? tooltip_text : null);
         }
         
         return true;
@@ -304,14 +333,28 @@ public class Cell : Gtk.EventBox {
     
     // If line number is negative, the top line is drawn; otherwise, zero-based line numbers get
     // "regular" treatment
-    private Pango.Layout draw_line_of_text(Cairo.Context ctx, int line_number, Gdk.RGBA rgba, string text) {
+    private Pango.Layout draw_line_of_text(Cairo.Context ctx, int line_number, Gdk.RGBA rgba,
+        string text, bool reversed) {
+        int allocated_width = get_allocated_width();
+        int top_y = get_line_top_y(line_number);
+        
         Pango.Layout layout = create_pango_layout(text);
         layout.set_font_description((line_number < 0) ? top_line_font : line_font);
         layout.set_ellipsize(Pango.EllipsizeMode.END);
-        layout.set_width((get_allocated_width() - (TEXT_MARGIN_PX * 2)) * Pango.SCALE);
+        layout.set_width((allocated_width - (TEXT_MARGIN_PX * 2)) * Pango.SCALE);
         
         Gdk.cairo_set_source_rgba(ctx, rgba);
-        ctx.move_to(TEXT_MARGIN_PX, get_line_top_y(line_number));
+        if (reversed) {
+            // draw background rectangle in spec'd color
+            ctx.rectangle(0, top_y, allocated_width, line_height_px);
+            ctx.fill_preserve();
+            ctx.stroke ();
+            
+            // set to white for text
+            Gdk.cairo_set_source_rgba(ctx, Gdk.RGBA() { red = 1.0, green = 1.0, blue = 1.0, alpha = 1.0 });
+        }
+        
+        ctx.move_to(TEXT_MARGIN_PX, top_y);
         Pango.cairo_show_layout(ctx, layout);
         
         return layout;


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