58#ifdef GDK_WINDOWING_QUARTZ
65#pragma GCC diagnostic ignored "-Wshadow"
89 return _(
"Masking & Blending");
94 static const char *
v[] = {
"darkroom", NULL};
135 if(G_VALUE_TYPE(&gv) == G_TYPE_POINTER)
136 *
module = (dt_iop_module_t *)g_value_get_pointer(&gv);
144 *groupid = g_value_get_int(&gv);
152 *formid = g_value_get_int(&gv);
159 return darktable.
develop &&
module && g_list_find(darktable.develop->iop, (gpointer)module);
166 GList *children = gtk_container_get_children(GTK_CONTAINER(self->
widget));
167 for(GList *iter = children; iter; iter = g_list_next(iter))
168 gtk_widget_destroy(GTK_WIDGET(iter->data));
169 g_list_free(children);
200 gtk_label_set_markup(GTK_LABEL(label), markup);
201 gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
202 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
205 gtk_widget_set_sensitive(label,
FALSE);
207 gtk_widget_show_all(self->
widget);
222 gchar *markup = g_markup_printf_escaped(_(
"<i>Select a module to edit its blending settings.</i>"));
236 gchar *markup = g_markup_printf_escaped(_(
"<i>Blending is not available for the <b>%s</b> module.</i>"), module_label);
245 const gboolean module_changed = (lm->
active_module != module);
254 gtk_widget_show(self->
widget);
309 const int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),
"formid"));
310 dt_iop_module_t *
module = g_object_get_data(G_OBJECT(button), "module");
334 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
335 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
337 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
338 for(GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
340 GtkTreePath *item = (GtkTreePath *)items_iter->data;
342 if(gtk_tree_model_get_iter(
model, &iter, item))
354 mask->points = g_list_append(mask->points, fpt);
358 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
376 g_strlcat(str, form->
name, str_size);
380 for(
const GList *modules =
darktable.
develop->
iop; modules; modules = g_list_next(modules))
386 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
391 if(
m == module)
return -1;
392 if(nbuse == 0) g_strlcat(str,
" (", str_size);
393 g_strlcat(str,
" ", str_size);
395 g_strlcat(str, module_label, str_size);
403 if(nbuse > 0) g_strlcat(str,
" )", str_size);
408 GtkTreeModel *
model, GtkTreeIter *iter,
int index)
416 g_snprintf(str,
sizeof(str),
"%s %d%%",
417 form->
name, (
int)(opacity * 100));
421 g_strlcpy(str, form->
name,
sizeof(str));
424 GdkPixbuf *icop = NULL;
425 GdkPixbuf *icinv = NULL;
463 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
464 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
466 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
467 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
469 GtkTreePath *item = (GtkTreePath *)items_iter->data;
471 if(gtk_tree_model_get_iter(
model, &iter, item))
482 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
487 const int old_state = pt->
state;
489 if(pt->
state != old_state)
502 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
518 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
519 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
521 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
522 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
524 GtkTreePath *item = (GtkTreePath *)items_iter->data;
526 if(gtk_tree_model_get_iter(
model, &iter, item))
537 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
542 const int old_state = pt->
state;
544 if(pt->
state != old_state)
557 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
573 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
574 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
576 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
577 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
579 GtkTreePath *item = (GtkTreePath *)items_iter->data;
581 if(gtk_tree_model_get_iter(
model, &iter, item))
592 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
597 const int old_state = pt->
state;
599 if(pt->
state != old_state)
612 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
628 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
629 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
631 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
632 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
634 GtkTreePath *item = (GtkTreePath *)items_iter->data;
636 if(gtk_tree_model_get_iter(
model, &iter, item))
647 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
652 const int old_state = pt->
state;
654 if(pt->
state != old_state)
667 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
683 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
684 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
686 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
687 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
689 GtkTreePath *item = (GtkTreePath *)items_iter->data;
691 if(gtk_tree_model_get_iter(
model, &iter, item))
702 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
707 const int old_state = pt->
state;
709 if(pt->
state != old_state)
722 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
741 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
742 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
744 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
745 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
747 GtkTreePath *item = (GtkTreePath *)items_iter->data;
749 if(gtk_tree_model_get_iter(
model, &iter, item))
758 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
774 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
775 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
777 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
778 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
780 GtkTreePath *item = (GtkTreePath *)items_iter->data;
782 if(gtk_tree_model_get_iter(
model, &iter, item))
791 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
807 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
808 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
811 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
812 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
814 GtkTreePath *item = (GtkTreePath *)items_iter->data;
816 if(gtk_tree_model_get_iter(
model, &iter, item))
826 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
838 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
839 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
840 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
842 GtkTreePath *item = (GtkTreePath *)
items->data;
844 if(gtk_tree_model_get_iter(
model, &iter, item))
856 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
864 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
866 if(!gtk_tree_model_get_iter_from_string(
model, &iter, path_string))
return;
876 gchar *text = strlen(new_text) == 0 ?
" " : new_text;
880 g_strlcpy(form->
name, text,
sizeof(form->
name));
894 const int nb = gtk_tree_selection_count_selected_rows(selection);
903 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->
treeview));
906 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
907 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
909 GtkTreePath *item = (GtkTreePath *)items_iter->data;
911 if(gtk_tree_model_get_iter(
model, &iter, item))
920 if(nb == 1) selected_form = form;
933 if(module && module->blend_data
939 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bd->
masks_edit),
TRUE);
946 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
964 GtkMenuShell *menu = GTK_MENU_SHELL(gtk_menu_new());
968 const int nb = gtk_tree_selection_count_selected_rows(selection);
976 GList *selected = gtk_tree_selection_get_selected_rows(selection, NULL);
977 GtkTreePath *it0 = (GtkTreePath *)selected->data;
978 depth = gtk_tree_path_get_depth(it0);
982 if(gtk_tree_model_get_iter(
model, &iter, it0))
987 g_list_free_full(selected, (GDestroyNotify)gtk_tree_path_free);
990 if(depth > 1) from_group = 1;
995 GtkWidget *add_item = gtk_menu_item_new_with_label(_(
"Add new shape ..."));
996 gtk_menu_item_set_submenu(GTK_MENU_ITEM(add_item), add_menu);
997 gtk_menu_shell_append(menu, add_item);
999 item = gtk_menu_item_new_with_label(_(
"add circle"));
1001 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1003 item = gtk_menu_item_new_with_label(_(
"add ellipse"));
1005 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1007 item = gtk_menu_item_new_with_label(_(
"add path"));
1009 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1011 item = gtk_menu_item_new_with_label(_(
"add gradient"));
1013 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1015 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1024 GtkWidget *add_item = gtk_menu_item_new_with_label(_(
"Add new shape ..."));
1025 gtk_menu_item_set_submenu(GTK_MENU_ITEM(add_item), add_menu);
1026 gtk_menu_shell_append(menu, add_item);
1028 item = gtk_menu_item_new_with_label(_(
"Add brush"));
1029 g_signal_connect(item,
"activate", (GCallback)
_tree_add_brush, module);
1030 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1032 item = gtk_menu_item_new_with_label(_(
"Add circle"));
1034 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1036 item = gtk_menu_item_new_with_label(_(
"Add ellipse"));
1038 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1040 item = gtk_menu_item_new_with_label(_(
"Add polygon"));
1042 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1044 item = gtk_menu_item_new_with_label(_(
"Add gradient"));
1046 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1049 gboolean has_unused_shapes =
FALSE;
1058 char str[10000] =
"";
1060 if(nbuse == -1)
continue;
1063 item = gtk_menu_item_new_with_label(str);
1064 g_object_set_data(G_OBJECT(item),
"formid", GUINT_TO_POINTER(form->
formid));
1065 g_object_set_data(G_OBJECT(item),
"module", module);
1066 g_signal_connect(G_OBJECT(item),
"activate", G_CALLBACK(
_tree_add_exist), grp);
1067 gtk_menu_shell_append(GTK_MENU_SHELL(menu0), item);
1068 has_unused_shapes =
TRUE;
1071 if(has_unused_shapes)
1073 item = gtk_menu_item_new_with_label(_(
"Add shape ..."));
1074 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu0);
1075 gtk_menu_shell_append(menu, item);
1080 if(nb > 1 && !from_group)
1082 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1083 item = gtk_menu_item_new_with_label(_(
"Group the forms"));
1084 g_signal_connect(item,
"activate", (GCallback)
_tree_group, self);
1085 gtk_menu_shell_append(menu, item);
1088 if(from_group && depth < 3)
1090 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1091 item = gtk_menu_item_new_with_label(_(
"Invert shape"));
1092 g_signal_connect(item,
"activate", (GCallback)
_tree_inverse, self);
1093 gtk_menu_shell_append(menu, item);
1096 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1097 item = gtk_menu_item_new_with_label(_(
"Union"));
1098 g_signal_connect(item,
"activate", (GCallback)
_tree_union, self);
1099 gtk_menu_shell_append(menu, item);
1100 item = gtk_menu_item_new_with_label(_(
"Intersection"));
1102 gtk_menu_shell_append(menu, item);
1103 item = gtk_menu_item_new_with_label(_(
"Difference"));
1105 gtk_menu_shell_append(menu, item);
1106 item = gtk_menu_item_new_with_label(_(
"Exclusion"));
1108 gtk_menu_shell_append(menu, item);
1110 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1111 item = gtk_menu_item_new_with_label(_(
"Move up"));
1112 g_signal_connect(item,
"activate", (GCallback)
_tree_moveup, self);
1113 gtk_menu_shell_append(menu, item);
1114 item = gtk_menu_item_new_with_label(_(
"Move down"));
1115 g_signal_connect(item,
"activate", (GCallback)
_tree_movedown, self);
1116 gtk_menu_shell_append(menu, item);
1117 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1123 item = gtk_menu_item_new_with_label(_(
"Duplicate shape"));
1125 gtk_menu_shell_append(menu, item);
1126 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1129 if(!from_group && nb > 0)
1133 item = gtk_menu_item_new_with_label(_(
"Delete shape"));
1135 gtk_menu_shell_append(menu, item);
1139 item = gtk_menu_item_new_with_label(_(
"Delete mask"));
1141 gtk_menu_shell_append(menu, item);
1144 else if(nb > 0 && depth < 3)
1146 item = gtk_menu_item_new_with_label(_(
"Remove shape from mask"));
1148 gtk_menu_shell_append(menu, item);
1151 item = gtk_menu_item_new_with_label(_(
"Cleanup unused shapes"));
1152 g_signal_connect(item,
"activate", (GCallback)
_tree_cleanup, self);
1153 gtk_menu_shell_append(menu, item);
1155 return GTK_WIDGET(menu);
1161 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
1162 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
1164 GtkTreePath *mouse_path = NULL;
1168 if(gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &mouse_path, NULL,
1173 if(gtk_tree_model_get_iter(
model, &iter, mouse_path))
1179 if(event->type == GDK_BUTTON_PRESS && event->button == 1)
1184 gtk_tree_selection_unselect_all(selection);
1187 else if(event->type == GDK_BUTTON_PRESS && event->button == 3)
1190 if(on_row && !gtk_tree_selection_path_is_selected(selection, mouse_path))
1192 if(!
dt_modifier_is(event->state, GDK_CONTROL_MASK)) gtk_tree_selection_unselect_all(selection);
1193 gtk_tree_selection_select_path(selection, mouse_path);
1194 gtk_tree_path_free(mouse_path);
1200 gtk_widget_show_all(menu);
1202 gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
1211 gboolean path_currently_selected, gpointer data)
1217 if(path_currently_selected)
return TRUE;
1220 if(gtk_tree_selection_count_selected_rows(selection) == 0)
return TRUE;
1224 int *indices = gtk_tree_path_get_indices(path);
1225 int depth = gtk_tree_path_get_depth(path);
1227 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
1228 GList *items_iter =
items;
1231 GtkTreePath *item = (GtkTreePath *)items_iter->data;
1232 int dd = gtk_tree_path_get_depth(item);
1233 int *ii = gtk_tree_path_get_indices(item);
1239 else if(ii[dd - 2] != indices[dd - 2])
1243 gtk_tree_selection_unselect_path(selection, item);
1244 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
1246 items_iter =
items = gtk_tree_selection_get_selected_rows(selection, NULL);
1249 items_iter = g_list_next(items_iter);
1251 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
1257 GtkTooltip *
tooltip, gpointer data)
1260 GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
1261 GtkTreeModel *
model = gtk_tree_view_get_model(tree_view);
1262 GtkTreePath *path = NULL;
1264 gboolean show =
FALSE;
1266 if(!gtk_tree_view_get_tooltip_context(tree_view, &
x, &y, keyboard_tip, &
model, &path, &iter))
return FALSE;
1271 gtk_tooltip_set_markup(
tooltip, tmp);
1272 gtk_tree_view_set_tooltip_row(tree_view,
tooltip, path);
1275 gtk_tree_path_free(path);
1293 for(
const GList *points = grp->
points; points; points = g_list_next(points))
1299 if(
point->formid == formid)
1302 if(*nb > 1) g_strlcat(text,
"\n", text_length);
1303 g_strlcat(text, grp->
name, text_length);
1318 g_strlcat(str, form->
name,
sizeof(str));
1320 GdkPixbuf *icop = NULL;
1321 GdkPixbuf *icinv = NULL;
1322 GdkPixbuf *icuse = NULL;
1332 char str2[1000] =
"";
1337 if(nbuse > 0) icuse = lm->
ic_wired;
1344 gtk_tree_store_append(treestore, &child, toplevel);
1350 _set_iter_name(lm, form, gstate, opacity, GTK_TREE_MODEL(treestore), &child, index);
1355 if(grp_id == 0 && !module)
1371 gtk_tree_store_append(treestore, &child, toplevel);
1377 _set_iter_name(lm, form, gstate, opacity, GTK_TREE_MODEL(treestore), &child, index);
1381 for(
const GList *forms = form->
points; forms; forms = g_list_next(forms))
1395 gboolean found =
FALSE;
1401 found = (fid == formid)
1403 || (
IS_NULL_PTR(module) || (mod && (!g_strcmp0(module->
op, mod->
op)))));
1404 if(found)
return found;
1405 GtkTreeIter child, parent = *iter;
1406 if(gtk_tree_model_iter_children(
model, &child, &parent))
1415 }
while(gtk_tree_model_iter_next(
model, iter));
1424 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1426 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1428 GList *
items = gtk_tree_selection_get_selected_rows(selection, &
model);
1430 for(GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
1432 GtkTreePath *item = (GtkTreePath *)items_iter->data;
1434 if(gtk_tree_model_get_iter(
model, &iter, item))
1440 res = g_list_prepend(res, GINT_TO_POINTER(fid));
1441 res = g_list_prepend(res, GINT_TO_POINTER(gid));
1442 res = g_list_prepend(res, (
void *)(mod));
1446 g_list_foreach(
items, (GFunc)gtk_tree_path_free, NULL);
1462 gboolean sync_center_view =
FALSE;
1466 GList *selectids = NULL;
1479 GtkTreeStore *treestore;
1481 treestore = gtk_tree_store_new(
TREE_COUNT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT,
1482 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
1483 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_STRING);
1499 gtk_tree_view_set_model(GTK_TREE_VIEW(lm->
treeview), GTK_TREE_MODEL(treestore));
1504 GList *ids = selectids;
1507 GtkTreeModel *
model = GTK_TREE_MODEL(treestore);
1509 ids = g_list_next(ids);
1511 ids = g_list_next(ids);
1512 const int fid = GPOINTER_TO_INT(ids->data);
1513 ids = g_list_next(ids);
1516 gtk_tree_model_get_iter_first(
model, &iter);
1522 GtkTreePath *path = gtk_tree_model_get_path(
model, &iter);
1523 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(lm->
treeview), path);
1524 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(lm->
treeview), path, NULL,
TRUE, 0.5, 0.5);
1525 gtk_tree_path_free(path);
1526 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1527 gtk_tree_selection_select_iter(selection, &iter);
1530 g_list_free(selectids);
1536 const int current_group_id
1545 GtkTreeModel *
model = GTK_TREE_MODEL(treestore);
1547 if(gtk_tree_model_get_iter_first(
model, &iter))
1552 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1553 GtkTreePath *path = gtk_tree_model_get_path(
model, &iter);
1554 gtk_tree_selection_unselect_all(selection);
1555 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(lm->
treeview), path);
1556 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(lm->
treeview), path, NULL,
TRUE, 0.5, 0.5);
1557 gtk_tree_selection_select_iter(selection, &iter);
1558 gtk_tree_path_free(path);
1559 sync_center_view =
TRUE;
1564 g_object_unref(treestore);
1568 if(sync_center_view)
1570 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1584 float opacity = 1.0f;
1589 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
1622 float opacity = 1.0f;
1627 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
1652 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1653 if(!GTK_IS_TREE_MODEL(
model))
return;
1660 GList **rl = (GList **)data;
1661 const int refid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(
model),
"formid"));
1662 const int refgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(
model),
"groupid"));
1668 if(grid == refgid &&
id == refid)
1670 GtkTreeRowReference *rowref = gtk_tree_row_reference_new(
model, path);
1671 *rl = g_list_append(*rl, rowref);
1680 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1682 g_object_set_data(G_OBJECT(
model),
"formid", GUINT_TO_POINTER(formid));
1683 g_object_set_data(G_OBJECT(
model),
"groupid", GUINT_TO_POINTER(parentid));
1686 for(
const GList *rlt = rl; rlt; rlt = g_list_next(rlt))
1688 GtkTreeRowReference *rowref = (GtkTreeRowReference *)rlt->data;
1689 GtkTreePath *path = gtk_tree_row_reference_get_path(rowref);
1690 gtk_tree_row_reference_free(rowref);
1694 if(gtk_tree_model_get_iter(
model, &iter, path))
1696 gtk_tree_store_remove(GTK_TREE_STORE(
model), &iter);
1698 gtk_tree_path_free(path);
1707 const int selectid,
int throw_event,
const int level)
1709 gboolean found =
FALSE;
1711 GtkTreeIter
i = *iter;
1720 || (
IS_NULL_PTR(module) || (mod && (!g_strcmp0(module->
op, mod->
op))))))
1722 gtk_tree_selection_select_iter(selection, &
i);
1728 GtkTreeIter child, parent =
i;
1729 if(gtk_tree_model_iter_children(
model, &child, &parent))
1737 }
while(gtk_tree_model_iter_next(
model, &
i) ==
TRUE);
1748 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1750 gtk_tree_selection_unselect_all(selection);
1756 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1757 if(!GTK_IS_TREE_MODEL(
model))
1762 gboolean valid = gtk_tree_model_get_iter_first(
model, &iter);
1766 gtk_tree_view_expand_all(GTK_TREE_VIEW(lm->
treeview));
1768 if(!found) gtk_tree_view_collapse_all(GTK_TREE_VIEW(lm->
treeview));
1777 gboolean found =
FALSE;
1780 if(gtk_tree_model_iter_children(
model, &iter, parent_iter))
1784 int current_formid = -1;
1787 if(current_formid == formid)
1793 }
while(gtk_tree_model_iter_next(
model, &iter));
1801 gboolean found =
FALSE;
1806 int current_parentid = -1;
1809 if(current_parentid == parentid)
1818 }
while(gtk_tree_model_iter_next(
model, iter));
1829 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1830 if(!GTK_IS_TREE_MODEL(
model))
return;
1832 gboolean found_iter = gtk_tree_model_get_iter_first(
model, &iter);
1899 if(!
d->popup_window)
return;
1901 if(gtk_widget_get_visible(
d->popup_window))
1903 gtk_widget_hide(
d->popup_window);
1907 gtk_widget_show_all(
d->popup_window);
1917 if(!
d || !
d->popup_button)
return FALSE;
1931 self->
data = (
void *)
d;
1944 d->popup_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1945 gtk_window_set_title(GTK_WINDOW(
d->popup_window), _(
"Mask Manager Panel"));
1946 gtk_window_set_type_hint(GTK_WINDOW(
d->popup_window), GDK_WINDOW_TYPE_HINT_UTILITY);
1950 gtk_window_set_modal(GTK_WINDOW(
d->popup_window),
FALSE);
1951 gtk_window_set_focus_on_map(GTK_WINDOW(
d->popup_window),
FALSE);
1952 gtk_window_set_accept_focus(GTK_WINDOW(
d->popup_window),
FALSE);
1955#ifdef GDK_WINDOWING_QUARTZ
1957 gtk_window_set_position(GTK_WINDOW(
d->popup_window), GTK_WIN_POS_CENTER_ON_PARENT);
1961 g_signal_connect(G_OBJECT(
d->popup_window),
"delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1965 gtk_container_add(GTK_CONTAINER(
d->popup_window), shape_manager_container);
1975 gtk_widget_set_tooltip_text(
d->popup_button, _(
"Open mask manager..."));
1989 .creation_module = NULL,
1990 .buttons = shape_buttons,
1992 .action_section = NULL,
2004 gtk_box_pack_end(GTK_BOX(hbox), shape_buttons_box,
FALSE,
FALSE, 0);
2011 gtk_box_pack_start(GTK_BOX(shape_manager_container), hbox,
TRUE,
TRUE, 0);
2013 d->treeview = gtk_tree_view_new();
2014 GtkTreeViewColumn *col = gtk_tree_view_column_new();
2015 gtk_tree_view_column_set_title(col,
"shapes");
2016 gtk_tree_view_append_column(GTK_TREE_VIEW(
d->treeview), col);
2018 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
2019 gtk_tree_view_column_pack_start(col, renderer,
FALSE);
2020 gtk_tree_view_column_set_attributes(col, renderer,
"pixbuf",
TREE_IC_OP, NULL);
2022 renderer = gtk_cell_renderer_pixbuf_new();
2023 gtk_tree_view_column_pack_start(col, renderer,
FALSE);
2024 gtk_tree_view_column_set_attributes(col, renderer,
"pixbuf",
TREE_IC_INVERSE, NULL);
2026 renderer = gtk_cell_renderer_text_new();
2027 gtk_tree_view_column_pack_start(col, renderer,
TRUE);
2028 gtk_tree_view_column_add_attribute(col, renderer,
"text",
TREE_TEXT);
2029 gtk_tree_view_column_add_attribute(col, renderer,
"editable",
TREE_EDITABLE);
2031 renderer = gtk_cell_renderer_pixbuf_new();
2032 gtk_tree_view_column_pack_end(col, renderer,
FALSE);
2033 gtk_tree_view_column_set_attributes(col, renderer,
"pixbuf",
TREE_IC_USED, NULL);
2036 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
d->treeview));
2037 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
2039 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(
d->treeview),
FALSE);
2041 g_object_set(
d->treeview,
"has-tooltip",
TRUE, (gchar *)0);
2047 gtk_box_pack_start(GTK_BOX(shape_manager_container),
2069 if(self && self->
data)
2076 gtk_widget_destroy(
d->popup_window);
2077 d->popup_window = NULL;
2080 if(!
IS_NULL_PTR(
d->ic_inverse)) g_object_unref(
d->ic_inverse);
2083 if(!
IS_NULL_PTR(
d->ic_intersection)) g_object_unref(
d->ic_intersection);
2084 if(!
IS_NULL_PTR(
d->ic_difference)) g_object_unref(
d->ic_difference);
2085 if(!
IS_NULL_PTR(
d->ic_exclusion)) g_object_unref(
d->ic_exclusion);
2087 d->ic_inverse = NULL;
2090 d->ic_intersection = NULL;
2091 d->ic_difference = NULL;
2092 d->ic_exclusion = NULL;
void gui_reset(dt_imageio_module_format_t *self)
void dt_iop_gui_init_blending_body(GtkWidget *container, dt_iop_module_t *module)
void dt_iop_gui_update_blending(dt_iop_module_t *module)
void dt_iop_gui_cleanup_blending_body(dt_iop_module_t *module)
void dt_masks_iop_update(dt_iop_module_t *module)
const dt_aligned_pixel_t f
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
void reset(dt_view_t *self)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define DT_MODULE(MODVER)
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_dev_add_history_item(dev, module, enable, redraw)
void dt_dev_pixelpipe_change_zoom_main(dt_develop_t *dev)
void dt_dev_masks_selection_change(dt_develop_t *dev, struct dt_iop_module_t *module, const int selectid, const int throw_event)
gchar * dt_history_item_get_name(const struct dt_iop_module_t *module)
static GdkPixbuf * dt_draw_get_pixbuf_from_cairo(DTGTKCairoPaintIconFunc paint, const int width, const int height)
void dtgtk_cairo_paint_masks_inverse(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_masks_difference(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_masks_union(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_masks_drawn(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_masks_exclusion(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_masks_intersection(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_link_chain(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
const dt_collection_sort_t items[]
GtkWidget * dt_ui_scroll_wrap(GtkWidget *w, gint min_size, char *config_str, dt_ui_resize_mode_t mode)
Wrap a scrollable content widget in a recessed, vertically resizable scrolled window.
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)
@ IOP_FLAGS_SUPPORTS_BLENDING
static void _tree_group(GtkButton *button, dt_lib_module_t *self)
static void _set_iter_name(dt_lib_masks_t *lm, dt_masks_form_t *form, int state, float opacity, GtkTreeModel *model, GtkTreeIter *iter, int index)
static gboolean _lib_masks_add_popup_button_idle(gpointer user_data)
static void _lib_masks_remove_item(dt_lib_module_t *self, int formid, int parentid)
static void _tree_add_circle(GtkButton *button, dt_iop_module_t *module)
static void _lib_masks_popup_button_clicked_cb(GtkWidget *button, gpointer user_data)
static void _tree_add_exist(GtkButton *button, dt_masks_form_t *grp)
static void _tree_union(GtkButton *button, dt_lib_module_t *self)
static void _lib_masks_update_list(dt_lib_module_t *self)
static void _tree_add_brush(GtkButton *button, dt_iop_module_t *module)
@ TREE_IC_INVERSE_VISIBLE
static void _lib_masks_update_item(dt_lib_module_t *self, int formid, int parentid, dt_lib_masks_t *lm, GtkTreeModel *model, GtkTreeIter *iter)
static void _lib_masks_get_values(GtkTreeModel *model, GtkTreeIter *iter, dt_iop_module_t **module, int *groupid, int *formid)
static void _tree_inverse(GtkButton *button, dt_lib_module_t *self)
static GtkWidget * _tree_context_menu(GtkTreeSelection *selection, GtkTreeModel *model, dt_lib_module_t *self, dt_iop_module_t *module)
static gboolean _find_iter_by_parentid_and_formid(GtkTreeModel *model, int parentid, int formid, GtkTreeIter *iter)
static gboolean _find_child_iter_by_formid(GtkTreeModel *model, GtkTreeIter *parent_iter, int formid, GtkTreeIter *child_iter)
static gboolean _remove_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
static void _tree_delete_shape(GtkButton *button, dt_lib_module_t *self)
static int _tree_format_form_usage_label(char *str, const size_t str_size, const dt_masks_form_t *form, const dt_iop_module_t *module)
static gboolean _tree_restrict_select(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data)
static gboolean _lib_masks_module_is_current(const dt_iop_module_t *module)
void gui_cleanup(dt_lib_module_t *self)
static void _lib_masks_selection_change(dt_lib_module_t *self, struct dt_iop_module_t *module, const int selectid, const int throw_event)
static void _lib_masks_release_blending(dt_lib_module_t *self)
static void _is_form_used(int formid, dt_masks_form_t *grp, char *text, size_t text_length, int *nb)
static gboolean _lib_masks_selection_change_r(GtkTreeModel *model, GtkTreeSelection *selection, GtkTreeIter *iter, struct dt_iop_module_t *module, const int selectid, int throw_event, const int level)
static void _tree_selection_change(GtkTreeSelection *selection, dt_lib_masks_t *self)
static void _add_masks_history_item(dt_lib_masks_t *lm)
static gboolean _update_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
static void _tree_add_gradient(GtkButton *button, dt_iop_module_t *module)
static void _lib_masks_recreate_list(dt_lib_module_t *self)
static void _tree_add_polygon(GtkButton *button, dt_iop_module_t *module)
static void _tree_moveup(GtkButton *button, dt_lib_module_t *self)
static void _tree_movedown(GtkButton *button, dt_lib_module_t *self)
static void _tree_add_ellipse(GtkButton *button, dt_iop_module_t *module)
static void _tree_duplicate_shape(GtkButton *button, dt_lib_module_t *self)
static int _tree_button_pressed(GtkWidget *treeview, GdkEventButton *event, dt_lib_module_t *self)
uint32_t container(dt_lib_module_t *self)
static void _tree_difference(GtkButton *button, dt_lib_module_t *self)
gboolean _find_mask_iter_by_values(GtkTreeModel *model, GtkTreeIter *iter, const dt_iop_module_t *module, const int formid, const int level)
static void _lib_masks_handler_callback(gpointer instance, const int formid, const int parentid, const dt_masks_event_t event, dt_lib_module_t *self)
static void _lib_masks_shape_button_started(GtkWidget *button, dt_iop_module_t *module, dt_masks_type_t type, gpointer user_data)
static void _tree_cell_edited(GtkCellRendererText *cell, gchar *path_string, gchar *new_text, dt_lib_module_t *self)
void gui_init(dt_lib_module_t *self)
static void _tree_intersection(GtkButton *button, dt_lib_module_t *self)
const char ** views(dt_lib_module_t *self)
static void _lib_masks_clear_blending_box(dt_lib_module_t *self)
static gboolean _lib_masks_can_host_blending(const dt_iop_module_t *module)
static void _tree_cleanup(GtkButton *button, dt_lib_module_t *self)
static gboolean _tree_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data)
static void _lib_masks_blending_gui_changed_callback(gpointer instance, dt_lib_module_t *self)
static void _lib_masks_list_recurs(GtkTreeStore *treestore, GtkTreeIter *toplevel, dt_masks_form_t *form, int grp_id, dt_iop_module_t *module, int gstate, float opacity, dt_lib_masks_t *lm, int index)
GList * _lib_masks_get_selected(dt_lib_module_t *self)
static void _tree_exclusion(GtkButton *button, dt_lib_module_t *self)
static void _lib_masks_show_blending_message(dt_lib_module_t *self, gchar *markup)
void apply_operation(struct dt_masks_form_group_t *pt, const dt_masks_state_t apply_state)
Apply a mask state operation on a group entry.
dt_masks_form_group_t * dt_masks_group_add_form(dt_masks_form_t *grp, dt_masks_form_t *form)
@ DT_MASKS_SHAPE_INDEX_BRUSH
@ DT_MASKS_SHAPE_INDEX_ELLIPSE
@ DT_MASKS_SHAPE_INDEX_CIRCLE
@ DT_MASKS_SHAPE_INDEX_GRADIENT
@ DT_MASKS_SHAPE_INDEX_POLYGON
void dt_masks_change_form_gui(dt_masks_form_t *newform)
@ DT_MASKS_STATE_DIFFERENCE
@ DT_MASKS_STATE_INTERSECTION
@ DT_MASKS_STATE_EXCLUSION
void dt_masks_shape_buttons_deactivate_all(GtkWidget *active_button)
GtkWidget * dt_masks_shape_buttons_create(const dt_masks_shape_buttons_config_t *config)
Build a synchronized toolbar for creating masks shapes.
int dt_masks_center_view_on_form(struct dt_develop_t *dev, const struct dt_masks_form_t *form)
void dt_masks_cleanup_unused(dt_develop_t *dev)
Cleanup unused masks and refresh the current forms snapshot.
void dt_masks_group_ungroup(dt_masks_form_t *dest_grp, dt_masks_form_t *grp)
dt_masks_form_t * dt_masks_create(dt_masks_type_t type)
@ DT_MASKS_SHAPE_BUTTONS_NONE
@ DT_MASKS_SHAPE_BUTTONS_ALL
gboolean dt_masks_creation_mode_enter(dt_iop_module_t *module, const dt_masks_type_t type)
Enter mask creation mode for a given shape type.
void dt_masks_form_move(dt_masks_form_t *grp, int formid, int up)
dt_masks_form_t * dt_masks_get_from_id(dt_develop_t *dev, int id)
void dt_masks_form_delete(struct dt_iop_module_t *module, dt_masks_form_t *grp, dt_masks_form_t *form)
#define DEVELOP_MASKS_NB_SHAPES
void dt_masks_reset_show_masks_icons(void)
int dt_masks_form_duplicate(dt_develop_t *dev, int formid)
void dt_masks_set_visible_form(struct dt_develop_t *dev, dt_masks_form_t *form)
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
@ DT_SIGNAL_DEVELOP_MASKS_GUI_CHANGED
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
const float uint32_t state[4]
struct dt_gui_gtk_t * gui
struct dt_control_signal_t * signals
struct dt_develop_t * develop
struct dt_view_manager_t * view_manager
void(* list_update)(struct dt_lib_module_t *self)
void(* list_remove)(struct dt_lib_module_t *self, int formid, int parentid)
struct dt_iop_module_t * gui_module
struct dt_lib_module_t *void(* list_change)(struct dt_lib_module_t *self)
struct dt_masks_form_gui_t * form_gui
struct dt_develop_t::@20::@28 masks
void(* selection_change)(struct dt_lib_module_t *self, struct dt_iop_module_t *module, const int selectid, const int throw_event)
struct dt_develop_t::@20 proxy
struct dt_develop_blend_params_t * blend_params
GModule *dt_dev_operation_t op
GdkPixbuf * ic_intersection
GdkPixbuf * ic_difference
dt_iop_module_t * hosted_module
dt_iop_module_t * active_module
struct dt_view_manager_t::@67 proxy
struct dt_view_manager_t::@67::@68 module_toolbox
void dt_view_manager_module_toolbox_add(dt_view_manager_t *vm, GtkWidget *tool, dt_view_type_flags_t views)
@ DT_UI_CONTAINER_PANEL_LEFT_CENTER