calendar: Use GDateTime to select days

This commit is contained in:
Timm Bäder 2020-02-04 14:38:19 +01:00 committed by Matthias Clasen
parent a6f9052cf1
commit 1151da5cf3
2 changed files with 111 additions and 73 deletions

View File

@ -351,7 +351,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
P_("Year"), P_("Year"),
P_("The selected year"), P_("The selected year"),
0, G_MAXINT >> 9, 0, 0, G_MAXINT >> 9, 0,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
/** /**
* GtkCalendar:month: * GtkCalendar:month:
@ -365,7 +365,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
P_("Month"), P_("Month"),
P_("The selected month (as a number between 0 and 11)"), P_("The selected month (as a number between 0 and 11)"),
0, 11, 0, 0, 11, 0,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
/** /**
* GtkCalendar:day: * GtkCalendar:day:
@ -380,7 +380,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
P_("Day"), P_("Day"),
P_("The selected day (as a number between 1 and 31, or 0 to unselect the currently selected day)"), P_("The selected day (as a number between 1 and 31, or 0 to unselect the currently selected day)"),
0, 31, 0, 0, 31, 0,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
/** /**
* GtkCalendar:show-heading: * GtkCalendar:show-heading:
@ -1004,13 +1004,20 @@ calendar_set_month_next (GtkCalendar *calendar)
if (month_len < priv->selected_day) if (month_len < priv->selected_day)
{ {
GDateTime *new_date = g_date_time_new_local (priv->year, priv->month + 1, month_len,
0, 0, 0);
priv->selected_day = 0; priv->selected_day = 0;
gtk_calendar_select_day (calendar, month_len); gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
} }
else else
gtk_calendar_select_day (calendar, priv->selected_day); {
GDateTime *new_date = g_date_time_new_local (priv->year, priv->month + 1, priv->selected_day,
0, 0, 0);
calendar_queue_refresh (calendar); gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
}
} }
static void static void
@ -1033,13 +1040,20 @@ calendar_set_year_prev (GtkCalendar *calendar)
if (month_len < priv->selected_day) if (month_len < priv->selected_day)
{ {
GDateTime *new_date = g_date_time_new_local (priv->year, priv->month + 1, month_len,
0, 0, 0);
priv->selected_day = 0; priv->selected_day = 0;
gtk_calendar_select_day (calendar, month_len); gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
} }
else else
gtk_calendar_select_day (calendar, priv->selected_day); {
GDateTime *new_date = g_date_time_new_local (priv->year, priv->month + 1, priv->selected_day,
0, 0, 0);
calendar_queue_refresh (calendar); gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
}
} }
static void static void
@ -1062,13 +1076,20 @@ calendar_set_year_next (GtkCalendar *calendar)
if (month_len < priv->selected_day) if (month_len < priv->selected_day)
{ {
GDateTime *new_date = g_date_time_new_local (priv->year, priv->month + 1, month_len,
0, 0, 0);
priv->selected_day = 0; priv->selected_day = 0;
gtk_calendar_select_day (calendar, month_len); gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
} }
else else
gtk_calendar_select_day (calendar, priv->selected_day); {
GDateTime *new_date = g_date_time_new_local (priv->year, priv->month + 1, priv->selected_day,
0, 0, 0);
calendar_queue_refresh (calendar); gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
}
} }
static void static void
@ -1140,9 +1161,10 @@ calendar_compute_days (GtkCalendar *calendar)
static void static void
calendar_select_and_focus_day (GtkCalendar *calendar, calendar_select_and_focus_day (GtkCalendar *calendar,
guint day) int day)
{ {
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar); GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
GDateTime *new_date;
gint row; gint row;
gint col; gint col;
@ -1154,10 +1176,15 @@ calendar_select_and_focus_day (GtkCalendar *calendar,
{ {
priv->focus_row = row; priv->focus_row = row;
priv->focus_col = col; priv->focus_col = col;
break;
} }
} }
gtk_calendar_select_day (calendar, day); new_date = g_date_time_new_local (priv->year, priv->month + 1, day,
0, 0, 0);
gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
} }
static void static void
@ -1187,14 +1214,29 @@ calendar_set_month_prev (GtkCalendar *calendar)
if (month_len < priv->selected_day) if (month_len < priv->selected_day)
{ {
GDateTime *new_date;
priv->selected_day = 0; priv->selected_day = 0;
gtk_calendar_select_day (calendar, month_len);
new_date = g_date_time_new_local (priv->year, priv->month + 1, month_len,
0, 0, 0);
gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
} }
else else
{ {
GDateTime *new_date;
if (priv->selected_day < 0) if (priv->selected_day < 0)
priv->selected_day = priv->selected_day + 1 + month_length[leap (priv->year)][priv->month + 1]; priv->selected_day = priv->selected_day + 1 + month_length[leap (priv->year)][priv->month + 1];
gtk_calendar_select_day (calendar, priv->selected_day);
new_date = g_date_time_new_local (priv->year, priv->month + 1, priv->selected_day,
0, 0, 0);
gtk_calendar_select_day (calendar, new_date);
g_date_time_unref (new_date);
} }
calendar_queue_refresh (calendar); calendar_queue_refresh (calendar);
@ -1207,24 +1249,9 @@ gtk_calendar_set_property (GObject *object,
GParamSpec *pspec) GParamSpec *pspec)
{ {
GtkCalendar *calendar = GTK_CALENDAR (object); GtkCalendar *calendar = GTK_CALENDAR (object);
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
switch (prop_id) switch (prop_id)
{ {
case PROP_YEAR:
gtk_calendar_select_month (calendar,
priv->month,
g_value_get_int (value));
break;
case PROP_MONTH:
gtk_calendar_select_month (calendar,
g_value_get_int (value),
priv->year);
break;
case PROP_DAY:
gtk_calendar_select_day (calendar,
g_value_get_int (value));
break;
case PROP_SHOW_HEADING: case PROP_SHOW_HEADING:
gtk_calendar_set_show_heading (calendar, g_value_get_boolean (value)); gtk_calendar_set_show_heading (calendar, g_value_get_boolean (value));
break; break;
@ -1302,14 +1329,14 @@ gtk_calendar_button_press (GtkGestureClick *gesture,
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar); GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar);
int button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)); int button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
GtkWidget *label; GtkWidget *label;
int row, col; int row = -1, col = -1;
int ix, iy; int ix, iy;
int day_month; int day_month;
int day; int day;
label = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT); label = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
for (iy = 0; iy < 6; iy ++) for (iy = 0; iy < 6; iy ++)
for (ix = 0; ix < 6; ix ++) for (ix = 0; ix < 7; ix ++)
{ {
if (label == priv->day_number_labels[iy][ix]) if (label == priv->day_number_labels[iy][ix])
{ {
@ -1685,9 +1712,9 @@ got_text (GObject *source,
GtkDropTarget *dest = GTK_DROP_TARGET (data); GtkDropTarget *dest = GTK_DROP_TARGET (data);
GtkCalendar *calendar = GTK_CALENDAR (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest))); GtkCalendar *calendar = GTK_CALENDAR (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest)));
GdkDrop *drop = GDK_DROP (source); GdkDrop *drop = GDK_DROP (source);
guint day;
gchar *str; gchar *str;
GDate *date; GDate *date;
GDateTime *datetime;
GdkDragAction suggested_action; GdkDragAction suggested_action;
suggested_action = get_status_pending (drop); suggested_action = get_status_pending (drop);
@ -1730,14 +1757,16 @@ got_text (GObject *source,
return; return;
} }
day = g_date_get_day (date); datetime = g_date_time_new_local (g_date_get_year (date),
g_date_get_month (date),
g_date_get_day (date),
0, 0, 0);
g_date_free (date); g_date_free (date);
gdk_drop_finish (drop, suggested_action); gdk_drop_finish (drop, suggested_action);
g_object_freeze_notify (G_OBJECT (calendar)); gtk_calendar_select_day (calendar, datetime);
gtk_calendar_select_day (calendar, day); g_date_time_unref (datetime);
g_object_thaw_notify (G_OBJECT (calendar));
} }
static gboolean static gboolean
@ -1802,67 +1831,76 @@ gtk_calendar_new (void)
/** /**
* gtk_calendar_select_month: * gtk_calendar_select_month:
* @calendar: a #GtkCalendar * @calendar: a #GtkCalendar
* @month: a month number between 0 and 11. * @date: (transfer none): a #GDateTime to use as reference
* @year: the year the month is in.
* *
* Shifts the calendar to a different month. * Shifts the calendar to the month showing @date.
* The exact day of @date will *NOT* be selected, only the month.
* If you want to select @date's day, use gtk_calendar_select_day()
**/ **/
void void
gtk_calendar_select_month (GtkCalendar *calendar, gtk_calendar_select_month (GtkCalendar *self,
guint month, GDateTime *date)
guint year)
{ {
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar); GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (self);
int month, year;
g_return_if_fail (GTK_IS_CALENDAR (calendar)); g_return_if_fail (GTK_IS_CALENDAR (self));
g_return_if_fail (month <= 11); g_return_if_fail (date != NULL);
g_object_freeze_notify (G_OBJECT (calendar)); year = g_date_time_get_year (date);
month = g_date_time_get_month (date);
g_object_freeze_notify (G_OBJECT (self));
if (priv->month != month) if (priv->month != month)
{ {
set_month (calendar, month); set_month (self, month);
g_object_notify (G_OBJECT (calendar), "month"); g_object_notify (G_OBJECT (self), "month");
} }
if (priv->year != year) if (priv->year != year)
{ {
set_year (calendar, year); set_year (self, year);
g_object_notify (G_OBJECT (calendar), "year"); g_object_notify (G_OBJECT (self), "year");
} }
calendar_compute_days (calendar); g_object_thaw_notify (G_OBJECT (self));
calendar_queue_refresh (calendar);
g_object_thaw_notify (G_OBJECT (calendar)); g_signal_emit (self, gtk_calendar_signals[MONTH_CHANGED_SIGNAL], 0);
g_signal_emit (calendar, gtk_calendar_signals[MONTH_CHANGED_SIGNAL], 0);
} }
/** /**
* gtk_calendar_select_day: * gtk_calendar_select_day:
* @calendar: a #GtkCalendar. * @calendar: a #GtkCalendar.
* @day: the day number between 1 and 31, or 0 to unselect * @date: (transfer none): a #GDateTime representing the day to select
* the currently selected day.
* *
* Selects a day from the current month. * Will switch to @date's year and month and select its day.
**/ **/
void void
gtk_calendar_select_day (GtkCalendar *calendar, gtk_calendar_select_day (GtkCalendar *self,
guint day) GDateTime *date)
{ {
GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (calendar); GtkCalendarPrivate *priv = gtk_calendar_get_instance_private (self);
int day, month, year;
g_return_if_fail (GTK_IS_CALENDAR (calendar)); g_return_if_fail (GTK_IS_CALENDAR (self));
g_return_if_fail (day <= 31); g_return_if_fail (date != NULL);
year = g_date_time_get_year (date);
month = g_date_time_get_month (date);
day = g_date_time_get_day_of_month (date);
if (priv->selected_day != day) if (priv->selected_day != day)
{ {
priv->selected_day = day; priv->selected_day = day;
set_month (calendar, priv->month); g_object_freeze_notify (G_OBJECT (self));
set_year (self, year);
set_month (self, month - 1);
g_object_notify (G_OBJECT (calendar), "day"); g_object_notify (G_OBJECT (self), "day");
g_signal_emit (calendar, gtk_calendar_signals[DAY_SELECTED_SIGNAL], 0); g_object_thaw_notify (G_OBJECT (self));
g_signal_emit (self, gtk_calendar_signals[DAY_SELECTED_SIGNAL], 0);
} }
} }

View File

@ -51,12 +51,12 @@ GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_calendar_new (void); GtkWidget* gtk_calendar_new (void);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gtk_calendar_select_month (GtkCalendar *calendar, void gtk_calendar_select_month (GtkCalendar *self,
guint month, GDateTime *date);
guint year);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gtk_calendar_select_day (GtkCalendar *calendar, void gtk_calendar_select_day (GtkCalendar *self,
guint day); GDateTime *date);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gtk_calendar_mark_day (GtkCalendar *calendar, void gtk_calendar_mark_day (GtkCalendar *calendar,