From 440e8fa47f5e99ac67f52f1d357367b4fc87cf93 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 4 May 2016 23:35:11 -0400 Subject: [PATCH] Integrated the GTK+ date/time picker. FINALLY! --- _wip/gtkdtp/dtp.h | 12 - _wip/gtkdtp/dtpwidget.c | 566 ------------------------------- _wip/gtkdtp/main.c | 30 -- examples/controlgallery/unix.png | Bin 43161 -> 41710 bytes unix/datetimepicker.c | 543 ++++++++++++++++++++++++++++- unix/uipriv_unix.h | 3 +- 6 files changed, 539 insertions(+), 615 deletions(-) delete mode 100644 _wip/gtkdtp/dtp.h delete mode 100644 _wip/gtkdtp/dtpwidget.c delete mode 100644 _wip/gtkdtp/main.c diff --git a/_wip/gtkdtp/dtp.h b/_wip/gtkdtp/dtp.h deleted file mode 100644 index 9e328500..00000000 --- a/_wip/gtkdtp/dtp.h +++ /dev/null @@ -1,12 +0,0 @@ -// 4 september 2015 -#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_32 -#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_32 -#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_4 -#define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_4 -#include -#include -#include - -extern GtkWidget *newDTP(void); -extern GtkWidget *newDP(void); -extern GtkWidget *newTP(void); diff --git a/_wip/gtkdtp/dtpwidget.c b/_wip/gtkdtp/dtpwidget.c deleted file mode 100644 index a915c3cc..00000000 --- a/_wip/gtkdtp/dtpwidget.c +++ /dev/null @@ -1,566 +0,0 @@ -// 4 september 2015 -#include "uipriv_unix.h" - -// TODO imitate gnome-calendar's day/month/year entries? -// TODO 24-hour time - -#define dateTimePickerWidgetType (dateTimePickerWidget_get_type()) -#define dateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), dateTimePickerWidgetType, dateTimePickerWidget)) -#define isDateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), dateTimePickerWidgetType)) -#define dateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), dateTimePickerWidgetType, dateTimePickerWidgetClass)) -#define isDateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), dateTimePickerWidget)) -#define getDateTimePickerWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), dateTimePickerWidgetType, dateTimePickerWidgetClass)) - -typedef struct dateTimePickerWidget dateTimePickerWidget; -typedef struct dateTimePickerWidgetClass dateTimePickerWidgetClass; - -struct dateTimePickerWidget { - GtkToggleButton parent_instance; - - gulong toggledSignal; - - gboolean hasTime; - gboolean hasDate; - - GtkWidget *window; - GtkWidget *box; - GtkWidget *calendar; - GtkWidget *timebox; - GtkWidget *hours; - GtkWidget *minutes; - GtkWidget *seconds; - GtkWidget *ampm; - - gulong hoursBlock; - gulong minutesBlock; - gulong secondsBlock; - gulong ampmBlock; - - GdkDevice *keyboard; - GdkDevice *mouse; -}; - -struct dateTimePickerWidgetClass { - GtkToggleButtonClass parent_class; -}; - -G_DEFINE_TYPE(dateTimePickerWidget, dateTimePickerWidget, GTK_TYPE_TOGGLE_BUTTON) - -static int realSpinValue(GtkSpinButton *spinButton) -{ - GtkAdjustment *adj; - - adj = gtk_spin_button_get_adjustment(spinButton); - return (int) gtk_adjustment_get_value(adj); -} - -static void setRealSpinValue(GtkSpinButton *spinButton, int value, gulong block) -{ - GtkAdjustment *adj; - - g_signal_handler_block(spinButton, block); - adj = gtk_spin_button_get_adjustment(spinButton); - gtk_adjustment_set_value(adj, value); - g_signal_handler_unblock(spinButton, block); -} - -static GDateTime *selected(dateTimePickerWidget *d) -{ - // choose a day for which all times are likely to be valid for the default date in case we're only dealing with time - guint year = 1970, month = 1, day = 1; - guint hour = 0, minute = 0, second = 0; - - if (d->hasDate) { - gtk_calendar_get_date(GTK_CALENDAR(d->calendar), &year, &month, &day); - month++; // GtkCalendar/GDateTime differences - } - if (d->hasTime) { - hour = realSpinValue(GTK_SPIN_BUTTON(d->hours)); - if (realSpinValue(GTK_SPIN_BUTTON(d->ampm)) != 0) - hour += 12; - minute = realSpinValue(GTK_SPIN_BUTTON(d->minutes)); - second = realSpinValue(GTK_SPIN_BUTTON(d->seconds)); - } - return g_date_time_new_local(year, month, day, hour, minute, second); -} - -static void setLabel(dateTimePickerWidget *d) -{ - GDateTime *dt; - char *fmt; - char *msg; - gboolean free; - - dt = selected(d); - free = FALSE; - if (d->hasDate && d->hasTime) { - // don't use D_T_FMT; that's too verbose - fmt = g_strdup_printf("%s %s", nl_langinfo(D_FMT), nl_langinfo(T_FMT)); - free = TRUE; - } else if (d->hasDate) - fmt = nl_langinfo(D_FMT); - else - fmt = nl_langinfo(T_FMT); - msg = g_date_time_format(dt, fmt); - gtk_button_set_label(GTK_BUTTON(d), msg); - g_free(msg); - if (free) - g_free(fmt); - g_date_time_unref(dt); -} - -static void dateTimeChanged(dateTimePickerWidget *d) -{ - setLabel(d); - // TODO fire event here -} - -// we don't want ::toggled to be sent again -static void setActive(dateTimePickerWidget *d, gboolean active) -{ - g_signal_handler_block(d, d->toggledSignal); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d), active); - g_signal_handler_unblock(d, d->toggledSignal); -} - -// like startGrab() below, a lot of this is in the order that GtkComboBox does it -static void endGrab(dateTimePickerWidget *d) -{ - if (d->keyboard != NULL) - gdk_device_ungrab(d->keyboard, GDK_CURRENT_TIME); - gdk_device_ungrab(d->mouse, GDK_CURRENT_TIME); - gtk_device_grab_remove(d->window, d->mouse); - d->keyboard = NULL; - d->mouse = NULL; -} - -static void hidePopup(dateTimePickerWidget *d) -{ - endGrab(d); - gtk_widget_hide(d->window); - setActive(d, FALSE); -} - -// this consolidates a good chunk of what GtkComboBox does -static gboolean startGrab(dateTimePickerWidget *d) -{ - GdkDevice *dev; - guint32 time; - GdkWindow *window; - GdkDevice *keyboard, *mouse; - - dev = gtk_get_current_event_device(); - if (dev == NULL) - return FALSE; // TODO - - time = gtk_get_current_event_time(); - keyboard = dev; - mouse = gdk_device_get_associated_device(dev); - if (gdk_device_get_source(dev) != GDK_SOURCE_KEYBOARD) { - dev = mouse; - mouse = keyboard; - keyboard = dev; - } - - window = gtk_widget_get_window(d->window); - if (keyboard != NULL) - if (gdk_device_grab(keyboard, window, - GDK_OWNERSHIP_WINDOW, TRUE, - GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, - NULL, time) != GDK_GRAB_SUCCESS) - return FALSE; - if (mouse != NULL) - if (gdk_device_grab(mouse, window, - GDK_OWNERSHIP_WINDOW, TRUE, - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, - NULL, time) != GDK_GRAB_SUCCESS) { - if (keyboard != NULL) - gdk_device_ungrab(keyboard, time); - return FALSE; - } - - gtk_device_grab_add(d->window, mouse, TRUE); - d->keyboard = keyboard; - d->mouse = mouse; - return TRUE; -} - -// based on gtk_combo_box_list_position() in the GTK+ source code -static void allocationToScreen(dateTimePickerWidget *d, gint *x, gint *y) -{ - GdkWindow *window; - GtkAllocation a; - - gtk_widget_get_allocation(GTK_WIDGET(d), &a); - *x = 0; - *y = 0; - if (!gtk_widget_get_has_window(GTK_WIDGET(d))) { - *x = a.x; - *y = a.y; - } - window = gtk_widget_get_window(GTK_WIDGET(d)); - gdk_window_get_root_coords(window, *x, *y, x, y); - if (gtk_widget_get_direction(GTK_WIDGET(d)) == GTK_TEXT_DIR_RTL) - *x += a.width; // TODO subtract target width - // TODO monitor detection - *y += a.height; -} - -static void showPopup(dateTimePickerWidget *d) -{ - GtkWidget *toplevel; - gint x, y; - - // GtkComboBox does it - toplevel = gtk_widget_get_toplevel(GTK_WIDGET(d)); - if (GTK_IS_WINDOW(toplevel)) - gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(toplevel)), GTK_WINDOW(d->window)); - - allocationToScreen(d, &x, &y); - gtk_window_move(GTK_WINDOW(d->window), x, y); - - gtk_widget_show(d->window); - setActive(d, TRUE); - - if (!startGrab(d)) - hidePopup(d); -} - -static void onToggled(GtkToggleButton *b, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(b); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d))) - showPopup(d); - else - hidePopup(d); -} - -static gboolean grabBroken(GtkWidget *w, GdkEventGrabBroken *e, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - - hidePopup(d); - return TRUE; // this is what GtkComboBox does -} - -static gboolean buttonReleased(GtkWidget *w, GdkEventButton *e, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - int winx, winy; - GtkAllocation wina; - gboolean in; - - gtk_widget_get_allocation(d->window, &wina); - winx = 0; - winy = 0; - if (!gtk_widget_get_has_window(d->window)) { - winx = wina.x; - winy = wina.y; - } - gdk_window_get_root_coords(gtk_widget_get_window(d->window), winx, winy, &winx, &winy); - in = TRUE; - if (e->x_root < winx) - in = FALSE; - if (e->x_root >= (winx + wina.width)) - in = FALSE; - if (e->y_root < winy) - in = FALSE; - if (e->y_root >= (winy + wina.height)) - in = FALSE; - if (!in) - hidePopup(d); - return TRUE; // this is what GtkComboBox does -} - -static gint hoursSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data) -{ - double *out = (double *) ptr; - const gchar *text; - int value; - - text = gtk_entry_get_text(GTK_ENTRY(sb)); - value = (int) g_strtod(text, NULL); - if (value < 0 || value > 12) - return GTK_INPUT_ERROR; - if (value == 12) // 12 to the user is 0 internally - value = 0; - *out = (double) value; - return TRUE; -} - -static gboolean hoursSpinboxOutput(GtkSpinButton *sb, gpointer data) -{ - gchar *text; - int value; - - value = realSpinValue(sb); - if (value == 0) // 0 internally is 12 to the user - value = 12; - text = g_strdup_printf("%d", value); - gtk_entry_set_text(GTK_ENTRY(sb), text); - g_free(text); - return TRUE; -} - -static gboolean zeroPadSpinbox(GtkSpinButton *sb, gpointer data) -{ - gchar *text; - int value; - - value = realSpinValue(sb); - text = g_strdup_printf("%02d", value); - gtk_entry_set_text(GTK_ENTRY(sb), text); - g_free(text); - return TRUE; -} - -// this is really hacky but we can't use GtkCombobox here :( -static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data) -{ - double *out = (double *) ptr; - const gchar *text; - char firstAM, firstPM; - - text = gtk_entry_get_text(GTK_ENTRY(sb)); - // TODO don't use ASCII here for case insensitivity - firstAM = g_ascii_tolower(nl_langinfo(AM_STR)[0]); - firstPM = g_ascii_tolower(nl_langinfo(PM_STR)[0]); - for (; *text != '\0'; text++) - if (g_ascii_tolower(*text) == firstAM) { - *out = 0; - return TRUE; - } else if (g_ascii_tolower(*text) == firstPM) { - *out = 1; - return TRUE; - } - return GTK_INPUT_ERROR; -} - -static gboolean ampmSpinboxOutput(GtkSpinButton *sb, gpointer data) -{ - int value; - - value = gtk_spin_button_get_value_as_int(sb); - if (value == 0) - gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(AM_STR)); - else - gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(PM_STR)); - return TRUE; -} - -static void spinboxChanged(GtkSpinButton *sb, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - - dateTimeChanged(d); -} - -static GtkWidget *newSpinbox(dateTimePickerWidget *d, int min, int max, gint (*input)(GtkSpinButton *, gpointer, gpointer), gboolean (*output)(GtkSpinButton *, gpointer), gulong *block) -{ - GtkWidget *sb; - - sb = gtk_spin_button_new_with_range(min, max, 1); - gtk_spin_button_set_digits(GTK_SPIN_BUTTON(sb), 0); - gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(sb), TRUE); - gtk_orientable_set_orientation(GTK_ORIENTABLE(sb), GTK_ORIENTATION_VERTICAL); - *block = g_signal_connect(sb, "value-changed", G_CALLBACK(spinboxChanged), d); - if (input != NULL) - g_signal_connect(sb, "input", G_CALLBACK(input), NULL); - if (output != NULL) - g_signal_connect(sb, "output", G_CALLBACK(output), NULL); - return sb; -} - -static void dateChanged(GtkCalendar *c, gpointer data) -{ - dateTimePickerWidget *d = dateTimePickerWidget(data); - - dateTimeChanged(d); -} - -static void setDateOnly(dateTimePickerWidget *d) -{ - d->hasTime = FALSE; - gtk_container_remove(GTK_CONTAINER(d->box), d->timebox); -} - -static void setTimeOnly(dateTimePickerWidget *d) -{ - d->hasDate = FALSE; - gtk_container_remove(GTK_CONTAINER(d->box), d->calendar); -} - -static void dateTimePickerWidget_init(dateTimePickerWidget *d) -{ - GDateTime *dt; - gint year, month, day; - gint hour; - gulong calendarBlock; - - d->window = gtk_window_new(GTK_WINDOW_POPUP); - gtk_window_set_resizable(GTK_WINDOW(d->window), FALSE); - gtk_window_set_attached_to(GTK_WINDOW(d->window), GTK_WIDGET(d)); - // TODO set_keep_above()? - gtk_window_set_decorated(GTK_WINDOW(d->window), FALSE); - gtk_window_set_deletable(GTK_WINDOW(d->window), FALSE); - gtk_window_set_type_hint(GTK_WINDOW(d->window), GDK_WINDOW_TYPE_HINT_COMBO); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(d->window), TRUE); - gtk_window_set_skip_pager_hint(GTK_WINDOW(d->window), TRUE); - // TODO accept_focus()? - // TODO focus_on_map()? - gtk_window_set_has_resize_grip(GTK_WINDOW(d->window), FALSE); - gtk_container_set_border_width(GTK_CONTAINER(d->window), 12); - // and make it stand out a bit - gtk_style_context_add_class(gtk_widget_get_style_context(d->window), "frame"); - - d->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_container_add(GTK_CONTAINER(d->window), d->box); - - d->calendar = gtk_calendar_new(); - calendarBlock = g_signal_connect(d->calendar, "day-selected", G_CALLBACK(dateChanged), d); - gtk_container_add(GTK_CONTAINER(d->box), d->calendar); - - d->timebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); - gtk_widget_set_valign(d->timebox, GTK_ALIGN_CENTER); - gtk_container_add(GTK_CONTAINER(d->box), d->timebox); - - d->hours = newSpinbox(d, 0, 11, hoursSpinboxInput, hoursSpinboxOutput, &(d->hoursBlock)); - gtk_container_add(GTK_CONTAINER(d->timebox), d->hours); - - gtk_container_add(GTK_CONTAINER(d->timebox), - gtk_label_new(":")); - - d->minutes = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->minutesBlock)); - gtk_container_add(GTK_CONTAINER(d->timebox), d->minutes); - - gtk_container_add(GTK_CONTAINER(d->timebox), - gtk_label_new(":")); - - d->seconds = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->secondsBlock)); - gtk_container_add(GTK_CONTAINER(d->timebox), d->seconds); - - // TODO this should be the case, but that interferes with grabs - // switch to it when we can drop GTK+ 3.10 and use popovers -#if 0 - d->ampm = gtk_combo_box_text_new(); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "AM"); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "PM"); -#endif - d->ampm = newSpinbox(d, 0, 1, ampmSpinboxInput, ampmSpinboxOutput, &(d->ampmBlock)); - gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(d->ampm), FALSE); - gtk_widget_set_valign(d->ampm, GTK_ALIGN_CENTER); - gtk_container_add(GTK_CONTAINER(d->timebox), d->ampm); - - gtk_widget_show_all(d->box); - - g_signal_connect(d->window, "grab-broken-event", G_CALLBACK(grabBroken), d); - g_signal_connect(d->window, "button-release-event", G_CALLBACK(buttonReleased), d); - - d->toggledSignal = g_signal_connect(d, "toggled", G_CALLBACK(onToggled), NULL); - d->keyboard = NULL; - d->mouse = NULL; - - d->hasTime = TRUE; - d->hasDate = TRUE; - - // set the current date/time - // notice how we block signals from firing - dt = g_date_time_new_now_local(); - g_date_time_get_ymd(dt, &year, &month, &day); - month--; // GDateTime/GtkCalendar differences - g_signal_handler_block(d->calendar, calendarBlock); - gtk_calendar_select_month(GTK_CALENDAR(d->calendar), month, year); - gtk_calendar_select_day(GTK_CALENDAR(d->calendar), day); - g_signal_handler_unblock(d->calendar, calendarBlock); - hour = g_date_time_get_hour(dt); - if (hour >= 12) { - hour -= 12; - setRealSpinValue(GTK_SPIN_BUTTON(d->ampm), 1, d->ampmBlock); - } - setRealSpinValue(GTK_SPIN_BUTTON(d->hours), hour, d->hoursBlock); - setRealSpinValue(GTK_SPIN_BUTTON(d->minutes), g_date_time_get_minute(dt), d->minutesBlock); - setRealSpinValue(GTK_SPIN_BUTTON(d->seconds), g_date_time_get_seconds(dt), d->secondsBlock); - g_date_time_unref(dt); -} - -static void dateTimePickerWidget_dispose(GObject *obj) -{ - // TODO destroy window - G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->dispose(obj); -} - -static void dateTimePickerWidget_finalize(GObject *obj) -{ - G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->finalize(obj); -} - -static void dateTimePickerWidget_class_init(dateTimePickerWidgetClass *class) -{ - G_OBJECT_CLASS(class)->dispose = dateTimePickerWidget_dispose; - G_OBJECT_CLASS(class)->finalize = dateTimePickerWidget_finalize; -} - -static GtkWidget *newDTP(void) -{ - GtkWidget *w; - - w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); - setLabel(dateTimePickerWidget(w)); - return w; -} - -static GtkWidget *newDP(void) -{ - GtkWidget *w; - - w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); - setDateOnly(dateTimePickerWidget(w)); - setLabel(dateTimePickerWidget(w)); - return w; -} - -static GtkWidget *newTP(void) -{ - GtkWidget *w; - - w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); - setTimeOnly(dateTimePickerWidget(w)); - setLabel(dateTimePickerWidget(w)); - return w; -} - -struct uiDateTimePicker { - uiUnixControl c; - GtkWidget *widget; - dateTimePickerWidget *d; -}; - -uiUnixControlAllDefaults(uiDateTimePicker) - -uiDateTimePicker *finishNewDateTimePicker(GtkWidget (*fn)(void)) -{ - uiDateTimePicker *d; - - uiUnixNewControl(uiDateTimePicker, d); - - d->widget = (*fn)(); - d->d = dateTimePickerWidget(d->widget); - - return d; -} - -uiDateTimePicker *uiNewDateTimePicker(void) -{ - return finishNewDateTimePicker(newDTP); -} - -uiDateTimePicker *uiNewDatePicker(void) -{ - return finishNewDateTimePicker(newDP); -} - -uiDateTimePicker *uiNewTimePicker(void) -{ - return finishNewDateTimePicker(newTP); -} diff --git a/_wip/gtkdtp/main.c b/_wip/gtkdtp/main.c deleted file mode 100644 index 5e5e4e31..00000000 --- a/_wip/gtkdtp/main.c +++ /dev/null @@ -1,30 +0,0 @@ -// 4 september 2015 -#include "dtp.h" - -// #qo pkg-config: gtk+-3.0 - -int main(void) -{ - GtkWidget *mainwin; - GtkWidget *box; - GtkWidget *button; - - gtk_init(NULL, NULL); - - mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); - g_signal_connect(mainwin, "destroy", G_CALLBACK(gtk_main_quit), NULL); - gtk_container_set_border_width(GTK_CONTAINER(mainwin), 12); - box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); - gtk_container_add(GTK_CONTAINER(mainwin), box); - button = newDTP(); - gtk_container_add(GTK_CONTAINER(box), button); - button = newDP(); - gtk_container_add(GTK_CONTAINER(box), button); - button = newTP(); - gtk_container_add(GTK_CONTAINER(box), button); - gtk_container_add(GTK_CONTAINER(box), gtk_entry_new()); - - gtk_widget_show_all(mainwin); - gtk_main(); - return 0; -} diff --git a/examples/controlgallery/unix.png b/examples/controlgallery/unix.png index 264af924974d9bd9cc332652a75a4041a8e83b99..2aa5ea0a0da2169c0d271b12753402e1a831407b 100644 GIT binary patch literal 41710 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 Umf|MBYXT~Y8qX`9zWU?e0P<3|dH?_b diff --git a/unix/datetimepicker.c b/unix/datetimepicker.c index 6a28eaf3..a38a5217 100644 --- a/unix/datetimepicker.c +++ b/unix/datetimepicker.c @@ -1,35 +1,566 @@ -// 11 june 2015 +// 4 september 2015 #include "uipriv_unix.h" +// TODO imitate gnome-calendar's day/month/year entries? +// TODO 24-hour time + +#define dateTimePickerWidgetType (dateTimePickerWidget_get_type()) +#define dateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), dateTimePickerWidgetType, dateTimePickerWidget)) +#define isDateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), dateTimePickerWidgetType)) +#define dateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), dateTimePickerWidgetType, dateTimePickerWidgetClass)) +#define isDateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), dateTimePickerWidget)) +#define getDateTimePickerWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), dateTimePickerWidgetType, dateTimePickerWidgetClass)) + +typedef struct dateTimePickerWidget dateTimePickerWidget; +typedef struct dateTimePickerWidgetClass dateTimePickerWidgetClass; + +struct dateTimePickerWidget { + GtkToggleButton parent_instance; + + gulong toggledSignal; + + gboolean hasTime; + gboolean hasDate; + + GtkWidget *window; + GtkWidget *box; + GtkWidget *calendar; + GtkWidget *timebox; + GtkWidget *hours; + GtkWidget *minutes; + GtkWidget *seconds; + GtkWidget *ampm; + + gulong hoursBlock; + gulong minutesBlock; + gulong secondsBlock; + gulong ampmBlock; + + GdkDevice *keyboard; + GdkDevice *mouse; +}; + +struct dateTimePickerWidgetClass { + GtkToggleButtonClass parent_class; +}; + +G_DEFINE_TYPE(dateTimePickerWidget, dateTimePickerWidget, GTK_TYPE_TOGGLE_BUTTON) + +static int realSpinValue(GtkSpinButton *spinButton) +{ + GtkAdjustment *adj; + + adj = gtk_spin_button_get_adjustment(spinButton); + return (int) gtk_adjustment_get_value(adj); +} + +static void setRealSpinValue(GtkSpinButton *spinButton, int value, gulong block) +{ + GtkAdjustment *adj; + + g_signal_handler_block(spinButton, block); + adj = gtk_spin_button_get_adjustment(spinButton); + gtk_adjustment_set_value(adj, value); + g_signal_handler_unblock(spinButton, block); +} + +static GDateTime *selected(dateTimePickerWidget *d) +{ + // choose a day for which all times are likely to be valid for the default date in case we're only dealing with time + guint year = 1970, month = 1, day = 1; + guint hour = 0, minute = 0, second = 0; + + if (d->hasDate) { + gtk_calendar_get_date(GTK_CALENDAR(d->calendar), &year, &month, &day); + month++; // GtkCalendar/GDateTime differences + } + if (d->hasTime) { + hour = realSpinValue(GTK_SPIN_BUTTON(d->hours)); + if (realSpinValue(GTK_SPIN_BUTTON(d->ampm)) != 0) + hour += 12; + minute = realSpinValue(GTK_SPIN_BUTTON(d->minutes)); + second = realSpinValue(GTK_SPIN_BUTTON(d->seconds)); + } + return g_date_time_new_local(year, month, day, hour, minute, second); +} + +static void setLabel(dateTimePickerWidget *d) +{ + GDateTime *dt; + char *fmt; + char *msg; + gboolean free; + + dt = selected(d); + free = FALSE; + if (d->hasDate && d->hasTime) { + // don't use D_T_FMT; that's too verbose + fmt = g_strdup_printf("%s %s", nl_langinfo(D_FMT), nl_langinfo(T_FMT)); + free = TRUE; + } else if (d->hasDate) + fmt = nl_langinfo(D_FMT); + else + fmt = nl_langinfo(T_FMT); + msg = g_date_time_format(dt, fmt); + gtk_button_set_label(GTK_BUTTON(d), msg); + g_free(msg); + if (free) + g_free(fmt); + g_date_time_unref(dt); +} + +static void dateTimeChanged(dateTimePickerWidget *d) +{ + setLabel(d); + // TODO fire event here +} + +// we don't want ::toggled to be sent again +static void setActive(dateTimePickerWidget *d, gboolean active) +{ + g_signal_handler_block(d, d->toggledSignal); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d), active); + g_signal_handler_unblock(d, d->toggledSignal); +} + +// like startGrab() below, a lot of this is in the order that GtkComboBox does it +static void endGrab(dateTimePickerWidget *d) +{ + if (d->keyboard != NULL) + gdk_device_ungrab(d->keyboard, GDK_CURRENT_TIME); + gdk_device_ungrab(d->mouse, GDK_CURRENT_TIME); + gtk_device_grab_remove(d->window, d->mouse); + d->keyboard = NULL; + d->mouse = NULL; +} + +static void hidePopup(dateTimePickerWidget *d) +{ + endGrab(d); + gtk_widget_hide(d->window); + setActive(d, FALSE); +} + +// this consolidates a good chunk of what GtkComboBox does +static gboolean startGrab(dateTimePickerWidget *d) +{ + GdkDevice *dev; + guint32 time; + GdkWindow *window; + GdkDevice *keyboard, *mouse; + + dev = gtk_get_current_event_device(); + if (dev == NULL) + return FALSE; // TODO + + time = gtk_get_current_event_time(); + keyboard = dev; + mouse = gdk_device_get_associated_device(dev); + if (gdk_device_get_source(dev) != GDK_SOURCE_KEYBOARD) { + dev = mouse; + mouse = keyboard; + keyboard = dev; + } + + window = gtk_widget_get_window(d->window); + if (keyboard != NULL) + if (gdk_device_grab(keyboard, window, + GDK_OWNERSHIP_WINDOW, TRUE, + GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, + NULL, time) != GDK_GRAB_SUCCESS) + return FALSE; + if (mouse != NULL) + if (gdk_device_grab(mouse, window, + GDK_OWNERSHIP_WINDOW, TRUE, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + NULL, time) != GDK_GRAB_SUCCESS) { + if (keyboard != NULL) + gdk_device_ungrab(keyboard, time); + return FALSE; + } + + gtk_device_grab_add(d->window, mouse, TRUE); + d->keyboard = keyboard; + d->mouse = mouse; + return TRUE; +} + +// based on gtk_combo_box_list_position() in the GTK+ source code +static void allocationToScreen(dateTimePickerWidget *d, gint *x, gint *y) +{ + GdkWindow *window; + GtkAllocation a; + + gtk_widget_get_allocation(GTK_WIDGET(d), &a); + *x = 0; + *y = 0; + if (!gtk_widget_get_has_window(GTK_WIDGET(d))) { + *x = a.x; + *y = a.y; + } + window = gtk_widget_get_window(GTK_WIDGET(d)); + gdk_window_get_root_coords(window, *x, *y, x, y); + if (gtk_widget_get_direction(GTK_WIDGET(d)) == GTK_TEXT_DIR_RTL) + *x += a.width; // TODO subtract target width + // TODO monitor detection + *y += a.height; +} + +static void showPopup(dateTimePickerWidget *d) +{ + GtkWidget *toplevel; + gint x, y; + + // GtkComboBox does it + toplevel = gtk_widget_get_toplevel(GTK_WIDGET(d)); + if (GTK_IS_WINDOW(toplevel)) + gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(toplevel)), GTK_WINDOW(d->window)); + + allocationToScreen(d, &x, &y); + gtk_window_move(GTK_WINDOW(d->window), x, y); + + gtk_widget_show(d->window); + setActive(d, TRUE); + + if (!startGrab(d)) + hidePopup(d); +} + +static void onToggled(GtkToggleButton *b, gpointer data) +{ + dateTimePickerWidget *d = dateTimePickerWidget(b); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d))) + showPopup(d); + else + hidePopup(d); +} + +static gboolean grabBroken(GtkWidget *w, GdkEventGrabBroken *e, gpointer data) +{ + dateTimePickerWidget *d = dateTimePickerWidget(data); + + hidePopup(d); + return TRUE; // this is what GtkComboBox does +} + +static gboolean buttonReleased(GtkWidget *w, GdkEventButton *e, gpointer data) +{ + dateTimePickerWidget *d = dateTimePickerWidget(data); + int winx, winy; + GtkAllocation wina; + gboolean in; + + gtk_widget_get_allocation(d->window, &wina); + winx = 0; + winy = 0; + if (!gtk_widget_get_has_window(d->window)) { + winx = wina.x; + winy = wina.y; + } + gdk_window_get_root_coords(gtk_widget_get_window(d->window), winx, winy, &winx, &winy); + in = TRUE; + if (e->x_root < winx) + in = FALSE; + if (e->x_root >= (winx + wina.width)) + in = FALSE; + if (e->y_root < winy) + in = FALSE; + if (e->y_root >= (winy + wina.height)) + in = FALSE; + if (!in) + hidePopup(d); + return TRUE; // this is what GtkComboBox does +} + +static gint hoursSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data) +{ + double *out = (double *) ptr; + const gchar *text; + int value; + + text = gtk_entry_get_text(GTK_ENTRY(sb)); + value = (int) g_strtod(text, NULL); + if (value < 0 || value > 12) + return GTK_INPUT_ERROR; + if (value == 12) // 12 to the user is 0 internally + value = 0; + *out = (double) value; + return TRUE; +} + +static gboolean hoursSpinboxOutput(GtkSpinButton *sb, gpointer data) +{ + gchar *text; + int value; + + value = realSpinValue(sb); + if (value == 0) // 0 internally is 12 to the user + value = 12; + text = g_strdup_printf("%d", value); + gtk_entry_set_text(GTK_ENTRY(sb), text); + g_free(text); + return TRUE; +} + +static gboolean zeroPadSpinbox(GtkSpinButton *sb, gpointer data) +{ + gchar *text; + int value; + + value = realSpinValue(sb); + text = g_strdup_printf("%02d", value); + gtk_entry_set_text(GTK_ENTRY(sb), text); + g_free(text); + return TRUE; +} + +// this is really hacky but we can't use GtkCombobox here :( +static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data) +{ + double *out = (double *) ptr; + const gchar *text; + char firstAM, firstPM; + + text = gtk_entry_get_text(GTK_ENTRY(sb)); + // TODO don't use ASCII here for case insensitivity + firstAM = g_ascii_tolower(nl_langinfo(AM_STR)[0]); + firstPM = g_ascii_tolower(nl_langinfo(PM_STR)[0]); + for (; *text != '\0'; text++) + if (g_ascii_tolower(*text) == firstAM) { + *out = 0; + return TRUE; + } else if (g_ascii_tolower(*text) == firstPM) { + *out = 1; + return TRUE; + } + return GTK_INPUT_ERROR; +} + +static gboolean ampmSpinboxOutput(GtkSpinButton *sb, gpointer data) +{ + int value; + + value = gtk_spin_button_get_value_as_int(sb); + if (value == 0) + gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(AM_STR)); + else + gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(PM_STR)); + return TRUE; +} + +static void spinboxChanged(GtkSpinButton *sb, gpointer data) +{ + dateTimePickerWidget *d = dateTimePickerWidget(data); + + dateTimeChanged(d); +} + +static GtkWidget *newSpinbox(dateTimePickerWidget *d, int min, int max, gint (*input)(GtkSpinButton *, gpointer, gpointer), gboolean (*output)(GtkSpinButton *, gpointer), gulong *block) +{ + GtkWidget *sb; + + sb = gtk_spin_button_new_with_range(min, max, 1); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(sb), 0); + gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(sb), TRUE); + gtk_orientable_set_orientation(GTK_ORIENTABLE(sb), GTK_ORIENTATION_VERTICAL); + *block = g_signal_connect(sb, "value-changed", G_CALLBACK(spinboxChanged), d); + if (input != NULL) + g_signal_connect(sb, "input", G_CALLBACK(input), NULL); + if (output != NULL) + g_signal_connect(sb, "output", G_CALLBACK(output), NULL); + return sb; +} + +static void dateChanged(GtkCalendar *c, gpointer data) +{ + dateTimePickerWidget *d = dateTimePickerWidget(data); + + dateTimeChanged(d); +} + +static void setDateOnly(dateTimePickerWidget *d) +{ + d->hasTime = FALSE; + gtk_container_remove(GTK_CONTAINER(d->box), d->timebox); +} + +static void setTimeOnly(dateTimePickerWidget *d) +{ + d->hasDate = FALSE; + gtk_container_remove(GTK_CONTAINER(d->box), d->calendar); +} + +static void dateTimePickerWidget_init(dateTimePickerWidget *d) +{ + GDateTime *dt; + gint year, month, day; + gint hour; + gulong calendarBlock; + + d->window = gtk_window_new(GTK_WINDOW_POPUP); + gtk_window_set_resizable(GTK_WINDOW(d->window), FALSE); + gtk_window_set_attached_to(GTK_WINDOW(d->window), GTK_WIDGET(d)); + // TODO set_keep_above()? + gtk_window_set_decorated(GTK_WINDOW(d->window), FALSE); + gtk_window_set_deletable(GTK_WINDOW(d->window), FALSE); + gtk_window_set_type_hint(GTK_WINDOW(d->window), GDK_WINDOW_TYPE_HINT_COMBO); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(d->window), TRUE); + gtk_window_set_skip_pager_hint(GTK_WINDOW(d->window), TRUE); + // TODO accept_focus()? + // TODO focus_on_map()? + gtk_window_set_has_resize_grip(GTK_WINDOW(d->window), FALSE); + gtk_container_set_border_width(GTK_CONTAINER(d->window), 12); + // and make it stand out a bit + gtk_style_context_add_class(gtk_widget_get_style_context(d->window), "frame"); + + d->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + gtk_container_add(GTK_CONTAINER(d->window), d->box); + + d->calendar = gtk_calendar_new(); + calendarBlock = g_signal_connect(d->calendar, "day-selected", G_CALLBACK(dateChanged), d); + gtk_container_add(GTK_CONTAINER(d->box), d->calendar); + + d->timebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); + gtk_widget_set_valign(d->timebox, GTK_ALIGN_CENTER); + gtk_container_add(GTK_CONTAINER(d->box), d->timebox); + + d->hours = newSpinbox(d, 0, 11, hoursSpinboxInput, hoursSpinboxOutput, &(d->hoursBlock)); + gtk_container_add(GTK_CONTAINER(d->timebox), d->hours); + + gtk_container_add(GTK_CONTAINER(d->timebox), + gtk_label_new(":")); + + d->minutes = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->minutesBlock)); + gtk_container_add(GTK_CONTAINER(d->timebox), d->minutes); + + gtk_container_add(GTK_CONTAINER(d->timebox), + gtk_label_new(":")); + + d->seconds = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->secondsBlock)); + gtk_container_add(GTK_CONTAINER(d->timebox), d->seconds); + + // TODO this should be the case, but that interferes with grabs + // switch to it when we can drop GTK+ 3.10 and use popovers +#if 0 + d->ampm = gtk_combo_box_text_new(); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "AM"); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "PM"); +#endif + d->ampm = newSpinbox(d, 0, 1, ampmSpinboxInput, ampmSpinboxOutput, &(d->ampmBlock)); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(d->ampm), FALSE); + gtk_widget_set_valign(d->ampm, GTK_ALIGN_CENTER); + gtk_container_add(GTK_CONTAINER(d->timebox), d->ampm); + + gtk_widget_show_all(d->box); + + g_signal_connect(d->window, "grab-broken-event", G_CALLBACK(grabBroken), d); + g_signal_connect(d->window, "button-release-event", G_CALLBACK(buttonReleased), d); + + d->toggledSignal = g_signal_connect(d, "toggled", G_CALLBACK(onToggled), NULL); + d->keyboard = NULL; + d->mouse = NULL; + + d->hasTime = TRUE; + d->hasDate = TRUE; + + // set the current date/time + // notice how we block signals from firing + dt = g_date_time_new_now_local(); + g_date_time_get_ymd(dt, &year, &month, &day); + month--; // GDateTime/GtkCalendar differences + g_signal_handler_block(d->calendar, calendarBlock); + gtk_calendar_select_month(GTK_CALENDAR(d->calendar), month, year); + gtk_calendar_select_day(GTK_CALENDAR(d->calendar), day); + g_signal_handler_unblock(d->calendar, calendarBlock); + hour = g_date_time_get_hour(dt); + if (hour >= 12) { + hour -= 12; + setRealSpinValue(GTK_SPIN_BUTTON(d->ampm), 1, d->ampmBlock); + } + setRealSpinValue(GTK_SPIN_BUTTON(d->hours), hour, d->hoursBlock); + setRealSpinValue(GTK_SPIN_BUTTON(d->minutes), g_date_time_get_minute(dt), d->minutesBlock); + setRealSpinValue(GTK_SPIN_BUTTON(d->seconds), g_date_time_get_seconds(dt), d->secondsBlock); + g_date_time_unref(dt); +} + +static void dateTimePickerWidget_dispose(GObject *obj) +{ + // TODO destroy window + G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->dispose(obj); +} + +static void dateTimePickerWidget_finalize(GObject *obj) +{ + G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->finalize(obj); +} + +static void dateTimePickerWidget_class_init(dateTimePickerWidgetClass *class) +{ + G_OBJECT_CLASS(class)->dispose = dateTimePickerWidget_dispose; + G_OBJECT_CLASS(class)->finalize = dateTimePickerWidget_finalize; +} + +static GtkWidget *newDTP(void) +{ + GtkWidget *w; + + w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); + setLabel(dateTimePickerWidget(w)); + return w; +} + +static GtkWidget *newDP(void) +{ + GtkWidget *w; + + w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); + setDateOnly(dateTimePickerWidget(w)); + setLabel(dateTimePickerWidget(w)); + return w; +} + +static GtkWidget *newTP(void) +{ + GtkWidget *w; + + w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL)); + setTimeOnly(dateTimePickerWidget(w)); + setLabel(dateTimePickerWidget(w)); + return w; +} + struct uiDateTimePicker { uiUnixControl c; GtkWidget *widget; + dateTimePickerWidget *d; }; uiUnixControlAllDefaults(uiDateTimePicker) -uiDateTimePicker *finishNewDateTimePicker(OSTHING OSARG) +uiDateTimePicker *finishNewDateTimePicker(GtkWidget *(*fn)(void)) { uiDateTimePicker *d; uiUnixNewControl(uiDateTimePicker, d); - d->widget = gtk_label_new("TODO uiDateTimePicker not implemented"); + d->widget = (*fn)(); + d->d = dateTimePickerWidget(d->widget); return d; } uiDateTimePicker *uiNewDateTimePicker(void) { - return finishNewDateTimePicker(OSARGDATETIME); + return finishNewDateTimePicker(newDTP); } uiDateTimePicker *uiNewDatePicker(void) { - return finishNewDateTimePicker(OSARGDATEONLY); + return finishNewDateTimePicker(newDP); } uiDateTimePicker *uiNewTimePicker(void) { - return finishNewDateTimePicker(OSARGTIMEONLY); + return finishNewDateTimePicker(newTP); } diff --git a/unix/uipriv_unix.h b/unix/uipriv_unix.h index 30f8a1e4..6a260830 100644 --- a/unix/uipriv_unix.h +++ b/unix/uipriv_unix.h @@ -5,9 +5,10 @@ #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_4 // TODO make this unnecessary #define _GNU_SOURCE +#include #include #include // see drawtext.c -#include +#include #include "../ui.h" #include "../ui_unix.h" #include "../common/uipriv.h"