Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_operator_props.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  * ***** END GPL LICENSE BLOCK *****
22  */
23
24 /** \file blender/windowmanager/intern/wm_operator_props.c
25  *  \ingroup wm
26  *
27  * Generic re-usable property definitions and accessors for operators to share.
28  * (`WM_operator_properties_*` functions).
29  */
30
31 #include "DNA_space_types.h"
32
33 #include "BLI_rect.h"
34 #include "BLI_math_base.h"
35
36 #include "UI_resources.h"
37
38 #include "RNA_access.h"
39 #include "RNA_define.h"
40 #include "RNA_enum_types.h"
41
42 #include "ED_select_utils.h"
43
44 #include "WM_api.h"
45 #include "WM_types.h"
46
47
48 void WM_operator_properties_confirm_or_exec(wmOperatorType *ot)
49 {
50         PropertyRNA *prop;
51
52         prop = RNA_def_boolean(ot->srna, "confirm", true, "Confirm", "Prompt for confirmation");
53         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
54 }
55
56 /* default properties for fileselect */
57 void WM_operator_properties_filesel(
58         wmOperatorType *ot, int filter, short type, short action,
59         short flag, short display, short sort)
60 {
61         PropertyRNA *prop;
62
63         static const EnumPropertyItem file_display_items[] = {
64                 {FILE_DEFAULTDISPLAY, "DEFAULT", 0, "Default", "Automatically determine display type for files"},
65                 {FILE_SHORTDISPLAY, "LIST_SHORT", ICON_SHORTDISPLAY, "Short List", "Display files as short list"},
66                 {FILE_LONGDISPLAY, "LIST_LONG", ICON_LONGDISPLAY, "Long List", "Display files as a detailed list"},
67                 {FILE_IMGDISPLAY, "THUMBNAIL", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
68                 {0, NULL, 0, NULL, NULL}
69         };
70
71         if (flag & WM_FILESEL_FILEPATH)
72                 RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path", "Path to file");
73
74         if (flag & WM_FILESEL_DIRECTORY)
75                 RNA_def_string_dir_path(ot->srna, "directory", NULL, FILE_MAX, "Directory", "Directory of the file");
76
77         if (flag & WM_FILESEL_FILENAME)
78                 RNA_def_string_file_name(ot->srna, "filename", NULL, FILE_MAX, "File Name", "Name of the file");
79
80         if (flag & WM_FILESEL_FILES)
81                 RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
82
83         if (action == FILE_SAVE) {
84                 /* note, this is only used to check if we should highlight the filename area red when the
85                  * filepath is an existing file. */
86                 prop = RNA_def_boolean(ot->srna, "check_existing", true, "Check Existing",
87                                        "Check and warn on overwriting existing files");
88                 RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
89         }
90
91         prop = RNA_def_boolean(ot->srna, "filter_blender", (filter & FILE_TYPE_BLENDER) != 0, "Filter .blend files", "");
92         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
93         prop = RNA_def_boolean(ot->srna, "filter_backup", (filter & FILE_TYPE_BLENDER_BACKUP) != 0, "Filter .blend files", "");
94         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
95         prop = RNA_def_boolean(ot->srna, "filter_image", (filter & FILE_TYPE_IMAGE) != 0, "Filter image files", "");
96         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
97         prop = RNA_def_boolean(ot->srna, "filter_movie", (filter & FILE_TYPE_MOVIE) != 0, "Filter movie files", "");
98         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
99         prop = RNA_def_boolean(ot->srna, "filter_python", (filter & FILE_TYPE_PYSCRIPT) != 0, "Filter python files", "");
100         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
101         prop = RNA_def_boolean(ot->srna, "filter_font", (filter & FILE_TYPE_FTFONT) != 0, "Filter font files", "");
102         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
103         prop = RNA_def_boolean(ot->srna, "filter_sound", (filter & FILE_TYPE_SOUND) != 0, "Filter sound files", "");
104         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
105         prop = RNA_def_boolean(ot->srna, "filter_text", (filter & FILE_TYPE_TEXT) != 0, "Filter text files", "");
106         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
107         prop = RNA_def_boolean(ot->srna, "filter_btx", (filter & FILE_TYPE_BTX) != 0, "Filter btx files", "");
108         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
109         prop = RNA_def_boolean(ot->srna, "filter_collada", (filter & FILE_TYPE_COLLADA) != 0, "Filter COLLADA files", "");
110         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
111         prop = RNA_def_boolean(ot->srna, "filter_alembic", (filter & FILE_TYPE_ALEMBIC) != 0, "Filter Alembic files", "");
112         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
113         prop = RNA_def_boolean(ot->srna, "filter_folder", (filter & FILE_TYPE_FOLDER) != 0, "Filter folders", "");
114         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
115         prop = RNA_def_boolean(ot->srna, "filter_blenlib", (filter & FILE_TYPE_BLENDERLIB) != 0, "Filter Blender IDs", "");
116         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
117
118         prop = RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL,
119                            "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file",
120                            FILE_LOADLIB, FILE_SPECIAL);
121         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
122
123         if (flag & WM_FILESEL_RELPATH)
124                 RNA_def_boolean(ot->srna, "relative_path", true, "Relative Path", "Select the file relative to the blend file");
125
126         if ((filter & FILE_TYPE_IMAGE) || (filter & FILE_TYPE_MOVIE)) {
127                 prop = RNA_def_boolean(ot->srna, "show_multiview", 0, "Enable Multi-View", "");
128                 RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
129                 prop = RNA_def_boolean(ot->srna, "use_multiview", 0, "Use Multi-View", "");
130                 RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
131         }
132
133         prop = RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", "");
134         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
135
136         prop = RNA_def_enum(ot->srna, "sort_method", rna_enum_file_sort_items, sort, "File sorting mode", "");
137         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
138
139 }
140
141 static void wm_operator_properties_select_action_ex(wmOperatorType *ot, int default_action,
142                                                     const EnumPropertyItem *select_actions)
143 {
144         PropertyRNA *prop;
145         prop = RNA_def_enum(ot->srna, "action", select_actions, default_action, "Action", "Selection action to execute");
146         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
147 }
148
149 void WM_operator_properties_select_action(wmOperatorType *ot, int default_action)
150 {
151         static const EnumPropertyItem select_actions[] = {
152                 {SEL_TOGGLE, "TOGGLE", 0, "Toggle", "Toggle selection for all elements"},
153                 {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
154                 {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
155                 {SEL_INVERT, "INVERT", 0, "Invert", "Invert selection of all elements"},
156                 {0, NULL, 0, NULL, NULL}
157         };
158
159         wm_operator_properties_select_action_ex(ot, default_action, select_actions);
160 }
161
162 /**
163  * only SELECT/DESELECT
164  */
165 void WM_operator_properties_select_action_simple(wmOperatorType *ot, int default_action)
166 {
167         static const EnumPropertyItem select_actions[] = {
168                 {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"},
169                 {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"},
170                 {0, NULL, 0, NULL, NULL}
171         };
172
173         wm_operator_properties_select_action_ex(ot, default_action, select_actions);
174 }
175
176 /**
177  * Use for all select random operators.
178  * Adds properties: percent, seed, action.
179  */
180 void WM_operator_properties_select_random(wmOperatorType *ot)
181 {
182         RNA_def_float_percentage(
183                 ot->srna, "percent", 50.f, 0.0f, 100.0f,
184                 "Percent", "Percentage of objects to select randomly", 0.f, 100.0f);
185         RNA_def_int(
186                 ot->srna, "seed", 0, 0, INT_MAX,
187                 "Random Seed", "Seed for the random number generator", 0, 255);
188
189         WM_operator_properties_select_action_simple(ot, SEL_SELECT);
190 }
191
192 int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
193 {
194         PropertyRNA *prop = RNA_struct_find_property(op->ptr, "seed");
195         int value = RNA_property_int_get(op->ptr, prop);
196
197         if (op->flag & OP_IS_INVOKE) {
198                 if (!RNA_property_is_set(op->ptr, prop)) {
199                         value += 1;
200                         RNA_property_int_set(op->ptr, prop, value);
201                 }
202         }
203         return value;
204 }
205
206 void WM_operator_properties_select_all(wmOperatorType *ot)
207 {
208         WM_operator_properties_select_action(ot, SEL_TOGGLE);
209 }
210
211 void WM_operator_properties_border(wmOperatorType *ot)
212 {
213         PropertyRNA *prop;
214
215         prop = RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
216         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
217         prop = RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
218         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
219         prop = RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
220         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
221         prop = RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
222         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
223 }
224
225 void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
226 {
227         rect->xmin = RNA_int_get(op->ptr, "xmin");
228         rect->ymin = RNA_int_get(op->ptr, "ymin");
229         rect->xmax = RNA_int_get(op->ptr, "xmax");
230         rect->ymax = RNA_int_get(op->ptr, "ymax");
231 }
232
233 void WM_operator_properties_border_to_rctf(struct wmOperator *op, rctf *rect)
234 {
235         rcti rect_i;
236         WM_operator_properties_border_to_rcti(op, &rect_i);
237         BLI_rctf_rcti_copy(rect, &rect_i);
238 }
239
240 /**
241  * Use with #WM_gesture_box_invoke
242  */
243 void WM_operator_properties_gesture_box_ex(wmOperatorType *ot, bool deselect, bool extend)
244 {
245         PropertyRNA *prop;
246
247         WM_operator_properties_border(ot);
248
249         if (deselect) {
250                 prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
251                 RNA_def_property_flag(prop, PROP_SKIP_SAVE);
252         }
253         if (extend) {
254                 prop = RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
255                 RNA_def_property_flag(prop, PROP_SKIP_SAVE);
256         }
257 }
258
259 void WM_operator_properties_gesture_box_select(wmOperatorType *ot)
260 {
261         WM_operator_properties_gesture_box_ex(ot, true, true);
262 }
263 void WM_operator_properties_gesture_box(wmOperatorType *ot)
264 {
265         WM_operator_properties_gesture_box_ex(ot, false, false);
266 }
267
268 void WM_operator_properties_select_operation(wmOperatorType *ot)
269 {
270         static const EnumPropertyItem select_mode_items[] = {
271                 {SEL_OP_SET, "SET", 0, "New", ""},
272                 {SEL_OP_ADD, "ADD", 0, "Add", ""},
273                 {SEL_OP_SUB, "SUB", 0, "Subtract", ""},
274                 {SEL_OP_XOR, "XOR", 0, "Difference", ""},
275                 {SEL_OP_AND, "AND", 0, "Intersect", ""},
276                 {0, NULL, 0, NULL, NULL}
277         };
278         PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
279         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
280 }
281
282 /* Some tools don't support XOR/AND. */
283 void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
284 {
285         static const EnumPropertyItem select_mode_items[] = {
286                 {SEL_OP_SET, "SET", 0, "New", ""},
287                 {SEL_OP_ADD, "ADD", 0, "Add", ""},
288                 {SEL_OP_SUB, "SUB", 0, "Subtract", ""},
289                 {0, NULL, 0, NULL, NULL}
290         };
291         PropertyRNA *prop = RNA_def_enum(ot->srna, "mode", select_mode_items, SEL_OP_SET, "Mode", "");
292         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
293 }
294
295 void WM_operator_properties_gesture_box_zoom(wmOperatorType *ot)
296 {
297         WM_operator_properties_border(ot);
298
299         PropertyRNA *prop;
300         prop = RNA_def_boolean(ot->srna, "zoom_out", false, "Zoom Out", "");
301         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
302 }
303
304 /**
305  * Use with #WM_gesture_lasso_invoke
306  */
307 void WM_operator_properties_gesture_lasso_ex(wmOperatorType *ot, bool deselect, bool extend)
308 {
309         PropertyRNA *prop;
310         prop = RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
311         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
312
313         if (deselect) {
314                 RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
315         }
316         if (extend) {
317                 RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
318         }
319 }
320
321 void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
322 {
323         WM_operator_properties_gesture_lasso_ex(ot, false, false);
324 }
325
326 void WM_operator_properties_gesture_lasso_select(wmOperatorType *ot)
327 {
328         WM_operator_properties_gesture_lasso_ex(ot, true, true);
329 }
330
331 /**
332  * Use with #WM_gesture_straightline_invoke
333  */
334 void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
335 {
336         PropertyRNA *prop;
337
338         prop = RNA_def_int(ot->srna, "xstart", 0, INT_MIN, INT_MAX, "X Start", "", INT_MIN, INT_MAX);
339         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
340         prop = RNA_def_int(ot->srna, "xend", 0, INT_MIN, INT_MAX, "X End", "", INT_MIN, INT_MAX);
341         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
342         prop = RNA_def_int(ot->srna, "ystart", 0, INT_MIN, INT_MAX, "Y Start", "", INT_MIN, INT_MAX);
343         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
344         prop = RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX);
345         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
346
347         if (cursor) {
348                 prop = RNA_def_int(ot->srna, "cursor", cursor, 0, INT_MAX,
349                                    "Cursor", "Mouse cursor style to use during the modal operator", 0, INT_MAX);
350                 RNA_def_property_flag(prop, PROP_HIDDEN);
351         }
352 }
353
354 /**
355  * Use with #WM_gesture_circle_invoke
356  */
357 void WM_operator_properties_gesture_circle_ex(wmOperatorType *ot, bool deselect)
358 {
359         PropertyRNA *prop;
360         const int radius_default = 25;
361
362         prop = RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
363         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
364         prop = RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
365         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
366         RNA_def_int(ot->srna, "radius", radius_default, 1, INT_MAX, "Radius", "", 1, INT_MAX);
367
368         if (deselect) {
369                 prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Deselect rather than select items");
370                 RNA_def_property_flag(prop, PROP_SKIP_SAVE);
371         }
372 }
373
374 void WM_operator_properties_gesture_circle(wmOperatorType *ot)
375 {
376         WM_operator_properties_gesture_circle_ex(ot, false);
377 }
378
379 void WM_operator_properties_gesture_circle_select(wmOperatorType *ot)
380 {
381         WM_operator_properties_gesture_circle_ex(ot, true);
382 }
383
384 void WM_operator_properties_mouse_select(wmOperatorType *ot)
385 {
386         PropertyRNA *prop;
387
388         prop = RNA_def_boolean(ot->srna, "extend", false, "Extend",
389                                "Extend selection instead of deselecting everything first");
390         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
391         prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from selection");
392         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
393         prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Selection", "Toggle the selection");
394         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
395 }
396
397 /**
398  * \param nth_can_disable: Enable if we want to be able to select no interval at all.
399  */
400 void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_disable)
401 {
402         const int nth_default = nth_can_disable ? 1 : 2;
403         const int nth_min =  min_ii(nth_default, 2);
404         RNA_def_int(ot->srna, "nth", nth_default, nth_min, INT_MAX, "Nth Element", "Skip every Nth element", nth_min, 100);
405         RNA_def_int(ot->srna, "skip", 1, 1, INT_MAX, "Skip", "Number of elements to skip at once", 1, 100);
406         RNA_def_int(ot->srna, "offset", 0, INT_MIN, INT_MAX, "Offset", "Offset from the starting point", -100, 100);
407 }
408
409 void WM_operator_properties_checker_interval_from_op(
410         struct wmOperator *op, struct CheckerIntervalParams *op_params)
411 {
412         const int nth = RNA_int_get(op->ptr, "nth") - 1;
413         const int skip = RNA_int_get(op->ptr, "skip");
414         int offset = RNA_int_get(op->ptr, "offset");
415
416         op_params->nth = nth;
417         op_params->skip = skip;
418         op_params->offset = mod_i(offset, nth + skip);  /* so input of offset zero ends up being (nth - 1) */
419 }
420
421 bool WM_operator_properties_checker_interval_test(
422         const struct CheckerIntervalParams *op_params, int depth)
423 {
424         return ((op_params->nth == 0) ||
425                 ((op_params->offset + depth) % (op_params->skip + op_params->nth) >= op_params->skip));
426 }