Skip to content

Commit d1238b4

Browse files
committed
migrate collection popover menu
1 parent 4024977 commit d1238b4

File tree

4 files changed

+134
-58
lines changed

4 files changed

+134
-58
lines changed

data/themes/darktable.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,22 @@ menuitem label,
875875
margin: 0;
876876
}
877877

878+
/*------------------------------------------------
879+
- Popup menu -
880+
----------------------------------------------*/
881+
popover.menu {
882+
padding: 0;
883+
}
884+
885+
popover.menu modelbutton {
886+
padding: 0.1em 0.5em;
887+
}
888+
889+
popover.menu modelbutton:hover {
890+
background-color: @selected_bg_color;
891+
}
892+
893+
878894
tooltip,
879895
#range-current
880896
{

src/gui/gtk.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4625,6 +4625,21 @@ void dt_gui_dialog_restore_size(GtkDialog *dialog, const char *conf)
46254625
g_signal_connect(dialog, "configure-event", G_CALLBACK(_resize_dialog), (gpointer)conf);
46264626
}
46274627

4628+
GtkWidget *dt_gui_popover_menu_from_model(GtkWidget *parent, GMenu *menu)
4629+
{
4630+
GtkWidget *popover_menu;
4631+
4632+
#if GTK_CHECK_VERSION(4, 0, 0)
4633+
popover_menu = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
4634+
gtk_widget_set_parent(popover_menu, parent);
4635+
#else
4636+
popover_menu = gtk_popover_new_from_model(parent, G_MENU_MODEL(menu));
4637+
#endif
4638+
4639+
return popover_menu;
4640+
}
4641+
4642+
46284643
// clang-format off
46294644
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
46304645
// vim: shiftwidth=2 expandtab tabstop=2 cindent

src/gui/gtk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,9 @@ void dt_gui_dialog_restore_size(GtkDialog *dialog, const char *conf);
637637

638638
// returns the session type at runtime
639639
dt_gui_session_type_t dt_gui_get_session_type(void);
640+
// Popover menu
641+
GtkWidget *dt_gui_popover_menu_from_model(GtkWidget *parent, GMenu *menu);
642+
640643

641644
G_END_DECLS
642645

src/libs/collect.c

Lines changed: 100 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ typedef struct dt_lib_collect_t
9696
gboolean inited;
9797

9898
GtkWidget *history_box;
99+
100+
GSimpleActionGroup *action_group;
99101
} dt_lib_collect_t;
100102

101103
typedef struct dt_lib_collect_params_rule_t
@@ -2924,9 +2926,41 @@ static gboolean entry_focus_in_callback(GtkWidget *w,
29242926
return FALSE;
29252927
}
29262928

2927-
static void menuitem_mode(GtkMenuItem *menuitem,
2928-
dt_lib_collect_rule_t *d)
2929+
static gboolean _process_variant_params(GVariant *parameter,
2930+
gpointer userdata,
2931+
dt_lib_collect_mode_t *mode,
2932+
dt_lib_collect_rule_t **d)
2933+
{
2934+
const gsize nb = g_variant_n_children(parameter);
2935+
2936+
if(nb != 2)
2937+
return FALSE;
2938+
2939+
dt_lib_collect_t *m = (dt_lib_collect_t *)userdata;
2940+
2941+
GVariant *v = g_variant_get_child_value(parameter, 0);
2942+
*mode = g_variant_get_int32(v);
2943+
g_variant_unref(v);
2944+
2945+
v = g_variant_get_child_value(parameter, 1);
2946+
const int rule_index = g_variant_get_int32(v);
2947+
g_variant_unref(v);
2948+
2949+
*d = &m->rule[rule_index];
2950+
2951+
return TRUE;
2952+
}
2953+
2954+
static void _menuitem_mode(GSimpleAction *action,
2955+
GVariant *parameter,
2956+
gpointer userdata)
29292957
{
2958+
dt_lib_collect_mode_t mode;
2959+
dt_lib_collect_rule_t *d = NULL;
2960+
2961+
if(!_process_variant_params(parameter, userdata, &mode, &d))
2962+
return;
2963+
29302964
// add next row with and operator
29312965
const int _a = dt_conf_get_int("plugins/lighttable/collect/num_rules");
29322966
const int active = CLAMP(_a, 1, MAX_RULES);
@@ -2935,8 +2969,6 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29352969
{
29362970
char confname[200] = { 0 };
29372971
snprintf(confname, sizeof(confname), "plugins/lighttable/collect/mode%1d", active);
2938-
const dt_lib_collect_mode_t mode =
2939-
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "menuitem_mode"));
29402972

