61 GtkStyleContext *context = gtk_widget_get_style_context(widget);
63 gtk_style_context_get_color(context, GTK_STATE_FLAG_NORMAL, &
color);
65 cairo_set_line_width(cr, 1.2);
68 gtk_widget_get_allocation(widget, &alloc);
69 const double pad = 1.0;
70 const double w =
MAX(0.0, (
double)alloc.width - 2.0 * pad);
71 const double h =
MAX(0.0, (
double)alloc.height - 2.0 * pad);
72 const double size = fmin(w, h);
73 const double x = ((
double)alloc.width -
size) * 0.5;
74 const double y = ((
double)alloc.height -
size) * 0.5;
98 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
101 GtkWidget *menu_item = gtk_menu_item_new();
103 GtkWidget *icon_widget = gtk_drawing_area_new();
104 GtkWidget *label_widget = gtk_label_new(NULL);
106 gtk_widget_set_size_request(icon_widget, 10, 10);
107 gtk_label_set_markup(GTK_LABEL(label_widget), label);
113 g_signal_connect_data(icon_widget,
"draw", G_CALLBACK(
_menu_icon_draw), data, (GClosureNotify)g_free, 0);
116 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
117 gtk_box_pack_start(GTK_BOX(box), label_widget,
FALSE,
FALSE, 0);
118 gtk_box_pack_start(GTK_BOX(box), icon_widget,
FALSE,
FALSE, 2);
119 gtk_container_add(GTK_CONTAINER(menu_item), box);
120 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
122 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
129 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
132 GtkWidget *menu_item = gtk_menu_item_new();
135 GtkWidget *icon_widget = gtk_drawing_area_new();
136 GtkWidget *label_widget = gtk_label_new(NULL);
137 GtkWidget *shortcut_widget = gtk_label_new(shortcut);
139 gtk_widget_set_size_request(icon_widget, 10, 10);
140 gtk_label_set_markup(GTK_LABEL(label_widget), label);
141 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
142 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
143 gtk_widget_set_hexpand(label_widget,
TRUE);
149 g_signal_connect_data(icon_widget,
"draw", G_CALLBACK(
_menu_icon_draw), data, (GClosureNotify)g_free, 0);
152 gtk_label_set_xalign(GTK_LABEL(shortcut_widget), 1.0f);
153 gtk_widget_set_halign(shortcut_widget, GTK_ALIGN_END);
154 gtk_style_context_add_class(gtk_widget_get_style_context(shortcut_widget),
"accelerator");
156 gtk_box_pack_start(GTK_BOX(left_box), label_widget,
TRUE,
TRUE, 0);
157 gtk_box_pack_start(GTK_BOX(left_box), icon_widget,
FALSE,
FALSE, 2);
158 gtk_box_pack_start(GTK_BOX(box), left_box,
TRUE,
TRUE, 0);
159 gtk_box_pack_end(GTK_BOX(box), shortcut_widget,
FALSE,
FALSE, 0);
161 gtk_container_add(GTK_CONTAINER(menu_item), box);
162 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
163 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
165 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
171 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
174 GtkWidget *menu_item = gtk_menu_item_new_with_label(
"");
175 GtkWidget *child = gtk_bin_get_child(GTK_BIN(menu_item));
176 gtk_label_set_markup(GTK_LABEL(child), label);
177 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
178 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
180 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
187 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
190 GtkWidget *menu_item = gtk_menu_item_new();
192 GtkWidget *label_widget = gtk_label_new(NULL);
193 GtkWidget *shortcut_widget = gtk_label_new(shortcut);
195 gtk_label_set_markup(GTK_LABEL(label_widget), label);
196 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
197 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
198 gtk_widget_set_hexpand(label_widget,
TRUE);
200 gtk_label_set_xalign(GTK_LABEL(shortcut_widget), 1.0f);
201 gtk_widget_set_halign(shortcut_widget, GTK_ALIGN_END);
202 gtk_style_context_add_class(gtk_widget_get_style_context(shortcut_widget),
"accelerator");
204 gtk_box_pack_start(GTK_BOX(box), label_widget,
TRUE,
TRUE, 0);
205 gtk_box_pack_end(GTK_BOX(box), shortcut_widget,
FALSE,
FALSE, 0);
206 gtk_container_add(GTK_CONTAINER(menu_item), box);
207 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
208 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
210 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
217 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
220 GtkWidget *menu_item = gtk_menu_item_new();
222 GtkWidget *image_widget = icon ? gtk_image_new_from_pixbuf(icon) : gtk_image_new();
223 GtkWidget *label_widget = gtk_label_new(NULL);
225 gtk_label_set_markup(GTK_LABEL(label_widget), label);
226 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
227 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
228 gtk_widget_set_hexpand(label_widget,
TRUE);
230 gtk_box_pack_start(GTK_BOX(box), label_widget,
TRUE,
TRUE, 0);
231 gtk_box_pack_end(GTK_BOX(box), image_widget,
FALSE,
FALSE, 0);
232 gtk_container_add(GTK_CONTAINER(menu_item), box);
233 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
234 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
236 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
243 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
245 const gboolean checked,
246 const gboolean show_checkbox)
248 GtkWidget *menu_item = gtk_check_menu_item_new();
250 GtkWidget *label_widget = gtk_label_new(NULL);
252 gtk_label_set_markup(GTK_LABEL(label_widget), label);
253 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
254 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
255 gtk_widget_set_hexpand(label_widget,
TRUE);
256 gtk_widget_set_hexpand(box,
TRUE);
257 gtk_widget_set_halign(box, GTK_ALIGN_FILL);
259 gtk_box_pack_start(GTK_BOX(box), label_widget,
TRUE,
TRUE, 0);
260 gtk_container_add(GTK_CONTAINER(menu_item), box);
261 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), checked);
263 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-inverse-item");
265 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-hide-check");
269 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-checked");
270 gtk_style_context_add_class(gtk_widget_get_style_context(label_widget),
"dt-masks-checked-label");
272 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
273 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
275 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
282 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
284 const gboolean checked,
285 const gboolean show_checkbox)
287 GtkWidget *menu_item = gtk_check_menu_item_new();
290 GtkWidget *image_widget = icon ? gtk_image_new_from_pixbuf(icon) : gtk_image_new();
291 GtkWidget *label_widget = gtk_label_new(NULL);
293 gtk_label_set_markup(GTK_LABEL(label_widget), label);
294 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
295 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
296 gtk_widget_set_hexpand(label_widget,
TRUE);
297 gtk_widget_set_hexpand(left_box,
TRUE);
298 gtk_widget_set_halign(left_box, GTK_ALIGN_FILL);
299 gtk_widget_set_hexpand(box,
TRUE);
300 gtk_widget_set_halign(box, GTK_ALIGN_FILL);
301 gtk_widget_set_halign(image_widget, GTK_ALIGN_END);
303 gtk_box_pack_start(GTK_BOX(left_box), label_widget,
TRUE,
TRUE, 0);
304 gtk_box_pack_start(GTK_BOX(box), left_box,
TRUE,
TRUE, 0);
305 gtk_box_pack_end(GTK_BOX(box), image_widget,
FALSE,
FALSE, 0);
306 gtk_container_add(GTK_CONTAINER(menu_item), box);
307 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), checked);
309 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-inverse-item");
311 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-hide-check");
315 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-checked");
316 gtk_style_context_add_class(gtk_widget_get_style_context(label_widget),
"dt-masks-checked-label");
318 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
319 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
321 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
331 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data),
332 gboolean (*checked_callback)(
GtkWidget *widget),
333 gboolean (*active_callback)(
GtkWidget *widget),
334 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
335 GdkModifierType mods, GtkAccelGroup *accel_group)
345 entry->
widget = gtk_check_menu_item_new_with_label(
"");
350 entry->
widget = gtk_menu_item_new_with_label(
"");
356 gtk_label_set_markup(GTK_LABEL(child), label);
360 g_object_set_data(G_OBJECT(entry->
widget),
"custom-data", data);
362 gtk_widget_show_all(GTK_WIDGET(entry->
widget));
364 entry->
menu = menu_index;
381 if(g_strrstr(clean_label,
"/") != NULL)
382 g_strdelimit(clean_label,
"/",
'-');
384 const gchar *parent_path = gtk_menu_get_accel_path(parent);
388 parent_path, clean_label,
389 key_val, mods,
FALSE, _(
"Triggers the action"));
392 gtk_widget_set_accel_path(entry->
widget, path, (!
IS_NULL_PTR(action_callback)) ? accel_group : NULL);
401 GtkAccelKey initial_key = { 0 };
402 if(gtk_accel_map_lookup_entry(path, &initial_key) && initial_key.accel_key)
403 gtk_accel_label_set_accel(GTK_ACCEL_LABEL(child), initial_key.accel_key,
419 *items_list = g_list_append(*items_list, entry);
455 GtkAccelKey
key = { 0 };
460 gtk_accel_label_set_accel(GTK_ACCEL_LABEL(child), 0, 0);
484 gchar *label, GtkAccelGroup *accel_group,
const char *accel_path_prefix)
487 menus[index] = gtk_menu_new();
488 gtk_menu_set_accel_group(GTK_MENU(menus[index]), accel_group);
493 assert(g_strrstr(clean_label,
"/") == NULL);
496 gtk_menu_set_accel_path(GTK_MENU(menus[index]), accel_path);
500 GtkWidget *menu_label = gtk_menu_item_new_with_mnemonic(label);
501 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_label), menus[index]);
502 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_label);
504 g_signal_connect(G_OBJECT(menu_label),
"activate", G_CALLBACK(
update_menu_entries), lists);
519 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
524 assert(g_strrstr(clean_label,
"/") == NULL);
526 gchar *accel_path =
dt_accels_build_path(gtk_menu_get_accel_path(GTK_MENU(menus[index])), clean_label);
527 gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path);
531 dt_menu_entry_t *entry =
set_menu_entry(menus, lists, label, index, GTK_MENU(menus[index]), NULL, NULL, NULL, NULL, NULL, 0, 0, accel_group);
532 gtk_menu_item_set_submenu(GTK_MENU_ITEM(entry->
widget), submenu);
533 gtk_menu_shell_append(GTK_MENU_SHELL(menus[index]), entry->
widget);
546 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
547 guint keyval, GdkModifierType mods, gpointer user_data),
548 gboolean (*checked_callback)(
GtkWidget *widget),
549 gboolean (*active_callback)(
GtkWidget *widget),
550 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
551 GdkModifierType mods, GtkAccelGroup *accel_group)
556 action_callback, checked_callback,
557 active_callback, sensitive_callback,
558 key_val, mods, accel_group);
560 gtk_menu_shell_append(GTK_MENU_SHELL(menus[index]), entry->
widget);
561 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(entry->
widget),
TRUE);
566 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval,
567 GdkModifierType mods, gpointer user_data),
568 gboolean (*checked_callback)(
GtkWidget *widget),
569 gboolean (*active_callback)(
GtkWidget *widget),
570 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val, GdkModifierType mods)
578 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
579 guint keyval, GdkModifierType mods, gpointer user_data),
580 gboolean (*checked_callback)(
GtkWidget *widget),
581 gboolean (*active_callback)(
GtkWidget *widget),
582 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
583 GdkModifierType mods)
586 sensitive_callback, key_val, mods, NULL);
591 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
592 guint keyval, GdkModifierType mods,
594 gboolean (*checked_callback)(
GtkWidget *widget),
595 gboolean (*active_callback)(
GtkWidget *widget),
596 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
597 GdkModifierType mods, GtkAccelGroup *accel_group)
601 menus, lists, label, index, GTK_MENU(gtk_menu_item_get_submenu(GTK_MENU_ITEM(parent))), data,
602 action_callback, checked_callback, active_callback, sensitive_callback, key_val, mods, accel_group);
604 gtk_menu_shell_append(GTK_MENU_SHELL(gtk_menu_item_get_submenu(GTK_MENU_ITEM(parent))), entry->
widget);
609 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval,
610 GdkModifierType mods, gpointer user_data),
611 gboolean (*checked_callback)(
GtkWidget *widget),
612 gboolean (*active_callback)(
GtkWidget *widget),
613 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val, GdkModifierType mods)
616 active_callback, sensitive_callback, key_val, mods,
dt_gui_get_accels()->global_accels);
void dt_accels_new_action_shortcut(dt_accels_t *accels, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gpointer data, GtkWidget *target_widget, GtkAccelGroup *accel_group, const gchar *action_scope, const gchar *action_name, guint key_val, GdkModifierType accel_mods, const gboolean lock, const char *description)
Register a new shortcut for a generic action, setting up its path, default keys and accel group....