[california/wip/725778-allday] Cap ends of all-day events with rounded and pointed corners
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725778-allday] Cap ends of all-day events with rounded and pointed corners
- Date: Fri, 25 Apr 2014 00:23:20 +0000 (UTC)
commit 9fb1d91b8169f62b36a77fb128ccd9c126d482d1
Author: Jim Nelson <jim yorba org>
Date: Thu Apr 24 17:23:18 2014 -0700
Cap ends of all-day events with rounded and pointed corners
src/view/month/month-cell.vala | 116 +++++++++++++++++++++++++++++++++++-----
1 files changed, 103 insertions(+), 13 deletions(-)
---
diff --git a/src/view/month/month-cell.vala b/src/view/month/month-cell.vala
index 1e3b68b..5ac7f3e 100644
--- a/src/view/month/month-cell.vala
+++ b/src/view/month/month-cell.vala
@@ -17,12 +17,24 @@ public class Cell : Gtk.EventBox {
private const int TEXT_MARGIN_PX = 2;
private const int LINE_SPACING_PX = 4;
+ private const double ROUNDED_CAP_RADIUS = 5.0;
+ private const int POINTED_CAP_WIDTH_PX = 6;
+
+ private const double DEGREES = Math.PI / 180.0;
+
private const string KEY_TOOLTIP = "california-view-month-cell-tooltip";
private const Calendar.WallTime.PrettyFlag PRETTY_TIME_FLAGS =
Calendar.WallTime.PrettyFlag.OPTIONAL_MINUTES
| Calendar.WallTime.PrettyFlag.BRIEF_MERIDIEM;
+ private enum CapEffect {
+ NONE,
+ BLOCKED,
+ ROUNDED,
+ POINTED
+ }
+
public weak Controllable owner { get; private set; }
public int row { get; private set; }
public int col { get; private set; }
@@ -333,7 +345,8 @@ 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, false);
+ draw_line_of_text(ctx, -1, color, date.day_of_month.informal_number, CapEffect.NONE,
+ CapEffect.NONE);
}
// walk the assigned line numbers for each event and draw
@@ -357,8 +370,28 @@ public class Cell : Gtk.EventBox {
tooltip_text = text;
}
+ // use caps on both ends of all-day events depending whether this is the start, end,
+ // or start/end of week of continuing event
+ CapEffect left_effect = CapEffect.NONE;
+ CapEffect right_effect = CapEffect.NONE;
+ if (event.is_all_day) {
+ if (event.date_span.start_date.equal_to(date))
+ left_effect = CapEffect.ROUNDED;
+ else if (date.day_of_week == owner.first_of_week.as_day_of_week())
+ left_effect = CapEffect.POINTED;
+ else
+ left_effect = CapEffect.BLOCKED;
+
+ if (event.date_span.end_date.equal_to(date))
+ right_effect = CapEffect.ROUNDED;
+ else if (date.day_of_week == owner.first_of_week.as_day_of_week().previous())
+ right_effect = CapEffect.POINTED;
+ else
+ right_effect = CapEffect.BLOCKED;
+ }
+
Pango.Layout layout = draw_line_of_text(ctx, iter.get_key(),
event.calendar_source.color_as_rgba(),
- text, event.is_all_day);
+ text, left_effect, right_effect);
event.set_data<string?>(KEY_TOOLTIP, layout.is_ellipsized() ? tooltip_text : null);
}
@@ -398,27 +431,84 @@ 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, bool reversed) {
- int allocated_width = get_allocated_width();
- int top_y = get_line_top_y(line_number);
+ string text, CapEffect left_effect, CapEffect right_effect) {
+ bool is_reversed = (left_effect != CapEffect.NONE || right_effect != CapEffect.NONE);
- 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((allocated_width - (TEXT_MARGIN_PX * 2)) * Pango.SCALE);
+ int left = 0;
+ int right = get_allocated_width();
+ int top = get_line_top_y(line_number);
+ int bottom = top + line_height_px;
+ // use event color for text unless reversed, where it becomes the background color
Gdk.cairo_set_source_rgba(ctx, rgba);
- if (reversed) {
- // draw background rectangle in spec'd color
- ctx.rectangle(0, top_y, allocated_width, line_height_px);
+ if (is_reversed) {
+ // draw background rectangle in spec'd color with text in white
+ switch (right_effect) {
+ case CapEffect.ROUNDED:
+ ctx.new_sub_path();
+ // sub 2 to avoid touching right calendar line
+ ctx.arc(right - 2 - ROUNDED_CAP_RADIUS, top + ROUNDED_CAP_RADIUS, ROUNDED_CAP_RADIUS,
+ -90.0 * DEGREES, 0 * DEGREES);
+ ctx.arc(right - 2 - ROUNDED_CAP_RADIUS, bottom - ROUNDED_CAP_RADIUS, ROUNDED_CAP_RADIUS,
+ 0 * DEGREES, 90.0 * DEGREES);
+ break;
+
+ case CapEffect.POINTED:
+ ctx.move_to(right - POINTED_CAP_WIDTH_PX, top);
+ ctx.line_to(right, top + (line_height_px / 2));
+ ctx.line_to(right - POINTED_CAP_WIDTH_PX, bottom);
+ break;
+
+ case CapEffect.BLOCKED:
+ default:
+ ctx.move_to(right, top);
+ ctx.line_to(right, bottom);
+ break;
+ }
+
+ switch (left_effect) {
+ case CapEffect.ROUNDED:
+ // add one to avoid touching cell to the left's right calendar line
+ ctx.arc(left + 1 + ROUNDED_CAP_RADIUS, bottom - ROUNDED_CAP_RADIUS, ROUNDED_CAP_RADIUS,
+ 90.0 * DEGREES, 180.0 * DEGREES);
+ ctx.arc(left + 1 + ROUNDED_CAP_RADIUS, top + ROUNDED_CAP_RADIUS, ROUNDED_CAP_RADIUS,
+ 180.0 * DEGREES, 270.0 * DEGREES);
+ break;
+
+ case CapEffect.POINTED:
+ ctx.line_to(left + POINTED_CAP_WIDTH_PX, bottom);
+ ctx.line_to(left, top + (line_height_px / 2));
+ ctx.line_to(left + POINTED_CAP_WIDTH_PX, top);
+ break;
+
+ case CapEffect.BLOCKED:
+ default:
+ ctx.line_to(left, bottom);
+ ctx.line_to(left, top);
+ break;
+ }
+
+ // fill with event color
ctx.fill_preserve();
+
+ // close path from last point (deals with capped and uncapped ends) and paint
+ ctx.close_path();
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);
+ // add a couple of pixels to the text margins if capped
+ int left_text_margin = TEXT_MARGIN_PX + (left_effect != CapEffect.NONE ? 3 : 0);
+ int right_text_margin = TEXT_MARGIN_PX + (right_effect != CapEffect.NONE ? 3 : 0);
+
+ 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((right - left - left_text_margin - right_text_margin) * Pango.SCALE);
+
+ ctx.move_to(left_text_margin, top);
Pango.cairo_show_layout(ctx, layout);
return layout;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]