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:
committed by
Georges Basile Stavracas Neto
parent
32a3a8f530
commit
97d8859574
@@ -89,6 +89,7 @@ calendar-view.second-view-header {
|
||||
}
|
||||
|
||||
.year-navigator.days {
|
||||
padding: 5px;
|
||||
color: @theme_fg_color;
|
||||
font: 9;
|
||||
}
|
||||
|
||||
+24
-10
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user