From 97d88595745ae85d94667eb63dd88755af902852 Mon Sep 17 00:00:00 2001 From: Isaque Galdino Date: Tue, 26 Apr 2016 21:55:37 -0300 Subject: [PATCH] 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 --- data/theme/gtk-styles.css | 1 + data/ui/year-view.ui | 34 ++++-- src/gcal-year-view.c | 215 +++++++++++++++++++++++++++----------- 3 files changed, 181 insertions(+), 69 deletions(-) diff --git a/data/theme/gtk-styles.css b/data/theme/gtk-styles.css index ae24c049..e1c5182d 100644 --- a/data/theme/gtk-styles.css +++ b/data/theme/gtk-styles.css @@ -89,6 +89,7 @@ calendar-view.second-view-header { } .year-navigator.days { + padding: 5px; color: @theme_fg_color; font: 9; } diff --git a/data/ui/year-view.ui b/data/ui/year-view.ui index 25b3ff00..9206279a 100644 --- a/data/ui/year-view.ui +++ b/data/ui/year-view.ui @@ -6,17 +6,31 @@ - + True - True - GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_STRUCTURE_MASK - - - - - + none + True + + + True + none + True + + + True + True + GDK_POINTER_MOTION_MASK|GDK_BUTTON_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_STRUCTURE_MASK + + + + + + + + + 0 diff --git a/src/gcal-year-view.c b/src/gcal-year-view.c index 60b061c4..147012f2 100644 --- a/src/gcal-year-view.c +++ b/src/gcal-year-view.c @@ -25,9 +25,7 @@ #include #include -#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); }