[gtk] calendar: Use widgets for everything
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] calendar: Use widgets for everything
- Date: Fri, 7 Feb 2020 18:22:50 +0000 (UTC)
commit a6f9052cf1c1c7b4224834ed18a63e70477d8729
Author: Timm Bäder <mail baedert org>
Date: Tue Feb 4 14:03:17 2020 +0100
calendar: Use widgets for everything
gtk/gtkcalendar.c | 1071 ++++++++--------------------------------
gtk/theme/Adwaita/_common.scss | 41 +-
2 files changed, 229 insertions(+), 883 deletions(-)
---
diff --git a/gtk/gtkcalendar.c b/gtk/gtkcalendar.c
index 80d99b1e6a..e6e85b5f23 100644
--- a/gtk/gtkcalendar.c
+++ b/gtk/gtkcalendar.c
@@ -92,8 +92,11 @@
#include "gtkdragicon.h"
#include "gtkbutton.h"
#include "gtkbox.h"
+#include "gtkboxlayout.h"
+#include "gtkorientable.h"
#include "gtklabel.h"
#include "gtkstack.h"
+#include "gtkgrid.h"
static const guint month_length[2][13] =
{
@@ -139,14 +142,6 @@ week_of_year (guint year, guint mm, guint dd)
return week;
}
-/* Spacing around day/week headers and main area, inside those windows */
-#define CALENDAR_MARGIN 0
-
-#define DAY_XSEP 0 /* not really good for small calendar */
-#define DAY_YSEP 0 /* not really good for small calendar */
-
-#define SCROLL_DELAY_FACTOR 5
-
enum {
ARROW_YEAR_LEFT,
ARROW_YEAR_RIGHT,
@@ -216,6 +211,11 @@ struct _GtkCalendarPrivate
GtkWidget *month_name_stack;
GtkWidget *arrow_widgets[4];
+ GtkWidget *grid;
+ GtkWidget *day_name_labels[7];
+ GtkWidget *week_number_labels[6];
+ GtkWidget *day_number_labels[6][7];
+
gint month;
gint year;
gint selected_day;
@@ -229,36 +229,9 @@ struct _GtkCalendarPrivate
gint focus_row;
gint focus_col;
- guint header_h;
- guint day_name_h;
- guint main_h;
-
- guint arrow_prelight : 4;
- guint arrow_width;
- guint max_month_width;
- guint max_year_width;
-
- guint day_width;
- guint week_width;
-
- guint min_day_width;
- guint max_day_char_width;
- guint max_day_char_ascent;
- guint max_day_char_descent;
- guint max_label_char_ascent;
- guint max_label_char_descent;
- guint max_week_char_width;
-
- /* flags */
guint year_before : 1;
-
- guint need_timer : 1;
-
guint in_drag : 1;
- guint32 timer;
- gint click_child;
-
gint week_start;
gint drag_start_x;
@@ -274,19 +247,6 @@ static void gtk_calendar_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
-static void gtk_calendar_measure (GtkWidget *widget,
- GtkOrientation orientation,
- int for_size,
- int *minimum,
- int *natural,
- int *minimum_baseline,
- int *natural_baseline);
-static void gtk_calendar_size_allocate (GtkWidget *widget,
- int width,
- int height,
- int baseline);
-static void gtk_calendar_snapshot (GtkWidget *widget,
- GtkSnapshot *snapshot);
static void gtk_calendar_button_press (GtkGestureClick *gesture,
int n_press,
double x,
@@ -336,9 +296,6 @@ static void calendar_invalidate_day_num (GtkCalendar *widget,
gint day);
static void calendar_compute_days (GtkCalendar *calendar);
-static gint calendar_get_xsep (GtkCalendar *calendar);
-static gint calendar_get_ysep (GtkCalendar *calendar);
-static gint calendar_get_inner_border (GtkCalendar *calendar);
static gboolean gtk_calendar_scroll_controller_scroll (GtkEventControllerScroll *scroll,
gdouble dx,
@@ -362,6 +319,7 @@ gtk_calendar_dispose (GObject *object)
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (GTK_CALENDAR (object));
g_clear_pointer (&priv->header_box, gtk_widget_unparent);
+ g_clear_pointer (&priv->grid, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_calendar_parent_class)->dispose (object);
}
@@ -379,9 +337,6 @@ gtk_calendar_class_init (GtkCalendarClass *class)
gobject_class->set_property = gtk_calendar_set_property;
gobject_class->get_property = gtk_calendar_get_property;
- widget_class->snapshot = gtk_calendar_snapshot;
- widget_class->measure = gtk_calendar_measure;
- widget_class->size_allocate = gtk_calendar_size_allocate;
widget_class->state_flags_changed = gtk_calendar_state_flags_changed;
/**
@@ -427,11 +382,11 @@ gtk_calendar_class_init (GtkCalendarClass *class)
0, 31, 0,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-/**
- * GtkCalendar:show-heading:
- *
- * Determines whether a heading is displayed.
- */
+ /**
+ * GtkCalendar:show-heading:
+ *
+ * Determines whether a heading is displayed.
+ */
g_object_class_install_property (gobject_class,
PROP_SHOW_HEADING,
g_param_spec_boolean ("show-heading",
@@ -440,11 +395,11 @@ gtk_calendar_class_init (GtkCalendarClass *class)
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-/**
- * GtkCalendar:show-day-names:
- *
- * Determines whether day names are displayed.
- */
+ /**
+ * GtkCalendar:show-day-names:
+ *
+ * Determines whether day names are displayed.
+ */
g_object_class_install_property (gobject_class,
PROP_SHOW_DAY_NAMES,
g_param_spec_boolean ("show-day-names",
@@ -452,11 +407,11 @@ gtk_calendar_class_init (GtkCalendarClass *class)
P_("If TRUE, day names are displayed"),
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-/**
- * GtkCalendar:show-week-numbers:
- *
- * Determines whether week numbers are displayed.
- */
+ /**
+ * GtkCalendar:show-week-numbers:
+ *
+ * Determines whether week numbers are displayed.
+ */
g_object_class_install_property (gobject_class,
PROP_SHOW_WEEK_NUMBERS,
g_param_spec_boolean ("show-week-numbers",
@@ -572,9 +527,11 @@ gtk_calendar_class_init (GtkCalendarClass *class)
G_TYPE_NONE, 0);
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_CALENDAR);
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("calendar"));
}
-
+static void set_month (GtkCalendar *calendar,
+ int new_month);
static void
set_year (GtkCalendar *calendar,
int new_year)
@@ -605,6 +562,9 @@ set_year (GtkCalendar *calendar,
str = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
gtk_label_set_label (GTK_LABEL (priv->year_label), str);
g_free (str);
+
+ /* Update month */
+ set_month (calendar, priv->month);
}
static void
@@ -612,13 +572,95 @@ set_month (GtkCalendar *calendar,
int new_month)
{
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
+ int i;
+ int x, y;
g_return_if_fail (new_month >= 0);
g_return_if_fail (new_month < 12);
priv->month = new_month;
+ calendar_compute_days (calendar);
gtk_stack_set_visible_child_name (GTK_STACK (priv->month_name_stack),
default_monthname[priv->month]);
+
+ /* Update week number labels */
+ for (i = 0; i < 6; i ++)
+ {
+ int year, month, week;
+ char buffer[255];
+
+ year = priv->year;
+ month = priv->month + priv->day_month[i][6] - MONTH_CURRENT;
+
+ if (month < 0)
+ {
+ month += 12;
+ year -= 1;
+ }
+ else if (month > 11)
+ {
+ month -= 12;
+ year += 1;
+ }
+
+ month += 1;
+
+ week = week_of_year (year, month, priv->day[i][6]);
+
+ /* Translators: this defines whether the week numbers should use
+ * localized digits or the ones used in English (0123...).
+ *
+ * Translate to "%Id" if you want to use localized digits, or
+ * translate to "%d" otherwise.
+ *
+ * Note that translating this doesn't guarantee that you get localized
+ * digits. That needs support from your system and locale definition
+ * too.
+ */
+ g_snprintf (buffer, sizeof (buffer), C_("calendar:week:digits", "%d"), week);
+
+ gtk_label_set_label (GTK_LABEL (priv->week_number_labels[i]), buffer);
+ }
+
+ /* Update day labels */
+ for (y = 0; y < 6; y ++)
+ for (x = 0; x < 7; x ++)
+ {
+ const int day = priv->day[y][x];
+ GtkWidget *label = priv->day_number_labels[y][x];
+ char buffer[255];
+
+ /* Translators: this defines whether the day numbers should use
+ * localized digits or the ones used in English (0123...).
+ *
+ * Translate to "%Id" if you want to use localized digits, or
+ * translate to "%d" otherwise.
+ *
+ * Note that translating this doesn't guarantee that you get localized
+ * digits. That needs support from your system and locale definition
+ * too.
+ */
+ g_snprintf (buffer, sizeof (buffer), C_("calendar:day:digits", "%d"), day);
+
+ gtk_label_set_label (GTK_LABEL (label), buffer);
+
+ if (priv->day_month[y][x] == MONTH_PREV ||
+ priv->day_month[y][x] == MONTH_NEXT)
+ gtk_widget_add_style_class (label, "other-month");
+ else
+ gtk_widget_remove_style_class (label, "other-month");
+
+ if (priv->marked_date[day-1])
+ gtk_widget_set_state_flags (label, GTK_STATE_FLAG_CHECKED, FALSE);
+ else
+ gtk_widget_unset_state_flags (label, GTK_STATE_FLAG_CHECKED);
+
+ if (priv->selected_day == day &&
+ priv->day_month[y][x] == MONTH_CURRENT)
+ gtk_widget_set_state_flags (label, GTK_STATE_FLAG_SELECTED, FALSE);
+ else
+ gtk_widget_unset_state_flags (label, GTK_STATE_FLAG_SELECTED);
+ }
}
#pragma GCC diagnostic push
@@ -653,6 +695,7 @@ gtk_calendar_init (GtkCalendar *calendar)
GdkContentFormats *formats;
GtkDropTarget *dest;
int min_year_width;
+ GDateTime *now;
gtk_widget_set_can_focus (widget, TRUE);
@@ -768,18 +811,60 @@ gtk_calendar_init (GtkCalendar *calendar)
gtk_stack_add_named (GTK_STACK (priv->month_name_stack), month_label, default_monthname[i]);
}
+ priv->grid = gtk_grid_new ();
+ gtk_grid_set_row_homogeneous (GTK_GRID (priv->grid), TRUE);
+ gtk_grid_set_column_homogeneous (GTK_GRID (priv->grid), TRUE);
+ /* Day name labels */
+ for (i = 0; i < 7; i ++)
+ {
+ GtkWidget *label = gtk_label_new (default_abbreviated_dayname[i]);
+
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_widget_set_vexpand (label, TRUE);
+ gtk_widget_add_style_class (label, "day-name");
+ gtk_grid_attach (GTK_GRID (priv->grid), label, 1 + i, 0, 1, 1);
+
+ priv->day_name_labels[i] = label;
+ }
+
+ /* Week number labels */
+ for (i = 0; i < 6; i ++)
+ {
+ GtkWidget *label = gtk_label_new ("");
+
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_widget_set_vexpand (label, TRUE);
+ gtk_widget_add_style_class (label, "week-number");
+ gtk_grid_attach (GTK_GRID (priv->grid), label, 0, 1 + i, 1, 1);
+
+ priv->week_number_labels[i] = label;
+ gtk_widget_hide (label);
+ }
+
+ {
+ int x, y;
+
+ for (y = 0; y < 6; y ++)
+ for (x = 0; x < 7; x ++)
+ {
+ GtkWidget *label = gtk_label_new ("");
+
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_widget_set_vexpand (label, TRUE);
+ gtk_widget_add_style_class (label, "day-number");
+ gtk_grid_attach (GTK_GRID (priv->grid), label, 1 + x, 1 + y, 1, 1);
+
+ priv->day_number_labels[y][x] = label;
+ }
+ }
+
+ gtk_widget_set_hexpand (priv->grid, TRUE);
+ gtk_widget_set_vexpand (priv->grid, TRUE);
+ gtk_widget_set_parent (priv->grid, GTK_WIDGET (calendar));
+
/* Set defaults */
secs = time (NULL);
tm = localtime (&secs);
- set_month (calendar, tm->tm_mon);
- set_year (calendar, 1900 + tm->tm_year);
-
- /* We just initialized the year label, now add some space to it so
- * changing the year does not increase the calendar width */
- gtk_widget_measure (priv->year_label, GTK_ORIENTATION_HORIZONTAL, -1,
- &min_year_width, NULL, NULL, NULL);
- gtk_widget_set_size_request (priv->year_label, min_year_width + 10, -1);
-
for (i=0;i<31;i++)
priv->marked_date[i] = FALSE;
@@ -792,22 +877,6 @@ gtk_calendar_init (GtkCalendar *calendar)
priv->focus_row = -1;
priv->focus_col = -1;
- priv->max_year_width = 0;
- priv->max_month_width = 0;
- priv->max_day_char_width = 0;
- priv->max_week_char_width = 0;
-
- priv->max_day_char_ascent = 0;
- priv->max_day_char_descent = 0;
- priv->max_label_char_ascent = 0;
- priv->max_label_char_descent = 0;
-
- priv->arrow_width = 10;
-
- priv->need_timer = 0;
- priv->timer = 0;
- priv->click_child = -1;
-
priv->in_drag = 0;
formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
@@ -819,7 +888,7 @@ gtk_calendar_init (GtkCalendar *calendar)
g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_calendar_drag_drop), calendar);
gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (dest));
-
+
priv->year_before = 0;
/* Translate to calendar:YM if you want years to be displayed
@@ -885,15 +954,24 @@ gtk_calendar_init (GtkCalendar *calendar)
#endif
#endif
- calendar_compute_days (calendar);
+ now = g_date_time_new_now_local ();
+ set_year (calendar, g_date_time_get_year (now));
+ set_month (calendar, g_date_time_get_month (now) - 1);
+
+ /* We just initialized the year label, now add some space to it so
+ * changing the year does not increase the calendar width */
+ gtk_widget_measure (priv->year_label, GTK_ORIENTATION_HORIZONTAL, -1,
+ &min_year_width, NULL, NULL, NULL);
+ gtk_widget_set_size_request (priv->year_label, min_year_width + 10, -1);
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (gtk_widget_get_layout_manager (GTK_WIDGET (calendar))),
+ GTK_ORIENTATION_VERTICAL);
+
+ g_date_time_unref (now);
}
#pragma GCC diagnostic pop
-/****************************************
- * Utility Functions *
- ****************************************/
-
static void
calendar_queue_refresh (GtkCalendar *calendar)
{
@@ -1065,194 +1143,23 @@ calendar_select_and_focus_day (GtkCalendar *calendar,
guint day)
{
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- gint old_focus_row = priv->focus_row;
- gint old_focus_col = priv->focus_col;
gint row;
gint col;
for (row = 0; row < 6; row ++)
for (col = 0; col < 7; col++)
{
- if (priv->day_month[row][col] == MONTH_CURRENT
- && priv->day[row][col] == day)
+ if (priv->day_month[row][col] == MONTH_CURRENT &&
+ priv->day[row][col] == day)
{
priv->focus_row = row;
priv->focus_col = col;
}
}
- if (old_focus_row != -1 && old_focus_col != -1)
- calendar_invalidate_day (calendar, old_focus_row, old_focus_col);
-
gtk_calendar_select_day (calendar, day);
}
-
-/****************************************
- * Layout computation utilities *
- ****************************************/
-
-static gint
-calendar_row_height (GtkCalendar *calendar)
-{
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
-
- return (priv->main_h - CALENDAR_MARGIN
- - ((priv->show_day_names)
- ? calendar_get_ysep (calendar) : CALENDAR_MARGIN)) / 6;
-}
-
-static void
-get_component_paddings (GtkCalendar *calendar,
- GtkBorder *day_padding,
- GtkBorder *day_name_padding,
- GtkBorder *week_padding)
-{
- GtkStyleContext * context;
- GtkWidget *widget;
-
- widget = GTK_WIDGET (calendar);
- context = gtk_widget_get_style_context (widget);
-
- if (day_padding)
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, I_("day-number"));
- gtk_style_context_get_padding (context, day_padding);
- gtk_style_context_restore (context);
- }
-
- if (day_name_padding)
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, I_("day-name"));
- gtk_style_context_get_padding (context, day_name_padding);
- gtk_style_context_restore (context);
- }
-
- if (week_padding)
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, I_("week-number"));
- gtk_style_context_get_padding (context, week_padding);
- gtk_style_context_restore (context);
- }
-}
-
-/* calendar_left_x_for_column: returns the x coordinate
- * for the left of the column */
-static gint
-calendar_left_x_for_column (GtkCalendar *calendar,
- gint column)
-{
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- gint width;
- gint x_left;
- gint week_width;
- gint calendar_xsep = calendar_get_xsep (calendar);
- gint inner_border = calendar_get_inner_border (calendar);
-
- get_component_paddings (calendar, NULL, NULL, NULL);
-
- week_width = priv->week_width + inner_border;
-
- if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL)
- {
- column = 6 - column;
- week_width = 0;
- }
-
- width = priv->day_width;
- if (priv->show_week_numbers)
- x_left = week_width + calendar_xsep + (width + DAY_XSEP) * column;
- else
- x_left = week_width + CALENDAR_MARGIN + (width + DAY_XSEP) * column;
-
- return x_left;
-}
-
-/* column_from_x: returns the column 0-6 that the
- * x pixel of the xwindow is in */
-static gint
-calendar_column_from_x (GtkCalendar *calendar,
- gint event_x)
-{
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- gint c, column;
- gint x_left, x_right;
-
- column = -1;
-
- for (c = 0; c < 7; c++)
- {
- x_left = calendar_left_x_for_column (calendar, c);
- x_right = x_left + priv->day_width;
-
- if (event_x >= x_left && event_x < x_right)
- {
- column = c;
- break;
- }
- }
-
- return column;
-}
-
-/* calendar_top_y_for_row: returns the y coordinate
- * for the top of the row */
-static gint
-calendar_top_y_for_row (GtkCalendar *calendar,
- gint row)
-{
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- gint inner_border = calendar_get_inner_border (calendar);
-
- return priv->header_h + priv->day_name_h + inner_border
- + row * calendar_row_height (calendar);
-}
-
-/* row_from_y: returns the row 0-5 that the
- * y pixel of the xwindow is in */
-static gint
-calendar_row_from_y (GtkCalendar *calendar,
- gint event_y)
-{
- gint r, row;
- gint height;
- gint y_top, y_bottom;
-
- height = calendar_row_height (calendar);
- row = -1;
-
- for (r = 0; r < 6; r++)
- {
- y_top = calendar_top_y_for_row (calendar, r);
- y_bottom = y_top + height;
-
- if (event_y >= y_top && event_y < y_bottom)
- {
- row = r;
- break;
- }
- }
-
- return row;
-}
-
-static void
-calendar_day_rectangle (GtkCalendar *calendar,
- gint row,
- gint col,
- GdkRectangle *rect)
-{
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
-
- rect->x = calendar_left_x_for_column (calendar, col);
- rect->y = calendar_top_y_for_row (calendar, row);
- rect->height = calendar_row_height (calendar);
- rect->width = priv->day_width;
-}
-
static void
calendar_set_month_prev (GtkCalendar *calendar)
{
@@ -1368,421 +1275,6 @@ gtk_calendar_get_property (GObject *object,
}
}
-static gint
-calendar_get_inner_border (GtkCalendar *calendar)
-{
- return 4;
-}
-
-static gint
-calendar_get_xsep (GtkCalendar *calendar)
-{
- return 4;
-}
-
-static gint
-calendar_get_ysep (GtkCalendar *calendar)
-{
-
- return 4;
-}
-
-/****************************************
- * Size Request and Allocate *
- ****************************************/
-
-static void
-gtk_calendar_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- GtkBorder day_padding, day_name_padding, week_padding;
- PangoLayout *layout;
- PangoRectangle logical_rect;
- gint height;
- gint i;
- gint calendar_margin = CALENDAR_MARGIN;
- gint header_width = 0, main_width;
- gint max_header_height = 0;
- gint inner_border = calendar_get_inner_border (calendar);
- gint calendar_ysep = calendar_get_ysep (calendar);
- gint calendar_xsep = calendar_get_xsep (calendar);
-
- layout = gtk_widget_create_pango_layout (widget, NULL);
-
- /* Header width */
-
- if (priv->show_heading)
- {
- gtk_widget_measure (priv->header_box, GTK_ORIENTATION_HORIZONTAL, -1,
- &header_width, NULL, NULL, NULL);
- gtk_widget_measure (priv->header_box, GTK_ORIENTATION_VERTICAL, -1,
- &max_header_height, NULL, NULL, NULL);
- }
- else
- {
- priv->max_month_width = 0;
- priv->max_year_width = 0;
- }
-
- /* Mainwindow labels width */
-
- priv->max_day_char_width = 0;
- priv->max_day_char_ascent = 0;
- priv->max_day_char_descent = 0;
- priv->min_day_width = 0;
-
- for (i = 0; i < 9; i++)
- {
- gchar buffer[32];
- g_snprintf (buffer, sizeof (buffer), C_("calendar:day:digits", "%d"), i * 11);
- pango_layout_set_text (layout, buffer, -1);
- pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
- priv->min_day_width = MAX (priv->min_day_width,
- logical_rect.width);
-
- priv->max_day_char_ascent = MAX (priv->max_day_char_ascent,
- PANGO_ASCENT (logical_rect));
- priv->max_day_char_descent = MAX (priv->max_day_char_descent,
- PANGO_DESCENT (logical_rect));
- }
-
- priv->max_label_char_ascent = 0;
- priv->max_label_char_descent = 0;
- if (priv->show_day_names)
- for (i = 0; i < 7; i++)
- {
- pango_layout_set_text (layout, default_abbreviated_dayname[i], -1);
- pango_layout_line_get_pixel_extents (pango_layout_get_lines_readonly (layout)->data, NULL,
&logical_rect);
-
- priv->min_day_width = MAX (priv->min_day_width, logical_rect.width);
- priv->max_label_char_ascent = MAX (priv->max_label_char_ascent,
- PANGO_ASCENT (logical_rect));
- priv->max_label_char_descent = MAX (priv->max_label_char_descent,
- PANGO_DESCENT (logical_rect));
- }
-
- priv->max_week_char_width = 0;
- if (priv->show_week_numbers)
- for (i = 0; i < 9; i++)
- {
- gchar buffer[32];
- g_snprintf (buffer, sizeof (buffer), C_("calendar:week:digits", "%d"), i * 11);
- pango_layout_set_text (layout, buffer, -1);
- pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
- priv->max_week_char_width = MAX (priv->max_week_char_width,
- logical_rect.width / 2);
- }
-
- get_component_paddings (calendar, &day_padding, &day_name_padding, &week_padding);
-
- priv->min_day_width += day_padding.left + day_padding.right;
- if (priv->show_week_numbers)
- priv->max_week_char_width += week_padding.left + week_padding.right;
-
- /* We add one to max_day_char_width to be able to make the marked day "bold" */
- priv->max_day_char_width = priv->min_day_width / 2 + 1;
-
- main_width = (7 * (priv->min_day_width) + (DAY_XSEP * 6) + CALENDAR_MARGIN * 2
- + (priv->show_week_numbers
- ? priv->max_week_char_width * 2 + calendar_xsep * 2
- : 0));
-
- requisition->width = MAX (header_width, main_width + inner_border * 2);
-
- /*
- * Calculate the requisition height for the widget.
- */
-
- if (priv->show_heading)
- {
- priv->header_h = (max_header_height + calendar_ysep * 2);
- }
- else
- {
- priv->header_h = 0;
- }
-
- if (priv->show_day_names)
- {
- priv->day_name_h = (priv->max_label_char_ascent
- + priv->max_label_char_descent
- + day_name_padding.top + day_name_padding.bottom
- + calendar_margin);
- calendar_margin = calendar_ysep;
- }
- else
- {
- priv->day_name_h = 0;
- }
-
- priv->main_h = (CALENDAR_MARGIN + calendar_margin
- + 6 * (priv->max_day_char_ascent
- + priv->max_day_char_descent
- + day_padding.top + day_padding.bottom)
- + DAY_YSEP * 5);
-
- height = priv->header_h + priv->day_name_h + priv->main_h;
-
- requisition->height = height + (inner_border * 2);
-
- g_object_unref (layout);
-}
-
-static void
-gtk_calendar_measure (GtkWidget *widget,
- GtkOrientation orientation,
- int for_size,
- int *minimum,
- int *natural,
- int *minimum_baseline,
- int *natural_baseline)
-{
- GtkRequisition requisition;
-
- gtk_calendar_size_request (widget, &requisition);
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- *minimum = *natural = requisition.width;
- else /* VERTICAL */
- *minimum = *natural = requisition.height;
-}
-
-static void
-gtk_calendar_size_allocate (GtkWidget *widget,
- int width,
- int height,
- int baseline)
-{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- gint inner_border = calendar_get_inner_border (calendar);
- gint calendar_xsep = calendar_get_xsep (calendar);
- int header_height;
-
- if (priv->show_week_numbers)
- {
- priv->day_width = (priv->min_day_width
- * ((width - (inner_border * 2)
- - (CALENDAR_MARGIN * 2) - (DAY_XSEP * 6) - calendar_xsep * 2))
- / (7 * priv->min_day_width + priv->max_week_char_width * 2));
- priv->week_width = ((width - (inner_border * 2)
- - (CALENDAR_MARGIN * 2) - (DAY_XSEP * 6) - calendar_xsep * 2 )
- - priv->day_width * 7 + CALENDAR_MARGIN + calendar_xsep);
- }
- else
- {
- priv->day_width = (width
- - (inner_border * 2)
- - (CALENDAR_MARGIN * 2)
- - (DAY_XSEP * 6))/7;
- priv->week_width = 0;
- }
-
- gtk_widget_measure (priv->header_box, GTK_ORIENTATION_VERTICAL, width,
- &header_height, NULL, NULL, NULL);
- gtk_widget_size_allocate (priv->header_box,
- &(GtkAllocation){ 0, 0, width, header_height }, -1);
-}
-
-
-/****************************************
- * Repainting *
- ****************************************/
-
-static void
-calendar_snapshot_day_names (GtkCalendar *calendar,
- GtkSnapshot *snapshot)
-{
- GtkWidget *widget = GTK_WIDGET (calendar);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- GtkStyleContext *context;
- GtkStateFlags state;
- GtkBorder day_name_padding;
- char buffer[255];
- int day,i;
- int day_width, cal_width;
- int day_wid_sep;
- PangoLayout *layout;
- PangoRectangle logical_rect;
- gint calendar_ysep = calendar_get_ysep (calendar);
- gint calendar_xsep = calendar_get_xsep (calendar);
- gint inner_border = calendar_get_inner_border (calendar);
-
- get_component_paddings (calendar, NULL, &day_name_padding, NULL);
- context = gtk_widget_get_style_context (widget);
-
- gtk_snapshot_save (snapshot);
- gtk_snapshot_translate (snapshot,
- &GRAPHENE_POINT_INIT (inner_border, priv->header_h + inner_border));
-
- day_width = priv->day_width;
- cal_width = gtk_widget_get_width (widget) - (inner_border * 2);
- day_wid_sep = day_width + DAY_XSEP;
-
- /*
- * Draw rectangles as inverted background for the labels.
- */
-
- state = gtk_style_context_get_state (context);
- state &= ~GTK_STATE_FLAG_DROP_ACTIVE;
-
- gtk_style_context_save (context);
-
- gtk_style_context_set_state (context, state);
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
-
- gtk_snapshot_render_background (snapshot, context,
- CALENDAR_MARGIN, CALENDAR_MARGIN,
- cal_width - CALENDAR_MARGIN * 2,
- priv->day_name_h - CALENDAR_MARGIN);
-
- if (priv->show_week_numbers)
- gtk_snapshot_render_background (snapshot, context,
- CALENDAR_MARGIN,
- priv->day_name_h - calendar_ysep,
- priv->week_width - calendar_ysep - CALENDAR_MARGIN,
- calendar_ysep);
-
- /*
- * Write the labels
- */
- layout = gtk_widget_create_pango_layout (widget, NULL);
-
- for (i = 0; i < 7; i++)
- {
- if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL)
- day = 6 - i;
- else
- day = i;
- day = (day + priv->week_start) % 7;
- g_snprintf (buffer, sizeof (buffer), "%s", default_abbreviated_dayname[day]);
-
- pango_layout_set_text (layout, buffer, -1);
- pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-
- gtk_snapshot_render_layout (snapshot, context,
- (CALENDAR_MARGIN +
- + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
- (priv->week_width + (priv->week_width ? calendar_xsep : 0))
- : 0)
- + day_wid_sep * i
- + (day_width - logical_rect.width)/2),
- CALENDAR_MARGIN + day_name_padding.top + logical_rect.y,
- layout);
- }
-
- g_object_unref (layout);
-
- gtk_style_context_restore (context);
- gtk_snapshot_restore (snapshot);
-}
-
-static void
-calendar_snapshot_week_numbers (GtkCalendar *calendar,
- GtkSnapshot *snapshot)
-{
- GtkWidget *widget = GTK_WIDGET (calendar);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- GtkStyleContext *context;
- GtkStateFlags state;
- GtkBorder week_padding;
- gint row, x_loc, y_loc;
- gint day_height;
- char buffer[32];
- PangoLayout *layout;
- PangoRectangle logical_rect;
- gint calendar_xsep = calendar_get_xsep (calendar);
- gint inner_border = calendar_get_inner_border (calendar);
- gint x, y;
-
- get_component_paddings (calendar, NULL, NULL, &week_padding);
- context = gtk_widget_get_style_context (widget);
-
- y = priv->header_h + priv->day_name_h + inner_border;
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- x = inner_border;
- else
- x = gtk_widget_get_width (widget) - priv->week_width - inner_border;
-
- state = gtk_style_context_get_state (context);
- state &= ~GTK_STATE_FLAG_DROP_ACTIVE;
-
- gtk_style_context_save (context);
-
- gtk_style_context_set_state (context, state);
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
-
- if (priv->show_day_names)
- gtk_snapshot_render_background (snapshot, context,
- x + CALENDAR_MARGIN, y,
- priv->week_width - CALENDAR_MARGIN,
- priv->main_h - CALENDAR_MARGIN);
- else
- gtk_snapshot_render_background (snapshot, context,
- x + CALENDAR_MARGIN,
- y + CALENDAR_MARGIN,
- priv->week_width - CALENDAR_MARGIN,
- priv->main_h - 2 * CALENDAR_MARGIN);
-
- /*
- * Write the labels
- */
-
- layout = gtk_widget_create_pango_layout (widget, NULL);
- day_height = calendar_row_height (calendar);
-
- for (row = 0; row < 6; row++)
- {
- gint year, month, week;
-
- year = priv->year;
- month = priv->month + priv->day_month[row][6] - MONTH_CURRENT;
-
- if (month < 0)
- {
- month += 12;
- year -= 1;
- }
- else if (month > 11)
- {
- month -= 12;
- year += 1;
- }
-
- month += 1;
-
- week = week_of_year (year, month, priv->day[row][6]);
-
- /* Translators: this defines whether the week numbers should use
- * localized digits or the ones used in English (0123...).
- *
- * Translate to "%Id" if you want to use localized digits, or
- * translate to "%d" otherwise.
- *
- * Note that translating this doesn't guarantee that you get localized
- * digits. That needs support from your system and locale definition
- * too.
- */
- g_snprintf (buffer, sizeof (buffer), C_("calendar:week:digits", "%d"), week);
- pango_layout_set_text (layout, buffer, -1);
- pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-
- y_loc = calendar_top_y_for_row (calendar, row) + (day_height - logical_rect.height) / 2;
-
- x_loc = x + (priv->week_width
- - logical_rect.width
- - calendar_xsep - week_padding.right);
-
- gtk_snapshot_render_layout (snapshot, context, x_loc, y_loc, layout);
- }
-
- g_object_unref (layout);
-
- gtk_style_context_restore (context);
-}
-
static void
calendar_invalidate_day_num (GtkCalendar *calendar,
gint day)
@@ -1799,137 +1291,32 @@ calendar_invalidate_day (GtkCalendar *calendar,
}
static void
-calendar_snapshot_day (GtkCalendar *calendar,
- GtkSnapshot *snapshot,
- gint row,
- gint col)
-{
- GtkWidget *widget = GTK_WIDGET (calendar);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- GtkStyleContext *context;
- GtkStateFlags state = 0;
- gchar buffer[32];
- gint day;
- gint x_loc, y_loc;
- GdkRectangle day_rect;
-
- PangoLayout *layout;
- PangoRectangle logical_rect;
-
- g_return_if_fail (row < 6);
- g_return_if_fail (col < 7);
-
- context = gtk_widget_get_style_context (widget);
- state = gtk_widget_get_state_flags (widget);
-
- day = priv->day[row][col];
-
- calendar_day_rectangle (calendar, row, col, &day_rect);
-
- gtk_style_context_save (context);
-
- state &= ~(GTK_STATE_FLAG_INCONSISTENT | GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_SELECTED |
GTK_STATE_FLAG_DROP_ACTIVE);
-
- if (priv->day_month[row][col] == MONTH_PREV ||
- priv->day_month[row][col] == MONTH_NEXT)
- state |= GTK_STATE_FLAG_INCONSISTENT;
- else
- {
- if (priv->marked_date[day-1])
- state |= GTK_STATE_FLAG_ACTIVE;
-
- if (priv->selected_day == day)
- {
- state |= GTK_STATE_FLAG_SELECTED;
-
- gtk_style_context_set_state (context, state);
- gtk_snapshot_render_background (snapshot, context,
- day_rect.x, day_rect.y,
- day_rect.width, day_rect.height);
- }
- }
-
- gtk_style_context_set_state (context, state);
-
- /* Translators: this defines whether the day numbers should use
- * localized digits or the ones used in English (0123...).
- *
- * Translate to "%Id" if you want to use localized digits, or
- * translate to "%d" otherwise.
- *
- * Note that translating this doesn't guarantee that you get localized
- * digits. That needs support from your system and locale definition
- * too.
- */
- g_snprintf (buffer, sizeof (buffer), C_("calendar:day:digits", "%d"), day);
-
- /* Get extra information to show, if any: */
-
- layout = gtk_widget_create_pango_layout (widget, buffer);
- pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
- pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-
- x_loc = day_rect.x + (day_rect.width - logical_rect.width) / 2;
- y_loc = day_rect.y;
-
- gtk_snapshot_render_layout (snapshot, context, x_loc, y_loc, layout);
-
- y_loc += priv->max_day_char_descent;
-
- if (gtk_widget_has_visible_focus (widget) &&
- priv->focus_row == row && priv->focus_col == col)
- gtk_snapshot_render_focus (snapshot, context,
- day_rect.x, day_rect.y,
- day_rect.width, day_rect.height);
-
- gtk_style_context_restore (context);
- g_object_unref (layout);
-}
-
-static void
-calendar_snapshot_main (GtkCalendar *calendar,
- GtkSnapshot *snapshot)
-{
- gint row, col;
-
- for (col = 0; col < 7; col++)
- for (row = 0; row < 6; row++)
- calendar_snapshot_day (calendar, snapshot, row, col);
-}
-
-static void
-gtk_calendar_snapshot (GtkWidget *widget,
- GtkSnapshot *snapshot)
-{
- GtkCalendar *calendar = GTK_CALENDAR (widget);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
-
- calendar_snapshot_main (calendar, snapshot);
-
- gtk_widget_snapshot_child (widget, priv->header_box, snapshot);
-
- if (priv->show_day_names)
- calendar_snapshot_day_names (calendar, snapshot);
-
- if (priv->show_week_numbers)
- calendar_snapshot_week_numbers (calendar, snapshot);
-}
-
-static void
-calendar_main_button_press (GtkCalendar *calendar,
- double x,
- double y,
- int n_press,
- int button)
+gtk_calendar_button_press (GtkGestureClick *gesture,
+ int n_press,
+ double x,
+ double y,
+ gpointer user_data)
{
+ GtkCalendar *calendar = user_data;
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- gint row, col;
- gint day_month;
- gint day;
-
- row = calendar_row_from_y (calendar, y);
- col = calendar_column_from_x (calendar, x);
+ int button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
+ GtkWidget *label;
+ int row, col;
+ int ix, iy;
+ int day_month;
+ int day;
+
+ label = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
+ for (iy = 0; iy < 6; iy ++)
+ for (ix = 0; ix < 6; ix ++)
+ {
+ if (label == priv->day_number_labels[iy][ix])
+ {
+ row = iy;
+ col = ix;
+ }
+ }
/* If row or column isn't found, just return. */
if (row == -1 || col == -1)
@@ -1968,26 +1355,6 @@ calendar_main_button_press (GtkCalendar *calendar,
}
}
-
-static void
-gtk_calendar_button_press (GtkGestureClick *gesture,
- int n_press,
- double x,
- double y,
- gpointer user_data)
-{
- GtkCalendar *calendar = user_data;
- GtkWidget *widget = GTK_WIDGET (calendar);
- GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
- int button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
-
- if (!gtk_widget_has_focus (widget))
- gtk_widget_grab_focus (widget);
-
- if (y > priv->header_h)
- calendar_main_button_press (calendar, x, y, n_press, button);
-}
-
static void
gtk_calendar_button_release (GtkGestureClick *gesture,
int n_press,
@@ -2490,27 +1857,13 @@ gtk_calendar_select_day (GtkCalendar *calendar,
if (priv->selected_day != day)
{
- /* Deselect the old day */
- if (priv->selected_day > 0)
- {
- if (gtk_widget_is_drawable (GTK_WIDGET (calendar)))
- calendar_invalidate_day_num (calendar, priv->selected_day);
- priv->selected_day = 0;
- }
-
priv->selected_day = day;
- /* Select the new day */
- if (priv->selected_day > 0)
- {
- if (gtk_widget_is_drawable (GTK_WIDGET (calendar)))
- calendar_invalidate_day_num (calendar, priv->selected_day);
- }
+ set_month (calendar, priv->month);
g_object_notify (G_OBJECT (calendar), "day");
+ g_signal_emit (calendar, gtk_calendar_signals[DAY_SELECTED_SIGNAL], 0);
}
-
- g_signal_emit (calendar, gtk_calendar_signals[DAY_SELECTED_SIGNAL], 0);
}
/**
@@ -2654,9 +2007,12 @@ gtk_calendar_set_show_week_numbers (GtkCalendar *self,
if (value != priv->show_week_numbers)
{
+ int i;
+
priv->show_week_numbers = value;
- gtk_widget_queue_resize (GTK_WIDGET (self));
+ for (i = 0; i < 6; i ++)
+ gtk_widget_set_visible (priv->week_number_labels[i], value);
g_object_notify (G_OBJECT (self), "show-week-numbers");
}
@@ -2700,8 +2056,6 @@ gtk_calendar_set_show_heading (GtkCalendar *self,
gtk_widget_set_visible (priv->header_box, value);
- gtk_widget_queue_draw (GTK_WIDGET (self));
-
g_object_notify (G_OBJECT (self), "show-heading");
}
}
@@ -2739,9 +2093,12 @@ gtk_calendar_set_show_day_names (GtkCalendar *self,
if (value != priv->show_day_names)
{
+ int i;
+
priv->show_day_names = value;
- gtk_widget_queue_draw (GTK_WIDGET (self));
+ for (i = 0; i < 7; i ++)
+ gtk_widget_set_visible (priv->day_name_labels[i], value);
g_object_notify (G_OBJECT (self), "show-day-names");
}
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 75e3a12562..4028bb0988 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -3398,42 +3398,31 @@ calendar {
}
}
- &:selected {
- @extend %selected_items;
-
- border-radius: 3px;
- }
-
- &.header {
- border-bottom-color: transparentize(black, 0.9);
-
- &:backdrop { border-bottom-color: transparentize(black, 0.9); }
- }
-
- &.button {
- @extend %undecorated_button;
-
- color: transparentize($fg_color, 0.55);
-
- &:hover { color: $fg_color; }
+ > grid {
+ > label.day-name {
+ }
- &:backdrop { color: transparentize($backdrop_fg_color,0.55); }
+ > label.week-number {
+ }
- &:disabled { color: transparentize($insensitive_fg_color,0.55); }
- }
+ > label.day-number {
+ padding: 4px;
- &.highlight {
- color: $insensitive_fg_color;
+ &:selected{
+ @extend %selected_items;
+ border-radius: 3px;
+ }
+ }
- &:backdrop { color: $backdrop_insensitive_color; }
+ > label.day-number.other-month {
+ color: gtkalpha(currentColor, 0.3);
+ }
}
&:backdrop {
color: $backdrop_text_color;
border-color: $backdrop_borders_color;
}
-
- &:indeterminate { color: gtkalpha(currentColor, 0.1); }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]