29412973
dt_conf_set_int(confname, mode);
29422974
snprintf(confname, sizeof(confname), "plugins/lighttable/collect/string%1d", active);
@@ -2951,17 +2983,22 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29512983
DT_COLLECTION_PROP_UNDEF, NULL);
29522984
}
29532985

2954-
static void menuitem_mode_change(GtkMenuItem *menuitem,
2955-
dt_lib_collect_rule_t *d)
2986+
static void _menuitem_mode_change(GSimpleAction *action,
2987+
GVariant *parameter,
2988+
gpointer userdata)
29562989
{
2990+
dt_lib_collect_mode_t mode;
2991+
dt_lib_collect_rule_t *d = NULL;
2992+
2993+
if(!_process_variant_params(parameter, userdata, &mode, &d))
2994+
return;
2995+
29572996
// add next row with and operator
29582997
const int num = d->num + 1;
29592998
if(num < MAX_RULES && num > 0)
29602999
{
29613000
char confname[200] = { 0 };
29623001
snprintf(confname, sizeof(confname), "plugins/lighttable/collect/mode%1d", num);
2963-
const dt_lib_collect_mode_t mode =
2964-
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "menuitem_mode"));
29653002
dt_conf_set_int(confname, mode);
29663003
}
29673004
dt_lib_collect_t *c = get_collect(d);
@@ -3184,9 +3221,15 @@ static void _metadata_changed(gpointer instance,
31843221
}
31853222
}
31863223

3187-
static void menuitem_clear(GtkMenuItem *menuitem,
3188-
dt_lib_collect_rule_t *d)
3224+
static void _menuitem_clear(GSimpleAction *simple,
3225+
GVariant *parameter,
3226+
gpointer userdata)
31893227
{
3228+
dt_lib_collect_t *m = (dt_lib_collect_t*) userdata;
3229+
3230+
const int index = g_variant_get_int32(parameter);
3231+
dt_lib_collect_rule_t *d = &m->rule[index];
3232+
31903233
// remove this row, or if 1st, clear text entry box
31913234
const int _a = dt_conf_get_int("plugins/lighttable/collect/num_rules");
31923235
const int active = CLAMP(_a, 1, MAX_RULES);
@@ -3231,72 +3274,58 @@ static void menuitem_clear(GtkMenuItem *menuitem,
32313274
DT_COLLECTION_PROP_UNDEF, NULL);
32323275
}
32333276

