year-view: Remove hardcoded values

Improve year-view code, removing hardcoded values.

year-view have hardcoded values for grid cell sizes (width and height).
Those values need to be recalculated every time a change in font or any
other style are changed.

Sidebar width was also hardcoded instead of getting its value directly
from the ui file. That would prevent it from drawing the content
accordingly when ui file is changed.

This patch fixes those two issues by retrieving those values from CSS or
ui files.

This patch also adds code to resize and redraw the window when
show-week-numbers property is changed.

Popover mode was also changed and now sidebar will always be shown when
show-week-numbers is set or when there is space for only 3 or less
columns.

https://bugzilla.gnome.org/show_bug.cgi?id=753533
This commit is contained in:
Isaque Galdino
2016-05-16 12:03:39 -03:00
committed by Georges Basile Stavracas Neto
parent 32a3a8f530
commit 97d8859574
3 changed files with 181 additions and 69 deletions
+1
View File
@@ -89,6 +89,7 @@ calendar-view.second-view-header {
}
.year-navigator.days {
padding: 5px;
color: @theme_fg_color;
font: 9;
}
+24 -10
View File
@@ -6,17 +6,31 @@
<class name="year-view"/>
</style>
<child>
<object class="GtkDrawingArea" id="navigator">
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="events">GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_STRUCTURE_MASK</property>
<signal name="draw" handler="draw_navigator" object="GcalYearView" swapped="yes"/>
<signal name="button-press-event" handler="navigator_button_press_cb" object="GcalYearView" swapped="yes"/>
<signal name="button-release-event" handler="navigator_button_release_cb" object="GcalYearView" swapped="yes"/>
<signal name="motion-notify-event" handler="navigator_motion_notify_cb" object="GcalYearView" swapped="yes"/>
<style>
<class name="year-navigator"/>
</style>
<property name="shadow_type">none</property>
<property name="vexpand">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="shadow_type">none</property>
<property name="vexpand">True</property>
<child>
<object class="GtkDrawingArea" id="navigator">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="events">GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_STRUCTURE_MASK</property>
<signal name="draw" handler="draw_navigator" object="GcalYearView" swapped="yes"/>
<signal name="button-press-event" handler="navigator_button_press_cb" object="GcalYearView" swapped="yes"/>
<signal name="button-release-event" handler="navigator_button_release_cb" object="GcalYearView" swapped="yes"/>
<signal name="motion-notify-event" handler="navigator_motion_notify_cb" object="GcalYearView" swapped="yes"/>
<style>
<class name="year-navigator"/>
</style>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">0</property>
+156 -59
View File
@@ -25,9 +25,7 @@
#include <math.h>
#include <string.h>
#define NAVIGATOR_CELL_WIDTH (210 + 15)
#define NAVIGATOR_CELL_HEIGHT 210
#define SIDEBAR_PREFERRED_WIDTH 200
#define NAVIGATOR_MAX_GRID_SIZE 6
#define VISUAL_CLUES_SIDE 3.0
#define WEEK_NUMBER_MARGIN 3.0
@@ -67,6 +65,12 @@ struct _GcalYearView
/* geometry info */
GridData *navigator_grid;
guint number_of_columns;
guint number_of_rows;
guint column_width;
guint row_height;
guint header_height;
guint sidebar_width;
/* state flags */
gboolean popover_mode;
@@ -402,6 +406,8 @@ update_sidebar (GcalYearView *year_view)
for (l = events; l != NULL; l = g_list_next (l))
add_event_to_day_array (year_view, l->data, days_widgets_array, days_span);
gtk_widget_queue_draw (year_view->navigator);
for (i = 0; i < days_span; i++)
{
GList *current_day = days_widgets_array[i];
@@ -547,7 +553,7 @@ calculate_day_month_for_coord (GcalYearView *year_view,
gint *out_day,
gint *out_month)
{
gint row, column, i, sw, clicked_cell, day, month;
gint row, column, i, sw, clicked_cell, day, month, columns_or_rows;
gdouble box_side;
row = -1;
@@ -555,18 +561,19 @@ calculate_day_month_for_coord (GcalYearView *year_view,
box_side = year_view->navigator_grid->box_side;
sw = 1 - 2 * year_view->k;
/* y selection */
for (i = 0; i < 4 && ((row == -1) || (column == -1)); i++)
columns_or_rows = year_view->number_of_columns > year_view->number_of_rows ? year_view->number_of_columns : year_view->number_of_rows;
for (i = 0; i < columns_or_rows && ((row == -1) || (column == -1)); i++)
{
if (row == -1 &&
y > year_view->navigator_grid->coordinates[i * 4].y &&
y < year_view->navigator_grid->coordinates[i * 4].y + box_side * 7)
y > year_view->navigator_grid->coordinates[i * year_view->number_of_columns].y + box_side &&
y < year_view->navigator_grid->coordinates[i * year_view->number_of_columns].y + year_view->row_height)
{
row = i;
}
if (column == -1 &&
x > year_view->navigator_grid->coordinates[i].x + box_side * (1 - year_view->k) &&
x < year_view->navigator_grid->coordinates[i].x + box_side * (8 - year_view->k))
x > year_view->navigator_grid->coordinates[i].x + box_side * year_view->show_week_numbers * (1 - year_view->k) &&
x < year_view->navigator_grid->coordinates[i].x + year_view->column_width - box_side * year_view->show_week_numbers * year_view->k)
{
column = i;
}
@@ -575,9 +582,13 @@ calculate_day_month_for_coord (GcalYearView *year_view,
if (row == -1 || column == -1)
return FALSE;
month = row * 4 + column;
month = row * year_view->number_of_columns + column;
if (month < 0 || month > 11)
return FALSE;
row = (y - (year_view->navigator_grid->coordinates[month].y + box_side)) / box_side;
column = (x - (year_view->navigator_grid->coordinates[month].x + box_side * (1 - year_view->k))) / box_side;
column = (x - (year_view->navigator_grid->coordinates[month].x + box_side * year_view->show_week_numbers * (1 - year_view->k))) / box_side;
clicked_cell = row * 7 + column;
day = 7 * ((clicked_cell + 7 * year_view->k) / 7) + sw * (clicked_cell % 7) + (1 - year_view->k);
day -= ((time_day_of_week (1, month, year_view->date->year) - year_view->first_weekday + 7) % 7);
@@ -640,11 +651,11 @@ draw_month_grid (GcalYearView *year_view,
layout = gtk_widget_create_pango_layout (widget, str);
pango_layout_set_font_description (layout, font_desc);
pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
gtk_render_layout (context, cr, x + (box_side * 8 - layout_width) / 2.0, y + (box_side - layout_height) / 2.0,
gtk_render_layout (context, cr, x + (year_view->column_width - layout_width) / 2.0, y + (box_side - layout_height) / 2.0,
layout);
gtk_render_background (context, cr,
x + (box_side * 8 - layout_width) / 2.0, y + (box_side - layout_height) / 2.0,
x + (year_view->column_width - layout_width) / 2.0, y + (box_side - layout_height) / 2.0,
layout_width, layout_width);
pango_font_description_free (font_desc);
@@ -658,7 +669,8 @@ draw_month_grid (GcalYearView *year_view,
gtk_style_context_get_color (context, state_flags, &color);
cairo_set_line_width (cr, 0.2);
gdk_cairo_set_source_rgba (cr, &color);
cairo_move_to (cr, x + box_side * (1 - year_view->k), y + box_side + 0.4);
cairo_move_to (cr, x + box_side * year_view->show_week_numbers * (1 - year_view->k), y + box_side + 0.4);
cairo_rel_line_to (cr, 7.0 * box_side, 0);
cairo_stroke (cr);
@@ -674,7 +686,7 @@ draw_month_grid (GcalYearView *year_view,
days_delay = (time_day_of_week (1, month_nr, year_view->date->year) - year_view->first_weekday + 7) % 7;
days = days_delay + icaltime_days_in_month (month_nr + 1, year_view->date->year);
shown_rows = ceil (days / 7.0);
sunday_idx = year_view->k * 6 + sw * ((7 - year_view->first_weekday) % 7) + 1;
sunday_idx = year_view->k * 7 + sw * ((7 - year_view->first_weekday) % 7) + year_view->show_week_numbers * (1 - year_view->k);
start_date.day = 1;
start_date.month = month_nr + 1;
@@ -691,7 +703,7 @@ draw_month_grid (GcalYearView *year_view,
for (i = 0; i < 7 * shown_rows; i++)
{
column = (i % 7) + 1;
column = (i % 7) + (year_view->k || year_view->show_week_numbers);
row = i / 7;
j = 7 * ((i + 7 * year_view->k) / 7) + sw * (i % 7) + (1 - year_view->k);
@@ -883,7 +895,7 @@ draw_navigator (GcalYearView *year_view,
gint header_padding_left, header_padding_top, header_height, layout_width, layout_height;
gint real_padding_left, real_padding_top, i, sw, weeks_counter;
gdouble width, height, box_side;
gdouble width, height;
gchar *header_str;
@@ -925,23 +937,20 @@ draw_navigator (GcalYearView *year_view,
header_height = header_padding_top * 2 + layout_height;
height = gtk_widget_get_allocated_height (widget) - header_height;
if (((width / 4.0) / 8.0) < ((height / 3.0) / 7.0))
box_side = (width / 4.0) / 8.0;
else
box_side = (height / 3.0) / 7.0;
real_padding_left = (width - year_view->column_width * year_view->number_of_columns) / (year_view->number_of_columns + 1);
real_padding_top = (height - year_view->row_height * year_view->number_of_rows) / year_view->number_of_rows;
real_padding_left = (width - (8 * 4 * box_side)) / 5.0;
real_padding_top = (height - (7 * 3 * box_side)) / 4.0;
if (real_padding_top < 0)
real_padding_top = 0;
year_view->navigator_grid->box_side = box_side;
weeks_counter = year_view->first_week_of_year;
for (i = 0; i < 12; i++)
{
gint row = i / 4;
gint column = year_view->k * 3 + sw * (i % 4);
gint row = i / year_view->number_of_columns;
gint column = year_view->k * (year_view->number_of_columns - 1) + sw * (i % year_view->number_of_columns);
year_view->navigator_grid->coordinates[i].x = (column + 1) * real_padding_left + column * box_side * 8;
year_view->navigator_grid->coordinates[i].y = (row + 1) * real_padding_top + row * box_side * 7 + header_height;
year_view->navigator_grid->coordinates[i].x = (column + 1) * real_padding_left + column * year_view->column_width;
year_view->navigator_grid->coordinates[i].y = row * real_padding_top + row * year_view->row_height + header_height;
draw_month_grid (year_view, widget, cr, i, &weeks_counter);
}
@@ -1086,6 +1095,86 @@ popover_closed_cb (GcalYearView *year_view,
reset_sidebar (year_view);
}
static void
calculate_grid_sizes (GcalYearView *self)
{
/* 1 column for week number and 7 for days */
if (self->show_week_numbers)
self->column_width = self->navigator_grid->box_side * 8;
else
self->column_width = self->navigator_grid->box_side * 7;
/* 1 line for month header and 6 lines for weeks */
self->row_height = self->navigator_grid->box_side * 7;
}
static void
calculate_sizes (GcalYearView *self)
{
GtkStyleContext *context;
PangoLayout *layout;
PangoFontDescription *font;
gint padding_left, padding_right, padding_top, padding_bottom;
gint width, height, box_width, box_height, natural;
gchar *test_str;
/* get header info from CSS */
context = gtk_widget_get_style_context (GTK_WIDGET (self));
gtk_style_context_save (context);
gtk_style_context_add_class (context, "first-view-header");
gtk_style_context_get (context, gtk_style_context_get_state (context),
"padding-top", &padding_top,
"padding-bottom", &padding_bottom,
"font", &font, NULL);
gtk_style_context_restore (context);
/* measure header height */
test_str = g_strdup_printf ("8888");
layout = gtk_widget_create_pango_layout (self->navigator, test_str);
pango_layout_set_font_description (layout, font);
pango_layout_get_pixel_size (layout, &width, &height);
pango_font_description_free (font);
g_object_unref (layout);
g_free (test_str);
self->header_height = padding_top + height + padding_bottom;
/* get day info from CSS */
context = gtk_widget_get_style_context (GTK_WIDGET (self->navigator));
gtk_style_context_save (context);
gtk_style_context_add_class (context, "days");
gtk_style_context_get (context, gtk_style_context_get_state (context),
"padding-left", &padding_left,
"padding-right", &padding_right,
"padding-top", &padding_top,
"padding-bottom", &padding_bottom,
"font", &font, NULL);
gtk_style_context_restore (context);
/* measure box size */
test_str = g_strdup_printf ("88");
layout = gtk_widget_create_pango_layout (self->navigator, test_str);
pango_layout_set_font_description (layout, font);
pango_layout_get_pixel_size (layout, &width, &height);
pango_font_description_free (font);
g_object_unref (layout);
g_free (test_str);
box_width = padding_left + width + padding_right;
box_height = padding_top + height + padding_bottom;
self->navigator_grid->box_side = (box_width > box_height) ? box_width : box_height;
/* get sidebar width */
gtk_widget_get_preferred_width (self->sidebar, &width, &natural);
self->sidebar_width = width;
calculate_grid_sizes (self);
}
static void
gcal_year_view_finalize (GObject *object)
{
@@ -1145,7 +1234,9 @@ gcal_year_view_set_property (GObject *object,
if (self->show_week_numbers != g_value_get_boolean (value))
{
self->show_week_numbers = g_value_get_boolean (value);
calculate_grid_sizes (self);
g_object_notify (object, "show-week-numbers");
gtk_widget_queue_allocate (GTK_WIDGET (self));
}
break;
@@ -1161,40 +1252,20 @@ gcal_year_view_get_preferred_width (GtkWidget *widget,
{
GcalYearView *year_view = GCAL_YEAR_VIEW (widget);
GtkStyleContext *context;
gint padding_left;
gint padding_left, padding_right, hpadding;
context = gtk_widget_get_style_context (year_view->navigator);
gtk_style_context_get (context,
gtk_style_context_get_state (context),
"padding-left", &padding_left, NULL);
"padding-left", &padding_left,
"padding-right", &padding_right, NULL);
hpadding = padding_left + padding_right;
if (minimum != NULL)
*minimum = NAVIGATOR_CELL_WIDTH * 4 + padding_left * 8;
*minimum = hpadding + year_view->column_width;
if (natural != NULL)
*natural = NAVIGATOR_CELL_WIDTH * 4 + padding_left * 8 + SIDEBAR_PREFERRED_WIDTH;
}
static void
gcal_year_view_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum,
gint *natural)
{
GcalYearView *year_view = GCAL_YEAR_VIEW (widget);
GtkStyleContext *context;
gint padding_top;
context = gtk_widget_get_style_context (year_view->navigator);
gtk_style_context_get (context,
gtk_style_context_get_state (context),
"padding-top", &padding_top, NULL);
if (minimum != NULL)
*minimum = NAVIGATOR_CELL_HEIGHT * 3 + padding_top * 6;
if (natural != NULL)
*natural = NAVIGATOR_CELL_HEIGHT * 3 + padding_top * 6;
*natural = hpadding + year_view->column_width + year_view->sidebar_width;
}
static void
@@ -1203,15 +1274,35 @@ gcal_year_view_size_allocate (GtkWidget *widget,
{
GcalYearView *year_view = GCAL_YEAR_VIEW (widget);
GtkStyleContext *context;
gint padding_left;
gint padding_left, padding_right, padding_top, padding_bottom, hpadding, vpadding;
context = gtk_widget_get_style_context (widget);
gtk_style_context_save (context);
gtk_style_context_add_class (context, "year-navigator");
gtk_style_context_get (context, gtk_style_context_get_state (context), "padding-left", &padding_left, NULL);
gtk_style_context_get (context,
gtk_style_context_get_state (context),
"padding-left", &padding_left,
"padding-right", &padding_right,
"padding-top", &padding_top,
"padding-bottom", &padding_bottom, NULL);
gtk_style_context_restore (context);
year_view->popover_mode = (alloc->width < NAVIGATOR_CELL_WIDTH * 4 + padding_left * 8 + SIDEBAR_PREFERRED_WIDTH);
hpadding = padding_left + padding_right;
vpadding = padding_top + padding_bottom;
year_view->popover_mode = (alloc->width < (hpadding + year_view->column_width * 2 + year_view->sidebar_width));
year_view->number_of_columns = (alloc->width - hpadding - year_view->sidebar_width * !year_view->popover_mode) / year_view->column_width;
if (year_view->number_of_columns > NAVIGATOR_MAX_GRID_SIZE)
year_view->number_of_columns = NAVIGATOR_MAX_GRID_SIZE;
year_view->number_of_rows = ceil (12.0 / year_view->number_of_columns);
gtk_widget_set_size_request (year_view->navigator,
hpadding + year_view->column_width * year_view->number_of_columns,
vpadding + year_view->row_height * year_view->number_of_rows + year_view->header_height);
if (year_view->popover_mode && !gtk_widget_is_ancestor (year_view->events_sidebar, year_view->popover))
{
g_object_ref (year_view->sidebar);
@@ -1343,6 +1434,8 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
g_list_free (current_day);
}
gtk_widget_queue_draw (year_view->navigator);
out:
g_clear_object (&event);
g_free (days_widgets_array);
@@ -1443,7 +1536,6 @@ gcal_year_view_class_init (GcalYearViewClass *klass)
object_class->set_property = gcal_year_view_set_property;
widget_class->get_preferred_width = gcal_year_view_get_preferred_width;
widget_class->get_preferred_height_for_width = gcal_year_view_get_preferred_height_for_width;
widget_class->size_allocate = gcal_year_view_size_allocate;
widget_class->direction_changed = gcal_year_view_direction_changed;
@@ -1506,6 +1598,11 @@ gcal_year_view_init (GcalYearView *self)
g_settings_bind (self->shell_settings, "show-weekdate", self, "show-week-numbers", G_SETTINGS_BIND_DEFAULT);
g_signal_connect_swapped (self->shell_settings, "changed::show-weekdate", G_CALLBACK (gtk_widget_queue_draw), self);
/* layout */
self->number_of_columns = 4;
self->number_of_rows = 3;
calculate_sizes (self);
gtk_list_box_set_header_func (GTK_LIST_BOX (self->events_sidebar), update_sidebar_headers, self, NULL);
gtk_list_box_set_sort_func (GTK_LIST_BOX (self->events_sidebar), sidebar_sort_func, NULL, NULL);
}