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); }