53#define DT_IOP_HEADER_MENU_OPEN "dt-module-header-menu-open"
54#define DT_IOP_HEADER_MENU_DISMISS_CLICK "dt-module-header-menu-dismiss-click"
56#define DT_IOP_HEADER_IGNORE_RELEASE "dt-module-header-ignore-release"
60 GdkModifierType modifier, gpointer data);
62 GdkModifierType modifier, gpointer data);
75#ifdef GDK_WINDOWING_QUARTZ
95 gboolean *field = (gboolean*)(data->
param);
97 gboolean previous = *field;
98 *field = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton));
100 if(*field != previous)
122 size_t param_index = 0;
123 gboolean skip_label =
FALSE;
125 const size_t param_length = strlen(
param) + 1;
126 char *param_name = g_malloc(param_length);
127 char *base_name = g_malloc(param_length);
128 if(sscanf(
param,
"%[^[][%" G_GSIZE_FORMAT
"]", base_name, ¶m_index) == 2)
130 sprintf(param_name,
"%s[0]", base_name);
135 memcpy(param_name,
param, param_length);
148 const float min =
f->Float.Min;
149 const float max =
f->Float.Max;
150 offset =
f->header.offset + param_index *
sizeof(float);
151 const float defval = *(
float*)((uint8_t *)
d + offset);
154 const int digits =
MAX(2, -floorf(log10f(
top/100)+.1));
160 const int min =
f->Int.Min;
161 const int max =
f->Int.Max;
162 offset =
f->header.offset + param_index *
sizeof(int);
163 const int defval = *(
int*)((uint8_t *)
d + offset);
169 const unsigned short min =
f->UShort.Min;
170 const unsigned short max =
f->UShort.Max;
171 offset =
f->header.offset + param_index *
sizeof(
unsigned short);
172 const unsigned short defval = *(
unsigned short*)((uint8_t *)
d + offset);
185 if (*
f->header.description)
203 gchar *str = g_strdup_printf(
"'%s' is not a float/int/unsigned short/slider parameter", param_name);
237 if (*
f->header.description)
263 if(*iter->description)
270 str = g_strdup_printf(
"'%s' is not an enum/int/bool/combobox parameter",
param);
298 str = *
f->header.description
299 ? g_strdup(
f->header.description)
302 GtkWidget *label = gtk_label_new(_(str));
303 gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
304 button = gtk_check_button_new();
305 gtk_container_add(GTK_CONTAINER(button), label);
307 module_param->module = self;
308 module_param->
param = (uint8_t *)
p +
f->header.offset;
309 g_signal_connect_data(G_OBJECT(button),
"toggled", G_CALLBACK(
_iop_toggle_callback), module_param, (GClosureNotify)g_free, 0);
313 str = g_strdup_printf(
"'%s' is not a bool/togglebutton parameter",
param);
315 button = gtk_check_button_new_with_label(str);
328 GCallback callback, gboolean local, guint accel_key, GdkModifierType mods,
332 g_signal_connect(G_OBJECT(w),
"button-press-event", callback, self);
335 gtk_widget_set_tooltip_text(w, _(label));
338 gchar *
tooltip = g_strdup_printf(_(
"%s\nctrl+click to %s"), _(label), _(ctrl_label));
339 gtk_widget_set_tooltip_text(w,
tooltip);
345 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
FALSE);
346 if(GTK_IS_BOX(box)) gtk_box_pack_end(GTK_BOX(box), w,
FALSE,
FALSE, 0);
352 const gchar *ctrl_label, GCallback callback, gboolean local,
353 guint accel_key, GdkModifierType mods,
357 g_signal_connect(G_OBJECT(w),
"button-press-event", callback, self);
360 gtk_widget_set_tooltip_text(w, _(label));
363 gchar *
tooltip = g_strdup_printf(_(
"%s\nctrl+click to %s"), _(label), _(ctrl_label));
364 gtk_widget_set_tooltip_text(w,
tooltip);
368 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
FALSE);
369 if(GTK_IS_BOX(box)) gtk_box_pack_end(GTK_BOX(box), w,
FALSE,
FALSE, 0);
375 GCallback callback, gboolean local, guint accel_key, GdkModifierType mods,
383 gtk_widget_set_tooltip_text(button, _(label));
387 button = gtk_button_new_with_label(_(label));
388 gtk_label_set_ellipsize(GTK_LABEL(gtk_bin_get_child(GTK_BIN(button))), PANGO_ELLIPSIZE_END);
392 g_signal_connect(G_OBJECT(button),
"clicked", callback, (gpointer)self);
394 if(GTK_IS_BOX(box)) gtk_box_pack_start(GTK_BOX(box), button,
TRUE,
TRUE, 0);
402 return up ? !mask_down : mask_down;
423 module->op, (
void *)picker, (
void *)
pipe,
piece ?
piece->global_hash : 0);
426 &&
module->color_picker_apply)
427 module->color_picker_apply(module, picker, pipe, (dt_dev_pixelpipe_iop_t *)piece);
435 return module->color_picker_apply || (module->flags() & IOP_FLAGS_SUPPORTS_BLENDING);
444 GList *modules =
module->dev->iop;
460 modules = g_list_next(modules);
464 if(module->module_will_remove && !module->module_will_remove(module))
return;
469 const gboolean is_zero = (
module->multi_priority == 0);
503 if(!hist || !hist->module)
505 history = g_list_next(history);
508 if(hist->module->instance == module->
instance && hist->module != module)
510 first = hist->module;
513 history = g_list_next(history);
521 for(history = dev->
history; history; history = g_list_next(history))
549 GtkWidget *expander =
module->gui ? module->gui->expander : NULL;
550 return (expander && gtk_widget_is_visible(expander) && !
dt_iop_is_hidden(module));
556 for(GList *modules = g_list_first(module->
dev->
iop); modules; modules = g_list_next(modules))
570 for(GList *modules = g_list_last(module->
dev->
iop); modules; modules = g_list_previous(modules))
607 memcpy(module->params, base->
params, module->params_size);
613 module->blend_params->mask_id = 0;
624 if(module->dev->gui_attached)
673 return G_SOURCE_REMOVE;
697 if(event->type == GDK_FOCUS_CHANGE ||
key == GDK_KEY_Return)
699 if(gtk_entry_get_text_length(GTK_ENTRY(entry)) > 0)
703 const gchar *
name = gtk_entry_get_text(GTK_ENTRY(entry));
706 module->multi_name[0] = module->multi_name[sizeof(module->multi_name) - 1];
707 module->multi_name[sizeof(module->multi_name) - 1] = 0;
718 module->multi_name[0] = 0;
724 else if(
key == GDK_KEY_Escape)
727 module->multi_name[0] = module->multi_name[sizeof(module->multi_name) - 1];
728 module->multi_name[sizeof(module->multi_name) - 1] = 0;
736 gtk_widget_destroy(entry);
751 pango_layout_get_pixel_size(gtk_entry_get_layout(GTK_ENTRY(entry)), &
width, NULL);
754 GtkStyleContext *context = gtk_widget_get_style_context(entry);
755 const GtkStateFlags
state = gtk_widget_get_state_flags(entry);
756 gtk_style_context_get_padding(context,
state, &padding);
757 gtk_style_context_get_border(context,
state, &border);
758 gtk_widget_set_size_request(entry,
width + padding.left + padding.right
759 + border.left + border.right + 1, -1);
768 GtkWidget *focused = gtk_container_get_focus_child(GTK_CONTAINER(module->
gui->
header));
769 if(focused && GTK_IS_ENTRY(focused))
return;
774 gtk_widget_set_name(entry,
"iop-panel-label");
775 gtk_entry_set_width_chars(GTK_ENTRY(entry), 0);
776 gtk_entry_set_max_length(GTK_ENTRY(entry),
sizeof(module->
multi_name) - 1);
777 gtk_entry_set_text(GTK_ENTRY(entry), module->
multi_name);
780 module->multi_name[sizeof(module->multi_name) - 1] = module->multi_name[0];
781 module->multi_name[0] = 0;
784 gtk_widget_add_events(entry, GDK_FOCUS_CHANGE_MASK);
791 gtk_widget_show(entry);
792 gtk_widget_grab_focus(entry);
802 GtkWidget *expander = GTK_WIDGET(user_data);
803 if(GTK_IS_WIDGET(expander))
806 g_object_unref(expander);
807 return G_SOURCE_REMOVE;
812 GtkWidget *expander = GTK_WIDGET(user_data);
813 if(!GTK_IS_WIDGET(expander))
return;
840 GtkMenuShell *menu = GTK_MENU_SHELL(gtk_menu_new());
843 item = gtk_menu_item_new_with_label(_(
"new instance"));
846 gtk_widget_set_sensitive(item, module->gui->multi_show_new);
847 gtk_menu_shell_append(menu, item);
849 item = gtk_menu_item_new_with_label(_(
"duplicate instance"));
852 gtk_widget_set_sensitive(item, module->gui->multi_show_new);
853 gtk_menu_shell_append(menu, item);
855 item = gtk_menu_item_new_with_label(_(
"delete"));
858 gtk_widget_set_sensitive(item, module->gui->multi_show_close);
859 gtk_menu_shell_append(menu, item);
861 gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
863 item = gtk_menu_item_new_with_label(_(
"rename"));
865 gtk_menu_shell_append(menu, item);
870 g_signal_connect_data(G_OBJECT(menu),
"deactivate",
872 g_object_ref(module->gui->expander), (GClosureNotify)g_object_unref, 0);
875 dt_gui_menu_popup(GTK_MENU(menu), GTK_WIDGET(button), GDK_GRAVITY_SOUTH_EAST, GDK_GRAVITY_NORTH_EAST);
888 if(gtk_toggle_button_get_active(togglebutton))
900 if(module->dev->proxy.chroma_adaptation == module)
901 module->dev->proxy.chroma_adaptation = NULL;
909 snprintf(
tooltip,
sizeof(
tooltip), module->enabled ? _(
"%s is switched on") : _(
"%s is switched off"),
912 gtk_widget_set_tooltip_text(GTK_WIDGET(togglebutton),
tooltip);
913 gtk_widget_queue_draw(GTK_WIDGET(togglebutton));
927 lab = gtk_bin_get_child(GTK_BIN(lab));
928 gtk_widget_set_name(lab,
"iop-panel-label");
932 gtk_label_set_markup_with_mnemonic(GTK_LABEL(lab), module_name);
936 if(!g_strcmp0(module_name, gtk_label_get_text(GTK_LABEL(lab))) || module->
multi_name[0] ==
'\0')
952 const char *instance = (
module->multi_name[0] != '\0') ? module->multi_name : "0";
961 gtk_label_set_ellipsize(GTK_LABEL(lab), !module->
multi_name[0] ? PANGO_ELLIPSIZE_END: PANGO_ELLIPSIZE_MIDDLE);
962 g_object_set(G_OBJECT(lab),
"xalign", 0.0, (gchar *)0);
1000 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->
gui->
off), module->
enabled);
1002 gtk_widget_set_sensitive(GTK_WIDGET(module->
gui->
off),
FALSE);
1004 gtk_widget_set_sensitive(GTK_WIDGET(module->
gui->
off),
TRUE);
1011 module->
enabled ?
"dt_iop_enable_forced_on" :
"dt_iop_enable_forced_off");
1022 if(
IS_NULL_PTR(module->
gui))
module->gui = (dt_iop_module_gui_t *)calloc(1, sizeof(dt_iop_module_gui_t));
1038 const gchar *
const main_scope = _(
"Darkroom/Modules");
1042 _(
"Focuses the module"));
1049 _(
"Enables the module"));
1055 if(module->gui_init)
module->gui_init(module);
1077 if(module->gui->header == (
GtkWidget *)where_the_object_was)
module->gui->header = NULL;
1078 if(module->gui->expander == (
GtkWidget *)where_the_object_was)
module->gui->expander = NULL;
1095 if(!
IS_NULL_PTR(module->
dev) &&
module->dev->gui_module == module) module->dev->gui_module = NULL;
1099 while(g_idle_remove_by_data(module->
gui->
widget));
1119 g_list_free(
m->widget_list);
1120 m->widget_list = NULL;
1121 g_list_free(
m->widget_list_bh);
1122 m->widget_list_bh = NULL;
1135 module->gui_cleanup(module);
1154 GtkWidget *expander =
module->gui->expander;
1155 g_object_ref_sink(expander);
1156 gtk_widget_destroy(expander);
1157 g_object_unref(expander);
1163 GtkWidget *header =
module->gui->header;
1164 g_object_ref_sink(header);
1165 gtk_widget_destroy(header);
1166 g_object_unref(header);
1171 GtkWidget *widget =
module->gui->widget;
1172 g_object_ref_sink(widget);
1173 gtk_widget_destroy(widget);
1174 g_object_unref(widget);
1178 module->gui->widget = NULL;
1179 module->gui->header = NULL;
1180 module->gui->expander = NULL;
1181 module->gui->off = NULL;
1196 if(module->
params && module->gui_update)
1197 module->gui_update(module);
1210 const gboolean disabled = !
module->default_enabled && module->hide_enable_button;
1211 if(disabled)
return FALSE;
1253 const gboolean disabled = !
module->default_enabled && module->hide_enable_button;
1254 if(disabled)
return;
1262 g_signal_connect_data(G_OBJECT(
dt_gui_get_global()->presets_popup_menu),
"deactivate",
1264 g_object_ref(module->
gui->
expander), (GClosureNotify)g_object_unref, 0);
1280 const gboolean scroll_new_instance_to_header
1282 && !IS_NULL_PTR(module->gui->header) && GTK_IS_WIDGET(module->gui->header));
1287 if(out_focus_module)
1291 if(scroll_focus && out_focus_widget && gtk_widget_is_ancestor(scroll_focus, out_focus_widget))
1294 gtk_widget_queue_draw(scroll_focus);
1297 if(out_focus_module->gui_focus)
1298 out_focus_module->gui_focus(out_focus_module,
FALSE);
1338 if(module->gui_focus)
module->gui_focus(module, TRUE);
1351 GList *first_child = g_list_first(widget_list);
1355 if(widget) gtk_widget_grab_focus(widget);
1385 module->gui->expanded = expanded;
1415 snprintf(var,
sizeof(var),
"plugins/darkroom/%s/expanded", module->
op);
1422 for(GList *iop = g_list_first(
dt_dev_get_global()->iop); iop; iop = g_list_next(iop))
1429 if(dim &&
m != module)
1441 for(GList *iop = g_list_first(module->
dev->
iop); iop; iop = g_list_next(iop))
1450 gtk_widget_queue_draw(module->
gui->
widget);
1457 const gboolean expanded =
module->gui->expanded;
1470 gboolean handled =
FALSE;
1477 else if(e->button == 3)
1489 return module->focus(module, TRUE);
1495 if(module && module->gui->expander)
1496 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-header-child-click", GINT_TO_POINTER(
TRUE));
1502 GdkModifierType modifier, gpointer data)
1506 if(
IS_NULL_PTR(module) || !
module->focus) return FALSE;
1510 if(iop->gui->expander)
1511 g_object_set_data(G_OBJECT(iop->gui->expander),
"dt-modulegroups-switch-from-active-once",
1512 GINT_TO_POINTER(
TRUE));
1514 return module->focus(module, FALSE);
1518 GdkModifierType modifier, gpointer data)
1526 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-modulegroups-prefer-active-once",
1527 GINT_TO_POINTER(
TRUE));
1532 if(!module->hide_enable_button)
1534 module->enabled = TRUE;
1545 if(e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS)
return TRUE;
1564 if(module->gui->expander) g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-dragged", NULL);
1572 if(module->gui->expander)
1578 else if(e->button == 3)
1589 if(e->button != 1 || e->type != GDK_BUTTON_RELEASE)
return FALSE;
1606 if(g_object_get_data(G_OBJECT(module->gui->expander),
"dt-module-header-child-click"))
1608 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-header-child-click", NULL);
1612 if(g_object_get_data(G_OBJECT(module->gui->expander),
"dt-module-dragged"))
1614 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-dragged", NULL);
1630 const gboolean is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bt));
1633 module->request_mask_display
1634 &= ~(DT_DEV_PIXELPIPE_DISPLAY_MASK | DT_DEV_PIXELPIPE_DISPLAY_CHANNEL
1635 | DT_DEV_PIXELPIPE_DISPLAY_ANY | DT_DEV_PIXELPIPE_DISPLAY_STICKY);
1638 module->request_mask_display |= DT_DEV_PIXELPIPE_DISPLAY_MASK;
1644 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bd->
showmask), is_active);
1658 gboolean *drawn_used, gboolean *parametric_used)
1669 gboolean raster =
FALSE;
1670 gboolean drawn =
FALSE;
1671 gboolean parametric =
FALSE;
1678 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bd->
raster_enable)))
1682 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bd->
masks_enable)))
1686 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bd->
blendif_enable)))
1690 if(!
IS_NULL_PTR(raster_used)) *raster_used = raster;
1692 if(!
IS_NULL_PTR(parametric_used)) *parametric_used = parametric;
1706 gchar *
type = _(
"unknown mask");
1708 gboolean top_enabled =
FALSE, raster_used =
FALSE, drawn_used =
FALSE, parametric_used =
FALSE;
1710 if(!top_enabled)
return FALSE;
1712 if(drawn_used && parametric_used)
1713 type=_(
"drawn + parametric mask");
1715 type=_(
"drawn mask");
1716 else if(parametric_used)
1717 type=_(
"parametric mask");
1718 else if(raster_used)
1719 type=_(
"raster mask");
1722 gchar *part1 = g_strdup_printf(_(
"this module has a '%s'"),
type);
1723 gchar *part2 = NULL;
1727 part2 = g_strdup_printf(_(
"taken from module %s"), source);
1733 gchar *details = g_strdup_printf(
"%s\n%s", part2, _(
"click to display (module must be activated first)"));
1739 part2 = g_strdup(_(
"click to display (module must be activated first)"));
1743 text = g_strconcat(part1,
"\n", part2, NULL);
1745 text = g_strdup(part1);
1747 gtk_tooltip_set_text(
tooltip, text);
1760 const gboolean support_blending = (
module->flags() & IOP_FLAGS_SUPPORTS_BLENDING) == IOP_FLAGS_SUPPORTS_BLENDING;
1770 gboolean top_enabled =
FALSE, raster_used =
FALSE, drawn_used =
FALSE, parametric_used =
FALSE;
1773 const gboolean use_masks = top_enabled && (raster_used || drawn_used || parametric_used);
1781 GtkTooltip *
tooltip, gpointer user_data)
1785 const char **des =
module->description(module);
1791 gtk_grid_set_column_homogeneous(GTK_GRID(grid),
FALSE);
1793 gtk_widget_set_hexpand(grid,
FALSE);
1795 GtkWidget *label = gtk_label_new(des[0] ? des[0] :
"");
1796 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1797 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1798 gtk_label_set_max_width_chars(GTK_LABEL(label), 40);
1801 gtk_box_pack_start(GTK_BOX(vbox), label,
FALSE,
FALSE, 0);
1807 const char *icon_purpose =
"\342\237\263";
1808 const char *icon_input =
"\342\207\245";
1809 const char *icon_process =
"\342\237\264";
1810 const char *icon_output =
"\342\206\246";
1812 const char *icons[4] = {icon_purpose, icon_input, icon_process, icon_output};
1813 const char *ilabs[4] = {_(
"Purpose"), _(
"Input"), _(
"Process"), _(
"Output")};
1815 for(
int k=1;
k<5;
k++)
1819 label = gtk_label_new(icons[
k-1]);
1820 gtk_widget_set_halign(label, GTK_ALIGN_START);
1821 gtk_grid_attach(GTK_GRID(grid), label, 0,
k, 1, 1);
1822 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1824 label = gtk_label_new(ilabs[
k-1]);
1825 gtk_widget_set_halign(label, GTK_ALIGN_START);
1826 gtk_grid_attach(GTK_GRID(grid), label, 1,
k, 1, 1);
1827 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1829 label = gtk_label_new(
":");
1830 gtk_widget_set_halign(label, GTK_ALIGN_START);
1831 gtk_grid_attach(GTK_GRID(grid), label, 2,
k, 1, 1);
1832 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1834 label = gtk_label_new(des[
k]);
1835 gtk_widget_set_halign(label, GTK_ALIGN_START);
1836 gtk_grid_attach(GTK_GRID(grid), label, 3,
k, 1, 1);
1837 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1841 gtk_box_pack_start(GTK_BOX(vbox), grid,
FALSE,
FALSE, 0);
1842 gtk_widget_show_all(vbox);
1843 gtk_tooltip_set_custom(
tooltip, vbox);
1851 gtk_widget_set_name(GTK_WIDGET(header),
"module-header");
1864 module->gui->header = header;
1870 gtk_widget_add_events(header_evb, GDK_POINTER_MOTION_MASK);
1874 gtk_widget_add_events(body_evb, GDK_POINTER_MOTION_MASK);
1882 char w_name[256] = { 0 };
1883 snprintf(w_name,
sizeof(w_name),
"iop-panel-icon-%s", module->
op);
1890 GtkWidget *label = gtk_label_new_with_mnemonic(
"");
1891 gtk_container_add(GTK_CONTAINER(lab), label);
1892 gtk_label_set_mnemonic_widget(GTK_LABEL(label), header_evb);
1895 gtk_widget_set_tooltip_text(lab, module->deprecated_msg());
1898 gtk_widget_set_name(lab,
"iop_description");
1911 module->gui->mask_indicator = hw[IOP_MODULE_MASK];
1915 module->gui->multimenu_button = GTK_WIDGET(hw[IOP_MODULE_INSTANCE]);
1917 _(
"multiple instance actions\nright-click creates new instance"));
1927 module->gui->reset_button = GTK_WIDGET(hw[IOP_MODULE_RESET]);
1928 gtk_widget_set_tooltip_text(GTK_WIDGET(hw[
IOP_MODULE_RESET]), _(
"reset parameters\nctrl+click to reapply any automatic presets"));
1935 module->gui->presets_button = GTK_WIDGET(hw[IOP_MODULE_PRESETS]);
1937 gtk_widget_set_tooltip_text(GTK_WIDGET(hw[
IOP_MODULE_PRESETS]), _(
"presets\nright-click to apply on new instance"));
1947 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(switch_button), module->
enabled);
1948 g_signal_connect(G_OBJECT(switch_button),
"button-press-event",
1950 g_signal_connect(G_OBJECT(switch_button),
"toggled", G_CALLBACK(
_gui_off_callback), module);
1952 module->gui->off = switch_button;
1971 gtk_box_pack_start(GTK_BOX(header), hw[
i],
FALSE,
FALSE, 0);
1976 gtk_box_pack_end(GTK_BOX(header), hw[
i],
FALSE,
FALSE, 0);
1987 if(module->deprecated_msg())
1989 GtkWidget *lb = gtk_label_new(module->deprecated_msg());
1990 gtk_label_set_line_wrap(GTK_LABEL(lb),
TRUE);
1991 gtk_label_set_xalign(GTK_LABEL(lb), 0.0);
1993 gtk_box_pack_start(GTK_BOX(iopw), lb,
TRUE,
TRUE, 0);
1994 gtk_widget_show(lb);
2002 gtk_widget_hide(iopw);
2004 module->gui->expander = expander;
2036 if(module->gui_changed)
module->gui_changed(module, widget, data);
2042 if(!
IS_NULL_PTR(widget) && g_object_get_data(G_OBJECT(widget),
"dt-blendop-header-update"))
2053 for(GList *w = g_list_first(
m->widget_list_bh); w; w = g_list_next(w))
2074 fprintf(stderr,
"[dt_bauhaus_update_module] unsupported slider data type\n");
2093 fprintf(stderr,
"[dt_bauhaus_update_module] unsupported combo data type\n");
2097 fprintf(stderr,
"[dt_bauhaus_update_module] invalid bauhaus widget type encountered\n");
2117 float *
f = w->
field, prevf = *
f; *
f = val;
2123 int *
i = w->
field, previ = *
i; *
i = val;
2129 unsigned short *s = w->
field, prevs = *s; *s = val;
2134 fprintf(stderr,
"[_bauhaus_slider_value_change] unsupported slider data type\n");
2148 int *e = w->
field, preve = *e; *e = GPOINTER_TO_INT(entry->
data);
2155 int *
i = w->
field, previ = *
i; *
i =
d->active;
2161 unsigned int *u = w->
field, prevu = *u; *u =
d->active;
2167 gboolean *b = w->
field, prevb = *b; *b =
d->active;
2172 fprintf(stderr,
"[_bauhaus_combobox_set] unsupported combo data type\n");
2177 fprintf(stderr,
"[dt_bauhaus_value_changed_default_callback] invalid bauhaus widget type encountered for %s %s: %i\n", w->
label, w->module->name, w->
type);
2195 return module && module->gui ? module->gui->off : NULL;
2200 return module->gui && (module->gui->expander == (const void *)target || module->gui->header == (const void *)target);
2222 memcpy(((
char *)
d->module->params) +
d->offset, ((
char *)
d->module->default_params) +
d->offset,
d->size);
2223 if(
d->module->gui_update)
d->module->gui_update(
d->module);
2235 d->size = param_size;
2238 (GClosureNotify)g_free, 0);
void dt_accels_remove_shortcut(dt_accels_t *accels, const char *path)
Remove the shortcut object identified by path and all its accels.
void dt_accels_new_virtual_instance_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)
gchar * dt_accels_build_path(const gchar *scope, const gchar *feature)
Build the accel path of feature under scope.
void dt_accels_remove_accel(dt_accels_t *accels, const char *path, gpointer data)
Recursively remove all accels for all shortcuts containing path. This is unneeded for accels attached...
void dt_accels_disconnect_on_text_input(GtkWidget *widget)
Disconnect accels while a text or search entry has the focus, and reconnect them when it loses it....
Handle default and user-set shortcuts (accelerators)
#define dt_accels_new_darkroom_action(a, b, w, c, d, e, f, g)
struct dt_accels_t * dt_gui_get_accels(void)
struct dt_ui_t * dt_gui_get_ui(void)
void dt_gui_add_help_link(GtkWidget *widget, char *link)
void dt_gui_refocus_center()
void dt_ui_container_focus_widget(dt_ui_t *ui, const dt_ui_container_t c, GtkWidget *w)
gives a widget focus in the container
GtkWidget * dt_bauhaus_slider_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
float dt_bauhaus_slider_get(GtkWidget *widget)
gboolean dt_bauhaus_combobox_set_from_value(GtkWidget *widget, int value)
GtkWidget * dt_bauhaus_slider_new_with_range_and_feedback(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits, int feedback)
void dt_bauhaus_widget_set_field(GtkWidget *widget, gpointer field, dt_introspection_type_t field_type)
void dt_bauhaus_combobox_add_full(GtkWidget *widget, const char *text, dt_bauhaus_combobox_alignment_t align, gpointer data, void(free_func)(void *data), gboolean sensitive)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
@ DT_BAUHAUS_COMBOBOX_ALIGN_RIGHT
#define DT_BAUHAUS_WIDGET(obj)
void dt_develop_blend_get_mask_usage(const dt_iop_module_t *module, const dt_develop_blend_params_t *params, gboolean *top_enabled, gboolean *raster_used, gboolean *drawn_used, gboolean *parametric_used)
void dt_iop_gui_init_blending(dt_iop_module_t *module)
void dt_iop_gui_update_blending(dt_iop_module_t *module)
void dt_iop_gui_blending_lose_focus(dt_iop_module_t *module)
void dt_iop_gui_cleanup_blending(dt_iop_module_t *module)
The blending panel's GUI state and API, cut out of develop/blend.h.
gboolean blend_color_picker_apply(dt_iop_module_t *module, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
dt_collection_t * dt_collection_get_global(void)
void dt_collection_hint_message(const dt_collection_t *collection)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
int dt_iop_color_picker_get_ready_data(const dt_iop_module_t *module, GtkWidget **picker, dt_dev_pixelpipe_t **pipe, const dt_dev_pixelpipe_iop_t **piece)
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
static const float const float const float min
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
GtkWidget * dt_gui_container_nth_child(GtkContainer *container, int which)
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
#define dt_control_queue_cursor(cursor)
struct dt_develop_t * dt_dev_get_global(void)
struct dt_gui_gtk_t * dt_gui_get_global(void)
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
void dt_dev_write_history(dt_develop_t *dev, gboolean async)
Thread-safe wrapper around dt_dev_write_history_ext() for dev->image_storage.id.
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_dev_history_flush_pending_commits(struct dt_develop_t *dev)
Run every history commit still queued for dev, now.
#define dt_dev_pixelpipe_rebuild_all(dev)
#define dt_dev_pixelpipe_update_history_main(dev)
void dt_dev_modulegroups_switch_tab(dt_develop_t *dev, dt_iop_module_t *module)
void dt_dev_module_remove(dt_develop_t *dev, dt_iop_module_t *module)
void dt_dev_undo_start_record(dt_develop_t *dev)
gchar * dt_history_item_get_label(const struct dt_iop_module_t *module)
void dt_dev_undo_end_record(dt_develop_t *dev)
gchar * dt_history_item_get_name(const struct dt_iop_module_t *module)
@ DT_DEV_PIXELPIPE_DISPLAY_NONE
static int dt_pthread_mutex_BAD_lock(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_BAD_unlock(dt_pthread_mutex_t *mutex)
GtkWidget * dtgtk_expander_get_header_event_box(GtkDarktableExpander *expander)
GtkWidget * dtgtk_expander_get_body_event_box(GtkDarktableExpander *expander)
GtkWidget * dtgtk_expander_get_frame(GtkDarktableExpander *expander)
GtkWidget * dtgtk_expander_get_body(GtkDarktableExpander *expander)
void dtgtk_expander_set_expanded(GtkDarktableExpander *expander, gboolean expanded)
GtkWidget * dtgtk_expander_new(GtkWidget *header, GtkWidget *body)
#define DTGTK_EXPANDER(obj)
static guint dt_keys_mainpad_alternatives(const guint key_val)
Remap keypad keys to usual mainpad ones.
gboolean dt_gui_presets_autoapply_for_module(dt_iop_module_t *module)
void dt_gui_presets_popup_menu_show_for_module(dt_iop_module_t *module)
Everything the history, styles and presets code says to the outside world: messages for the user,...
void dt_iop_reload_defaults(dt_iop_module_t *module)
void dt_iop_commit_blend_params(dt_iop_module_t *module, const dt_develop_blend_params_t *blendop_params)
void dt_iop_gui_reset(dt_iop_module_t *module)
gboolean dt_iop_is_hidden(dt_iop_module_t *module)
void dt_iop_set_cache_bypass(dt_iop_module_t *module, gboolean state)
void dt_iop_update_multi_priority(dt_iop_module_t *module, int new_priority)
@ IOP_FLAGS_SUPPORTS_BLENDING
static gboolean _iop_plugin_enable_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType modifier, gpointer data)
GtkWidget * dt_iop_togglebutton_new_no_register(dt_iop_module_t *self, const char *section, const gchar *label, const gchar *ctrl_label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, GtkWidget *box)
static gboolean _gui_multiinstance_callback(GtkButton *button, GdkEventButton *event, gpointer user_data)
void dt_iop_gui_cleanup_module(dt_iop_module_t *module)
static gboolean _iop_plugin_header_button_release(GtkWidget *w, GdkEventButton *e, gpointer user_data)
GtkWidget * dt_iop_gui_get_pluginui(dt_iop_module_t *module)
static void _iop_plugin_header_menu_deactivate(GtkWidget *menu, gpointer user_data)
void dt_iop_add_remove_mask_indicator(dt_iop_module_t *module)
GtkWidget * dt_iop_button_new(dt_iop_module_t *self, const gchar *label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, gint paintflags, GtkWidget *box)
void dt_iop_gui_set_expander(dt_iop_module_t *module)
dt_iop_module_t * dt_iop_gui_get_next_visible_module(dt_iop_module_t *module)
static gboolean _rename_module_key_press(GtkWidget *entry, GdkEventKey *event, dt_iop_module_t *module)
static gboolean _iop_plugin_header_activate(GtkWidget *self, gboolean group_cycling, gpointer user_data)
static void _iop_panel_label(dt_iop_module_t *module)
void dt_iop_gui_init(dt_iop_module_t *module)
static gboolean _iop_plugin_focus_accel(GtkAccelGroup *accel_group, GObject *accelerable, guint keyval, GdkModifierType modifier, gpointer data)
void dt_iop_gui_update(dt_iop_module_t *module)
void dt_bauhaus_update_module(dt_iop_module_t *self)
GtkWidget * dt_iop_gui_reset_label_new(const gchar *label, dt_iop_module_t *module, void *param, int param_size)
void dt_iop_gui_leave_critical_section(dt_iop_module_t *const module)
Release what dt_iop_gui_enter_critical_section() took. Also a no-op headless.
static void _display_mask_indicator_callback(GtkToggleButton *bt, dt_iop_module_t *module)
static gboolean _iop_listens_to_picker_data(const dt_iop_module_t *module)
static void _iop_toggle_callback(GtkWidget *togglebutton, dt_module_param_t *data)
void _iop_dim_all_but(dt_iop_module_t *module, gboolean dim)
void dt_iop_gui_update_expanded(dt_iop_module_t *module)
void dt_iop_gui_update_header(dt_iop_module_t *module)
static gboolean _iop_plugin_header_menu_dismiss_idle(gpointer user_data)
void dt_iop_gui_set_enable_button(dt_iop_module_t *module)
static void _iop_reset_label_reset(GtkWidget *widget, gpointer user_data)
static void _gui_copy_callback(GtkButton *button, gpointer user_data)
gboolean dt_iop_is_visible(dt_iop_module_t *module)
void dt_iop_request_focus(dt_iop_module_t *module)
Move darkroom focus to module, or clear it with NULL.
dt_iop_module_t * dt_iop_gui_get_previous_visible_module(dt_iop_module_t *module)
GtkWidget * dt_iop_togglebutton_new(dt_iop_module_t *self, const char *section, const gchar *label, const gchar *ctrl_label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, GtkWidget *box)
static gboolean _iop_plugin_body_button_press(GtkWidget *w, GdkEventButton *e, gpointer user_data)
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_iop_gui_get_widget(dt_iop_module_t *module)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
static void _gui_set_single_expanded(dt_iop_module_t *module, gboolean expanded)
void dt_iop_gui_changed(dt_iop_module_t *action, GtkWidget *widget, gpointer data)
static void _iop_color_picker_data_ready_callback(gpointer instance, gpointer user_data)
gboolean dt_iop_gui_owns_widget(const dt_iop_module_t *module, const GtkWidget *target)
static void _mask_indicator_get_usage(dt_iop_module_t *module, gboolean *top_enabled, gboolean *raster_used, gboolean *drawn_used, gboolean *parametric_used)
static gboolean _iop_plugin_header_child_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
static gboolean _mask_indicator_tooltip(GtkWidget *treeview, gint x, gint y, gboolean kb_mode, GtkTooltip *tooltip, dt_iop_module_t *module)
void dt_iop_gui_set_enable_button_icon(GtkWidget *w, dt_iop_module_t *module)
void dt_bauhaus_value_changed_default_callback(GtkWidget *widget)
static void _add_widget_to_module_list(dt_iop_module_t *self, GtkWidget *widget)
void dt_iop_gui_enter_critical_section(dt_iop_module_t *const module)
Take the module's GUI lock, serialising access to its dt_iop_gui_data_t.
#define DT_IOP_HEADER_IGNORE_RELEASE
static void _presets_popup_callback(GtkButton *button, dt_iop_module_t *module)
static gboolean _gui_reset_callback(GtkButton *button, GdkEventButton *event, dt_iop_module_t *module)
#define DT_IOP_HEADER_MENU_DISMISS_CLICK
static void _iop_gui_widget_gone(gpointer user_data, GObject *where_the_object_was)
Clear GUI pointers that still reference one iop widget being finalized.
static gboolean _rename_module_resize(GtkWidget *entry, GdkEventKey *event, dt_iop_module_t *module)
void dt_iop_gui_set_expanded(dt_iop_module_t *module, gboolean expanded, gboolean collapse_others)
static void _gui_delete_callback(GtkButton *button, dt_iop_module_t *module)
static gboolean _rename_module_idle(gpointer user_data)
static gboolean _iop_plugin_header_button_press(GtkWidget *w, GdkEventButton *e, gpointer user_data)
gboolean dt_mask_scroll_increases(int up)
gboolean _iop_tooltip_callback(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
void dt_iop_gui_rename_module(dt_iop_module_t *module)
dt_iop_module_t * dt_iop_gui_duplicate(dt_iop_module_t *base, gboolean copy_params)
Create another instance of base, insert it into dev->iop and give it a GUI.
gboolean dt_iop_gui_module_is_visible(dt_iop_module_t *module)
GtkWidget * dt_iop_gui_get_off(dt_iop_module_t *module)
static void _gui_duplicate_callback(GtkButton *button, gpointer user_data)
static void _gui_off_callback(GtkToggleButton *togglebutton, gpointer user_data)
static void _gui_rename_callback(GtkButton *button, dt_iop_module_t *module)
#define DT_IOP_HEADER_MENU_OPEN
static dt_iop_gui_data_t * dt_iop_gui_data(const struct dt_iop_module_t *m)
The module's GUI data blob, NULL-safe for headless callers: IOP process() implementations read it for...
@ DT_INTROSPECTION_TYPE_BOOL
@ DT_INTROSPECTION_TYPE_ENUM
@ DT_INTROSPECTION_TYPE_FLOAT
@ DT_INTROSPECTION_TYPE_UINT
@ DT_INTROSPECTION_TYPE_USHORT
@ DT_INTROSPECTION_TYPE_INT
gchar * delete_underscore(const char *s)
static const dt_dev_pixelpipe_t * pipe
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
_lib_location_type_t type
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void dt_masks_iop_use_same_as(struct dt_iop_module_t *module, struct dt_iop_module_t *src)
void dt_masks_form_delete(dt_develop_t *dev, struct dt_iop_module_t *module, dt_masks_form_t *grp, dt_masks_form_t *form)
dt_masks_form_t * dt_masks_get_from_id(dt_develop_t *dev, int id)
void dt_masks_reset_form_gui(dt_develop_t *dev)
void dt_masks_group_update_name(dt_iop_module_t *module)
The interactive half of the masks subsystem: the editing state (dt_masks_form_gui_t),...
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
data.presets: a module's saved parameters, with the conditions under which it auto-applies.
GtkWidget * dtgtk_reset_label_new(const gchar *text)
void dt_sentry_record_module_usage(const char *category, const char *name)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_DEVELOP_MASKS_GUI_CHANGED
@ DT_SIGNAL_CONTROL_PICKERDATA_READY
This signal is raised when new color picker data are available in darkroom. no param,...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
const float uint32_t state[4]
const float const float param
struct dt_iop_module_t * gui_module
GtkWidget * scroll_to_header_once
The dt_gui_module_t type is the intersection between a dt_lib_module_t and a dt_iop_module_t structur...
char * instance_accel_path
GtkWidget * raster_enable
GtkWidget * blendif_enable
dt_iop_gui_blendif_filter_t filter[2]
GtkWidget * channel_display
GtkWidget * mask_indicator
dt_pthread_mutex_t gui_lock
int32_t hide_enable_button
dt_iop_params_t * default_params
struct dt_develop_blend_params_t * blend_params
struct dt_iop_module_gui_t * gui
struct dt_develop_t * dev
struct dt_iop_module_t::@23::@24 source
struct dt_iop_module_t::@23::@25 sink
struct dt_develop_blend_params_t * default_blendop_params
struct dt_iop_module_t::@23 raster_mask
dt_iop_module_t *int offset
dt_iop_module_t *void * param
void dt_telemetry_record_module_usage(const char *category, const char *name)
dt_bauhaus_combobox_data_t combobox
char * dt_get_help_url(char *name)
gchar * dt_util_str_replace(const gchar *string, const gchar *pattern, const gchar *substitute)
void dt_ui_container_add_widget(dt_ui_t *ui, const dt_ui_container_t c, GtkWidget *w)
@ DT_UI_CONTAINER_PANEL_RIGHT_CENTER