64 GtkStyleContext *context = gtk_widget_get_style_context(widget);
66 gtk_style_context_get_color(context, GTK_STATE_FLAG_NORMAL, &color);
67 cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
68 cairo_set_line_width(cr, 1.2);
71 gtk_widget_get_allocation(widget, &alloc);
72 const double pad = 1.0;
73 const double w =
MAX(0.0, (
double)alloc.width - 2.0 * pad);
74 const double h =
MAX(0.0, (
double)alloc.height - 2.0 * pad);
75 const double size = fmin(w, h);
76 const double x = ((
double)alloc.width -
size) * 0.5;
77 const double y = ((
double)alloc.height -
size) * 0.5;
100 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
103 GtkWidget *menu_item = gtk_menu_item_new();
105 GtkWidget *icon_widget = gtk_drawing_area_new();
106 GtkWidget *label_widget = gtk_label_new(NULL);
108 gtk_widget_set_size_request(icon_widget, 10, 10);
109 gtk_label_set_markup(GTK_LABEL(label_widget), label);
115 g_signal_connect_data(icon_widget,
"draw", G_CALLBACK(
_menu_icon_draw), data, (GClosureNotify)g_free, 0);
118 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
119 gtk_box_pack_start(GTK_BOX(box), label_widget,
FALSE,
FALSE, 0);
120 gtk_box_pack_start(GTK_BOX(box), icon_widget,
FALSE,
FALSE, 2);
121 gtk_container_add(GTK_CONTAINER(menu_item), box);
122 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
124 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
131 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
134 GtkWidget *menu_item = gtk_menu_item_new();
137 GtkWidget *icon_widget = gtk_drawing_area_new();
138 GtkWidget *label_widget = gtk_label_new(NULL);
139 GtkWidget *shortcut_widget = gtk_label_new(shortcut);
141 gtk_widget_set_size_request(icon_widget, 10, 10);
142 gtk_label_set_markup(GTK_LABEL(label_widget), label);
143 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
144 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
145 gtk_widget_set_hexpand(label_widget,
TRUE);
151 g_signal_connect_data(icon_widget,
"draw", G_CALLBACK(
_menu_icon_draw), data, (GClosureNotify)g_free, 0);
154 gtk_label_set_xalign(GTK_LABEL(shortcut_widget), 1.0f);
155 gtk_widget_set_halign(shortcut_widget, GTK_ALIGN_END);
156 gtk_style_context_add_class(gtk_widget_get_style_context(shortcut_widget),
"accelerator");
158 gtk_box_pack_start(GTK_BOX(left_box), label_widget,
TRUE,
TRUE, 0);
159 gtk_box_pack_start(GTK_BOX(left_box), icon_widget,
FALSE,
FALSE, 2);
160 gtk_box_pack_start(GTK_BOX(box), left_box,
TRUE,
TRUE, 0);
161 gtk_box_pack_end(GTK_BOX(box), shortcut_widget,
FALSE,
FALSE, 0);
163 gtk_container_add(GTK_CONTAINER(menu_item), box);
164 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
165 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
167 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
173 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
176 GtkWidget *menu_item = gtk_menu_item_new_with_label(
"");
177 GtkWidget *child = gtk_bin_get_child(GTK_BIN(menu_item));
178 gtk_label_set_markup(GTK_LABEL(child), label);
179 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
180 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
182 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
189 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
192 GtkWidget *menu_item = gtk_menu_item_new();
194 GtkWidget *label_widget = gtk_label_new(NULL);
195 GtkWidget *shortcut_widget = gtk_label_new(shortcut);
197 gtk_label_set_markup(GTK_LABEL(label_widget), label);
198 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
199 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
200 gtk_widget_set_hexpand(label_widget,
TRUE);
202 gtk_label_set_xalign(GTK_LABEL(shortcut_widget), 1.0f);
203 gtk_widget_set_halign(shortcut_widget, GTK_ALIGN_END);
204 gtk_style_context_add_class(gtk_widget_get_style_context(shortcut_widget),
"accelerator");
206 gtk_box_pack_start(GTK_BOX(box), label_widget,
TRUE,
TRUE, 0);
207 gtk_box_pack_end(GTK_BOX(box), shortcut_widget,
FALSE,
FALSE, 0);
208 gtk_container_add(GTK_CONTAINER(menu_item), box);
209 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
210 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
212 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
219 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
222 GtkWidget *menu_item = gtk_menu_item_new();
224 GtkWidget *image_widget = icon ? gtk_image_new_from_pixbuf(icon) : gtk_image_new();
225 GtkWidget *label_widget = gtk_label_new(NULL);
227 gtk_label_set_markup(GTK_LABEL(label_widget), label);
228 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
229 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
230 gtk_widget_set_hexpand(label_widget,
TRUE);
232 gtk_box_pack_start(GTK_BOX(box), label_widget,
TRUE,
TRUE, 0);
233 gtk_box_pack_end(GTK_BOX(box), image_widget,
FALSE,
FALSE, 0);
234 gtk_container_add(GTK_CONTAINER(menu_item), box);
235 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
236 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
238 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
245 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
247 const gboolean checked,
248 const gboolean show_checkbox)
250 GtkWidget *menu_item = gtk_check_menu_item_new();
252 GtkWidget *label_widget = gtk_label_new(NULL);
254 gtk_label_set_markup(GTK_LABEL(label_widget), label);
255 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
256 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
257 gtk_widget_set_hexpand(label_widget,
TRUE);
258 gtk_widget_set_hexpand(box,
TRUE);
259 gtk_widget_set_halign(box, GTK_ALIGN_FILL);
261 gtk_box_pack_start(GTK_BOX(box), label_widget,
TRUE,
TRUE, 0);
262 gtk_container_add(GTK_CONTAINER(menu_item), box);
263 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), checked);
265 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-inverse-item");
267 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-hide-check");
271 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-checked");
272 gtk_style_context_add_class(gtk_widget_get_style_context(label_widget),
"dt-masks-checked-label");
274 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
275 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
277 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
284 void (*activate_callback)(
GtkWidget *widget, gpointer user_data),
286 const gboolean checked,
287 const gboolean show_checkbox)
289 GtkWidget *menu_item = gtk_check_menu_item_new();
292 GtkWidget *image_widget = icon ? gtk_image_new_from_pixbuf(icon) : gtk_image_new();
293 GtkWidget *label_widget = gtk_label_new(NULL);
295 gtk_label_set_markup(GTK_LABEL(label_widget), label);
296 gtk_label_set_xalign(GTK_LABEL(label_widget), 0.0f);
297 gtk_widget_set_halign(label_widget, GTK_ALIGN_START);
298 gtk_widget_set_hexpand(label_widget,
TRUE);
299 gtk_widget_set_hexpand(left_box,
TRUE);
300 gtk_widget_set_halign(left_box, GTK_ALIGN_FILL);
301 gtk_widget_set_hexpand(box,
TRUE);
302 gtk_widget_set_halign(box, GTK_ALIGN_FILL);
303 gtk_widget_set_halign(image_widget, GTK_ALIGN_END);
305 gtk_box_pack_start(GTK_BOX(left_box), label_widget,
TRUE,
TRUE, 0);
306 gtk_box_pack_start(GTK_BOX(box), left_box,
TRUE,
TRUE, 0);
307 gtk_box_pack_end(GTK_BOX(box), image_widget,
FALSE,
FALSE, 0);
308 gtk_container_add(GTK_CONTAINER(menu_item), box);
309 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), checked);
311 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-inverse-item");
313 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-hide-check");
317 gtk_style_context_add_class(gtk_widget_get_style_context(menu_item),
"dt-masks-checked");
318 gtk_style_context_add_class(gtk_widget_get_style_context(label_widget),
"dt-masks-checked-label");
320 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(menu_item),
FALSE);
321 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
323 if(activate_callback) g_signal_connect(G_OBJECT(menu_item),
"activate", G_CALLBACK(activate_callback), user_data);
333 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data),
334 gboolean (*checked_callback)(
GtkWidget *widget),
335 gboolean (*active_callback)(
GtkWidget *widget),
336 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
337 GdkModifierType mods, GtkAccelGroup *accel_group)
347 entry->
widget = gtk_check_menu_item_new_with_label(
"");
352 entry->
widget = gtk_menu_item_new_with_label(
"");
358 gtk_label_set_markup(GTK_LABEL(child), label);
362 g_object_set_data(G_OBJECT(entry->
widget),
"custom-data", data);
364 gtk_widget_show_all(GTK_WIDGET(entry->
widget));
366 entry->
menu = menu_index;
383 if(g_strrstr(clean_label,
"/") != NULL)
384 g_strdelimit(clean_label,
"/",
'-');
386 const gchar *parent_path = gtk_menu_get_accel_path(parent);
390 parent_path, clean_label,
391 key_val, mods,
FALSE, _(
"Triggers the action"));
394 gtk_widget_set_accel_path(entry->
widget, path, (!
IS_NULL_PTR(action_callback)) ? accel_group : NULL);
401 gtk_accel_label_set_accel(GTK_ACCEL_LABEL(child), key_val, mods);
408 *items_list = g_list_append(*items_list, entry);
460 gchar *label, GtkAccelGroup *accel_group,
const char *accel_path_prefix)
463 menus[index] = gtk_menu_new();
464 gtk_menu_set_accel_group(GTK_MENU(menus[index]), accel_group);
469 assert(g_strrstr(clean_label,
"/") == NULL);
472 gtk_menu_set_accel_path(GTK_MENU(menus[index]), accel_path);
476 GtkWidget *menu_label = gtk_menu_item_new_with_mnemonic(label);
477 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_label), menus[index]);
478 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_label);
480 g_signal_connect(G_OBJECT(menu_label),
"activate", G_CALLBACK(
update_menu_entries), lists);
495 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
500 assert(g_strrstr(clean_label,
"/") == NULL);
502 gchar *accel_path =
dt_accels_build_path(gtk_menu_get_accel_path(GTK_MENU(menus[index])), clean_label);
503 gtk_menu_set_accel_path(GTK_MENU(submenu), accel_path);
507 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);
508 gtk_menu_item_set_submenu(GTK_MENU_ITEM(entry->
widget), submenu);
509 gtk_menu_shell_append(GTK_MENU_SHELL(menus[index]), entry->
widget);
522 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
523 guint keyval, GdkModifierType mods, gpointer user_data),
524 gboolean (*checked_callback)(
GtkWidget *widget),
525 gboolean (*active_callback)(
GtkWidget *widget),
526 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
527 GdkModifierType mods, GtkAccelGroup *accel_group)
532 action_callback, checked_callback,
533 active_callback, sensitive_callback,
534 key_val, mods, accel_group);
536 gtk_menu_shell_append(GTK_MENU_SHELL(menus[index]), entry->
widget);
537 gtk_menu_item_set_reserve_indicator(GTK_MENU_ITEM(entry->
widget),
TRUE);
542 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval,
543 GdkModifierType mods, gpointer user_data),
544 gboolean (*checked_callback)(
GtkWidget *widget),
545 gboolean (*active_callback)(
GtkWidget *widget),
546 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val, GdkModifierType mods)
554 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
555 guint keyval, GdkModifierType mods, gpointer user_data),
556 gboolean (*checked_callback)(
GtkWidget *widget),
557 gboolean (*active_callback)(
GtkWidget *widget),
558 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
559 GdkModifierType mods)
562 sensitive_callback, key_val, mods, NULL);
567 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
568 guint keyval, GdkModifierType mods,
570 gboolean (*checked_callback)(
GtkWidget *widget),
571 gboolean (*active_callback)(
GtkWidget *widget),
572 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val,
573 GdkModifierType mods, GtkAccelGroup *accel_group)
577 menus, lists, label, index, GTK_MENU(gtk_menu_item_get_submenu(GTK_MENU_ITEM(parent))), data,
578 action_callback, checked_callback, active_callback, sensitive_callback, key_val, mods, accel_group);
580 gtk_menu_shell_append(GTK_MENU_SHELL(gtk_menu_item_get_submenu(GTK_MENU_ITEM(parent))), entry->
widget);
585 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval,
586 GdkModifierType mods, gpointer user_data),
587 gboolean (*checked_callback)(
GtkWidget *widget),
588 gboolean (*active_callback)(
GtkWidget *widget),
589 gboolean (*sensitive_callback)(
GtkWidget *widget), guint key_val, GdkModifierType mods)
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, 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....