Manipulator: Support click only manipulator's
[blender.git] / source / blender / windowmanager / manipulators / WM_manipulator_types.h
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) 2016 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): none yet.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/windowmanager/manipulators/WM_manipulator_types.h
27  *  \ingroup wm
28  *
29  * \name Manipulator Types
30  * \brief Manipulator defines for external use.
31  *
32  * Only included in WM_types.h and lower level files.
33  */
34
35
36 #ifndef __WM_MANIPULATOR_TYPES_H__
37 #define __WM_MANIPULATOR_TYPES_H__
38
39 #include "BLI_compiler_attrs.h"
40
41 struct wmManipulatorMapType;
42 struct wmManipulatorGroupType;
43 struct wmManipulatorGroup;
44 struct wmManipulator;
45 struct wmManipulatorProperty;
46 struct wmKeyConfig;
47
48 #include "DNA_listBase.h"
49
50
51 /* -------------------------------------------------------------------- */
52 /* Enum Typedef's */
53
54
55 /**
56  * #wmManipulator.state
57  */
58 typedef enum eWM_ManipulatorState {
59         WM_MANIPULATOR_STATE_HIGHLIGHT   = (1 << 0), /* while hovered */
60         WM_MANIPULATOR_STATE_MODAL       = (1 << 1), /* while dragging */
61         WM_MANIPULATOR_STATE_SELECT      = (1 << 2),
62 } eWM_ManipulatorState;
63
64
65 /**
66  * #wmManipulator.flag
67  * Flags for individual manipulators.
68  */
69 typedef enum eWM_ManipulatorFlag {
70         WM_MANIPULATOR_DRAW_HOVER  = (1 << 0), /* draw *only* while hovering */
71         WM_MANIPULATOR_DRAW_MODAL  = (1 << 1), /* draw while dragging */
72         WM_MANIPULATOR_DRAW_VALUE  = (1 << 2), /* draw an indicator for the current value while dragging */
73         WM_MANIPULATOR_HIDDEN      = (1 << 3),
74         /**
75          * When set 'scale_final' value also scales the offset.
76          * Use when offset is to avoid screen-space overlap instead of absolute positioning. */
77         WM_MANIPULATOR_DRAW_OFFSET_SCALE  = (1 << 4),
78         /**
79          * User should still use 'scale_final' for any handles and UI elements.
80          * This simply skips scale when calculating the final matrix.
81          * Needed when the manipulator needs to align with the interface underneath it. */
82         WM_MANIPULATOR_DRAW_NO_SCALE  = (1 << 5),
83         /**
84          * Hide the cursor and lock it's position while interacting with this manipulator.
85          */
86         WM_MANIPULATOR_GRAB_CURSOR = (1 << 6),
87 } eWM_ManipulatorFlag;
88
89 /**
90  * #wmManipulatorGroupType.flag
91  * Flags that influence the behavior of all manipulators in the group.
92  */
93 typedef enum eWM_ManipulatorGroupTypeFlag {
94         /* Mark manipulator-group as being 3D */
95         WM_MANIPULATORGROUPTYPE_3D       = (1 << 0),
96         /* Scale manipulators as 3D object that respects zoom (otherwise zoom independent draw size).
97          * note: currently only for 3D views, 2D support needs adding. */
98         WM_MANIPULATORGROUPTYPE_SCALE    = (1 << 1),
99         /* Manipulators can be depth culled with scene objects (covered by other geometry - TODO) */
100         WM_MANIPULATORGROUPTYPE_DEPTH_3D = (1 << 2),
101         /* Manipulators can be selected */
102         WM_MANIPULATORGROUPTYPE_SELECT  = (1 << 3),
103         /* The manipulator group is to be kept (not removed on loading a new file for eg). */
104         WM_MANIPULATORGROUPTYPE_PERSISTENT = (1 << 4),
105         /* Show all other manipulators when interacting. */
106         WM_MANIPULATORGROUPTYPE_DRAW_MODAL_ALL = (1 << 5),
107 } eWM_ManipulatorGroupTypeFlag;
108
109
110 /**
111  * #wmManipulatorGroup.init_flag
112  */
113 typedef enum eWM_ManipulatorGroupInitFlag {
114         /* mgroup has been initialized */
115         WM_MANIPULATORGROUP_INIT_SETUP = (1 << 0),
116         WM_MANIPULATORGROUP_INIT_REFRESH = (1 << 1),
117 } eWM_ManipulatorGroupInitFlag;
118
119 /**
120  * #wmManipulatorMapType.type_update_flag
121  * Manipulator-map type update flag
122  */
123 typedef enum eWM_ManipulatorMapTypeUpdateFlag {
124         /* A new type has been added, needs to be initialized for all views. */
125         WM_MANIPULATORMAPTYPE_UPDATE_INIT = (1 << 0),
126         WM_MANIPULATORMAPTYPE_UPDATE_REMOVE = (1 << 1),
127
128         /* Needed because keymap may be registered before and after window initialization.
129          * So we need to keep track of keymap initialization separately. */
130         WM_MANIPULATORMAPTYPE_KEYMAP_INIT = (1 << 2),
131 } eWM_ManipulatorMapTypeUpdateFlag;
132
133 /* -------------------------------------------------------------------- */
134 /* wmManipulator */
135
136 /**
137  * \brief Manipulator tweak flag.
138  * Bitflag passed to manipulator while tweaking.
139  *
140  * \note Manipulators are responsible for handling this #wmManipulator.modal callback!.
141  */
142 typedef enum {
143         /* Drag with extra precision (Shift). */
144         WM_MANIPULATOR_TWEAK_PRECISE = (1 << 0),
145         /* Drag with snap enabled (Ctrl).  */
146         WM_MANIPULATOR_TWEAK_SNAP = (1 << 1),
147 } eWM_ManipulatorTweak;
148
149 #include "wm_manipulator_fn.h"
150
151 typedef struct wmManipulatorOpElem {
152         struct wmOperatorType *type;
153         /* operator properties if manipulator spawns and controls an operator,
154          * or owner pointer if manipulator spawns and controls a property */
155         PointerRNA ptr;
156 } wmManipulatorOpElem;
157
158 /* manipulators are set per region by registering them on manipulator-maps */
159 struct wmManipulator {
160         struct wmManipulator *next, *prev;
161
162         /* While we don't have a real type, use this to put type-like vars. */
163         const struct wmManipulatorType *type;
164
165         /* Overrides 'type->modal' when set.
166          * Note that this is a workaround, remove if we can. */
167         wmManipulatorFnModal custom_modal;
168
169         /* pointer back to group this manipulator is in (just for quick access) */
170         struct wmManipulatorGroup *parent_mgroup;
171
172         void *py_instance;
173
174         /* rna pointer to access properties */
175         struct PointerRNA *ptr;
176
177         /* flags that influence the behavior or how the manipulators are drawn */
178         eWM_ManipulatorFlag flag;
179         /* state flags (active, highlighted, selected) */
180         eWM_ManipulatorState state;
181
182         /* Optional ID for highlighting different parts of this manipulator.
183          * -1 when unset, otherwise a valid index. (Used as index to 'op_data'). */
184         int highlight_part;
185         /* For single click button manipulators, use a different part as a fallback, -1 when unused. */
186         int drag_part;
187
188         /* Transformation of the manipulator in 2d or 3d space.
189          * - Matrix axis are expected to be unit length (scale is applied after).
190          * - Behavior when axis aren't orthogonal depends on each manipulator.
191          * - Typically the +Z is the primary axis for manipulators to use.
192          * - 'matrix[3]' must be used for location,
193          *   besides this it's up to the manipulators internal code how the
194          *   rotation components are used for drawing and interaction.
195          */
196
197         /* The space this manipulator is being modified in. */
198         float matrix_space[4][4];
199         /* Transformation of this manipulator. */
200         float matrix_basis[4][4];
201         /* custom offset from origin */
202         float matrix_offset[4][4];
203         /* runtime property, set the scale while drawing on the viewport */
204         float scale_final;
205         /* user defined scale, in addition to the original one */
206         float scale_basis;
207         /* user defined width for line drawing */
208         float line_width;
209         /* manipulator colors (uses default fallbacks if not defined) */
210         float color[4], color_hi[4];
211
212         /* data used during interaction */
213         void *interaction_data;
214
215         /* Operator to spawn when activating the manipulator (overrides property editing),
216          * an array of items (aligned with #wmManipulator.highlight_part). */
217         wmManipulatorOpElem *op_data;
218         int op_data_len;
219
220         struct IDProperty *properties;
221
222         /* over alloc target_properties after 'wmManipulatorType.struct_size' */
223 };
224
225 /* Similar to PropertyElemRNA, but has an identifier. */
226 typedef struct wmManipulatorProperty {
227         const struct wmManipulatorPropertyType *type;
228
229         PointerRNA ptr;
230         PropertyRNA *prop;
231         int index;
232
233
234         /* Optional functions for converting to/from RNA  */
235         struct {
236                 wmManipulatorPropertyFnGet value_get_fn;
237                 wmManipulatorPropertyFnSet value_set_fn;
238                 wmManipulatorPropertyFnRangeGet range_get_fn;
239                 wmManipulatorPropertyFnFree free_fn;
240                 void *user_data;
241         } custom_func;
242 } wmManipulatorProperty;
243
244 typedef struct wmManipulatorPropertyType {
245         struct wmManipulatorPropertyType *next, *prev;
246         /* PropertyType, typically 'PROP_FLOAT' */
247         int data_type;
248         int array_length;
249
250         /* index within 'wmManipulatorType' */
251         int index_in_type;
252
253         /* over alloc */
254         char idname[0];
255 } wmManipulatorPropertyType;
256
257
258 /**
259  * Simple utility wrapper for storing a single manipulator as wmManipulatorGroup.customdata (which gets freed).
260  */
261 typedef struct wmManipulatorWrapper {
262         struct wmManipulator *manipulator;
263 } wmManipulatorWrapper;
264
265 struct wmManipulatorMapType_Params {
266         short spaceid;
267         short regionid;
268 };
269
270 typedef struct wmManipulatorType {
271
272         const char *idname; /* MAX_NAME */
273
274         /* Set to 'sizeof(wmManipulator)' or larger for instances of this type,
275          * use so we can cant to other types without the hassle of a custom-data pointer. */
276         uint struct_size;
277
278         /* Initialize struct (calloc'd 'struct_size' region). */
279         wmManipulatorFnSetup setup;
280
281         /* draw manipulator */
282         wmManipulatorFnDraw draw;
283
284         /* determines 3d intersection by rendering the manipulator in a selection routine. */
285         wmManipulatorFnDrawSelect draw_select;
286
287         /* Determine if the mouse intersects with the manipulator.
288          * The calculation should be done in the callback itself, -1 for no seleciton. */
289         wmManipulatorFnTestSelect test_select;
290
291         /* handler used by the manipulator. Usually handles interaction tied to a manipulator type */
292         wmManipulatorFnModal modal;
293
294         /* manipulator-specific handler to update manipulator attributes based on the property value */
295         wmManipulatorFnPropertyUpdate property_update;
296
297         /* Returns the final transformation which may be different from the 'matrix',
298          * depending on the manipulator.
299          * Notes:
300          * - Scale isn't applied (wmManipulator.scale/user_scale).
301          * - Offset isn't applied (wmManipulator.matrix_offset).
302          */
303         wmManipulatorFnMatrixBasisGet matrix_basis_get;
304
305         /* activate a manipulator state when the user clicks on it */
306         wmManipulatorFnInvoke invoke;
307
308         /* called when manipulator tweaking is done - used to free data and reset property when cancelling */
309         wmManipulatorFnExit exit;
310
311         wmManipulatorFnCursorGet cursor_get;
312
313         /* called when manipulator selection state changes */
314         wmManipulatorFnSelectRefresh select_refresh;
315
316         /* RNA for properties */
317         struct StructRNA *srna;
318
319         /* RNA integration */
320         ExtensionRNA ext;
321
322         ListBase target_property_defs;
323         int target_property_defs_len;
324
325 } wmManipulatorType;
326
327
328 /* -------------------------------------------------------------------- */
329 /* wmManipulatorGroup */
330
331 /* factory class for a manipulator-group type, gets called every time a new area is spawned */
332 typedef struct wmManipulatorGroupTypeRef {
333         struct wmManipulatorGroupTypeRef *next, *prev;
334         struct wmManipulatorGroupType *type;
335 } wmManipulatorGroupTypeRef;
336
337 /* factory class for a manipulator-group type, gets called every time a new area is spawned */
338 typedef struct wmManipulatorGroupType {
339         const char *idname;  /* MAX_NAME */
340         const char *name; /* manipulator-group name - displayed in UI (keymap editor) */
341
342         /* poll if manipulator-map should be visible */
343         wmManipulatorGroupFnPoll poll;
344         /* initially create manipulators and set permanent data - stuff you only need to do once */
345         wmManipulatorGroupFnInit setup;
346         /* refresh data, only called if recreate flag is set (WM_manipulatormap_tag_refresh) */
347         wmManipulatorGroupFnRefresh refresh;
348         /* refresh data for drawing, called before each redraw */
349         wmManipulatorGroupFnDrawPrepare draw_prepare;
350
351         /* Keymap init callback for this manipulator-group (optional),
352          * will fall back to default tweak keymap when left NULL. */
353         wmManipulatorGroupFnSetupKeymap setup_keymap;
354
355         /* Optionally subscribe to wmMsgBus events,
356          * these are calculated automatically from RNA properties,
357          * only needed if manipulators depend indirectly on properties. */
358         wmManipulatorGroupFnMsgBusSubscribe message_subscribe;
359
360         /* keymap created with callback from above */
361         struct wmKeyMap *keymap;
362         /* Only for convenient removal. */
363         struct wmKeyConfig *keyconf;
364
365         /* Disable for now, maybe some day we want properties. */
366 #if 0
367         /* rna for properties */
368         struct StructRNA *srna;
369 #endif
370
371         /* RNA integration */
372         ExtensionRNA ext;
373
374         eWM_ManipulatorGroupTypeFlag flag;
375
376         /* So we know which group type to update. */
377         eWM_ManipulatorMapTypeUpdateFlag type_update_flag;
378
379         /* same as manipulator-maps, so registering/unregistering goes to the correct region */
380         struct wmManipulatorMapType_Params mmap_params;
381
382 } wmManipulatorGroupType;
383
384 typedef struct wmManipulatorGroup {
385         struct wmManipulatorGroup *next, *prev;
386
387         struct wmManipulatorGroupType *type;
388         ListBase manipulators;
389
390         struct wmManipulatorMap *parent_mmap;
391
392         void *py_instance;            /* python stores the class instance here */
393         struct ReportList *reports;   /* errors and warnings storage */
394
395         void *customdata;
396         void (*customdata_free)(void *); /* for freeing customdata from above */
397         eWM_ManipulatorGroupInitFlag init_flag;
398 } wmManipulatorGroup;
399
400 /* -------------------------------------------------------------------- */
401 /* wmManipulatorMap */
402
403 /**
404  * Pass a value of this enum to #WM_manipulatormap_draw to tell it what to draw.
405  */
406 typedef enum eWM_ManipulatorMapDrawStep {
407         /** Draw 2D manipulator-groups (#WM_MANIPULATORGROUPTYPE_3D not set). */
408         WM_MANIPULATORMAP_DRAWSTEP_2D = 0,
409         /** Draw 3D manipulator-groups (#WM_MANIPULATORGROUPTYPE_3D set). */
410         WM_MANIPULATORMAP_DRAWSTEP_3D,
411 } eWM_ManipulatorMapDrawStep;
412 #define WM_MANIPULATORMAP_DRAWSTEP_MAX 2
413
414 #endif  /* __WM_MANIPULATOR_TYPES_H__ */