Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions data/themes/darktable.css
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,22 @@ menuitem label,
margin: 0;
}

/*------------------------------------------------
- Popup menu -
----------------------------------------------*/
popover.menu {
padding: 0;
}

popover.menu modelbutton {
padding: 0.1em 0.5em;
}

popover.menu modelbutton:hover {
background-color: @selected_bg_color;
}


tooltip,
#range-current
{
Expand Down
15 changes: 15 additions & 0 deletions src/gui/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -4636,6 +4636,21 @@ void dt_gui_dialog_restore_size(GtkDialog *dialog, const char *conf)
g_signal_connect(dialog, "configure-event", G_CALLBACK(_resize_dialog), (gpointer)conf);
}

GtkWidget *dt_gui_popover_menu_from_model(GtkWidget *parent, GMenu *menu)
{
GtkWidget *popover_menu;

#if GTK_CHECK_VERSION(4, 0, 0)
popover_menu = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
gtk_widget_set_parent(popover_menu, parent);
#else
popover_menu = gtk_popover_new_from_model(parent, G_MENU_MODEL(menu));
#endif

return popover_menu;
}


// clang-format off
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
// vim: shiftwidth=2 expandtab tabstop=2 cindent
Expand Down
3 changes: 3 additions & 0 deletions src/gui/gtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,9 @@ void dt_gui_dialog_restore_size(GtkDialog *dialog, const char *conf);

// returns the session type at runtime
dt_gui_session_type_t dt_gui_get_session_type(void);
// Popover menu
GtkWidget *dt_gui_popover_menu_from_model(GtkWidget *parent, GMenu *menu);


G_END_DECLS

Expand Down
139 changes: 81 additions & 58 deletions src/libs/collect.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ typedef struct dt_lib_collect_t
gboolean inited;

GtkWidget *history_box;

GSimpleActionGroup *action_group;
} dt_lib_collect_t;

typedef struct dt_lib_collect_params_rule_t
Expand Down Expand Up @@ -2924,9 +2926,19 @@ static gboolean entry_focus_in_callback(GtkWidget *w,
return FALSE;
}

static void menuitem_mode(GtkMenuItem *menuitem,
dt_lib_collect_rule_t *d)
static void _menuitem_mode(GSimpleAction *action,
GVariant *parameter,
gpointer userdata)
{
dt_lib_collect_t *m = (dt_lib_collect_t *)userdata;

dt_lib_collect_mode_t mode = 0;
int rule_index = 0;

g_variant_get(parameter, "(ii)", &mode, &rule_index);

dt_lib_collect_rule_t *d = &m->rule[rule_index];

// add next row with and operator
const int _a = dt_conf_get_int("plugins/lighttable/collect/num_rules");
const int active = CLAMP(_a, 1, MAX_RULES);
Expand All @@ -2935,8 +2947,6 @@ static void menuitem_mode(GtkMenuItem *menuitem,
{
char confname[200] = { 0 };
snprintf(confname, sizeof(confname), "plugins/lighttable/collect/mode%1d", active);
const dt_lib_collect_mode_t mode =
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "menuitem_mode"));

dt_conf_set_int(confname, mode);
snprintf(confname, sizeof(confname), "plugins/lighttable/collect/string%1d", active);
Expand All @@ -2951,17 +2961,25 @@ static void menuitem_mode(GtkMenuItem *menuitem,
DT_COLLECTION_PROP_UNDEF, NULL);
}

static void menuitem_mode_change(GtkMenuItem *menuitem,
dt_lib_collect_rule_t *d)
static void _menuitem_mode_change(GSimpleAction *action,
GVariant *parameter,
gpointer userdata)
{
dt_lib_collect_t *m = (dt_lib_collect_t *)userdata;

dt_lib_collect_mode_t mode = 0;
int rule_index = 0;

g_variant_get(parameter, "(ii)", &mode, &rule_index);

dt_lib_collect_rule_t *d = &m->rule[rule_index];

// add next row with and operator
const int num = d->num + 1;
if(num < MAX_RULES && num > 0)
{
char confname[200] = { 0 };
snprintf(confname, sizeof(confname), "plugins/lighttable/collect/mode%1d", num);
const dt_lib_collect_mode_t mode =
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "menuitem_mode"));
dt_conf_set_int(confname, mode);
}
dt_lib_collect_t *c = get_collect(d);
Expand Down Expand Up @@ -3184,9 +3202,15 @@ static void _metadata_changed(gpointer instance,
}
}

