1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup wm
22  *
23  * Generic re-usable property definitions and accessors for operators to share.
24  * (`WM_operator_properties_*` functions).
25  */
26 
27 #include "DNA_space_types.h"
28 
29 #include "BLI_math_base.h"
30 #include "BLI_rect.h"
31 
32 #include "UI_resources.h"
33 
34 #include "RNA_access.h"
35 #include "RNA_define.h"
36 #include "RNA_enum_types.h"
37 
38 #include "ED_select_utils.h"
39 
40 #include "WM_api.h"
41 #include "WM_types.h"
42 
WM_operator_properties_confirm_or_exec(wmOperatorType * ot)43 void WM_operator_properties_confirm_or_exec(wmOperatorType *ot)
44 {
45   PropertyRNA *prop;
46 
47   prop = RNA_def_boolean(ot->srna, "confirm", true, "Confirm", "Prompt for confirmation");
48   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
49 }
50 
51 /* default properties for fileselect */
WM_operator_properties_filesel(wmOperatorType * ot,int filter,short type,short action,short flag,short display,short sort)52 void WM_operator_properties_filesel(wmOperatorType *ot,
53                                     int filter,
54                                     short type,
55                                     short action,
56                                     short flag,
57                                     short display,
58                                     short sort)
59 {
60   PropertyRNA *prop;
61 
62   static const EnumPropertyItem file_display_items[] = {
63       {FILE_DEFAULTDISPLAY,
64        "DEFAULT",
65        0,
66        "Default",
67        "Automatically determine display type for files"},
68       {FILE_VERTICALDISPLAY,
69        "LIST_VERTICAL",
70        ICON_SHORTDISPLAY, /* Name of deprecated short list */
71        "Short List",
72        "Display files as short list"},
73       {FILE_HORIZONTALDISPLAY,
74        "LIST_HORIZONTAL",
75        ICON_LONGDISPLAY, /* Name of deprecated long list */
76        "Long List",
77        "Display files as a detailed list"},
78       {FILE_IMGDISPLAY, "THUMBNAIL", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
79       {0, NULL, 0, NULL, NULL},
80   };
81 
82   if (flag & WM_FILESEL_FILEPATH) {
83     RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path", "Path to file");
84   }
85 
86   if (flag & WM_FILESEL_DIRECTORY) {
87     RNA_def_string_dir_path(
88         ot->srna, "directory", NULL, FILE_MAX, "Directory", "Directory of the file");
89   }
90 
91   if (flag & WM_FILESEL_FILENAME) {
92     RNA_def_string_file_name(
93         ot->srna, "filename", NULL, FILE_MAX, "File Name", "Name of the file");
94   }
95 
96   if (flag & WM_FILESEL_FILES) {
97     prop = RNA_def_collection_runtime(
98         ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
99     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
100   }
101 
102   if ((flag & WM_FILESEL_SHOW_PROPS) == 0) {
103     prop = RNA_def_boolean(ot->srna,
104                            "hide_props_region",
105                            true,
106                            "Hide Operator Properties",
107                            "Collapse the region displaying the operator settings");
108     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
109   }
110 
111   if (action == FILE_SAVE) {
112     /* note, this is only used to check if we should highlight the filename area red when the
113      * filepath is an existing file. */
114     prop = RNA_def_boolean(ot->srna,
115                            "check_existing",
116                            true,
117                            "Check Existing",
118                            "Check and warn on overwriting existing files");
119     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
120   }
121 
122   prop = RNA_def_boolean(
123       ot->srna, "filter_blender", (filter & FILE_TYPE_BLENDER) != 0, "Filter .blend files", "");
124   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
125   prop = RNA_def_boolean(ot->srna,
126                          "filter_backup",
127                          (filter & FILE_TYPE_BLENDER_BACKUP) != 0,
128                          "Filter .blend files",
129                          "");
130   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
131   prop = RNA_def_boolean(
132       ot->srna, "filter_image", (filter & FILE_TYPE_IMAGE) != 0, "Filter image files", "");
133   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
134   prop = RNA_def_boolean(
135       ot->srna, "filter_movie", (filter & FILE_TYPE_MOVIE) != 0, "Filter movie files", "");
136   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
137   prop = RNA_def_boolean(
138       ot->srna, "filter_python", (filter & FILE_TYPE_PYSCRIPT) != 0, "Filter python files", "");
139   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
140   prop = RNA_def_boolean(
141       ot->srna, "filter_font", (filter & FILE_TYPE_FTFONT) != 0, "Filter font files", "");
142   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
143   prop = RNA_def_boolean(
144       ot->srna, "filter_sound", (filter & FILE_TYPE_SOUND) != 0, "Filter sound files", "");
145   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
146   prop = RNA_def_boolean(
147       ot->srna, "filter_text", (filter & FILE_TYPE_TEXT) != 0, "Filter text files", "");
148   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
149   prop = RNA_def_boolean(
150       ot->srna, "filter_archive", (filter & FILE_TYPE_ARCHIVE) != 0, "Filter archive files", "");
151   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
152   prop = RNA_def_boolean(
153       ot->srna, "filter_btx", (filter & FILE_TYPE_BTX) != 0, "Filter btx files", "");
154   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
155   prop = RNA_def_boolean(
156       ot->srna, "filter_collada", (filter & FILE_TYPE_COLLADA) != 0, "Filter COLLADA files", "");
157   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
158   prop = RNA_def_boolean(
159       ot->srna, "filter_alembic", (filter & FILE_TYPE_ALEMBIC) != 0, "Filter Alembic files", "");
160   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
161   prop = RNA_def_boolean(
162       ot->srna, "filter_usd", (filter & FILE_TYPE_USD) != 0, "Filter USD files", "");
163   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
164   prop = RNA_def_boolean(ot->srna,
165                          "filter_volume",
166                          (filter & FILE_TYPE_VOLUME) != 0,
167                          "Filter OpenVDB volume files",
168                          "");
169   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
170   prop = RNA_def_boolean(
171       ot->srna, "filter_folder", (filter & FILE_TYPE_FOLDER) != 0, "Filter folders", "");
172   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
173   prop = RNA_def_boolean(
174       ot->srna, "filter_blenlib", (filter & FILE_TYPE_BLENDERLIB) != 0, "Filter Blender IDs", "");
175   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
176 
177   prop = RNA_def_int(
178       ot->srna,
179       "filemode",
180       type,
181       FILE_LOADLIB,
182       FILE_SPECIAL,
183       "File Browser Mode",
184       "The setting for the file browser mode to load a .blend file, a library or a special file",
185       FILE_LOADLIB,
186       FILE_SPECIAL);
187   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
188 
189   if (flag & WM_FILESEL_RELPATH) {
190     RNA_def_boolean(ot->srna,
191                     "relative_path",
192                     true,
193                     "Relative Path",
194                     "Select the file relative to the blend file");
195   }
196 
197   if ((filter & FILE_TYPE_IMAGE) || (filter & FILE_TYPE_MOVIE)) {
198     prop = RNA_def_boolean(ot->srna, "show_multiview", 0, "Enable Multi-View", "");
199     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
200     prop = RNA_def_boolean(ot->srna, "use_multiview", 0, "Use Multi-View", "");
201     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
202   }
203 
204   prop = RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", "");
205   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
206 
207   prop = RNA_def_enum(
208       ot->srna, "sort_method", rna_enum_file_sort_items, sort, "File sorting mode", "");
209   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
210 }
211 
wm_operator_properties_select_action_ex(wmOperatorType * ot,int default_action,const EnumPropertyItem * select_actions,bool hide_gui)212 static void wm_operator_properties_select_action_ex(wmOperatorType *ot,
213                                                     int default_action,
214                                                     const EnumPropertyItem *select_actions,
215                                                     bool hide_gui)
216 {
217   PropertyRNA *prop;
218   prop = RNA_def_enum(
219       ot->srna, "action", select_actions, default_action, "Action", "Selection action to execute");
220 
221   if (hide_gui) {
222     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
223   }
224 }
225 
WM_operator_properties_select_action(wmOperatorType * ot,int default_action,bool hide_gui)226 void WM_operator_properties_select_action(wmOperatorType *ot, int default_action, bool hide_gui)
227 {
228   static const EnumPropertyItem select_actions[] = {
229       {SEL_TOGGLE, "TOGGLE", 0, "Toggle", "Toggle selection for all elements"},
230       {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
231       {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
232       {SEL_INVERT, "INVERT", 0, "Invert", "Invert selection of all elements"},
233       {0, NULL, 0, NULL, NULL},
234   };
235 
236   wm_operator_properties_select_action_ex(ot, default_action, select_actions, hide_gui);
237 }
238 
239 /**
240  * only SELECT/DESELECT
241  */
WM_operator_properties_select_action_simple(wmOperatorType * ot,int default_action,bool hide_gui)242 void WM_operator_properties_select_action_simple(wmOperatorType *ot,
243                                                  int default_action,
244                                                  bool hide_gui)
245 {
246   static const EnumPropertyItem select_actions[] = {
247       {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
248       {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
249       {0, NULL, 0, NULL, NULL},
250   };
251 
252   wm_operator_properties_select_action_ex(ot, default_action, select_actions, hide_gui);
253 }
254 
255 /**
256  * Use for all select random operators.
257  * Adds properties: percent, seed, action.
258  */
WM_operator_properties_select_random(wmOperatorType * ot)259 void WM_operator_properties_select_random(wmOperatorType *ot)
260 {
261   RNA_def_float_percentage(ot->srna,
262                            "percent",
263                            50.f,
264                            0.0f,
265                            100.0f,
266                            "Percent",
267                            "Percentage of objects to select randomly",
268                            0.f,
269                            100.0f);
270   RNA_def_int(ot->srna,
271               "seed",
272               0,
273               0,
274               INT_MAX,
275               "Random Seed",
276               "Seed for the random number generator",
277               0,
278               255);
279 
280   WM_operator_properties_select_action_simple(ot, SEL_SELECT, false);
281 }
282 
WM_operator_properties_select_random_seed_increment_get(wmOperator * op)283 int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
284 {
285   PropertyRNA *prop = RNA_struct_find_property(op->ptr, "seed");
286   int value = RNA_property_int_get(op->ptr, prop);
287 
288   if (op->flag & OP_IS_INVOKE) {
289     if (!RNA_property_is_set(op->ptr, prop)) {
290       value += 1;
291       RNA_property_int_set(op->ptr, prop, value);
292     }
293   }
294   return value;
295 }
296 
WM_operator_properties_select_all(wmOperatorType * ot)297 void WM_operator_properties_select_all(wmOperatorType *ot)
298 {
299   WM_operator_properties_select_action(ot, SEL_TOGGLE, true);
300 }
301 
WM_operator_properties_border(wmOperatorType * ot)302 void WM_operator_properties_border(wmOperatorType *ot)
303 {
304   PropertyRNA *prop;
305 
306   prop = RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
307   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
308   prop = RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
309   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
310   prop = RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
311   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
312   prop = RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
313   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
314 
315   prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
316   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
317 }
318 
WM_operator_properties_border_to_rcti(struct wmOperator * op,rcti * rect)319 void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
320 {
321   rect->xmin = RNA_int_get(op->ptr, "xmin");
322   rect->ymin = RNA_int_get(op->ptr, "ymin");
323   rect->xmax = RNA_int_get(op->ptr, "xmax");
324   rect->ymax = RNA_int_get(op->ptr, "ymax");
325 }
326 
WM_operator_properties_border_to_rctf(struct wmOperator * op,rctf * rect)327 void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect)
328 {
329   rcti rect_i;
330   WM_operator_properties_border_to_rcti(op, &rect_i);
331   BLI_rctf_rcti_copy(rect, &rect_i);
332 }
333 
334 /**
335  * Use with #WM_gesture_box_invoke
336  */
WM_operator_properties_gesture_box_ex(wmOperatorType * ot,bool deselect,bool extend)337 void WM_operator_properties_gesture_box_ex(wmOperatorType *ot, bool deselect, bool extend)
338 {
339   PropertyRNA *prop;
340 
341   WM_operator_properties_border(ot);
342 
343   if (deselect) {
344     prop = RNA_def_boolean(
345         ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
346     RNA_def_property_flag(prop, PROP_SKIP_SAVE);
347   }
348   if (extend) {
349     prop = RNA_def_boolean(ot->srna,
350                            "extend",
351                            true,
352                            "Extend",
353                            "Extend selection instead of deselecting everything first");
354     RNA_def_property_flag(prop, PROP_SKIP_SAVE);
355   }
356 }
357 
358 /**
359  * Disable using cursor position,
360  * use when view operators are initialized from buttons.
361  */
WM_operator_properties_use_cursor_init(wmOperatorType * ot)362 void WM_operator_properties_use_cursor_init(wmOperatorType *ot)
363 {
364   PropertyRNA *prop = RNA_def_boolean(ot->srna,
365                                       "use_cursor_init",
366                                       true,
367                                       "Use Mouse Position",
368                                       "Allow the initial mouse position to be used");
369   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
370 }
371 
WM_operator_properties_gesture_box_select(wmOperatorType * ot)372 void WM_operator_properties_gesture_box_select(wmOperatorType *ot)
373 {
374   WM_operator_properties_gesture_box_ex(ot, true, true);
375 }
WM_operator_properties_gesture_box(wmOperatorType * ot)376 void WM_operator_properties_gesture_box(wmOperatorType *ot)
377 {
378   WM_operator_properties_gesture_box_ex(ot, false, false);
379 }
380 
WM_operator_properties_select_operation(wmOperatorType * ot)381 void WM_operator_properties_select_operation(wmOperatorType *ot)
382 {
383   static const EnumPropertyItem select_mode_items[] = {
384       {SEL_OP_SET, "SET", ICON_SELECT_SET, "Set", "Set a new selection"},
385       {SEL_OP_ADD, "ADD", ICON_SELECT_EXTEND, "Extend", "Extend existing selection"},
386       {SEL_OP_SUB, "SUB", ICON_SELECT_SUBTRACT, "Subtract", "Subtract existing selection"},
387       {SEL_OP_XOR, "XOR", ICON_SELECT_DIFFERENCE, "Difference", "Inverts existing selection"},
388       {SEL_OP_AND, "AND", ICON_SELECT_INTERSECT, "Intersect", "Intersect existing selection"},
389       {0, NULL, 0, NULL, NULL},
390   };
391   PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
392   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
393 }
394 
395 /* Some tools don't support XOR/AND. */
WM_operator_properties_select_operation_simple(wmOperatorType * ot)396 void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
397 {
398   static const EnumPropertyItem select_mode_items[] = {
399       {SEL_OP_SET, "SET", ICON_SELECT_SET, "Set", "Set a new selection"},
400       {SEL_OP_ADD, "ADD", ICON_SELECT_EXTEND, "Extend", "Extend existing selection"},
401       {SEL_OP_SUB, "SUB", ICON_SELECT_SUBTRACT, "Subtract", "Subtract existing selection"},
402       {0, NULL, 0, NULL, NULL},
403   };
404   PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
405   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
406 }
407 
WM_operator_properties_select_walk_direction(wmOperatorType * ot)408 void WM_operator_properties_select_walk_direction(wmOperatorType *ot)
409 {
410   static const EnumPropertyItem direction_items[] = {
411       {UI_SELECT_WALK_UP, "UP", 0, "Prev", ""},
412       {UI_SELECT_WALK_DOWN, "DOWN", 0, "Next", ""},
413       {UI_SELECT_WALK_LEFT, "LEFT", 0, "Left", ""},
414       {UI_SELECT_WALK_RIGHT, "RIGHT", 0, "Right", ""},
415       {0, NULL, 0, NULL, NULL},
416   };
417   PropertyRNA *prop;
418   prop = RNA_def_enum(ot->srna,
419                       "direction",
420                       direction_items,
421                       0,
422                       "Walk Direction",
423                       "Select/Deselect element in this direction");
424   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
425 }
426 
427 /**
428  * Selecting and tweaking items are overlapping operations. Getting both to work without conflicts
429  * requires special care. See
430  * https://wiki.blender.org/wiki/Human_Interface_Guidelines/Selection#Select-tweaking for the
431  * desired behavior.
432  *
433  * For default click selection (with no modifier keys held), the select operators can do the
434  * following:
435  * - On a mouse press on an unselected item, change selection and finish immediately after.
436  *   This sends an undo push and allows transform to take over should a tweak event be caught now.
437  * - On a mouse press on a selected item, don't change selection state, but start modal execution
438  *   of the operator. Idea is that we wait with deselecting other items until we know that the
439  *   intention wasn't to tweak (mouse press+drag) all selected items.
440  * - If a tweak is recognized before the release event happens, cancel the operator, so that
441  *   transform can take over and no undo-push is sent.
442  * - If the release event occurs rather than a tweak one, deselect all items but the one under the
443  *   cursor, and finish the modal operator.
444  *
445  * This utility, together with #WM_generic_select_invoke() and #WM_generic_select_modal() should
446  * help getting the wanted behavior to work. Most generic logic should be handled in these, so that
447  * the select operators only have to care for the case dependent handling.
448  *
449  * Every select operator has slightly different requirements, e.g. sequencer strip selection
450  * also needs to account for handle selection. This should be the baseline behavior though.
451  */
WM_operator_properties_generic_select(wmOperatorType * ot)452 void WM_operator_properties_generic_select(wmOperatorType *ot)
453 {
454   /* On the initial mouse press, this is set by #WM_generic_select_modal() to let the select
455    * operator exec callback know that it should not __yet__ deselect other items when clicking on
456    * an already selected one. Instead should make sure the operator executes modal then (see
457    * #WM_generic_select_modal()), so that the exec callback can be called a second time on the
458    * mouse release event to do this part. */
459   PropertyRNA *prop = RNA_def_boolean(
460       ot->srna, "wait_to_deselect_others", false, "Wait to Deselect Others", "");
461   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
462 
463   RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX);
464   RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX);
465 }
466 
WM_operator_properties_gesture_box_zoom(wmOperatorType * ot)467 void WM_operator_properties_gesture_box_zoom(wmOperatorType *ot)
468 {
469   WM_operator_properties_border(ot);
470 
471   PropertyRNA *prop;
472   prop = RNA_def_boolean(ot->srna, "zoom_out", false, "Zoom Out", "");
473   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
474 }
475 
476 /**
477  * Use with #WM_gesture_lasso_invoke
478  */
WM_operator_properties_gesture_lasso(wmOperatorType * ot)479 void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
480 {
481   PropertyRNA *prop;
482   prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
483   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
484 }
485 
486 /**
487  * Use with #WM_gesture_straightline_invoke
488  */
WM_operator_properties_gesture_straightline(wmOperatorType * ot,int cursor)489 void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
490 {
491   PropertyRNA *prop;
492 
493   prop = RNA_def_int(ot->srna, "xstart", 0, INT_MIN, INT_MAX, "X Start", "", INT_MIN, INT_MAX);
494   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
495   prop = RNA_def_int(ot->srna, "xend", 0, INT_MIN, INT_MAX, "X End", "", INT_MIN, INT_MAX);
496   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
497   prop = RNA_def_int(ot->srna, "ystart", 0, INT_MIN, INT_MAX, "Y Start", "", INT_MIN, INT_MAX);
498   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
499   prop = RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX);
500   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
501   prop = RNA_def_boolean(ot->srna, "flip", false, "Flip", "");
502   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
503 
504   if (cursor) {
505     prop = RNA_def_int(ot->srna,
506                        "cursor",
507                        cursor,
508                        0,
509                        INT_MAX,
510                        "Cursor",
511                        "Mouse cursor style to use during the modal operator",
512                        0,
513                        INT_MAX);
514     RNA_def_property_flag(prop, PROP_HIDDEN);
515   }
516 }
517 
518 /**
519  * Use with #WM_gesture_circle_invoke
520  */
WM_operator_properties_gesture_circle(wmOperatorType * ot)521 void WM_operator_properties_gesture_circle(wmOperatorType *ot)
522 {
523   PropertyRNA *prop;
524   const int radius_default = 25;
525 
526   prop = RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
527   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
528   prop = RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
529   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
530   RNA_def_int(ot->srna, "radius", radius_default, 1, INT_MAX, "Radius", "", 1, INT_MAX);
531 
532   prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
533   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
534 }
535 
WM_operator_properties_mouse_select(wmOperatorType * ot)536 void WM_operator_properties_mouse_select(wmOperatorType *ot)
537 {
538   PropertyRNA *prop;
539 
540   prop = RNA_def_boolean(ot->srna,
541                          "extend",
542                          false,
543                          "Extend",
544                          "Extend selection instead of deselecting everything first");
545   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
546   prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from selection");
547   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
548   prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Selection", "Toggle the selection");
549   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
550 
551   prop = RNA_def_boolean(ot->srna,
552                          "deselect_all",
553                          false,
554                          "Deselect On Nothing",
555                          "Deselect all when nothing under the cursor");
556   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
557 }
558 
559 /**
560  * \param nth_can_disable: Enable if we want to be able to select no interval at all.
561  */
WM_operator_properties_checker_interval(wmOperatorType * ot,bool nth_can_disable)562 void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_disable)
563 {
564   const int nth_default = nth_can_disable ? 0 : 1;
565   const int nth_min = min_ii(nth_default, 1);
566   RNA_def_int(ot->srna,
567               "skip",
568               nth_default,
569               nth_min,
570               INT_MAX,
571               "Deselected",
572               "Number of deselected elements in the repetitive sequence",
573               nth_min,
574               100);
575   RNA_def_int(ot->srna,
576               "nth",
577               1,
578               1,
579               INT_MAX,
580               "Selected",
581               "Number of selected elements in the repetitive sequence",
582               1,
583               100);
584   RNA_def_int(ot->srna,
585               "offset",
586               0,
587               INT_MIN,
588               INT_MAX,
589               "Offset",
590               "Offset from the starting point",
591               -100,
592               100);
593 }
594 
WM_operator_properties_checker_interval_from_op(struct wmOperator * op,struct CheckerIntervalParams * op_params)595 void WM_operator_properties_checker_interval_from_op(struct wmOperator *op,
596                                                      struct CheckerIntervalParams *op_params)
597 {
598   const int nth = RNA_int_get(op->ptr, "nth");
599   const int skip = RNA_int_get(op->ptr, "skip");
600   int offset = RNA_int_get(op->ptr, "offset");
601 
602   op_params->nth = nth;
603   op_params->skip = skip;
604 
605   /* So input of offset zero ends up being (nth - 1). */
606   op_params->offset = mod_i(offset, nth + skip);
607 }
608 
WM_operator_properties_checker_interval_test(const struct CheckerIntervalParams * op_params,int depth)609 bool WM_operator_properties_checker_interval_test(const struct CheckerIntervalParams *op_params,
610                                                   int depth)
611 {
612   return ((op_params->skip == 0) ||
613           ((op_params->offset + depth) % (op_params->skip + op_params->nth) >= op_params->skip));
614 }
615