Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
menu.h
Go to the documentation of this file.
1/*
2 This file is part of the Ansel project.
3 Copyright (C) 2023, 2025 Aurélien PIERRE.
4 Copyright (C) 2023 Luca Zulberti.
5 Copyright (C) 2026 Guillaume Stutin.
6
7 Ansel is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Ansel is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
19*/
20#include <gtk/gtk.h>
21#include <glib.h>
22
23#ifdef GDK_WINDOWING_QUARTZ
24#endif
25
26#ifndef DT_GUI_ACTIONS_MENU_H
27#define DT_GUI_ACTIONS_MENU_H
28
35
40
54
62
63
64typedef struct dt_menu_entry_t
65{
66 GtkWidget *widget; // Bounding box for the whole menu item
67 gboolean has_checkbox; // Show or hide the checkbox, aka "is the current action setting a boolean ?"
68 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data); // Callback to run when the menu item is clicked, aka the action
69 gboolean (*sensitive_callback)(GtkWidget *widget); // Callback checking some conditions to decide whether the menu item should be made insensitive in current context
70 gboolean (*checked_callback)(GtkWidget *widget); // Callback checking some conditions to determine if the boolean pref set by the item is currently TRUE or FALSE
71 gboolean (*active_callback)(GtkWidget *widget); // Callback checking some conditions to determine if the menu item is the current view
72 dt_menus_t menu; // Index of first-level menu
74 GtkAccelGroup *accel_group;
75 gchar *accel_path; // NULL if this entry has no real (accel_group-backed) shortcut.
76 // GTK has no public getter for a widget's own accel path (only
77 // gtk_widget_set_accel_path()), so update_entry() needs its own copy
78 // to look up the live GtkAccelMap entry on every menu open.
80
81
94dt_menu_entry_t *set_menu_entry(GtkWidget **menus, GList **items_list, const gchar *label, dt_menus_t menu_index,
95 GtkMenu *parent, void *data,
96 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
97 guint keyval, GdkModifierType mods, gpointer user_data),
98 gboolean (*checked_callback)(GtkWidget *widget),
99 gboolean (*active_callback)(GtkWidget *widget),
100 gboolean (*sensitive_callback)(GtkWidget *widget), guint key_val,
101 GdkModifierType mods, GtkAccelGroup *accel_group);
102
103void update_entry(dt_menu_entry_t *entry);
104void update_menu_entries(GtkWidget *widget, gpointer user_data);
105
106// Use for first-level entries in any menubar
107void add_generic_top_menu_entry(GtkWidget *menu_bar, GtkWidget **menus, GList **lists, const dt_menus_t index,
108 gchar *label, GtkAccelGroup *accel_group, const char *accel_path_prefix);
109
110
111// Use for first-level entries in the global menubar
112void add_top_menu_entry(GtkWidget *menu_bar, GtkWidget **menus, GList **lists, const dt_menus_t index,
113 gchar *label);
114
115// Special submenus entries that only open a sub-submenu
116void add_generic_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index,
117 GtkAccelGroup *accel_group);
118
119// Global menu only
120void add_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index);
121void add_generic_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index,
122 GtkAccelGroup *accel_group);
123
124void add_generic_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index,
125 void *data,
126 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
127 guint keyval, GdkModifierType mods, gpointer user_data),
128 gboolean (*checked_callback)(GtkWidget *widget),
129 gboolean (*active_callback)(GtkWidget *widget),
130 gboolean (*sensitive_callback)(GtkWidget *widget), guint key_val,
131 GdkModifierType mods, GtkAccelGroup *accel_group);
132
133void add_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index, void *data,
134 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval,
135 GdkModifierType mods, gpointer user_data),
136 gboolean (*checked_callback)(GtkWidget *widget),
137 gboolean (*active_callback)(GtkWidget *widget),
138 gboolean (*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods);
139
140void add_generic_sub_sub_menu_entry(GtkWidget **menus, GtkWidget *parent, GList **lists, const gchar *label,
141 const dt_menus_t index, void *data,
142 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
143 guint keyval, GdkModifierType mods,
144 gpointer user_data),
145 gboolean (*checked_callback)(GtkWidget *widget),
146 gboolean (*active_callback)(GtkWidget *widget),
147 gboolean (*sensitive_callback)(GtkWidget *widget), guint key_val,
148 GdkModifierType mods, GtkAccelGroup *accel_group);
149
150// add a submenu entry without a real accel, for when the key shortcut is handled in key_pressed event.
151void add_no_accel_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index,
152 void *data,
153 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable,
154 guint keyval, GdkModifierType mods, gpointer user_data),
155 gboolean (*checked_callback)(GtkWidget *widget),
156 gboolean (*active_callback)(GtkWidget *widget),
157 gboolean (*sensitive_callback)(GtkWidget *widget), guint key_val,
158 GdkModifierType mods);
159
160void add_sub_sub_menu_entry(GtkWidget **menus, GtkWidget *parent, GList **lists, const gchar *label,
161 const dt_menus_t index, void *data,
162 gboolean (*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval,
163 GdkModifierType mods, gpointer user_data),
164 gboolean (*checked_callback)(GtkWidget *widget),
165 gboolean (*active_callback)(GtkWidget *widget),
166 gboolean (*sensitive_callback)(GtkWidget *widget), guint key_val,
167 GdkModifierType mods);
168
169// We don't go further than 3 levels of menus. This is not a Dassault Systems software.
170
171void add_menu_separator(GtkWidget *menu);
172
174
175void *get_custom_data(GtkWidget *widget);
176
177GtkWidget *get_last_widget(GList **list);
178
179gboolean has_selection();
180gboolean has_active_images();
181gboolean _is_lighttable();
183
184
185void append_display(GtkWidget **menus, GList **lists, const dt_menus_t index);
186void append_edit(GtkWidget **menus, GList **lists, const dt_menus_t index);
187void append_file(GtkWidget **menus, GList **lists, const dt_menus_t index);
188void append_help(GtkWidget **menus, GList **lists, const dt_menus_t index);
189void append_image(GtkWidget **menus, GList **lists, const dt_menus_t index);
190void append_run(GtkWidget **menus, GList **lists, const dt_menus_t index);
191void append_select(GtkWidget **menus, GList **lists, const dt_menus_t index);
192void append_styles(GtkWidget **menus, GList **lists, const dt_menus_t index);
193void append_views(GtkWidget **menus, GList **lists, const dt_menus_t index);
194
195GtkWidget *ctx_gtk_menu_item_new_with_icon(const char *label, GtkWidget *menu,
196 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
197 gpointer user_data, dt_menu_icon_t icon);
198GtkWidget *ctx_gtk_menu_item_new_with_icon_and_shortcut(const char *label, const char *shortcut,
199 GtkWidget *menu,
200 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
201 gpointer user_data, dt_menu_icon_t icon);
203 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
204 gpointer user_data);
205GtkWidget *ctx_gtk_menu_item_new_with_markup_and_shortcut(const char *label, const char *shortcut,
206 GtkWidget *menu,
207 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
208 gpointer user_data);
209GtkWidget *ctx_gtk_menu_item_new_with_markup_and_pixbuf(const char *label, GdkPixbuf *icon,
210 GtkWidget *menu,
211 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
212 gpointer user_data);
214 GtkWidget *menu,
215 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
216 gpointer user_data,
217 const gboolean checked,
218 const gboolean show_checkbox);
219GtkWidget *ctx_gtk_check_menu_item_new_with_markup_and_pixbuf(const char *label, GdkPixbuf *icon,
220 GtkWidget *menu,
221 void (*activate_callback)(GtkWidget *widget, gpointer user_data),
222 gpointer user_data,
223 const gboolean checked,
224 const gboolean show_checkbox);
225
226// Helper to wrap (*void)(void) functions into GtkAccel compatible callbacks
227#define MAKE_ACCEL_WRAPPER(cb) \
228static gboolean \
229cb##__accel (GtkAccelGroup *group, \
230 GObject *acceleratable, \
231 guint keyval, \
232 GdkModifierType mods, \
233 gpointer user_data) \
234{ \
235 cb(); \
236 return TRUE; \
237}
238
239#define GET_ACCEL_WRAPPER(cb) cb##__accel
240#endif // DT_GUI_ACTIONS_MENU_H
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
gboolean has_active_image_in_lighttable()
Definition menu.c:676
GtkWidget * ctx_gtk_menu_item_new_with_icon_and_shortcut(const char *label, const char *shortcut, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data, dt_menu_icon_t icon)
Definition menu.c:127
gboolean has_selection()
Definition menu.c:653
void append_views(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition views.c:60
void append_select(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition select.c:71
void append_display(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition display.c:447
void add_sub_sub_menu_entry(GtkWidget **menus, GtkWidget *parent, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods)
Definition menu.c:607
dt_menu_entry_style_t
Definition menu.h:56
@ DT_MENU_ENTRY_LAST
Definition menu.h:60
@ DT_MENU_ENTRY_CHECKBUTTON
Definition menu.h:58
@ DT_MENU_ENTRY_DEFAULT
Definition menu.h:57
@ DT_MENU_ENTRY_RADIOBUTTON
Definition menu.h:59
dt_menu_icon_t
Definition menu.h:30
@ DT_MENU_ICON_CIRCLE
Definition menu.h:32
@ DT_MENU_ICON_NONE
Definition menu.h:31
@ DT_MENU_ICON_SQUARE
Definition menu.h:33
void add_no_accel_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods)
Definition menu.c:576
void append_help(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition help.c:245
void add_top_menu_entry(GtkWidget *menu_bar, GtkWidget **menus, GList **lists, const dt_menus_t index, gchar *label)
Definition menu.c:509
void append_image(GtkWidget **menus, GList **lists, const dt_menus_t index)
gboolean _is_lighttable()
Definition menu.c:664
GtkWidget * ctx_gtk_menu_item_new_with_markup(const char *label, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data)
Definition menu.c:170
void append_run(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition run.c:215
void add_generic_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods, GtkAccelGroup *accel_group)
Definition menu.c:544
void add_generic_sub_sub_menu_entry(GtkWidget **menus, GtkWidget *parent, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods, GtkAccelGroup *accel_group)
Definition menu.c:589
GtkWidget * ctx_gtk_check_menu_item_new_with_markup_and_pixbuf(const char *label, GdkPixbuf *icon, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data, const gboolean checked, const gboolean show_checkbox)
Definition menu.c:280
GtkWidget * ctx_gtk_check_menu_item_new_with_markup(const char *label, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data, const gboolean checked, const gboolean show_checkbox)
Definition menu.c:241
void append_styles(GtkWidget **menus, GList **lists, const dt_menus_t index)
void update_menu_entries(GtkWidget *widget, gpointer user_data)
Definition menu.c:464
dt_menu_entry_t * set_menu_entry(GtkWidget **menus, GList **items_list, const gchar *label, dt_menus_t menu_index, GtkMenu *parent, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods, GtkAccelGroup *accel_group)
Definition menu.c:327
void append_edit(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition edit.c:523
GtkWidget * get_last_widget(GList **list)
Definition menu.c:641
void add_sub_menu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index, void *data, gboolean(*action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data), gboolean(*checked_callback)(GtkWidget *widget), gboolean(*active_callback)(GtkWidget *widget), gboolean(*sensitive_callback)(GtkWidget *widget), guint key_val, GdkModifierType mods)
Definition menu.c:565
void add_sub_menu_separator(GtkWidget *parent)
Definition menu.c:628
void * get_custom_data(GtkWidget *widget)
Definition menu.c:635
GtkWidget * ctx_gtk_menu_item_new_with_icon(const char *label, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data, dt_menu_icon_t icon)
Definition menu.c:97
void add_generic_top_menu_entry(GtkWidget *menu_bar, GtkWidget **menus, GList **lists, const dt_menus_t index, gchar *label, GtkAccelGroup *accel_group, const char *accel_path_prefix)
Definition menu.c:483
GtkWidget * ctx_gtk_menu_item_new_with_markup_and_pixbuf(const char *label, GdkPixbuf *icon, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data)
Definition menu.c:215
void add_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index)
Definition menu.c:538
void add_menu_separator(GtkWidget *menu)
Definition menu.c:621
void append_file(GtkWidget **menus, GList **lists, const dt_menus_t index)
Definition file.c:392
void add_generic_top_submenu_entry(GtkWidget **menus, GList **lists, const gchar *label, const dt_menus_t index, GtkAccelGroup *accel_group)
Definition menu.c:516
dt_menus_t
Definition menu.h:42
@ DT_MENU_IMAGE
Definition menu.h:46
@ DT_MENU_FILE
Definition menu.h:43
@ DT_MENU_STYLES
Definition menu.h:47
@ DT_MENU_EDIT
Definition menu.h:44
@ DT_MENU_DISPLAY
Definition menu.h:49
@ DT_MENU_SELECTION
Definition menu.h:45
@ DT_MENU_LAST
Definition menu.h:52
@ DT_MENU_ATELIERS
Definition menu.h:50
@ DT_MENU_HELP
Definition menu.h:51
@ DT_MENU_RUN
Definition menu.h:48
GtkWidget * ctx_gtk_menu_item_new_with_markup_and_shortcut(const char *label, const char *shortcut, GtkWidget *menu, void(*activate_callback)(GtkWidget *widget, gpointer user_data), gpointer user_data)
Definition menu.c:185
void update_entry(dt_menu_entry_t *entry)
Definition menu.c:427
gboolean has_active_images()
Definition menu.c:659
Definition menu.h:65
GtkAccelGroup * accel_group
Definition menu.h:74
gboolean has_checkbox
Definition menu.h:67
dt_menu_entry_style_t style
Definition menu.h:73
gboolean(* sensitive_callback)(GtkWidget *widget)
Definition menu.h:69
gchar * accel_path
Definition menu.h:75
dt_menus_t menu
Definition menu.h:72
gboolean(* checked_callback)(GtkWidget *widget)
Definition menu.h:70
gboolean(* action_callback)(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
Definition menu.h:68
gboolean(* active_callback)(GtkWidget *widget)
Definition menu.h:71
GtkWidget * widget
Definition menu.h:66
dt_menu_icon_t shape
Definition menu.h:38