static void menuitem_clear(GtkMenuItem *menuitem,
dt_lib_collect_rule_t *d)
static void _menuitem_clear(GSimpleAction *simple,
GVariant *parameter,
gpointer userdata)
{
dt_lib_collect_t *m = (dt_lib_collect_t*) userdata;

const int index = g_variant_get_int32(parameter);
dt_lib_collect_rule_t *d = &m->rule[index];

// remove this row, or if 1st, clear text entry box
const int _a = dt_conf_get_int("plugins/lighttable/collect/num_rules");
const int active = CLAMP(_a, 1, MAX_RULES);
Expand Down Expand Up @@ -3231,72 +3255,58 @@ static void menuitem_clear(GtkMenuItem *menuitem,
DT_COLLECTION_PROP_UNDEF, NULL);
}

static gboolean popup_button_callback(GtkWidget *widget,
static gboolean popup_button_callback(GtkWidget *button,
GdkEventButton *event,
dt_lib_collect_rule_t *d)
{
if(event->button != 1)
return FALSE;

GtkWidget *menu = gtk_menu_new();
GtkWidget *mi;
GMenu *menu = g_menu_new();
const int _a = dt_conf_get_int("plugins/lighttable/collect/num_rules");
const int active = CLAMP(_a, 1, MAX_RULES);

mi = gtk_menu_item_new_with_label(_("clear this rule"));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menuitem_clear), d);

gchar *action;

action = g_strdup_printf("collect.clear(%d)", d->num);
g_menu_append(menu, _("clear this rule"), action);
g_free(action);

if(d->num == active - 1)
{
mi = gtk_menu_item_new_with_label(_("narrow down search"));
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate",
G_CALLBACK(menuitem_mode), d);

mi = gtk_menu_item_new_with_label(_("add more images"));
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_OR));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate",
G_CALLBACK(menuitem_mode), d);

mi = gtk_menu_item_new_with_label(_("exclude images"));
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND_NOT));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate",
G_CALLBACK(menuitem_mode), d);
const char *fmt = "collect.mode((%d,%d))";

action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND, d->num);
g_menu_append(menu, _("narrow down search"), action);
g_free(action);

action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_OR, d->num);
g_menu_append(menu, _("add more images"), action);
g_free(action);

action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND_NOT, d->num);
g_menu_append(menu, _("exclude images"), action);
g_free(action);
}
else if(d->num < active - 1)
{
mi = gtk_menu_item_new_with_label(_("change to: and"));
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate",
G_CALLBACK(menuitem_mode_change), d);
const char *fmt = "collect.modechange((%d,%d))";

mi = gtk_menu_item_new_with_label(_("change to: or"));
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_OR));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate",
G_CALLBACK(menuitem_mode_change), d);
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND, d->num);
g_menu_append(menu, _("change to: and"), action);
g_free(action);

mi = gtk_menu_item_new_with_label(_("change to: except"));
g_object_set_data(G_OBJECT(mi), "menuitem_mode",
GINT_TO_POINTER(DT_LIB_COLLECT_MODE_AND_NOT));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
g_signal_connect(G_OBJECT(mi), "activate",
G_CALLBACK(menuitem_mode_change), d);
}
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_OR, d->num);
g_menu_append(menu, _("change to: or"), action);
g_free(action);

gtk_widget_show_all(GTK_WIDGET(menu));
action = g_strdup_printf(fmt, DT_LIB_COLLECT_MODE_AND_NOT, d->num);
g_menu_append(menu, _("change to: except"), action);
g_free(action);
}

gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
GtkWidget *popover_menu = dt_gui_popover_menu_from_model(button, menu);
gtk_popover_popup(GTK_POPOVER(popover_menu));

return TRUE;
}
Expand Down Expand Up @@ -3654,6 +3664,17 @@ void gui_init(dt_lib_module_t *self)
self->widget = dt_gui_vbox();
dt_gui_add_class(self->widget, "dt_spacing_sw");

// setup the actions for this module
const GActionEntry entries[] = {
{ "clear", _menuitem_clear, "i" },
{ "mode", _menuitem_mode, "(ii)" },
{ "modechange", _menuitem_mode_change, "(ii)" }
};

d->action_group = g_simple_action_group_new();
g_action_map_add_action_entries(G_ACTION_MAP(d->action_group), entries, G_N_ELEMENTS(entries), d);
gtk_widget_insert_action_group(self->widget, "collect", G_ACTION_GROUP(d->action_group));

d->active_rule = 0;
d->nb_rules = 0;
d->params = (dt_lib_collect_params_t *)malloc(sizeof(dt_lib_collect_params_t));
Expand Down Expand Up @@ -3808,6 +3829,8 @@ void gui_cleanup(dt_lib_module_t *self)
g_object_unref(d->listfilter);
g_object_unref(d->vmonitor);

g_object_unref(d->action_group);

/* TODO: Make sure we are cleaning up all allocations */

free(self->data);
Expand Down
Loading