Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
masks_gui.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2013-2014, 2016, 2019, 2021 Aldric Renaudin.
4 Copyright (C) 2013, 2018, 2020-2021 Pascal Obry.
5 Copyright (C) 2013 Simon Spannagel.
6 Copyright (C) 2013-2014, 2016-2018 Tobias Ellinghaus.
7 Copyright (C) 2013-2017, 2019-2020 Ulrich Pegelow.
8 Copyright (C) 2014-2016 Roman Lebedev.
9 Copyright (C) 2017-2019 Edgardo Hoszowski.
10 Copyright (C) 2021 Hanno Schwalm.
11 Copyright (C) 2021 Hubert Kowalski.
12 Copyright (C) 2021 luzpaz.
13 Copyright (C) 2021 Philipp Lutz.
14 Copyright (C) 2021 Ralf Brown.
15 Copyright (C) 2022 Martin Bařinka.
16 Copyright (C) 2023, 2025-2026 Aurélien PIERRE.
17 Copyright (C) 2023 Luca Zulberti.
18 Copyright (C) 2025 Alynx Zhou.
19 Copyright (C) 2025-2026 Guillaume Stutin.
20
21 darktable is free software: you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation, either version 3 of the License, or
24 (at your option) any later version.
25
26 darktable is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
30
31 You should have received a copy of the GNU General Public License
32 along with darktable. If not, see <http://www.gnu.org/licenses/>.
33*/
34
47#ifndef DT_DEVELOP_MASKS_GUI_H
48#define DT_DEVELOP_MASKS_GUI_H
49
50#include "develop/masks.h"
51#include "widgets/draw.h"
52
53#include <gtk/gtk.h>
54
55#ifdef __cplusplus
56extern "C" {
57#endif
58struct dt_masks_form_t;
60struct dt_develop_t;
63{
64 float *points; // points in absolute coordinates in output image space
66 float *border; // border points in absolute coordinates in output image space
68 float *source; // source point in absolute coordinates in output image space
70 gboolean clockwise;
72
73
75typedef struct dt_masks_form_gui_t
76{
77 // Owning develop instance, set once at init. Mask GUI code must use this (or an explicit
78 // dev/module argument) instead of the darktable.develop global: shape handlers can run with
79 // module == NULL (mask-manager editing), and reaching for the global both couples every
80 // shape file to the whole application and hides which develop instance the code mutates.
82
84 // currently visible form when editing masks (GUI-only; may be a temporary copy)
86 // points used to draw the form
87 GList *points; // list of dt_masks_form_gui_points_t
88
89 // points used to sample mouse moves
92
93 // values for mouse positions, etc...
94
95 // Mouse position in absolute coordinates in final image space
96 // This is used to map input event handlers to *_post_expose() drawing functions
97 // and to record drag & drop starting coordinates.
98 float pos[2];
99
100 // Mouse position in normalized coordinates in output image space.
101 // This is cached once per top-level event and replaces ad-hoc pzx/pzy recomputation.
102 float rel_pos[2];
103
104 // Mouse position in absolute coordinates in raw input image space.
105 // This is cached once per top-level event so nested handlers can reuse it.
106 float raw_pos[2];
107
108 // delta movement of the mouse in absolute coordinates in final image space
109 // This is used to map input event handlers to *_post_expose() drawing functions
110 float delta[2];
111
112 // scroll offset
114
115 // Position of a clone mask's source point (in what coordinates space ?)
116 float pos_source[2];
117
119
120 int node_hovered; // this is the index of the node, refreshed on mouse_moved when a a group is selected
121 int handle_hovered; // this is the index of the node, refreshed on mouse_moved when a a group is selected
122 int seg_hovered; // this is the index of the segment, refreshed on mouse_moved when a a group is selected
123 int handle_border_hovered; // this is the index of the node, refreshed on mouse_moved when a a group is selected
124
125 gboolean node_selected; // this is the state of the node referenced by node_hovered
126 gboolean handle_selected; // this is the state of the handle referenced by handle_hovered
127 gboolean seg_selected; // this is the state of the segment referenced by segment_hovered
128 gboolean handle_border_selected; // this is the state of the border handle referenced by handle_border_hovered
129 int node_selected_idx; // stable selected node index, distinct from current hover
130
135
137
139
149
150 // Throttle GUI rebuilds while dragging to avoid heavy border recomputation.
154
155 // Throttle handle hit-testing when cursor barely moves.
157
158 gboolean creation;
161 // Shape type reused to create the next temporary form in a continuous creation session.
163 // Form ids completed during the active creation session; only these are drawn while creation stays active.
165 // Last completed form id, selected when the creation session is disabled.
167
169
170 // ids
174
179void dt_masks_gui_init(struct dt_develop_t *dev);
180void dt_masks_gui_cleanup(struct dt_develop_t *dev);
184
185// Test wether the form, the border, the source or the pivot is selected
187{
188 return gui && (gui->form_selected || gui->border_selected || gui->source_selected || gui->pivot_selected);
189}
190
192{
193 return (gui && gui->node_selected) ? gui->node_selected_idx : -1;
194}
195
197{
198 return (gui && gui->handle_selected) ? gui->handle_hovered : -1;
199}
200
202{
203 return (gui && gui->handle_border_selected) ? gui->handle_border_hovered : -1;
204}
205
207{
208 return (gui) ? gui->seg_hovered : -1;
209}
210
212 const int index)
213{
214 if(IS_NULL_PTR(gui)) return TRUE;
215
217 return selected_node < 0 || selected_node == index;
218}
219
220static inline float dt_masks_get_form_size_from_nodes(const GList *points)
221{
222 if(IS_NULL_PTR(points) || IS_NULL_PTR(points->data)) return 0.0f;
223
224 // Brush and polygon node payloads both start with `float node[2]`.
225 const float *first = (const float *)points->data;
226 float min_x = first[0];
227 float max_x = first[0];
228 float min_y = first[1];
229 float max_y = first[1];
230
232 {
233 const float *node = (const float *)point_node->data;
234 if(IS_NULL_PTR(node)) continue;
235 min_x = fminf(min_x, node[0]);
236 max_x = fmaxf(max_x, node[0]);
237 min_y = fminf(min_y, node[1]);
238 max_y = fmaxf(max_y, node[1]);
239 }
240
241 return fmaxf(max_x - min_x, max_y - min_y);
242}
243
245{
246 const float hit_thresh = DT_GUI_MOUSE_EFFECT_RADIUS * 0.5f;
247 const float dx = gui->pos[0] - gui->last_hit_test_pos[0];
248 const float dy = gui->pos[1] - gui->last_hit_test_pos[1];
249 if(gui->last_hit_test_pos[0] < 0.0f || (dx * dx + dy * dy) > (hit_thresh * hit_thresh))
250 {
251 gui->last_hit_test_pos[0] = gui->pos[0];
252 gui->last_hit_test_pos[1] = gui->pos[1];
253 return TRUE;
254 }
255 return FALSE;
256}
257
258// High-level mask event dispatchers cache the current cursor in raw absolute coordinates.
259// Reuse that cache for current-cursor conversions instead of backtransforming `gui->pos` again.
260static inline void dt_masks_gui_cursor_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
261{
262 point[0] = gui->raw_pos[0];
263 point[1] = gui->raw_pos[1];
265}
266
267// Reuse the cached absolute output-image cursor and drag delta to derive a raw-normalized point.
268static inline void dt_masks_gui_delta_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
269{
270 point[0] = gui->pos[0] + gui->delta[0];
271 point[1] = gui->pos[1] + gui->delta[1];
273}
274
275static inline void dt_masks_gui_delta_to_image_abs(const dt_masks_form_gui_t *gui, float point[2])
276{
277 point[0] = gui->pos[0] + gui->delta[0];
278 point[1] = gui->pos[1] + gui->delta[1];
279}
280
281// Drag branches need the same "cursor + drag delta" converted back to raw space.
282// Keep that conversion in one place so all shapes use the same anchor semantics.
284 const float anchor[2], float *delta_x, float *delta_y)
285{
286 float point[2];
288 *delta_x = point[0] - anchor[0];
289 *delta_y = point[1] - anchor[1];
290}
291
292gboolean dt_masks_node_is_cusp(const dt_masks_form_gui_points_t *gpt, const int index);
294 struct dt_iop_module_t *module);
295
296// Brush and polygon nodes share the same node/control-point edit semantics.
300 const int form_index,
302 const int node_index,
303 float node[2], float ctrl1[2], float ctrl2[2],
305
306
310 const int form_index,
312 const int node_index,
314
315
316// Brush and polygon border handles both constrain the cursor to the node->handle axis.
317static inline void dt_masks_project_on_line(const float cursor[2], const float node[2],
318 const float handle[2], float point[2])
319{
320 const float dx_line = handle[0] - node[0];
321 const float dy_line = handle[1] - node[1];
322
323 if(fabsf(dx_line) < 1e-6f)
324 {
325 point[0] = node[0];
326 point[1] = cursor[1];
327 }
328 else
329 {
330 const float a = dy_line / dx_line;
331 const float b = node[1] - a * node[0];
332 const float denom = a * a + 1.0f;
333 const float xproj = (a * cursor[1] + cursor[0] - b * a) / denom;
334
335 point[0] = xproj;
336 point[1] = a * xproj + b;
337 }
338}
339
340// Border handles store normalized raw-space radii, but hit/drag code works in image space.
341// Convert both ends once here so all shapes derive border thickness the same way.
342static inline float dt_masks_border_from_projected_handle(dt_develop_t *dev, const float node[2],
343 const float projected_image_pos[2],
344 const float scale_ref)
345{
347 float node_raw[2] = { node[0], node[1] };
350
351 const float delta_x = projected_raw[0] - node_raw[0];
352 const float delta_y = projected_raw[1] - node_raw[1];
354}
355
356// Circle, ellipse and gradient creation previews all follow the same drawing sequence:
357// optional save/restore, draw the shape, then draw the border preview if present.
358static inline void dt_masks_draw_preview_shape(struct dt_develop_t *dev, cairo_t *cr, const float zoom_scale,
359 const int num_points,
360 float *points, const int points_count,
361 float *border, const int border_count,
362 const shape_draw_function_t *draw_shape,
365 const gboolean save_restore,
366 const gboolean source)
367{
368 if(save_restore) cairo_save(cr);
369 if(points && points_count > 0)
370 dt_draw_shape_lines(dev, DT_MASKS_NO_DASH, source, cr, num_points, FALSE, zoom_scale, points, points_count,
371 draw_shape, shape_cap);
372 if(border && border_count > 0)
373 dt_draw_shape_lines(dev, DT_MASKS_DASH_STICK, source, cr, num_points, FALSE, zoom_scale, border, border_count,
374 draw_shape, border_cap);
376}
377
378// Shared scratch buffers for creation previews. Keeping them grouped makes the shape
379// preview helpers return a single value and centralizes cleanup.
389
396
398{
399 struct
400 {
401 float x;
402 float y;
404
405 struct
406 {
407 float x;
408 float y;
413 dt_masks_form_gui_t *gui, int index, int node_index);
414
429
451 dt_masks_type_t type, gpointer user_data);
453 gpointer user_data);
455 dt_masks_type_t type, gpointer user_data);
456
477
478int dt_masks_events_mouse_moved(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, double pressure,
479 int which);
480int dt_masks_events_button_released(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, int which,
481 uint32_t state);
482int dt_masks_events_button_pressed(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, double pressure,
483 int which, int type, uint32_t state);
484int dt_masks_events_mouse_scrolled(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, int up, uint32_t state, int delta_y);
485
498gboolean dt_masks_node_is_cusp(const dt_masks_form_gui_points_t *gpt, const int index);
499
510void dt_masks_draw_source(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const int nb,
512void dt_masks_draw_path_seg_by_seg(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const float *points,
513 const int points_count, const int node_count, const float zoom_scale);
514
515void dt_masks_events_post_expose(dt_develop_t *dev, struct dt_iop_module_t *module, cairo_t *cr, int32_t width, int32_t height,
516 int32_t pointerx, int32_t pointery);
519
522 struct dt_iop_module_t *module);
524 struct dt_iop_module_t *module, float posx, float posy);
525
536gboolean dt_masks_gui_remove(struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui, const int parentid);
537
550
559
568
569// Remove a mask
571
574
588
590int dt_masks_point_in_form_exact(const float *pts, int num_pts, const float *points, int points_start, int points_count);
591
594
599 const float initial_ypos, const float xpos, const float ypos, float *px,
600 float *py, const int adding);
601static inline void dt_masks_draw_source_preview(cairo_t *cr, const float zoom_scale, dt_masks_form_gui_t *gui,
602 const float initial_xpos, const float initial_ypos,
603 const float xpos, const float ypos, const int adding)
604{
605 float source_pos[2] = { 0.0f, 0.0f };
607 &source_pos[0], &source_pos[1], adding);
609}
620float dt_masks_rotate_with_anchor(dt_develop_t *dev, const float anchor[2], const float center[2], dt_masks_form_gui_t *gui);
621
641 const struct dt_masks_form_gui_t *gui);
642
645
648
658 const struct dt_masks_form_gui_t *gui);
660 dt_masks_interaction_t interaction);
661gboolean dt_masks_form_get_gravity_center(dt_develop_t *dev, const struct dt_masks_form_t *form, float center[2], float *area);
669 dt_masks_interaction_t interaction,
670 float value, dt_masks_increment_t increment, int flow,
671 struct dt_masks_form_gui_t *gui, struct dt_iop_module_t *module);
672
686 dt_masks_increment_t increment, const int flow);
694 float v_min, float v_max, dt_masks_increment_t increment, int flow,
695 const char *toast_fmt, float toast_scale);
696
700float dt_masks_apply_increment(float current, float amount, dt_masks_increment_t increment, int flow);
701
705float dt_masks_apply_increment_precomputed(float current, float amount, float scale_amount, float offset_amount,
706 dt_masks_increment_t increment);
707
710
721gboolean dt_masks_point_is_within_radius(const float px, const float py,
722 const float cx, const float cy,
723 const float radius);
724
731 int node_index, float *handle_x, float *handle_y, void *user_data);
738 float *handle_x, float *handle_y, void *user_data);
745 float *node_x, float *node_y, void *user_data);
752typedef void (*dt_masks_distance_fn)(float pointer_x, float pointer_y, float cursor_radius,
754 int *inside, int *inside_border, int *near_handle, int *inside_source, float *dist,
755 void *user_data);
760 int inside_source, void *user_data);
761
777 void *user_data);
778
782
785#define menu_item_set_fake_accel(menu_item, keyval, mods) \
786 \
787{ \
788 GtkWidget *child = gtk_bin_get_child(GTK_BIN(menu_item)); \
789 if(GTK_IS_ACCEL_LABEL(child)) \
790 gtk_accel_label_set_accel(GTK_ACCEL_LABEL(child), keyval, mods); \
791}
792
793void _masks_gui_delete_node_callback(GtkWidget *menu, gpointer user_data);
794
796
798 const float pzx, const float pzy);
799
807 dt_masks_interaction_t interaction, dt_masks_increment_t increment,
808 float min, float max, float step, float value, int digits,
809 const char *format, float factor,
811
822
823int dt_masks_gui_confirm_delete_form_dialog(const char *form_name);
824
831gboolean dt_masks_gui_confirm_permanent_delete(const char *form_name);
832
835
836#ifdef __cplusplus
837}
838#endif
839
840#endif // DT_DEVELOP_MASKS_GUI_H
static double dist(double x1, double y1, double x2, double y2)
Definition ashift_lsd.c:250
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
static const float x
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
static const float const float const float min
const float max
void dt_dev_coordinates_raw_norm_to_raw_abs(dt_develop_t *dev, float *points, size_t num_points)
Definition develop.c:1223
int dt_dev_coordinates_image_abs_to_raw_abs(dt_develop_t *dev, float *points, size_t points_count)
Definition develop.c:1658
void dt_dev_coordinates_raw_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
Definition develop.c:1205
void dt_dev_coordinates_image_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
Definition develop.c:1253
static void dt_draw_cross(cairo_t *cr, const float zoom_scale, const float x, const float y)
Definition draw.h:947
static void dt_draw_shape_lines(struct dt_develop_t *dev, const dt_draw_dash_type_t dash_type, const gboolean source, cairo_t *cr, const int nb, const gboolean selected, const float zoom_scale, const float *points, const int points_count, const shape_draw_function_t *draw_shape_func, const cairo_line_cap_t line_cap)
Draw the lines of a mask shape.
Definition draw.h:788
@ DT_MASKS_DASH_STICK
Definition draw.h:134
@ DT_MASKS_NO_DASH
Definition draw.h:133
void(* shape_draw_function_t)(struct dt_develop_t *dev, cairo_t *cr, const float *points, const int points_count, const int nb, const gboolean border, const gboolean source)
Definition draw.h:773
_lib_location_type_t type
Definition location.c:1
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65
dt_masks_edit_mode_t
Definition masks.h:210
dt_masks_state_t
Definition masks.h:176
dt_masks_type_t
Definition masks.h:139
dt_masks_interaction_t
Definition masks.h:310
dt_masks_increment_t
Definition masks.h:203
dt_masks_pressure_sensitivity_t
Definition masks.h:217
dt_masks_points_states_t
Definition masks.h:191
GdkModifierType dt_masks_get_accel_mods(dt_masks_interaction_t interaction)
static void dt_masks_gui_delta_to_image_abs(const dt_masks_form_gui_t *gui, float point[2])
Definition masks_gui.h:275
gboolean dt_masks_remove_or_delete(struct dt_iop_module_t *module, dt_masks_form_t *sel, int parent_id, dt_masks_form_gui_t *mask_gui, int form_id)
If the form to remove is used once, ask to the user if he wants to delete it from the list or just re...
Definition masks_gui.c:2103
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.
Definition masks_gui.c:4190
dt_masks_form_group_t * dt_masks_group_add_form(dt_develop_t *dev, dt_masks_form_t *grp, dt_masks_form_t *form)
Definition masks_gui.c:3802
void dt_masks_group_ungroup(dt_develop_t *dev, dt_masks_form_t *dest_grp, dt_masks_form_t *grp)
Definition masks_gui.c:3825
void dt_masks_gui_form_remove(dt_masks_form_t *form, dt_masks_form_gui_t *gui, int index)
Definition masks_gui.c:2277
static int dt_masks_gui_selected_segment_index(const dt_masks_form_gui_t *gui)
Definition masks_gui.h:206
dt_masks_type_t(* dt_masks_shape_buttons_type_f)(dt_iop_module_t *module, dt_masks_type_t type, gpointer user_data)
Definition masks_gui.h:452
gboolean(* dt_masks_shape_buttons_start_f)(GtkWidget *button, dt_iop_module_t *module, dt_masks_type_t type, gpointer user_data)
Definition masks_gui.h:450
static int dt_masks_gui_selected_node_index(const dt_masks_form_gui_t *gui)
Definition masks_gui.h:191
void dt_masks_gui_set_dragging(dt_masks_form_gui_t *gui)
Definition masks_gui.c:1325
static int dt_masks_gui_selected_handle_index(const dt_masks_form_gui_t *gui)
Definition masks_gui.h:196
void dt_masks_calculate_source_pos_origin(dt_masks_form_gui_t *gui, const float initial_xpos, const float initial_ypos, const float xpos, const float ypos, float *px, float *py, const int adding)
Compute preview-space source position for drawing the clone indicator.
Definition masks_gui.c:4043
void dt_masks_change_form_gui(dt_develop_t *dev, dt_masks_form_t *newform)
Definition masks_gui.c:3337
void dt_masks_remove_form(dt_develop_t *dev, dt_masks_form_t *form)
Definition masks_gui.c:2343
dt_masks_shape_button_index_t
Definition masks_gui.h:422
@ DT_MASKS_SHAPE_INDEX_BRUSH
Definition masks_gui.h:427
@ DT_MASKS_SHAPE_INDEX_ELLIPSE
Definition masks_gui.h:425
@ DT_MASKS_SHAPE_INDEX_CIRCLE
Definition masks_gui.h:426
@ DT_MASKS_SHAPE_INDEX_GRADIENT
Definition masks_gui.h:423
@ DT_MASKS_SHAPE_INDEX_POLYGON
Definition masks_gui.h:424
void dt_masks_gui_form_create(dt_masks_form_t *form, dt_masks_form_gui_t *gui, int index, struct dt_iop_module_t *module)
Definition masks_gui.c:1829
void dt_masks_creation_mode_quit(dt_masks_form_gui_t *gui)
Exit mask creation mode, restoring cursor visibility and resetting GUI state.
Definition masks_gui.c:4151
gboolean dt_masks_reset_bezier_ctrl_points(struct dt_iop_module_t *module, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const int form_index, const struct dt_masks_form_gui_points_t *gui_points, const int node_index, dt_masks_points_states_t *state)
Definition masks_gui.c:999
gboolean dt_masks_gui_remove(struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui, const int parentid)
remove a mask shape or node form from the GUI. This function is used with a popupmenu "Delete" action...
Definition masks_gui.c:2247
void dt_masks_events_post_expose(dt_develop_t *dev, struct dt_iop_module_t *module, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
Definition masks_gui.c:3213
gboolean dt_masks_node_is_cusp(const dt_masks_form_gui_points_t *gpt, const int index)
returns wether a node is a corner or not. A node is a corner if its 2 control handles are at the same...
Definition masks_gui.c:2913
int dt_masks_events_button_pressed(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, double pressure, int which, int type, uint32_t state)
Definition masks_gui.c:2727
gboolean dt_masks_toggle_bezier_node_type(struct dt_iop_module_t *module, struct dt_masks_form_t *mask_form, struct dt_masks_form_gui_t *mask_gui, const int form_index, const struct dt_masks_form_gui_points_t *gui_points, const int node_index, float node[2], float ctrl1[2], float ctrl2[2], dt_masks_points_states_t *state)
Definition masks_gui.c:971
static void dt_masks_draw_source_preview(cairo_t *cr, const float zoom_scale, dt_masks_form_gui_t *gui, const float initial_xpos, const float initial_ypos, const float xpos, const float ypos, const int adding)
Definition masks_gui.h:601
int dt_masks_point_in_form_exact(const float *pts, int num_pts, const float *points, int points_start, int points_count)
Check whether any 2D point in pts[] lies inside the form points[].
Definition masks_gui.c:3872
void dt_masks_gui_reset_dragging(dt_masks_form_gui_t *gui)
Definition masks_gui.c:1339
void dt_masks_init_form_gui(dt_develop_t *dev, dt_masks_form_gui_t *gui)
Definition masks_gui.c:1776
void dt_masks_gui_init(struct dt_develop_t *dev)
Definition masks_gui.c:1296
void(* dt_masks_post_select_fn)(dt_masks_form_gui_t *mask_gui, int inside, int inside_border, int inside_source, void *user_data)
Optional hook to customize selection flags after inside/border/source resolution.
Definition masks_gui.h:759
gboolean dt_masks_gui_confirm_permanent_delete(const char *form_name)
Ask the user to confirm a permanent shape deletion, gated by the "ask_before_delete_mask_shape" pref....
Definition masks_gui.c:483
dt_masks_form_group_t * dt_masks_form_group_from_parentid(dt_develop_t *dev, int parentid, int formid)
Return the group entry for a (parent, form) pair.
Definition masks_gui.c:1365
gboolean dt_masks_is_anything_selected(const dt_masks_form_gui_t *mask_gui)
Definition masks_gui.c:2486
void(* dt_masks_distance_fn)(float pointer_x, float pointer_y, float cursor_radius, dt_masks_form_gui_t *mask_gui, int form_index, int node_count, int *inside, int *inside_border, int *near_handle, int *inside_source, float *dist, void *user_data)
Shape-specific callback for inside/border/segment hit testing.
Definition masks_gui.h:752
static float dt_masks_get_form_size_from_nodes(const GList *points)
Definition masks_gui.h:220
int dt_masks_events_mouse_moved(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, double pressure, int which)
Definition masks_gui.c:2634
gboolean dt_masks_gui_form_create_throttled(dt_masks_form_t *form, dt_masks_form_gui_t *gui, int index, struct dt_iop_module_t *module, float posx, float posy)
Definition masks_gui.c:1869
void dt_masks_gui_form_save_creation(dt_develop_t *dev, struct dt_iop_module_t *module, dt_masks_form_t *form, dt_masks_form_gui_t *gui)
Save the form creation right after a shape has been finished drawing.
Definition masks_gui.c:2353
void dt_masks_shape_buttons_deactivate_all(GtkWidget *active_button)
Definition masks_gui.c:103
void dt_masks_select_form(dt_develop_t *dev, struct dt_iop_module_t *module, dt_masks_form_t *sel)
Select or clear the current mask form, notifying the owning module if needed.
Definition masks_gui.c:3928
static int dt_masks_gui_selected_handle_border_index(const dt_masks_form_gui_t *gui)
Definition masks_gui.h:201
GtkWidget * dt_masks_shape_buttons_create(const dt_masks_shape_buttons_config_t *config)
Build a synchronized toolbar for creating masks shapes.
Definition masks_gui.c:200
float dt_masks_get_set_conf_value(dt_masks_form_t *form, char *feature, float new_value, float v_min, float v_max, dt_masks_increment_t increment, const int flow)
Change a numerical property of a mask shape, either by in/de-crementing the current value or setting ...
Definition masks_gui.c:3760
void dt_masks_clear_form_gui(dt_develop_t *dev)
Definition masks_gui.c:3287
gboolean dt_masks_form_exit_creation(dt_iop_module_t *module, dt_masks_form_gui_t *gui)
Definition masks_gui.c:2139
void dt_masks_draw_source(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const int nb, const float zoom_scale, struct dt_masks_gui_center_point_t *center_point, const shape_draw_function_t *draw_shape_func)
Draw the source for a correction mask.
Definition masks_gui.c:2999
gboolean(* dt_masks_border_handle_fn)(const dt_masks_form_gui_points_t *gui_points, int node_count, int node_index, float *handle_x, float *handle_y, void *user_data)
Shape-specific callback to fetch a node's border handle in GUI space.
Definition masks_gui.h:730
int dt_masks_group_index_from_formid(const dt_masks_form_t *group_form, int formid)
Definition masks_gui.c:1264
void _masks_gui_delete_node_callback(GtkWidget *menu, gpointer user_data)
Definition masks_gui.c:560
static void dt_masks_gui_cursor_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
Definition masks_gui.h:260
int dt_masks_center_view_on_form(struct dt_develop_t *dev, const struct dt_masks_form_t *form)
float dt_masks_form_get_interaction_value(dt_develop_t *dev, dt_masks_form_group_t *form_group, dt_masks_interaction_t interaction)
Definition masks_gui.c:3613
dt_masks_form_group_t * dt_masks_form_get_selected_group(const struct dt_masks_form_t *form, const struct dt_masks_form_gui_t *gui)
static void dt_masks_draw_preview_shape(struct dt_develop_t *dev, cairo_t *cr, const float zoom_scale, const int num_points, float *points, const int points_count, float *border, const int border_count, const shape_draw_function_t *draw_shape, const cairo_line_cap_t shape_cap, const cairo_line_cap_t border_cap, const gboolean save_restore, const gboolean source)
Definition masks_gui.h:358
static float dt_masks_border_from_projected_handle(dt_develop_t *dev, const float node[2], const float projected_image_pos[2], const float scale_ref)
Definition masks_gui.h:342
int dt_masks_events_mouse_leave(struct dt_iop_module_t *module)
Definition masks_gui.c:2476
void dt_masks_form_invalidate_gravity_center(struct dt_masks_form_t *form)
void(* dt_masks_shape_buttons_notify_f)(GtkWidget *button, dt_iop_module_t *module, dt_masks_type_t type, gpointer user_data)
Definition masks_gui.h:454
gboolean dt_masks_gui_is_dragging(const dt_masks_form_gui_t *gui)
Definition masks_gui.c:1351
gboolean dt_masks_remove_shape_from_group(struct dt_iop_module_t *module, dt_masks_form_t *sel, int parent_id, dt_masks_form_gui_t *mask_gui, int form_id)
Remove the form from its current group only, keeping it around unused for potential reuse....
Definition masks_gui.c:2124
void dt_masks_reset_show_masks_icons(dt_develop_t *dev)
Definition masks_gui.c:3388
gboolean dt_masks_point_is_within_radius(const float px, const float py, const float cx, const float cy, const float radius)
Check if a point (px,py) is inside a radius from a center point (cx,cy)
Definition masks_gui.c:1033
static void dt_masks_preview_buffers_cleanup(dt_masks_preview_buffers_t *buffers)
Definition masks_gui.h:390
static gboolean dt_masks_gui_was_anything_selected(const dt_masks_form_gui_t *gui)
Definition masks_gui.h:186
int dt_masks_gui_confirm_delete_form_dialog(const char *form_name)
Definition masks_gui.c:459
static gboolean dt_masks_gui_change_affects_selected_node_or_all(const dt_masks_form_gui_t *gui, const int index)
Definition masks_gui.h:211
static gboolean dt_masks_gui_should_hit_test(dt_masks_form_gui_t *gui)
Definition masks_gui.h:244
static void dt_masks_gui_delta_from_raw_anchor(dt_develop_t *dev, const dt_masks_form_gui_t *gui, const float anchor[2], float *delta_x, float *delta_y)
Definition masks_gui.h:283
int dt_masks_events_mouse_scrolled(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, int up, uint32_t state, int delta_y)
Definition masks_gui.c:2860
float dt_masks_apply_increment(float current, float amount, dt_masks_increment_t increment, int flow)
Apply a scroll increment to a scalar value.
Definition masks_gui.c:3731
float dt_masks_get_set_conf_value_with_toast(dt_masks_form_t *form, const char *feature, float amount, float v_min, float v_max, dt_masks_increment_t increment, int flow, const char *toast_fmt, float toast_scale)
Update a mask configuration value and emit a toast message.
Definition masks_gui.c:3790
int dt_masks_events_mouse_enter(struct dt_iop_module_t *module)
Definition masks_gui.c:2481
float dt_masks_rotate_with_anchor(dt_develop_t *dev, const float anchor[2], const float center[2], dt_masks_form_gui_t *gui)
Rotate a mask shape around its center. WARNING: gui->delta will be updated with the new position afte...
Definition masks_gui.c:4107
dt_masks_shape_buttons_flags_t
Definition masks_gui.h:431
@ DT_MASKS_SHAPE_BUTTONS_GRADIENT
Definition masks_gui.h:443
@ DT_MASKS_SHAPE_BUTTONS_NONE
Definition masks_gui.h:433
@ DT_MASKS_SHAPE_BUTTONS_CIRCLE
Definition masks_gui.h:435
@ DT_MASKS_SHAPE_BUTTONS_BRUSH
Definition masks_gui.h:441
@ DT_MASKS_SHAPE_BUTTONS_ALL
Definition masks_gui.h:445
@ DT_MASKS_SHAPE_BUTTONS_ELLIPSE
Definition masks_gui.h:437
@ DT_MASKS_SHAPE_BUTTONS_POLYGON
Definition masks_gui.h:439
float dt_masks_apply_increment_precomputed(float current, float amount, float scale_amount, float offset_amount, dt_masks_increment_t increment)
Apply a scroll increment using precomputed scale/offset factors.
Definition masks_gui.c:3745
float dt_masks_form_set_interaction_value(dt_masks_form_group_t *form_group, dt_masks_interaction_t interaction, float value, dt_masks_increment_t increment, int flow, struct dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Definition masks_gui.c:3669
dt_masks_form_group_t * dt_masks_form_group_find_entry(dt_masks_form_t *group_form, int formid, int *out_index)
Find the group-membership entry for formid inside group_form's own points list (not recursive into su...
Definition masks_gui.c:1244
int dt_masks_events_button_released(dt_develop_t *dev, struct dt_iop_module_t *module, double x, double y, int which, uint32_t state)
Definition masks_gui.c:2679
gboolean dt_masks_delete_shape(struct dt_iop_module_t *module, dt_masks_form_t *sel, int parent_id, dt_masks_form_gui_t *mask_gui, int form_id)
Permanently delete the form from every group and from dev->forms. Gated by dt_masks_gui_confirm_perma...
Definition masks_gui.c:2131
void dt_masks_reset_form_gui(dt_develop_t *dev)
Definition masks_gui.c:3373
void dt_masks_append_form(dt_develop_t *dev, dt_masks_form_t *form)
Definition masks_gui.c:2333
void dt_masks_soft_reset_form_gui(dt_masks_form_gui_t *gui)
Definition masks_gui.c:1805
dt_masks_form_group_t * dt_masks_form_get_selected_group_live(const struct dt_masks_form_t *form, const struct dt_masks_form_gui_t *gui)
Return the currently selected group entry, resolving to the live form group when the GUI is operating...
void dt_masks_set_source_pos_initial_value(dt_masks_form_gui_t *gui, dt_masks_form_t *form)
Initialize the clone source position based on current GUI state.
Definition masks_gui.c:3971
int dt_masks_events_key_pressed(dt_develop_t *dev, struct dt_iop_module_t *module, GdkEventKey *event)
Definition masks_gui.c:2799
void dt_masks_iop_value_changed_callback(GtkWidget *widget, struct dt_iop_module_t *module)
Definition masks_gui.c:3543
GtkWidget * dt_masks_create_menu(dt_masks_form_gui_t *gui, dt_masks_form_t *form, const dt_masks_form_group_t *fpt, const float pzx, const float pzy)
Definition masks_gui.c:741
void dt_masks_gui_cleanup(struct dt_develop_t *dev)
Definition masks_gui.c:1312
gboolean dt_masks_creation_mode_enter(dt_develop_t *dev, dt_iop_module_t *module, const dt_masks_type_t type)
Enter mask creation mode for a given shape type.
Definition masks_gui.c:4163
static void dt_masks_project_on_line(const float cursor[2], const float node[2], const float handle[2], float point[2])
Definition masks_gui.h:317
void dt_masks_gui_form_test_create(dt_masks_form_t *form, dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Definition masks_gui.c:2296
void(* dt_masks_node_position_fn)(const dt_masks_form_gui_points_t *gui_points, int node_index, float *node_x, float *node_y, void *user_data)
Shape-specific callback to fetch a node's position in GUI space.
Definition masks_gui.h:744
gboolean dt_masks_is_anything_hovered(const dt_masks_form_gui_t *mask_gui)
Definition masks_gui.c:2496
int dt_masks_find_closest_handle_common(dt_masks_form_t *mask_form, dt_masks_form_gui_t *mask_gui, int form_index, int node_count_override, dt_masks_border_handle_fn border_handle_cb, dt_masks_curve_handle_fn curve_handle_cb, dt_masks_node_position_fn node_position_cb, dt_masks_distance_fn distance_cb, dt_masks_post_select_fn post_select_cb, void *user_data)
Shared selection logic for node/handle/segment hit testing.
Definition masks_gui.c:1059
gboolean dt_masks_form_get_gravity_center(dt_develop_t *dev, const struct dt_masks_form_t *form, float center[2], float *area)
void dt_masks_gui_populate_interaction_sliders(GtkWidget *menu, dt_develop_t *dev, dt_masks_form_t *form, dt_masks_form_group_t *op_form, dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Append the full set of shape-parameter sliders (size/fading/rotation or curvature/fade/rotation depen...
Definition masks_gui.c:679
void dt_masks_form_update_gravity_center(dt_develop_t *dev, struct dt_masks_form_t *form)
void dt_masks_group_update_name(dt_iop_module_t *module)
Definition masks_gui.c:3447
dt_masks_form_t * dt_masks_get_visible_form(const struct dt_develop_t *dev)
void dt_masks_remove_node(struct dt_iop_module_t *module, dt_masks_form_t *form, int parentid, dt_masks_form_gui_t *gui, int index, int node_index)
Definition masks_gui.c:1909
void dt_group_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_t *form, dt_masks_form_gui_t *gui)
Definition group.c:141
void(* dt_masks_curve_handle_fn)(const dt_masks_form_gui_points_t *gui_points, int node_index, float *handle_x, float *handle_y, void *user_data)
Shape-specific callback to fetch a node's curve handle in GUI space.
Definition masks_gui.h:737
void dt_masks_draw_path_seg_by_seg(cairo_t *cr, dt_masks_form_gui_t *gui, const int index, const float *points, const int points_count, const int node_count, const float zoom_scale)
Definition masks_gui.c:3114
static void dt_masks_gui_delta_to_raw_norm(dt_develop_t *dev, const dt_masks_form_gui_t *gui, float point[2])
Definition masks_gui.h:268
void dt_masks_set_source_pos_initial_state(dt_masks_form_gui_t *gui, const uint32_t state)
Decide initial source positioning mode for clone masks.
Definition masks_gui.c:3946
void dt_masks_iop_combo_populate(GtkWidget *w, void *module)
Definition masks_gui.c:3459
dt_masks_form_group_t * dt_masks_form_group_find_any(dt_develop_t *dev, int formid, int *out_parentid)
Find any group that currently references formid, searching every top-level group in dev->forms and th...
Definition masks_gui.c:1419
void dt_masks_set_visible_form(struct dt_develop_t *dev, dt_masks_form_t *form)
Definition masks_gui.c:1290
GtkWidget * dt_masks_gui_add_interaction_slider(GtkWidget *menu, const char *label, dt_masks_form_group_t *form_group, dt_masks_interaction_t interaction, dt_masks_increment_t increment, float min, float max, float step, float value, int digits, const char *format, float factor, dt_masks_form_gui_t *gui, struct dt_iop_module_t *module)
Append a bauhaus-slider menu item to a mask context menu, bound to one shape interaction (size,...
Definition masks_gui.c:403
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
const float factor
Definition pdf.h:91
#define dt_pixelpipe_cache_free_align(mem)
static const dt_aligned_pixel_simd_t value
Definition simd.h:144
const float uint32_t state[4]
unsigned __int64 uint64_t
Definition strptime.c:75
GtkWidget * widget
Definition develop.h:350
gboolean rebuild_pending
Definition masks_gui.h:153
gboolean node_selected
Definition masks_gui.h:125
gboolean handle_border_selected
Definition masks_gui.h:128
gboolean border_toggling
Definition masks_gui.h:143
dt_masks_dynbuf_t * guipoints_payload
Definition masks_gui.h:90
gboolean source_selected
Definition masks_gui.h:133
dt_masks_type_t creation_type
Definition masks_gui.h:162
gboolean source_dragging
Definition masks_gui.h:141
dt_masks_edit_mode_t edit_mode
Definition masks_gui.h:118
dt_iop_module_t * creation_module
Definition masks_gui.h:160
gboolean creation_closing_form
Definition masks_gui.h:159
GList * creation_formids
Definition masks_gui.h:164
dt_masks_pressure_sensitivity_t pressure_sensitivity
Definition masks_gui.h:168
gboolean seg_selected
Definition masks_gui.h:127
gboolean form_dragging
Definition masks_gui.h:140
gboolean gradient_toggling
Definition masks_gui.h:144
dt_masks_type_t type
Definition masks_gui.h:83
dt_masks_form_t * form_visible
Definition masks_gui.h:85
gboolean form_selected
Definition masks_gui.h:131
gboolean handle_selected
Definition masks_gui.h:126
gboolean form_rotating
Definition masks_gui.h:142
dt_masks_dynbuf_t * guipoints
Definition masks_gui.h:90
gboolean border_selected
Definition masks_gui.h:132
float last_rebuild_pos[2]
Definition masks_gui.h:152
gboolean pivot_selected
Definition masks_gui.h:134
float last_hit_test_pos[2]
Definition masks_gui.h:156
struct dt_develop_t * dev
Definition masks_gui.h:81
struct dt_masks_gui_center_point_t::@27 main
struct dt_masks_gui_center_point_t::@28 source
dt_iop_module_t * creation_module
Definition masks_gui.h:463
dt_masks_shape_buttons_flags_t register_flags
Definition masks_gui.h:468
dt_masks_shape_buttons_type_f form_type
Definition masks_gui.h:472
dt_masks_shape_buttons_start_f can_start
Definition masks_gui.h:471
dt_masks_shape_buttons_notify_f exited
Definition masks_gui.h:474
struct dt_develop_t * dev
Definition masks_gui.h:461
dt_masks_shape_buttons_notify_f started
Definition masks_gui.h:473
dt_iop_module_t * owner_module
Definition masks_gui.h:462
dt_masks_shape_buttons_flags_t flags
Definition masks_gui.h:467
#define DT_GUI_MOUSE_EFFECT_RADIUS