[california/wip/725767-week] Fixed scrolling, drawing hour and half-hour lines now



commit 33d874fa844603a50400f576564feead6e60fa4c
Author: Jim Nelson <jim yorba org>
Date:   Wed May 7 16:52:33 2014 -0700

    Fixed scrolling, drawing hour and half-hour lines now

 src/view/month/month-cell.vala |    3 +-
 src/view/view-palette.vala     |   31 +++++++++++++++++++
 src/view/week/week-grid.vala   |   18 +++++++++--
 src/view/week/week-pane.vala   |   63 ++++++++++++++++++++++++++++-----------
 4 files changed, 92 insertions(+), 23 deletions(-)
---
diff --git a/src/view/month/month-cell.vala b/src/view/month/month-cell.vala
index ae04260..cc3d773 100644
--- a/src/view/month/month-cell.vala
+++ b/src/view/month/month-cell.vala
@@ -375,8 +375,7 @@ private class Cell : Gtk.EventBox {
         int height = get_allocated_height();
         
         // draw border lines (creates grid effect)
-        Gdk.cairo_set_source_rgba(ctx, Palette.instance.border);
-        ctx.set_line_width(0.5);
+        Palette.prepare_hairline_border(ctx);
         
         // only draw top line if on the top row
         if (row == 0) {
diff --git a/src/view/view-palette.vala b/src/view/view-palette.vala
index ae9be91..a3dc4ee 100644
--- a/src/view/view-palette.vala
+++ b/src/view/view-palette.vala
@@ -24,6 +24,16 @@ public class Palette : BaseObject {
      */
     public const int LINE_SPACING_PX = 4;
     
+    /**
+     * Hairline line width.
+     */
+    public const double HAIRLINE_WIDTH = 0.5;
+    
+    /**
+     * Dash pattern for Cairo.
+     */
+    public const double DASHES[] = { 1.0, 3.0 };
+    
     private const int NORMAL_FONT_SIZE_PT = 11;
     private const int SMALL_FONT_SIZE_PT = 8;
     
@@ -158,6 +168,27 @@ public class Palette : BaseObject {
         return height;
     }
     
+    /**
+     * Prepare a Cairo.Context for drawing hairline borders.
+     */
+    public static Cairo.Context prepare_hairline_border(Cairo.Context ctx) {
+        Gdk.cairo_set_source_rgba(ctx, instance.border);
+        ctx.set_line_width(HAIRLINE_WIDTH);
+        
+        return ctx;
+    }
+    
+    /**
+     * Prepare a Cairo.Context for drawing hairline dashed lines.
+     */
+    public static Cairo.Context prepare_hairline_dashed(Cairo.Context ctx) {
+        Gdk.cairo_set_source_rgba(ctx, instance.border);
+        ctx.set_line_width(HAIRLINE_WIDTH);
+        ctx.set_dash(DASHES, 0);
+        
+        return ctx;
+    }
+    
     public override string to_string() {
         return "View.Palette";
     }
diff --git a/src/view/week/week-grid.vala b/src/view/week/week-grid.vala
index 87a9afc..a4a2eec 100644
--- a/src/view/week/week-grid.vala
+++ b/src/view/week/week-grid.vala
@@ -43,7 +43,7 @@ internal class Grid : Gtk.Grid {
         
         scrolled_panes.hscrollbar_policy = Gtk.PolicyType.NEVER;
         scrolled_panes.vscrollbar_policy = Gtk.PolicyType.ALWAYS;
-        scrolled_panes.add_with_viewport(pane_grid);
+        scrolled_panes.add(pane_grid);
         
         // date labels across the top, week panes extending across the bottom, all stored inside
         // a scrolled window
@@ -51,8 +51,20 @@ internal class Grid : Gtk.Grid {
         foreach (Calendar.Date date in week) {
             Gtk.Label date_label = new Gtk.Label("%s %d/%d".printf(date.day_of_week.abbrev_name,
                 date.month_of_year().month.value, date.day_of_month.value));
-            date_label.margin_top = 2;
-            date_label.margin_bottom = 2;
+            
+            // draw a line along the bottom of the label
+            date_label.draw.connect((ctx) => {
+                int width = date_label.get_allocated_width();
+                int height = date_label.get_allocated_height();
+                
+                Palette.prepare_hairline_border(ctx);
+                ctx.move_to(0, height);
+                ctx.line_to(width, height);
+                ctx.stroke();
+                
+                return false;
+            });
+            
             attach(date_label, col, 0, 1, 1);
             
             Pane pane = new Pane(this, date);
diff --git a/src/view/week/week-pane.vala b/src/view/week/week-pane.vala
index 87232b7..b52f05a 100644
--- a/src/view/week/week-pane.vala
+++ b/src/view/week/week-pane.vala
@@ -18,17 +18,19 @@ internal class Pane : Gtk.EventBox {
     public bool selected { get; set; default = false; }
     
     private Gtk.DrawingArea canvas = new Gtk.DrawingArea();
+    private int line_height_px = 0;
     
     public Pane(Grid owner, Calendar.Date initial_date) {
         this.owner = owner;
         date = initial_date;
         
-        canvas.set_size_request(-1, get_line_y(Calendar.WallTime.latest) + get_line_height());
+        margin = 0;
+        
         add(canvas);
         
         notify[PROP_DATE].connect(queue_draw);
         notify[PROP_SELECTED].connect(queue_draw);
-        Palette.instance.palette_changed.connect(queue_draw);
+        Palette.instance.palette_changed.connect(on_palette_changed);
         Calendar.System.instance.is_24hr_changed.connect(queue_draw);
         Calendar.System.instance.today_changed.connect(on_today_changed);
         
@@ -36,11 +38,22 @@ internal class Pane : Gtk.EventBox {
     }
     
     ~Pane() {
-        Palette.instance.palette_changed.disconnect(queue_draw);
+        Palette.instance.palette_changed.disconnect(on_palette_changed);
         Calendar.System.instance.is_24hr_changed.disconnect(queue_draw);
         Calendar.System.instance.today_changed.disconnect(on_today_changed);
     }
     
+    private void on_palette_changed() {
+        // calculcate the amount of space each "line" gets when drawing (normal font height plus
+        // padding on top and bottom)
+        line_height_px = Palette.instance.normal_font_height_px + (Palette.LINE_SPACING_PX * 2);
+        
+        // update the height request based on the number of lines needed to show the entire day
+        canvas.set_size_request(-1, get_line_y(Calendar.WallTime.latest) + line_height_px);
+        
+        queue_draw();
+    }
+    
     private void on_today_changed(Calendar.Date old_today, Calendar.Date new_today) {
         // need to know re: redrawing background color to indicate current day
         if (date.equal_to(old_today) || date.equal_to(new_today))
@@ -60,36 +73,50 @@ internal class Pane : Gtk.EventBox {
         int width = get_allocated_width();
         int height = get_allocated_height();
         
-        // draw border lines (one across top, one on right side)
-        Gdk.cairo_set_source_rgba(ctx, Palette.instance.border);
-        ctx.set_line_width(0.5);
-        ctx.move_to(0, 0);
-        ctx.line_to(width, 0);
+        // draw right-side border line
+        Palette.prepare_hairline_border(ctx);
+        ctx.move_to(width, 0);
         ctx.line_to(width, height);
+        ctx.line_to(0, height);
         ctx.stroke();
         
-        // draw hour lines
+        // draw hour and half-hour lines
         Calendar.WallTime wall_time = Calendar.WallTime.earliest;
-        bool rollover = false;
-        do {
-            wall_time = wall_time.adjust(1, Calendar.TimeUnit.HOUR, out rollover);
+        for(;;) {
+            bool rollover;
+            wall_time = wall_time.adjust(30, Calendar.TimeUnit.MINUTE, out rollover);
+            if (rollover)
+                break;
             
             int line_y = get_line_y(wall_time);
             
+            // solid line on the hour, dashed on the half-hour
+            if (wall_time.minute == 0)
+                Palette.prepare_hairline_border(ctx);
+            else
+                Palette.prepare_hairline_dashed(ctx);
+            
             ctx.move_to(0, line_y);
             ctx.line_to(width, line_y);
             ctx.stroke();
-        } while (!rollover);
+        }
         
         return true;
     }
     
-    private int get_line_height() {
-        return (Palette.instance.normal_font_height_px + Palette.LINE_SPACING_PX) * 2;
-    }
-    
     private int get_line_y(Calendar.WallTime wall_time) {
-        return get_line_height() * wall_time.hour;
+        // every hour gets two "lines" of text
+        int line_y = line_height_px * 2 * wall_time.hour;
+        
+        // break up space for each minute in the two lines per hour
+        if (wall_time.minute != 0) {
+            double fraction = (double) wall_time.minute / (double) Calendar.WallTime.MINUTES_PER_HOUR;
+            double amt = (double) line_height_px * 2.0 * fraction;
+            
+            line_y += (int) Math.round(amt);
+        }
+        
+        return line_y;
     }
 }
 


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