58#ifdef GDK_WINDOWING_QUARTZ
65#pragma GCC diagnostic ignored "-Wshadow"
89 return _(
"Masking & Blending");
94 static const char *
v[] = {
"darkroom", NULL};
140 if(G_VALUE_TYPE(&gv) == G_TYPE_POINTER)
141 *
module = (dt_iop_module_t *)g_value_get_pointer(&gv);
149 *groupid = g_value_get_int(&gv);
157 *formid = g_value_get_int(&gv);
164 return darktable.
develop &&
module && g_list_find(darktable.develop->iop, (gpointer)module);
171 GList *children = gtk_container_get_children(GTK_CONTAINER(self->
widget));
172 for(GList *iter = children; iter; iter = g_list_next(iter))
173 gtk_widget_destroy(GTK_WIDGET(iter->data));
174 g_list_free(children);
205 gtk_label_set_markup(GTK_LABEL(label), markup);
206 gtk_label_set_xalign(GTK_LABEL(label), 0.0f);
207 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
210 gtk_widget_set_sensitive(label,
FALSE);
214 gtk_widget_show_all(label);
229 gchar *markup = g_markup_printf_escaped(_(
"<i>Select a module to edit its blending settings.</i>"));
243 gchar *markup = g_markup_printf_escaped(_(
"<i>Blending is not available for the <b>%s</b> module.</i>"), module_label);
252 const gboolean module_changed = (lm->
active_module != module);
318 const int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),
"formid"));
319 dt_iop_module_t *
module = g_object_get_data(G_OBJECT(button), "module");
344 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
345 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
347 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
348 for(GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
350 GtkTreePath *item = (GtkTreePath *)items_iter->data;
352 if(gtk_tree_model_get_iter(
model, &iter, item))
364 mask->points = g_list_append(mask->points, fpt);
368 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
386 g_strlcat(str, form->
name, str_size);
390 for(
const GList *modules =
darktable.
develop->
iop; modules; modules = g_list_next(modules))
396 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
401 if(
m == module)
return -1;
402 if(nbuse == 0) g_strlcat(str,
" (", str_size);
403 g_strlcat(str,
" ", str_size);
405 g_strlcat(str, module_label, str_size);
413 if(nbuse > 0) g_strlcat(str,
" )", str_size);
418 GtkTreeModel *
model, GtkTreeIter *iter,
int index)
426 g_snprintf(str,
sizeof(str),
"%s %d%%",
427 form->
name, (
int)(opacity * 100));
431 g_strlcpy(str, form->
name,
sizeof(str));
434 GdkPixbuf *icop = NULL;
435 GdkPixbuf *icinv = NULL;
473 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
474 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
476 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
477 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
479 GtkTreePath *item = (GtkTreePath *)items_iter->data;
481 if(gtk_tree_model_get_iter(
model, &iter, item))
492 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
497 const int old_state = pt->
state;
499 if(pt->
state != old_state)
512 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
528 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
529 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
531 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
532 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
534 GtkTreePath *item = (GtkTreePath *)items_iter->data;
536 if(gtk_tree_model_get_iter(
model, &iter, item))
547 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
552 const int old_state = pt->
state;
554 if(pt->
state != old_state)
567 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
583 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
584 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
586 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
587 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
589 GtkTreePath *item = (GtkTreePath *)items_iter->data;
591 if(gtk_tree_model_get_iter(
model, &iter, item))
602 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
607 const int old_state = pt->
state;
609 if(pt->
state != old_state)
622 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
638 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
639 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
641 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
642 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
644 GtkTreePath *item = (GtkTreePath *)items_iter->data;
646 if(gtk_tree_model_get_iter(
model, &iter, item))
657 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
662 const int old_state = pt->
state;
664 if(pt->
state != old_state)
677 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
693 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
694 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
696 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
697 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
699 GtkTreePath *item = (GtkTreePath *)items_iter->data;
701 if(gtk_tree_model_get_iter(
model, &iter, item))
712 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
717 const int old_state = pt->
state;
719 if(pt->
state != old_state)
732 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
751 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
752 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
754 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
755 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
757 GtkTreePath *item = (GtkTreePath *)items_iter->data;
759 if(gtk_tree_model_get_iter(
model, &iter, item))
770 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
789 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
790 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
792 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
793 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
795 GtkTreePath *item = (GtkTreePath *)items_iter->data;
797 if(gtk_tree_model_get_iter(
model, &iter, item))
808 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
827 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
828 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
831 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
832 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
834 GtkTreePath *item = (GtkTreePath *)items_iter->data;
836 if(gtk_tree_model_get_iter(
model, &iter, item))
846 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
863 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
864 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
865 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
867 GtkTreePath *item = (GtkTreePath *)
items->data;
869 if(gtk_tree_model_get_iter(
model, &iter, item))
889 for(GList *pts = grp->
points; pts; pts = g_list_next(pts))
892 if(pt->
formid ==
id) { orig_entry = pt;
break; }
897 if(new_entry && orig_entry)
919 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
927 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
929 if(!gtk_tree_model_get_iter_from_string(
model, &iter, path_string))
return;
939 gchar *text = strlen(new_text) == 0 ?
" " : new_text;
943 g_strlcpy(form->
name, text,
sizeof(form->
name));
957 const int nb = gtk_tree_selection_count_selected_rows(selection);
966 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->
treeview));
969 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
970 for(
const GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
972 GtkTreePath *item = (GtkTreePath *)items_iter->data;
974 if(gtk_tree_model_get_iter(
model, &iter, item))
983 if(nb == 1) selected_form = form;
996 if(module && module->blend_data
1002 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bd->
masks_edit),
TRUE);
1009 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
1027 GtkMenuShell *menu = GTK_MENU_SHELL(gtk_menu_new());
1031 const int nb = gtk_tree_selection_count_selected_rows(selection);
1039 GList *selected = gtk_tree_selection_get_selected_rows(selection, NULL);
1040 GtkTreePath *it0 = (GtkTreePath *)selected->data;
1041 depth = gtk_tree_path_get_depth(it0);
1045 if(gtk_tree_model_get_iter(
model, &iter, it0))
1050 g_list_free_full(selected, (GDestroyNotify)gtk_tree_path_free);
1053 if(depth > 1) from_group = 1;
1058 GtkWidget *add_item = gtk_menu_item_new_with_label(_(
"Add new shape ..."));
1059 gtk_menu_item_set_submenu(GTK_MENU_ITEM(add_item), add_menu);
1060 gtk_menu_shell_append(menu, add_item);
1062 item = gtk_menu_item_new_with_label(_(
"add circle"));
1064 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1066 item = gtk_menu_item_new_with_label(_(
"add ellipse"));
1068 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1070 item = gtk_menu_item_new_with_label(_(
"add path"));
1072 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1074 item = gtk_menu_item_new_with_label(_(
"add gradient"));
1076 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1078 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1087 GtkWidget *add_item = gtk_menu_item_new_with_label(_(
"Add new shape ..."));
1088 gtk_menu_item_set_submenu(GTK_MENU_ITEM(add_item), add_menu);
1089 gtk_menu_shell_append(menu, add_item);
1091 item = gtk_menu_item_new_with_label(_(
"Add brush"));
1092 g_signal_connect(item,
"activate", (GCallback)
_tree_add_brush, module);
1093 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1095 item = gtk_menu_item_new_with_label(_(
"Add circle"));
1097 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1099 item = gtk_menu_item_new_with_label(_(
"Add ellipse"));
1101 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1103 item = gtk_menu_item_new_with_label(_(
"Add polygon"));
1105 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1107 item = gtk_menu_item_new_with_label(_(
"Add gradient"));
1109 gtk_menu_shell_append(GTK_MENU_SHELL(add_menu), item);
1112 gboolean has_unused_shapes =
FALSE;
1121 char str[10000] =
"";
1123 if(nbuse == -1)
continue;
1126 item = gtk_menu_item_new_with_label(str);
1127 g_object_set_data(G_OBJECT(item),
"formid", GUINT_TO_POINTER(form->
formid));
1128 g_object_set_data(G_OBJECT(item),
"module", module);
1129 g_signal_connect(G_OBJECT(item),
"activate", G_CALLBACK(
_tree_add_exist), grp);
1130 gtk_menu_shell_append(GTK_MENU_SHELL(menu0), item);
1131 has_unused_shapes =
TRUE;
1134 if(has_unused_shapes)
1136 item = gtk_menu_item_new_with_label(_(
"Add shape ..."));
1137 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu0);
1138 gtk_menu_shell_append(menu, item);
1143 if(nb > 1 && !from_group)
1145 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1146 item = gtk_menu_item_new_with_label(_(
"Group the forms"));
1147 g_signal_connect(item,
"activate", (GCallback)
_tree_group, self);
1148 gtk_menu_shell_append(menu, item);
1151 if(from_group && depth < 3)
1153 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1154 item = gtk_menu_item_new_with_label(_(
"Invert shape"));
1155 g_signal_connect(item,
"activate", (GCallback)
_tree_inverse, self);
1156 gtk_menu_shell_append(menu, item);
1159 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1160 item = gtk_menu_item_new_with_label(_(
"Union"));
1161 g_signal_connect(item,
"activate", (GCallback)
_tree_union, self);
1162 gtk_menu_shell_append(menu, item);
1163 item = gtk_menu_item_new_with_label(_(
"Intersection"));
1165 gtk_menu_shell_append(menu, item);
1166 item = gtk_menu_item_new_with_label(_(
"Difference"));
1168 gtk_menu_shell_append(menu, item);
1169 item = gtk_menu_item_new_with_label(_(
"Exclusion"));
1171 gtk_menu_shell_append(menu, item);
1173 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1174 item = gtk_menu_item_new_with_label(_(
"Move up"));
1175 g_signal_connect(item,
"activate", (GCallback)
_tree_moveup, self);
1176 gtk_menu_shell_append(menu, item);
1177 item = gtk_menu_item_new_with_label(_(
"Move down"));
1178 g_signal_connect(item,
"activate", (GCallback)
_tree_movedown, self);
1179 gtk_menu_shell_append(menu, item);
1180 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1186 item = gtk_menu_item_new_with_label(_(
"Duplicate shape"));
1188 gtk_menu_shell_append(menu, item);
1189 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
1192 if(!from_group && nb > 0)
1196 item = gtk_menu_item_new_with_label(_(
"Delete shape"));
1198 gtk_menu_shell_append(menu, item);
1202 item = gtk_menu_item_new_with_label(_(
"Delete mask"));
1204 gtk_menu_shell_append(menu, item);
1207 else if(nb > 0 && depth < 3)
1209 item = gtk_menu_item_new_with_label(_(
"Remove shape from mask"));
1211 gtk_menu_shell_append(menu, item);
1214 item = gtk_menu_item_new_with_label(_(
"Cleanup unused shapes"));
1215 g_signal_connect(item,
"activate", (GCallback)
_tree_cleanup, self);
1216 gtk_menu_shell_append(menu, item);
1218 return GTK_WIDGET(menu);
1224 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
1225 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
1227 GtkTreePath *mouse_path = NULL;
1231 if(gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &mouse_path, NULL,
1236 if(gtk_tree_model_get_iter(
model, &iter, mouse_path))
1242 if(event->type == GDK_BUTTON_PRESS && event->button == 1)
1247 gtk_tree_selection_unselect_all(selection);
1250 else if(event->type == GDK_BUTTON_PRESS && event->button == 3)
1253 if(on_row && !gtk_tree_selection_path_is_selected(selection, mouse_path))
1255 if(!
dt_modifier_is(event->state, GDK_CONTROL_MASK)) gtk_tree_selection_unselect_all(selection);
1256 gtk_tree_selection_select_path(selection, mouse_path);
1257 gtk_tree_path_free(mouse_path);
1263 gtk_widget_show_all(menu);
1265 gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
1274 gboolean path_currently_selected, gpointer data)
1280 if(path_currently_selected)
return TRUE;
1283 if(gtk_tree_selection_count_selected_rows(selection) == 0)
return TRUE;
1287 int *indices = gtk_tree_path_get_indices(path);
1288 int depth = gtk_tree_path_get_depth(path);
1290 GList *
items = gtk_tree_selection_get_selected_rows(selection, NULL);
1291 GList *items_iter =
items;
1294 GtkTreePath *item = (GtkTreePath *)items_iter->data;
1295 int dd = gtk_tree_path_get_depth(item);
1296 int *ii = gtk_tree_path_get_indices(item);
1302 else if(ii[dd - 2] != indices[dd - 2])
1306 gtk_tree_selection_unselect_path(selection, item);
1307 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
1309 items_iter =
items = gtk_tree_selection_get_selected_rows(selection, NULL);
1312 items_iter = g_list_next(items_iter);
1314 g_list_free_full(
items, (GDestroyNotify)gtk_tree_path_free);
1320 GtkTooltip *
tooltip, gpointer data)
1323 GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
1324 GtkTreeModel *
model = gtk_tree_view_get_model(tree_view);
1325 GtkTreePath *path = NULL;
1327 gboolean show =
FALSE;
1329 if(!gtk_tree_view_get_tooltip_context(tree_view, &
x, &y, keyboard_tip, &
model, &path, &iter))
return FALSE;
1334 gtk_tooltip_set_markup(
tooltip, tmp);
1335 gtk_tree_view_set_tooltip_row(tree_view,
tooltip, path);
1338 gtk_tree_path_free(path);
1356 for(
const GList *points = grp->
points; points; points = g_list_next(points))
1362 if(
point->formid == formid)
1365 if(*nb > 1) g_strlcat(text,
"\n", text_length);
1366 g_strlcat(text, grp->
name, text_length);
1381 g_strlcat(str, form->
name,
sizeof(str));
1383 GdkPixbuf *icop = NULL;
1384 GdkPixbuf *icinv = NULL;
1385 GdkPixbuf *icuse = NULL;
1395 char str2[1000] =
"";
1400 if(nbuse > 0) icuse = lm->
ic_wired;
1407 gtk_tree_store_append(treestore, &child, toplevel);
1413 _set_iter_name(lm, form, gstate, opacity, GTK_TREE_MODEL(treestore), &child, index);
1418 if(grp_id == 0 && !module)
1434 gtk_tree_store_append(treestore, &child, toplevel);
1440 _set_iter_name(lm, form, gstate, opacity, GTK_TREE_MODEL(treestore), &child, index);
1444 for(
const GList *forms = form->
points; forms; forms = g_list_next(forms))
1458 gboolean found =
FALSE;
1464 found = (fid == formid)
1466 || (
IS_NULL_PTR(module) || (mod && (!g_strcmp0(module->
op, mod->
op)))));
1467 if(found)
return found;
1468 GtkTreeIter child, parent = *iter;
1469 if(gtk_tree_model_iter_children(
model, &child, &parent))
1478 }
while(gtk_tree_model_iter_next(
model, iter));
1487 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1489 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1491 GList *
items = gtk_tree_selection_get_selected_rows(selection, &
model);
1493 for(GList *items_iter =
items; items_iter; items_iter = g_list_next(items_iter))
1495 GtkTreePath *item = (GtkTreePath *)items_iter->data;
1497 if(gtk_tree_model_get_iter(
model, &iter, item))
1503 res = g_list_prepend(res, GINT_TO_POINTER(fid));
1504 res = g_list_prepend(res, GINT_TO_POINTER(gid));
1505 res = g_list_prepend(res, (
void *)(mod));
1509 g_list_foreach(
items, (GFunc)gtk_tree_path_free, NULL);
1525 gboolean sync_center_view =
FALSE;
1529 GList *selectids = NULL;
1542 GtkTreeStore *treestore;
1544 treestore = gtk_tree_store_new(
TREE_COUNT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT,
1545 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
1546 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_STRING);
1562 gtk_tree_view_set_model(GTK_TREE_VIEW(lm->
treeview), GTK_TREE_MODEL(treestore));
1567 GList *ids = selectids;
1570 GtkTreeModel *
model = GTK_TREE_MODEL(treestore);
1572 ids = g_list_next(ids);
1574 ids = g_list_next(ids);
1575 const int fid = GPOINTER_TO_INT(ids->data);
1576 ids = g_list_next(ids);
1579 gtk_tree_model_get_iter_first(
model, &iter);
1585 GtkTreePath *path = gtk_tree_model_get_path(
model, &iter);
1586 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(lm->
treeview), path);
1587 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(lm->
treeview), path, NULL,
TRUE, 0.5, 0.5);
1588 gtk_tree_path_free(path);
1589 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1590 gtk_tree_selection_select_iter(selection, &iter);
1593 g_list_free(selectids);
1599 const int current_group_id
1608 GtkTreeModel *
model = GTK_TREE_MODEL(treestore);
1610 if(gtk_tree_model_get_iter_first(
model, &iter))
1615 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1616 GtkTreePath *path = gtk_tree_model_get_path(
model, &iter);
1617 gtk_tree_selection_unselect_all(selection);
1618 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(lm->
treeview), path);
1619 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(lm->
treeview), path, NULL,
TRUE, 0.5, 0.5);
1620 gtk_tree_selection_select_iter(selection, &iter);
1621 gtk_tree_path_free(path);
1622 sync_center_view =
TRUE;
1627 g_object_unref(treestore);
1631 if(sync_center_view)
1633 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1647 float opacity = 1.0f;
1652 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
1685 float opacity = 1.0f;
1690 for(
const GList *pts = grp->
points; pts; pts = g_list_next(pts))
1715 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1716 if(!GTK_IS_TREE_MODEL(
model))
return;
1723 GList **rl = (GList **)data;
1724 const int refid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(
model),
"formid"));
1725 const int refgid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(
model),
"groupid"));
1731 if(grid == refgid &&
id == refid)
1733 GtkTreeRowReference *rowref = gtk_tree_row_reference_new(
model, path);
1734 *rl = g_list_append(*rl, rowref);
1743 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1745 g_object_set_data(G_OBJECT(
model),
"formid", GUINT_TO_POINTER(formid));
1746 g_object_set_data(G_OBJECT(
model),
"groupid", GUINT_TO_POINTER(parentid));
1749 for(
const GList *rlt = rl; rlt; rlt = g_list_next(rlt))
1751 GtkTreeRowReference *rowref = (GtkTreeRowReference *)rlt->data;
1752 GtkTreePath *path = gtk_tree_row_reference_get_path(rowref);
1753 gtk_tree_row_reference_free(rowref);
1757 if(gtk_tree_model_get_iter(
model, &iter, path))
1759 gtk_tree_store_remove(GTK_TREE_STORE(
model), &iter);
1761 gtk_tree_path_free(path);
1770 const int selectid,
int throw_event,
const int level)
1772 gboolean found =
FALSE;
1774 GtkTreeIter
i = *iter;
1783 || (
IS_NULL_PTR(module) || (mod && (!g_strcmp0(module->
op, mod->
op))))))
1785 gtk_tree_selection_select_iter(selection, &
i);
1791 GtkTreeIter child, parent =
i;
1792 if(gtk_tree_model_iter_children(
model, &child, &parent))
1800 }
while(gtk_tree_model_iter_next(
model, &
i) ==
TRUE);
1811 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(lm->
treeview));
1813 gtk_tree_selection_unselect_all(selection);
1819 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1820 if(!GTK_IS_TREE_MODEL(
model))
1825 gboolean valid = gtk_tree_model_get_iter_first(
model, &iter);
1829 gtk_tree_view_expand_all(GTK_TREE_VIEW(lm->
treeview));
1831 if(!found) gtk_tree_view_collapse_all(GTK_TREE_VIEW(lm->
treeview));
1840 gboolean found =
FALSE;
1843 if(gtk_tree_model_iter_children(
model, &iter, parent_iter))
1847 int current_formid = -1;
1850 if(current_formid == formid)
1856 }
while(gtk_tree_model_iter_next(
model, &iter));
1864 gboolean found =
FALSE;
1869 int current_parentid = -1;
1872 if(current_parentid == parentid)
1881 }
while(gtk_tree_model_iter_next(
model, iter));
1892 GtkTreeModel *
model = gtk_tree_view_get_model(GTK_TREE_VIEW(lm->
treeview));
1893 if(!GTK_IS_TREE_MODEL(
model))
return;
1895 gboolean found_iter = gtk_tree_model_get_iter_first(
model, &iter);
1962 if(!
d->popup_window)
return;
1964 if(gtk_widget_get_visible(
d->popup_window))
1966 gtk_widget_hide(
d->popup_window);
1970 gtk_widget_show_all(
d->popup_window);
1980 if(!
d || !
d->popup_button)
return FALSE;
1994 self->
data = (
void *)
d;
2007 d->popup_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2008 gtk_window_set_title(GTK_WINDOW(
d->popup_window), _(
"Mask Manager Panel"));
2009 gtk_window_set_type_hint(GTK_WINDOW(
d->popup_window), GDK_WINDOW_TYPE_HINT_UTILITY);
2013 gtk_window_set_modal(GTK_WINDOW(
d->popup_window),
FALSE);
2014 gtk_window_set_focus_on_map(GTK_WINDOW(
d->popup_window),
FALSE);
2015 gtk_window_set_accept_focus(GTK_WINDOW(
d->popup_window),
FALSE);
2018#ifdef GDK_WINDOWING_QUARTZ
2020 gtk_window_set_position(GTK_WINDOW(
d->popup_window), GTK_WIN_POS_CENTER_ON_PARENT);
2024 g_signal_connect(G_OBJECT(
d->popup_window),
"delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
2028 gtk_container_add(GTK_CONTAINER(
d->popup_window), shape_manager_container);
2038 gtk_widget_set_tooltip_text(
d->popup_button, _(
"Open mask manager..."));
2052 .creation_module = NULL,
2053 .buttons = shape_buttons,
2055 .action_section = NULL,
2067 gtk_box_pack_end(GTK_BOX(hbox), shape_buttons_box,
FALSE,
FALSE, 0);
2074 gtk_box_pack_start(GTK_BOX(shape_manager_container), hbox,
TRUE,
TRUE, 0);
2076 d->treeview = gtk_tree_view_new();
2077 GtkTreeViewColumn *col = gtk_tree_view_column_new();
2078 gtk_tree_view_column_set_title(col,
"shapes");
2079 gtk_tree_view_append_column(GTK_TREE_VIEW(
d->treeview), col);
2081 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
2082 gtk_tree_view_column_pack_start(col, renderer,
FALSE);
2083 gtk_tree_view_column_set_attributes(col, renderer,
"pixbuf",
TREE_IC_OP, NULL);
2085 renderer = gtk_cell_renderer_pixbuf_new();
2086 gtk_tree_view_column_pack_start(col, renderer,
FALSE);
2087 gtk_tree_view_column_set_attributes(col, renderer,
"pixbuf",
TREE_IC_INVERSE, NULL);
2089 renderer = gtk_cell_renderer_text_new();
2090 gtk_tree_view_column_pack_start(col, renderer,
TRUE);
2091 gtk_tree_view_column_add_attribute(col, renderer,
"text",
TREE_TEXT);
2092 gtk_tree_view_column_add_attribute(col, renderer,
"editable",
TREE_EDITABLE);
2094 renderer = gtk_cell_renderer_pixbuf_new();
2095 gtk_tree_view_column_pack_end(col, renderer,
FALSE);
2096 gtk_tree_view_column_set_attributes(col, renderer,
"pixbuf",
TREE_IC_USED, NULL);
2099 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
d->treeview));
2100 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
2102 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(
d->treeview),
FALSE);
2104 g_object_set(
d->treeview,
"has-tooltip",
TRUE, (gchar *)0);
2110 gtk_box_pack_start(GTK_BOX(shape_manager_container),
2132 if(self && self->
data)
2139 gtk_widget_destroy(
d->popup_window);
2140 d->popup_window = NULL;
2143 if(!
IS_NULL_PTR(
d->ic_inverse)) g_object_unref(
d->ic_inverse);
2146 if(!
IS_NULL_PTR(
d->ic_intersection)) g_object_unref(
d->ic_intersection);
2147 if(!
IS_NULL_PTR(
d->ic_difference)) g_object_unref(
d->ic_difference);
2148 if(!
IS_NULL_PTR(
d->ic_exclusion)) g_object_unref(
d->ic_exclusion);
2150 d->ic_inverse = NULL;
2153 d->ic_intersection = NULL;
2154 d->ic_difference = NULL;
2155 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)
int expandable(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)
dt_masks_form_t * dt_masks_cow_touch(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::@69 proxy
struct dt_view_manager_t::@69::@70 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