21636153904522118f3aeead6a7b8b08d4593851
[blender.git] / source / blender / windowmanager / intern / wm_operator_props.c
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_rect.h"
30 #include "BLI_math_base.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
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 */
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_folder", (filter & FILE_TYPE_FOLDER) != 0, "Filter folders", "");
163   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
164   prop = RNA_def_boolean(
165       ot->srna, "filter_blenlib", (filter & FILE_TYPE_BLENDERLIB) != 0, "Filter Blender IDs", "");
166   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
167
168   prop = RNA_def_int(
169       ot->srna,
170       "filemode",
171       type,
172       FILE_LOADLIB,
173       FILE_SPECIAL,
174       "File Browser Mode",
175       "The setting for the file browser mode to load a .blend file, a library or a special file",
176       FILE_LOADLIB,
177       FILE_SPECIAL);
178   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
179
180   if (flag & WM_FILESEL_RELPATH) {
181     RNA_def_boolean(ot->srna,
182                     "relative_path",
183                     true,
184                     "Relative Path",
185                     "Select the file relative to the blend file");
186   }
187
188   if ((filter & FILE_TYPE_IMAGE) || (filter & FILE_TYPE_MOVIE)) {
189     prop = RNA_def_boolean(ot->srna, "show_multiview", 0, "Enable Multi-View", "");
190     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
191     prop = RNA_def_boolean(ot->srna, "use_multiview", 0, "Use Multi-View", "");
192     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
193   }
194
195   prop = RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", "");
196   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
197
198   prop = RNA_def_enum(
199       ot->srna, "sort_method", rna_enum_file_sort_items, sort, "File sorting mode", "");
200   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
201 }
202
203 static void wm_operator_properties_select_action_ex(wmOperatorType *ot,
204                                                     int default_action,
205                                                     const EnumPropertyItem *select_actions,
206                                                     bool hide_gui)
207 {
208   PropertyRNA *prop;
209   prop = RNA_def_enum(
210       ot->srna, "action", select_actions, default_action, "Action", "Selection action to execute");
211
212   if (hide_gui) {
213     RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
214   }
215 }
216
217 void WM_operator_properties_select_action(wmOperatorType *ot, int default_action, bool hide_gui)
218 {
219   static const EnumPropertyItem select_actions[] = {
220       {SEL_TOGGLE, "TOGGLE", 0, "Toggle", "Toggle selection for all elements"},
221       {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
222       {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
223       {SEL_INVERT, "INVERT", 0, "Invert", "Invert selection of all elements"},
224       {0, NULL, 0, NULL, NULL},
225   };
226
227   wm_operator_properties_select_action_ex(ot, default_action, select_actions, hide_gui);
228 }
229
230 /**
231  * only SELECT/DESELECT
232  */
233 void WM_operator_properties_select_action_simple(wmOperatorType *ot,
234                                                  int default_action,
235                                                  bool hide_gui)
236 {
237   static const EnumPropertyItem select_actions[] = {
238       {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
239       {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
240       {0, NULL, 0, NULL, NULL},
241   };
242
243   wm_operator_properties_select_action_ex(ot, default_action, select_actions, hide_gui);
244 }
245
246 /**
247  * Use for all select random operators.
248  * Adds properties: percent, seed, action.
249  */
250 void WM_operator_properties_select_random(wmOperatorType *ot)
251 {
252   RNA_def_float_percentage(ot->srna,
253                            "percent",
254                            50.f,
255                            0.0f,
256                            100.0f,
257                            "Percent",
258                            "Percentage of objects to select randomly",
259                            0.f,
260                            100.0f);
261   RNA_def_int(ot->srna,
262               "seed",
263               0,
264               0,
265               INT_MAX,
266               "Random Seed",
267               "Seed for the random number generator",
268               0,
269               255);
270
271   WM_operator_properties_select_action_simple(ot, SEL_SELECT, false);
272 }
273
274 int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
275 {
276   PropertyRNA *prop = RNA_struct_find_property(op->ptr, "seed");
277   int value = RNA_property_int_get(op->ptr, prop);
278
279   if (op->flag & OP_IS_INVOKE) {
280     if (!RNA_property_is_set(op->ptr, prop)) {
281       value += 1;
282       RNA_property_int_set(op->ptr, prop, value);
283     }
284   }
285   return value;
286 }
287
288 void WM_operator_properties_select_all(wmOperatorType *ot)
289 {
290   WM_operator_properties_select_action(ot, SEL_TOGGLE, true);
291 }
292
293 void WM_operator_properties_border(wmOperatorType *ot)
294 {
295   PropertyRNA *prop;
296
297   prop = RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
298   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
299   prop = RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
300   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
301   prop = RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
302   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
303   prop = RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
304   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
305
306   prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
307   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
308 }
309
310 void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
311 {
312   rect->xmin = RNA_int_get(op->ptr, "xmin");
313   rect->ymin = RNA_int_get(op->ptr, "ymin");
314   rect->xmax = RNA_int_get(op->ptr, "xmax");
315   rect->ymax = RNA_int_get(op->ptr, "ymax");
316 }
317
318 void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect)
319 {
320   rcti rect_i;
321   WM_operator_properties_border_to_rcti(op, &rect_i);
322   BLI_rctf_rcti_copy(rect, &rect_i);
323 }
324
325 /**
326  * Use with #WM_gesture_box_invoke
327  */
328 void WM_operator_properties_gesture_box_ex(wmOperatorType *ot, bool deselect, bool extend)
329 {
330   PropertyRNA *prop;
331
332   WM_operator_properties_border(ot);
333
334   if (deselect) {
335     prop = RNA_def_boolean(
336         ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
337     RNA_def_property_flag(prop, PROP_SKIP_SAVE);
338   }
339   if (extend) {
340     prop = RNA_def_boolean(ot->srna,
341                            "extend",
342                            true,
343                            "Extend",
344                            "Extend selection instead of deselecting everything first");
345     RNA_def_property_flag(prop, PROP_SKIP_SAVE);
346   }
347 }
348
349 /**
350  * Disable using cursor position,
351  * use when view operators are initialized from buttons.
352  */
353 void WM_operator_properties_use_cursor_init(wmOperatorType *ot)
354 {
355   PropertyRNA *prop = RNA_def_boolean(ot->srna,
356                                       "use_cursor_init",
357                                       true,
358                                       "Use Mouse Position",
359                                       "Allow the initial mouse position to be used");
360   RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
361 }
362
363 void WM_operator_properties_gesture_box_select(wmOperatorType *ot)
364 {
365   WM_operator_properties_gesture_box_ex(ot, true, true);
366 }
367 void WM_operator_properties_gesture_box(wmOperatorType *ot)
368 {
369   WM_operator_properties_gesture_box_ex(ot, false, false);
370 }
371
372 void WM_operator_properties_select_operation(wmOperatorType *ot)
373 {
374   static const EnumPropertyItem select_mode_items[] = {
375       {SEL_OP_SET, "SET", ICON_SELECT_SET, "Set", "Set a new selection"},
376       {SEL_OP_ADD, "ADD", ICON_SELECT_EXTEND, "Extend", "Extend existing selection"},
377       {SEL_OP_SUB, "SUB", ICON_SELECT_SUBTRACT, "Subtract", "Subtract existing selection"},
378       {SEL_OP_XOR, "XOR", ICON_SELECT_DIFFERENCE, "Difference", "Inverts existing selection"},
379       {SEL_OP_AND, "AND", ICON_SELECT_INTERSECT, "Intersect", "Intersect existing selection"},
380       {0, NULL, 0, NULL, NULL},
381   };
382   PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
383   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
384 }
385
386 /* Some tools don't support XOR/AND. */
387 void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
388 {
389   static const EnumPropertyItem select_mode_items[] = {
390       {SEL_OP_SET, "SET", ICON_SELECT_SET, "Set", "Set a new selection"},
391       {SEL_OP_ADD, "ADD", ICON_SELECT_EXTEND, "Extend", "Extend existing selection"},
392       {SEL_OP_SUB, "SUB", ICON_SELECT_SUBTRACT, "Subtract", "Subtract existing selection"},
393       {0, NULL, 0, NULL, NULL},
394   };
395   PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
396   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
397 }
398
399 void WM_operator_properties_generic_select(wmOperatorType *ot)
400 {
401   PropertyRNA *prop = RNA_def_boolean(
402       ot->srna, "wait_to_deselect_others", false, "Wait to Deselect Others", "");
403   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
404
405   RNA_def_int(ot->srna, "mouse_x", 0, INT_MIN, INT_MAX, "Mouse X", "", INT_MIN, INT_MAX);
406   RNA_def_int(ot->srna, "mouse_y", 0, INT_MIN, INT_MAX, "Mouse Y", "", INT_MIN, INT_MAX);
407 }
408
409 void WM_operator_properties_gesture_box_zoom(wmOperatorType *ot)
410 {
411   WM_operator_properties_border(ot);
412
413   PropertyRNA *prop;
414   prop = RNA_def_boolean(ot->srna, "zoom_out", false, "Zoom Out", "");
415   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
416 }
417
418 /**
419  * Use with #WM_gesture_lasso_invoke
420  */
421 void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
422 {
423   PropertyRNA *prop;
424   prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
425   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
426 }
427
428 /**
429  * Use with #WM_gesture_straightline_invoke
430  */
431 void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
432 {
433   PropertyRNA *prop;
434
435   prop = RNA_def_int(ot->srna, "xstart", 0, INT_MIN, INT_MAX, "X Start", "", INT_MIN, INT_MAX);
436   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
437   prop = RNA_def_int(ot->srna, "xend", 0, INT_MIN, INT_MAX, "X End", "", INT_MIN, INT_MAX);
438   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
439   prop = RNA_def_int(ot->srna, "ystart", 0, INT_MIN, INT_MAX, "Y Start", "", INT_MIN, INT_MAX);
440   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
441   prop = RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX);
442   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
443
444   if (cursor) {
445     prop = RNA_def_int(ot->srna,
446                        "cursor",
447                        cursor,
448                        0,
449                        INT_MAX,
450                        "Cursor",
451                        "Mouse cursor style to use during the modal operator",
452                        0,
453                        INT_MAX);
454     RNA_def_property_flag(prop, PROP_HIDDEN);
455   }
456 }
457
458 /**
459  * Use with #WM_gesture_circle_invoke
460  */
461 void WM_operator_properties_gesture_circle(wmOperatorType *ot)
462 {
463   PropertyRNA *prop;
464   const int radius_default = 25;
465
466   prop = RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
467   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
468   prop = RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
469   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
470   RNA_def_int(ot->srna, "radius", radius_default, 1, INT_MAX, "Radius", "", 1, INT_MAX);
471
472   prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
473   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
474 }
475
476 void WM_operator_properties_mouse_select(wmOperatorType *ot)
477 {
478   PropertyRNA *prop;
479
480   prop = RNA_def_boolean(ot->srna,
481                          "extend",
482                          false,
483                          "Extend",
484                          "Extend selection instead of deselecting everything first");
485   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
486   prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from selection");
487   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
488   prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Selection", "Toggle the selection");
489   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
490
491   prop = RNA_def_boolean(ot->srna,
492                          "deselect_all",
493                          false,
494                          "Deselect On Nothing",
495                          "Deselect all when nothing under the cursor");
496   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
497 }
498
499 /**
500  * \param nth_can_disable: Enable if we want to be able to select no interval at all.
501  */
502 void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_disable)
503 {
504   const int nth_default = nth_can_disable ? 0 : 1;
505   const int nth_min = min_ii(nth_default, 1);
506   RNA_def_int(ot->srna,
507               "skip",
508               nth_default,
509               nth_min,
510               INT_MAX,
511               "Deselected",
512               "Number of deselected elements in the repetitive sequence",
513               nth_min,
514               100);
515   RNA_def_int(ot->srna,
516               "nth",
517               1,
518               1,
519               INT_MAX,
520               "Selected",
521               "Number of selected elements in the repetitive sequence",
522               1,
523               100);
524   RNA_def_int(ot->srna,
525               "offset",
526               0,
527               INT_MIN,
528               INT_MAX,
529               "Offset",
530               "Offset from the starting point",
531               -100,
532               100);
533 }
534
535 void WM_operator_properties_checker_interval_from_op(struct wmOperator *op,
536                                                      struct CheckerIntervalParams *op_params)
537 {
538   const int nth = RNA_int_get(op->ptr, "nth");
539   const int skip = RNA_int_get(op->ptr, "skip");
540   int offset = RNA_int_get(op->ptr, "offset");
541
542   op_params->nth = nth;
543   op_params->skip = skip;
544
545   /* So input of offset zero ends up being (nth - 1). */
546   op_params->offset = mod_i(offset, nth + skip);
547 }
548
549 bool WM_operator_properties_checker_interval_test(const struct CheckerIntervalParams *op_params,
550                                                   int depth)
551 {
552   return ((op_params->skip == 0) ||
553           ((op_params->offset + depth) % (op_params->skip + op_params->nth) >= op_params->skip));
554 }