52#define DT_IOP_HEADER_MENU_OPEN "dt-module-header-menu-open"
53#define DT_IOP_HEADER_MENU_DISMISS_CLICK "dt-module-header-menu-dismiss-click"
55#define DT_IOP_HEADER_IGNORE_RELEASE "dt-module-header-ignore-release"
59 GdkModifierType modifier, gpointer data);
61 GdkModifierType modifier, gpointer data);
74#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 = g_strdup_printf(
"%s/%s", clean_name, (module->
multi_name[0] !=
'\0') ? module->
multi_name :
"0");
960 gtk_label_set_ellipsize(GTK_LABEL(lab), !module->
multi_name[0] ? PANGO_ELLIPSIZE_END: PANGO_ELLIPSIZE_MIDDLE);
961 g_object_set(G_OBJECT(lab),
"xalign", 0.0, (gchar *)0);
999 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->
gui->
off), module->
enabled);
1001 gtk_widget_set_sensitive(GTK_WIDGET(module->
gui->
off),
FALSE);
1003 gtk_widget_set_sensitive(GTK_WIDGET(module->
gui->
off),
TRUE);
1010 module->
enabled ?
"dt_iop_enable_forced_on" :
"dt_iop_enable_forced_off");
1021 if(
IS_NULL_PTR(module->
gui))
module->gui = (dt_iop_module_gui_t *)calloc(1, sizeof(dt_iop_module_gui_t));
1037 assert(g_strrstr(clean_name,
"/") == NULL);
1040 const gchar *
const main_scope = _(
"Darkroom/Modules");
1044 _(
"Focuses the module"));
1051 _(
"Enables the module"));
1057 if(module->gui_init)
module->gui_init(module);
1079 if(module->gui->header == (
GtkWidget *)where_the_object_was)
module->gui->header = NULL;
1080 if(module->gui->expander == (
GtkWidget *)where_the_object_was)
module->gui->expander = NULL;
1097 if(!
IS_NULL_PTR(module->
dev) &&
module->dev->gui_module == module) module->dev->gui_module = NULL;
1101 while(g_idle_remove_by_data(module->
gui->
widget));
1125 g_list_free(
m->widget_list);
1126 m->widget_list = NULL;
1127 g_list_free(
m->widget_list_bh);
1128 m->widget_list_bh = NULL;
1141 module->gui_cleanup(module);
1160 GtkWidget *expander =
module->gui->expander;
1161 g_object_ref_sink(expander);
1162 gtk_widget_destroy(expander);
1163 g_object_unref(expander);
1169 GtkWidget *header =
module->gui->header;
1170 g_object_ref_sink(header);
1171 gtk_widget_destroy(header);
1172 g_object_unref(header);
1177 GtkWidget *widget =
module->gui->widget;
1178 g_object_ref_sink(widget);
1179 gtk_widget_destroy(widget);
1180 g_object_unref(widget);
1184 module->gui->widget = NULL;
1185 module->gui->header = NULL;
1186 module->gui->expander = NULL;
1187 module->gui->off = NULL;
1202 if(module->
params && module->gui_update)
1203 module->gui_update(module);
1216 const gboolean disabled = !
module->default_enabled && module->hide_enable_button;
1217 if(disabled)
return;
1258 const gboolean disabled = !
module->default_enabled && module->hide_enable_button;
1259 if(disabled)
return;
1267 g_signal_connect_data(G_OBJECT(
dt_gui_get_global()->presets_popup_menu),
"deactivate",
1269 g_object_ref(module->
gui->
expander), (GClosureNotify)g_object_unref, 0);
1285 const gboolean scroll_new_instance_to_header
1287 && !IS_NULL_PTR(module->gui->header) && GTK_IS_WIDGET(module->gui->header));
1292 if(out_focus_module)
1296 if(scroll_focus && out_focus_widget && gtk_widget_is_ancestor(scroll_focus, out_focus_widget))
1299 gtk_widget_queue_draw(scroll_focus);
1302 if(out_focus_module->gui_focus)
1303 out_focus_module->gui_focus(out_focus_module,
FALSE);
1343 if(module->gui_focus)
module->gui_focus(module, TRUE);
1356 GList *first_child = g_list_first(widget_list);
1360 if(widget) gtk_widget_grab_focus(widget);
1390 module->gui->expanded = expanded;
1420 snprintf(var,
sizeof(var),
"plugins/darkroom/%s/expanded", module->
op);
1427 for(GList *iop = g_list_first(
dt_dev_get_global()->iop); iop; iop = g_list_next(iop))
1434 if(dim &&
m != module)
1446 for(GList *iop = g_list_first(module->
dev->
iop); iop; iop = g_list_next(iop))
1455 gtk_widget_queue_draw(module->
gui->
widget);
1462 const gboolean expanded =
module->gui->expanded;
1475 gboolean handled =
FALSE;
1482 else if(e->button == 3)
1494 return module->focus(module, TRUE);
1500 if(module && module->gui->expander)
1501 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-header-child-click", GINT_TO_POINTER(
TRUE));
1507 GdkModifierType modifier, gpointer data)
1511 if(
IS_NULL_PTR(module) || !
module->focus) return FALSE;
1515 if(iop->gui->expander)
1516 g_object_set_data(G_OBJECT(iop->gui->expander),
"dt-modulegroups-switch-from-active-once",
1517 GINT_TO_POINTER(
TRUE));
1519 return module->focus(module, FALSE);
1523 GdkModifierType modifier, gpointer data)
1531 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-modulegroups-prefer-active-once",
1532 GINT_TO_POINTER(
TRUE));
1537 if(!module->hide_enable_button)
1539 module->enabled = TRUE;
1550 if(e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS)
return TRUE;
1569 if(module->gui->expander) g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-dragged", NULL);
1577 if(module->gui->expander)
1583 else if(e->button == 3)
1594 if(e->button != 1 || e->type != GDK_BUTTON_RELEASE)
return FALSE;
1611 if(g_object_get_data(G_OBJECT(module->gui->expander),
"dt-module-header-child-click"))
1613 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-header-child-click", NULL);
1617 if(g_object_get_data(G_OBJECT(module->gui->expander),
"dt-module-dragged"))
1619 g_object_set_data(G_OBJECT(module->gui->expander),
"dt-module-dragged", NULL);
1635 const gboolean is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bt));
1638 module->request_mask_display
1639 &= ~(DT_DEV_PIXELPIPE_DISPLAY_MASK | DT_DEV_PIXELPIPE_DISPLAY_CHANNEL
1640 | DT_DEV_PIXELPIPE_DISPLAY_ANY | DT_DEV_PIXELPIPE_DISPLAY_STICKY);
1643 module->request_mask_display |= DT_DEV_PIXELPIPE_DISPLAY_MASK;
1649 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bd->
showmask), is_active);
1663 gboolean *drawn_used, gboolean *parametric_used)
1674 gboolean raster =
FALSE;
1675 gboolean drawn =
FALSE;
1676 gboolean parametric =
FALSE;
1683 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bd->
raster_enable)))
1687 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bd->
masks_enable)))
1691 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bd->
blendif_enable)))
1695 if(!
IS_NULL_PTR(raster_used)) *raster_used = raster;
1697 if(!
IS_NULL_PTR(parametric_used)) *parametric_used = parametric;
1711 gchar *
type = _(
"unknown mask");
1713 gboolean top_enabled =
FALSE, raster_used =
FALSE, drawn_used =
FALSE, parametric_used =
FALSE;
1715 if(!top_enabled)
return FALSE;
1717 if(drawn_used && parametric_used)
1718 type=_(
"drawn + parametric mask");
1720 type=_(
"drawn mask");
1721 else if(parametric_used)
1722 type=_(
"parametric mask");
1723 else if(raster_used)
1724 type=_(
"raster mask");
1727 gchar *part1 = g_strdup_printf(_(
"this module has a '%s'"),
type);
1728 gchar *part2 = NULL;
1732 part2 = g_strdup_printf(_(
"taken from module %s"), source);
1738 gchar *details = g_strdup_printf(
"%s\n%s", part2, _(
"click to display (module must be activated first)"));
1744 part2 = g_strdup(_(
"click to display (module must be activated first)"));
1748 text = g_strconcat(part1,
"\n", part2, NULL);
1750 text = g_strdup(part1);
1752 gtk_tooltip_set_text(
tooltip, text);
1765 const gboolean support_blending = (
module->flags() & IOP_FLAGS_SUPPORTS_BLENDING) == IOP_FLAGS_SUPPORTS_BLENDING;
1775 gboolean top_enabled =
FALSE, raster_used =
FALSE, drawn_used =
FALSE, parametric_used =
FALSE;
1778 const gboolean use_masks = top_enabled && (raster_used || drawn_used || parametric_used);
1786 GtkTooltip *
tooltip, gpointer user_data)
1790 const char **des =
module->description(module);
1796 gtk_grid_set_column_homogeneous(GTK_GRID(grid),
FALSE);
1798 gtk_widget_set_hexpand(grid,
FALSE);
1800 GtkWidget *label = gtk_label_new(des[0] ? des[0] :
"");
1801 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1802 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1803 gtk_label_set_max_width_chars(GTK_LABEL(label), 40);
1806 gtk_box_pack_start(GTK_BOX(vbox), label,
FALSE,
FALSE, 0);
1812 const char *icon_purpose =
"\342\237\263";
1813 const char *icon_input =
"\342\207\245";
1814 const char *icon_process =
"\342\237\264";
1815 const char *icon_output =
"\342\206\246";
1817 const char *icons[4] = {icon_purpose, icon_input, icon_process, icon_output};
1818 const char *ilabs[4] = {_(
"Purpose"), _(
"Input"), _(
"Process"), _(
"Output")};
1820 for(
int k=1;
k<5;
k++)
1824 label = gtk_label_new(icons[
k-1]);
1825 gtk_widget_set_halign(label, GTK_ALIGN_START);
1826 gtk_grid_attach(GTK_GRID(grid), label, 0,
k, 1, 1);
1827 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1829 label = gtk_label_new(ilabs[
k-1]);
1830 gtk_widget_set_halign(label, GTK_ALIGN_START);
1831 gtk_grid_attach(GTK_GRID(grid), label, 1,
k, 1, 1);
1832 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1834 label = gtk_label_new(
":");
1835 gtk_widget_set_halign(label, GTK_ALIGN_START);
1836 gtk_grid_attach(GTK_GRID(grid), label, 2,
k, 1, 1);
1837 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1839 label = gtk_label_new(des[
k]);
1840 gtk_widget_set_halign(label, GTK_ALIGN_START);
1841 gtk_grid_attach(GTK_GRID(grid), label, 3,
k, 1, 1);
1842 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
1846 gtk_box_pack_start(GTK_BOX(vbox), grid,
FALSE,
FALSE, 0);
1847 gtk_widget_show_all(vbox);
1848 gtk_tooltip_set_custom(
tooltip, vbox);
1856 gtk_widget_set_name(GTK_WIDGET(header),
"module-header");
1869 module->gui->header = header;
1875 gtk_widget_add_events(header_evb, GDK_POINTER_MOTION_MASK);
1879 gtk_widget_add_events(body_evb, GDK_POINTER_MOTION_MASK);
1887 char w_name[256] = { 0 };
1888 snprintf(w_name,
sizeof(w_name),
"iop-panel-icon-%s", module->
op);
1895 GtkWidget *label = gtk_label_new_with_mnemonic(
"");
1896 gtk_container_add(GTK_CONTAINER(lab), label);
1897 gtk_label_set_mnemonic_widget(GTK_LABEL(label), header_evb);
1900 gtk_widget_set_tooltip_text(lab, module->deprecated_msg());
1903 gtk_widget_set_name(lab,
"iop_description");
1916 module->gui->mask_indicator = hw[IOP_MODULE_MASK];
1920 module->gui->multimenu_button = GTK_WIDGET(hw[IOP_MODULE_INSTANCE]);
1922 _(
"multiple instance actions\nright-click creates new instance"));
1932 module->gui->reset_button = GTK_WIDGET(hw[IOP_MODULE_RESET]);
1933 gtk_widget_set_tooltip_text(GTK_WIDGET(hw[
IOP_MODULE_RESET]), _(
"reset parameters\nctrl+click to reapply any automatic presets"));
1940 module->gui->presets_button = GTK_WIDGET(hw[IOP_MODULE_PRESETS]);
1942 gtk_widget_set_tooltip_text(GTK_WIDGET(hw[
IOP_MODULE_PRESETS]), _(
"presets\nright-click to apply on new instance"));
1952 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(switch_button), module->
enabled);
1953 g_signal_connect(G_OBJECT(switch_button),
"button-press-event",
1955 g_signal_connect(G_OBJECT(switch_button),
"toggled", G_CALLBACK(
_gui_off_callback), module);
1957 module->gui->off = switch_button;
1976 gtk_box_pack_start(GTK_BOX(header), hw[
i],
FALSE,
FALSE, 0);
1981 gtk_box_pack_end(GTK_BOX(header), hw[
i],
FALSE,
FALSE, 0);
1992 if(module->deprecated_msg())
1994 GtkWidget *lb = gtk_label_new(module->deprecated_msg());
1995 gtk_label_set_line_wrap(GTK_LABEL(lb),
TRUE);
1996 gtk_label_set_xalign(GTK_LABEL(lb), 0.0);
1998 gtk_box_pack_start(GTK_BOX(iopw), lb,
TRUE,
TRUE, 0);
1999 gtk_widget_show(lb);
2007 gtk_widget_hide(iopw);
2009 module->gui->expander = expander;
2041 if(module->gui_changed)
module->gui_changed(module, widget, data);
2047 if(!
IS_NULL_PTR(widget) && g_object_get_data(G_OBJECT(widget),
"dt-blendop-header-update"))
2058 for(GList *w = g_list_first(
m->widget_list_bh); w; w = g_list_next(w))
2079 fprintf(stderr,
"[dt_bauhaus_update_module] unsupported slider data type\n");
2098 fprintf(stderr,
"[dt_bauhaus_update_module] unsupported combo data type\n");
2102 fprintf(stderr,
"[dt_bauhaus_update_module] invalid bauhaus widget type encountered\n");
2122 float *
f = w->
field, prevf = *
f; *
f = val;
2128 int *
i = w->
field, previ = *
i; *
i = val;
2134 unsigned short *s = w->
field, prevs = *s; *s = val;
2139 fprintf(stderr,
"[_bauhaus_slider_value_change] unsupported slider data type\n");
2153 int *e = w->
field, preve = *e; *e = GPOINTER_TO_INT(entry->
data);
2160 int *
i = w->
field, previ = *
i; *
i =
d->active;
2166 unsigned int *u = w->
field, prevu = *u; *u =
d->active;
2172 gboolean *b = w->
field, prevb = *b; *b =
d->active;
2177 fprintf(stderr,
"[_bauhaus_combobox_set] unsupported combo data type\n");
2182 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);
2200 return module && module->gui ? module->gui->off : NULL;
2205 return module->gui && (module->gui->expander == (const void *)target || module->gui->header == (const void *)target);
2227 memcpy(((
char *)
d->module->params) +
d->offset, ((
char *)
d->module->default_params) +
d->offset,
d->size);
2228 if(
d->module->gui_update)
d->module->gui_update(
d->module);
2240 d->size = param_size;
2243 (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)
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 void _gui_reset_callback(GtkButton *button, GdkEventButton *event, dt_iop_module_t *module)
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)
#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)
_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...
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