[Goodies-dev] [PATCH 3/4] Add calendar popup menu to go to/select today
Olivier Brunel
jjk at jjacky.com
Sun May 13 21:43:06 CEST 2018
Also refactor calendar creation via a function. This will all become
(more) useful in the next commit when adding reminders.
Signed-off-by: Olivier Brunel <jjk at jjacky.com>
---
panel-plugin/datetime.c | 110 +++++++++++++++++++++++++++++++++++++++++++++---
panel-plugin/datetime.h | 6 +++
2 files changed, 109 insertions(+), 7 deletions(-)
diff --git a/panel-plugin/datetime.c b/panel-plugin/datetime.c
index 1722dd1..a96f791 100644
--- a/panel-plugin/datetime.c
+++ b/panel-plugin/datetime.c
@@ -259,6 +259,104 @@ static gboolean close_calendar_window(t_datetime *datetime)
return TRUE;
}
+static gboolean unblock_focus_out(GtkWidget *cal)
+{
+ gulong bop_sid;
+
+ bop_sid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cal), "block-on-popup-sid"));
+ if (G_LIKELY(bop_sid))
+ {
+ GtkWidget *win;
+
+ win = gtk_widget_get_toplevel(cal);
+ g_signal_handler_unblock(win, bop_sid);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void on_today_activate(GtkCalendar *cal)
+{
+ time_t ts;
+ struct tm tm;
+
+ ts = time(NULL);
+ if (!localtime_r(&ts, &tm))
+ return;
+
+ gtk_calendar_select_month(cal, tm.tm_mon, tm.tm_year + 1900);
+ gtk_calendar_select_day(cal, tm.tm_mday);
+}
+
+void inline menu_popup_and_destroy(GtkMenu *menu, guint button, guint32 time)
+{
+ g_signal_connect_swapped(G_OBJECT(menu), "hide",
+ G_CALLBACK(gtk_widget_destroy),
+ menu);
+ gtk_menu_popup(menu, NULL, NULL, NULL, NULL, button, time);
+}
+
+static gboolean on_calendar_button_released(GtkWidget *cal,
+ GdkEventButton *event,
+ t_datetime *datetime)
+{
+ GtkWidget *menu;
+ GtkWidget *w;
+ gulong bop_sid;
+
+ if (event->button != GDK_BUTTON_SECONDARY)
+ return FALSE;
+
+ /* check if a signal was set to block on pop-up. This is because if the
+ * toplevel window containing the calendar autocloses on loss of focus, it
+ * would autoclose because of the menu popup */
+ bop_sid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cal), "block-on-popup-sid"));
+ if (bop_sid)
+ {
+ GtkWidget *win;
+
+ win = gtk_widget_get_toplevel(cal);
+ g_signal_handler_block(win, bop_sid);
+ }
+
+ menu = gtk_menu_new();
+
+ w = gtk_menu_item_new_with_label(_("Today"));
+ /* FIXME somehow with "activate" is doesn't work? (callback never triggered) */
+ g_signal_connect_swapped(G_OBJECT(w), "button-release-event",
+ G_CALLBACK(on_today_activate),
+ cal);
+ gtk_menu_attach(GTK_MENU(menu), w, 0, 1, 0, 1);
+
+ gtk_widget_show_all(menu);
+ menu_popup_and_destroy(GTK_MENU(menu), event->button, event->time);
+
+ /* restore autoclosing once done */
+ if (bop_sid)
+ g_idle_add((GSourceFunc) unblock_focus_out, cal);
+
+ return TRUE;
+}
+
+GtkWidget * datetime_calendar_new(t_datetime *datetime)
+{
+ GtkWidget *cal;
+ GtkCalendarDisplayOptions display_options;
+
+ cal = gtk_calendar_new();
+
+ display_options = GTK_CALENDAR_SHOW_HEADING |
+ GTK_CALENDAR_SHOW_WEEK_NUMBERS |
+ GTK_CALENDAR_SHOW_DAY_NAMES;
+ gtk_calendar_set_display_options(GTK_CALENDAR(cal), display_options);
+
+ g_signal_connect(G_OBJECT(cal), "button-release-event",
+ G_CALLBACK(on_calendar_button_released),
+ datetime);
+
+ return cal;
+}
+
/*
* call the gtk calendar
*/
@@ -269,7 +367,7 @@ static GtkWidget * pop_calendar_window(t_datetime *datetime, int orientation)
GtkWidget *cal;
GtkWidget *parent = datetime->button;
GdkScreen *screen;
- GtkCalendarDisplayOptions display_options;
+ gulong sid;
int num;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -288,11 +386,7 @@ static GtkWidget * pop_calendar_window(t_datetime *datetime, int orientation)
gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER(window), frame);
- cal = gtk_calendar_new();
- display_options = GTK_CALENDAR_SHOW_HEADING |
- GTK_CALENDAR_SHOW_WEEK_NUMBERS |
- GTK_CALENDAR_SHOW_DAY_NAMES;
- gtk_calendar_set_display_options(GTK_CALENDAR (cal), display_options);
+ cal = datetime_calendar_new(datetime);
gtk_container_add (GTK_CONTAINER(frame), cal);
g_signal_connect_after(G_OBJECT(window), "realize",
@@ -301,9 +395,11 @@ static GtkWidget * pop_calendar_window(t_datetime *datetime, int orientation)
g_signal_connect_swapped(G_OBJECT(window), "delete-event",
G_CALLBACK(close_calendar_window),
datetime);
- g_signal_connect_swapped(G_OBJECT(window), "focus-out-event",
+ sid = g_signal_connect_swapped(G_OBJECT(window), "focus-out-event",
G_CALLBACK(close_calendar_window),
datetime);
+ /* set as signal to block on popup -- see on_calendar_button_released */
+ g_object_set_data(G_OBJECT(cal), "block-on-popup-sid", GINT_TO_POINTER(sid));
gtk_widget_show_all(window);
xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (datetime->plugin), TRUE);
diff --git a/panel-plugin/datetime.h b/panel-plugin/datetime.h
index 3fe434b..109bd0a 100644
--- a/panel-plugin/datetime.h
+++ b/panel-plugin/datetime.h
@@ -107,5 +107,11 @@ void
datetime_write_rc_file(XfcePanelPlugin *plugin,
t_datetime *dt);
+GtkWidget *
+datetime_calendar_new(t_datetime *datetime);
+
+void
+menu_popup_and_destroy(GtkMenu *menu, guint button, guint32 time);
+
#endif /* datetime.h */
--
2.15.1
More information about the Goodies-dev
mailing list