3234-
static gboolean popup_button_callback(GtkWidget *widget,
3277+
static gboolean popup_button_callback(GtkWidget *button,
32353278
GdkEventButton *event,
32363279
dt_lib_collect_rule_t *d)
32373280
{
32383281
if(event->button != 1)
32393282
return FALSE;
32403283

3241-
GtkWidget *menu = gtk_menu_new();
3242-
GtkWidget *mi;
3284+
GMenu *menu = g_menu_new();
32433285
const int _a = dt_conf_get_int("plugins/lighttable/collect/num_rules");
32443286
const int active = CLAMP(_a, 1, MAX_RULES);
32453287

3246-
mi = gtk_menu_item_new_with_label(_("clear this rule"));
3247-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3248-
g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menuitem_clear), d);
3249-
3288+
gchar *action;
3289+
3290+
action = g_strdup_printf("collect.clear(%d)", d->num);
3291+
g_menu_append(menu, _("clear this rule"), action);
3292+
g_free(action);
3293+
32503294
if(d->num == active - 1)
32513295
{
3252-
mi = gtk_menu_item_new_with_label(_("narrow down search"));
3253-
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
3254-
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND));
3255-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3256-
g_signal_connect(G_OBJECT(mi), "activate",
3257-
G_CALLBACK(menuitem_mode), d);
3258-
3259-
mi = gtk_menu_item_new_with_label(_("add more images"));
3260-
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
3261-
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_OR));
3262-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3263-
g_signal_connect(G_OBJECT(mi), "activate",
3264-
G_CALLBACK(menuitem_mode), d);
3265-
3266-
mi = gtk_menu_item_new_with_label(_("exclude images"));
3267-
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
3268-
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND_NOT));
3269-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3270-
g_signal_connect(G_OBJECT(mi), "activate",
3271-
G_CALLBACK(menuitem_mode), d);
3296+
const char *fmt = "collect.mode((%d,%d))";
3297+
3298+
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND, d->num);
3299+
g_menu_append(menu, _("narrow down search"), action);
3300+
g_free(action);
3301+
3302+
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_OR, d->num);
3303+
g_menu_append(menu, _("add more images"), action);
3304+
g_free(action);
3305+
3306+
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND_NOT, d->num);
3307+
g_menu_append(menu, _("exclude images"), action);
3308+
g_free(action);
32723309
}
32733310
else if(d->num < active - 1)
32743311
{
3275-
mi = gtk_menu_item_new_with_label(_("change to: and"));
3276-
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
3277-
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND));
3278-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3279-
g_signal_connect(G_OBJECT(mi), "activate",
3280-
G_CALLBACK(menuitem_mode_change), d);
3312+
const char *fmt = "collect.modechange((%d,%d))";
32813313

3282-
mi = gtk_menu_item_new_with_label(_("change to: or"));
3283-
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
3284-
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_OR));
3285-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3286-
g_signal_connect(G_OBJECT(mi), "activate",
3287-
G_CALLBACK(menuitem_mode_change), d);
3314+
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND, d->num);
3315+
g_menu_append(menu, _("change to: and"), action);
3316+
g_free(action);
32883317

3289-
mi = gtk_menu_item_new_with_label(_("change to: except"));
3290-
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
3291-
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND_NOT));
3292-
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
3293-
g_signal_connect(G_OBJECT(mi), "activate",
3294-
G_CALLBACK(menuitem_mode_change), d);
3295-
}
3318+
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_OR, d->num);
3319+
g_menu_append(menu, _("change to: or"), action);
3320+
g_free(action);
32963321

3297-
gtk_widget_show_all(GTK_WIDGET(menu));
3322+
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND_NOT, d->num);
3323+
g_menu_append(menu, _("change to: except"), action);
3324+
g_free(action);
3325+
}
32983326

3299-
gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
3327+
GtkWidget *popover_menu = dt_gui_popover_menu_from_model(button, menu);
3328+
gtk_popover_popup(GTK_POPOVER(popover_menu));
33003329

33013330
return TRUE;
33023331
}
@@ -3654,6 +3683,17 @@ void gui_init(dt_lib_module_t *self)
36543683
self->widget = dt_gui_vbox();
36553684
dt_gui_add_class(self->widget, "dt_spacing_sw");
36563685

3686+
// setup the actions for this module
3687+
const GActionEntry entries[] = {
3688+
{ "clear", _menuitem_clear, "i" },
3689+
{ "mode", _menuitem_mode, "(ii)" },
3690+
{ "modechange", _menuitem_mode_change, "(ii)" }
3691+
};
3692+
3693+
d->action_group = g_simple_action_group_new();
3694+
g_action_map_add_action_entries(G_ACTION_MAP(d->action_group), entries, G_N_ELEMENTS(entries), d);
3695+
gtk_widget_insert_action_group(self->widget, "collect", G_ACTION_GROUP(d->action_group));
3696+
36573697
d->active_rule = 0;
36583698
d->nb_rules = 0;
36593699
d->params = (dt_lib_collect_params_t *)malloc(sizeof(dt_lib_collect_params_t));
@@ -3808,6 +3848,8 @@ void gui_cleanup(dt_lib_module_t *self)
38083848
g_object_unref(d->listfilter);
38093849
g_object_unref(d->vmonitor);
38103850

3851+
g_object_unref(d->action_group);
3852+
38113853
/* TODO: Make sure we are cleaning up all allocations */
38123854

38133855
free(self->data);

0 commit comments

Comments
 (0)