Merge branch 'blender2.7'
[blender.git] / source / blender / windowmanager / gizmo / WM_gizmo_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/gizmo/WM_gizmo_types.h
27  *  \ingroup wm
28  *
29  * \name Gizmo Types
30  * \brief Gizmo defines for external use.
31  *
32  * Only included in WM_types.h and lower level files.
33  */
34
35
36 #ifndef __WM_GIZMO_TYPES_H__
37 #define __WM_GIZMO_TYPES_H__
38
39 #include "BLI_compiler_attrs.h"
40
41 struct wmGizmoMapType;
42 struct wmGizmoGroupType;
43 struct wmGizmoGroup;
44 struct wmGizmo;
45 struct wmGizmoProperty;
46 struct wmKeyConfig;
47
48 #include "DNA_listBase.h"
49
50
51 /* -------------------------------------------------------------------- */
52 /* Enum Typedef's */
53
54
55 /**
56  * #wmGizmo.state
57  */
58 typedef enum eWM_GizmoFlagState {
59         WM_GIZMO_STATE_HIGHLIGHT   = (1 << 0), /* while hovered */
60         WM_GIZMO_STATE_MODAL       = (1 << 1), /* while dragging */
61         WM_GIZMO_STATE_SELECT      = (1 << 2),
62 } eWM_GizmoFlagState;
63
64
65 /**
66  * #wmGizmo.flag
67  * Flags for individual gizmos.
68  */
69 typedef enum eWM_GizmoFlag {
70         WM_GIZMO_DRAW_HOVER    = (1 << 0), /* draw *only* while hovering */
71         WM_GIZMO_DRAW_MODAL    = (1 << 1), /* draw while dragging */
72         WM_GIZMO_DRAW_VALUE    = (1 << 2), /* draw an indicator for the current value while dragging */
73         WM_GIZMO_HIDDEN        = (1 << 3),
74         WM_GIZMO_HIDDEN_SELECT = (1 << 4),
75         /**
76          * When set 'scale_final' value also scales the offset.
77          * Use when offset is to avoid screen-space overlap instead of absolute positioning. */
78         WM_GIZMO_DRAW_OFFSET_SCALE  = (1 << 5),
79         /**
80          * User should still use 'scale_final' for any handles and UI elements.
81          * This simply skips scale when calculating the final matrix.
82          * Needed when the gizmo needs to align with the interface underneath it. */
83         WM_GIZMO_DRAW_NO_SCALE  = (1 << 6),
84         /**
85          * Hide the cursor and lock it's position while interacting with this gizmo.
86          */
87         WM_GIZMO_MOVE_CURSOR = (1 << 7),
88         /** Don't write into the depth buffer when selecting. */
89         WM_GIZMO_SELECT_BACKGROUND  = (1 << 8),
90 } eWM_GizmoFlag;
91
92 /**
93  * #wmGizmoGroupType.flag
94  * Flags that influence the behavior of all gizmos in the group.
95  */
96 typedef enum eWM_GizmoFlagGroupTypeFlag {
97         /** Mark gizmo-group as being 3D */
98         WM_GIZMOGROUPTYPE_3D       = (1 << 0),
99         /** Scale gizmos as 3D object that respects zoom (otherwise zoom independent draw size).
100          * note: currently only for 3D views, 2D support needs adding. */
101         WM_GIZMOGROUPTYPE_SCALE    = (1 << 1),
102         /** Gizmos can be depth culled with scene objects (covered by other geometry - TODO) */
103         WM_GIZMOGROUPTYPE_DEPTH_3D = (1 << 2),
104         /** Gizmos can be selected */
105         WM_GIZMOGROUPTYPE_SELECT  = (1 << 3),
106         /** The gizmo group is to be kept (not removed on loading a new file for eg). */
107         WM_GIZMOGROUPTYPE_PERSISTENT = (1 << 4),
108         /** Show all other gizmos when interacting. */
109         WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL = (1 << 5),
110         /**
111          * When used with tool, only run when activating the tool,
112          * instead of linking the gizmo while the tool is active.
113          *
114          * \warning this option has some limitations, we might even re-implement this differently.
115          * Currently it's quite minimal so we can see how it works out.
116          * The main issue is controlling how a gizmo is activated with a tool
117          * when a tool can activate multiple operators based on the key-map.
118          * We could even move the options into the key-map item.
119          * ~ campbell */
120         WM_GIZMOGROUPTYPE_TOOL_INIT = (1 << 6),
121 } eWM_GizmoFlagGroupTypeFlag;
122
123
124 /**
125  * #wmGizmoGroup.init_flag
126  */
127 typedef enum eWM_GizmoFlagGroupInitFlag {
128         /* mgroup has been initialized */
129         WM_GIZMOGROUP_INIT_SETUP = (1 << 0),
130         WM_GIZMOGROUP_INIT_REFRESH = (1 << 1),
131 } eWM_GizmoFlagGroupInitFlag;
132
133 /**
134  * #wmGizmoMapType.type_update_flag
135  * Gizmo-map type update flag
136  */
137 typedef enum eWM_GizmoFlagMapTypeUpdateFlag {
138         /* A new type has been added, needs to be initialized for all views. */
139         WM_GIZMOMAPTYPE_UPDATE_INIT = (1 << 0),
140         WM_GIZMOMAPTYPE_UPDATE_REMOVE = (1 << 1),
141
142         /* Needed because keymap may be registered before and after window initialization.
143          * So we need to keep track of keymap initialization separately. */
144         WM_GIZMOMAPTYPE_KEYMAP_INIT = (1 << 2),
145 } eWM_GizmoFlagMapTypeUpdateFlag;
146
147 /* -------------------------------------------------------------------- */
148 /* wmGizmo */
149
150 /**
151  * \brief Gizmo tweak flag.
152  * Bitflag passed to gizmo while tweaking.
153  *
154  * \note Gizmos are responsible for handling this #wmGizmo.modal callback!.
155  */
156 typedef enum {
157         /* Drag with extra precision (Shift). */
158         WM_GIZMO_TWEAK_PRECISE = (1 << 0),
159         /* Drag with snap enabled (Ctrl).  */
160         WM_GIZMO_TWEAK_SNAP = (1 << 1),
161 } eWM_GizmoFlagTweak;
162
163 #include "wm_gizmo_fn.h"
164
165 typedef struct wmGizmoOpElem {
166         struct wmOperatorType *type;
167         /* operator properties if gizmo spawns and controls an operator,
168          * or owner pointer if gizmo spawns and controls a property */
169         PointerRNA ptr;
170
171         bool is_redo;
172 } wmGizmoOpElem;
173
174 /* gizmos are set per region by registering them on gizmo-maps */
175 struct wmGizmo {
176         struct wmGizmo *next, *prev;
177
178         /* While we don't have a real type, use this to put type-like vars. */
179         const struct wmGizmoType *type;
180
181         /* Overrides 'type->modal' when set.
182          * Note that this is a workaround, remove if we can. */
183         wmGizmoFnModal custom_modal;
184
185         /* pointer back to group this gizmo is in (just for quick access) */
186         struct wmGizmoGroup *parent_gzgroup;
187
188         void *py_instance;
189
190         /* rna pointer to access properties */
191         struct PointerRNA *ptr;
192
193         /* flags that influence the behavior or how the gizmos are drawn */
194         eWM_GizmoFlag flag;
195         /* state flags (active, highlighted, selected) */
196         eWM_GizmoFlagState state;
197
198         /* Optional ID for highlighting different parts of this gizmo.
199          * -1 when unset, otherwise a valid index. (Used as index to 'op_data'). */
200         int highlight_part;
201         /* For single click button gizmos, use a different part as a fallback, -1 when unused. */
202         int drag_part;
203
204         /* Transformation of the gizmo in 2d or 3d space.
205          * - Matrix axis are expected to be unit length (scale is applied after).
206          * - Behavior when axis aren't orthogonal depends on each gizmo.
207          * - Typically the +Z is the primary axis for gizmos to use.
208          * - 'matrix[3]' must be used for location,
209          *   besides this it's up to the gizmos internal code how the
210          *   rotation components are used for drawing and interaction.
211          */
212
213         /* The space this gizmo is being modified in. */
214         float matrix_space[4][4];
215         /* Transformation of this gizmo. */
216         float matrix_basis[4][4];
217         /* custom offset from origin */
218         float matrix_offset[4][4];
219         /* runtime property, set the scale while drawing on the viewport */
220         float scale_final;
221         /* user defined scale, in addition to the original one */
222         float scale_basis;
223         /* user defined width for line drawing */
224         float line_width;
225         /* gizmo colors (uses default fallbacks if not defined) */
226         float color[4], color_hi[4];
227
228         /* data used during interaction */
229         void *interaction_data;
230
231         /* Operator to spawn when activating the gizmo (overrides property editing),
232          * an array of items (aligned with #wmGizmo.highlight_part). */
233         wmGizmoOpElem *op_data;
234         int op_data_len;
235
236         struct IDProperty *properties;
237
238         /* Temporary data (assume dirty). */
239         union {
240                 float f;
241         } temp;
242
243         /* over alloc target_properties after 'wmGizmoType.struct_size' */
244 };
245
246 /* Similar to PropertyElemRNA, but has an identifier. */
247 typedef struct wmGizmoProperty {
248         const struct wmGizmoPropertyType *type;
249
250         PointerRNA ptr;
251         PropertyRNA *prop;
252         int index;
253
254
255         /* Optional functions for converting to/from RNA  */
256         struct {
257                 wmGizmoPropertyFnGet value_get_fn;
258                 wmGizmoPropertyFnSet value_set_fn;
259                 wmGizmoPropertyFnRangeGet range_get_fn;
260                 wmGizmoPropertyFnFree free_fn;
261                 void *user_data;
262         } custom_func;
263 } wmGizmoProperty;
264
265 typedef struct wmGizmoPropertyType {
266         struct wmGizmoPropertyType *next, *prev;
267         /* PropertyType, typically 'PROP_FLOAT' */
268         int data_type;
269         int array_length;
270
271         /* index within 'wmGizmoType' */
272         int index_in_type;
273
274         /* over alloc */
275         char idname[0];
276 } wmGizmoPropertyType;
277
278
279 /**
280  * Simple utility wrapper for storing a single gizmo as wmGizmoGroup.customdata (which gets freed).
281  */
282 typedef struct wmGizmoWrapper {
283         struct wmGizmo *gizmo;
284 } wmGizmoWrapper;
285
286 struct wmGizmoMapType_Params {
287         short spaceid;
288         short regionid;
289 };
290
291 typedef struct wmGizmoType {
292
293         const char *idname; /* MAX_NAME */
294
295         /* Set to 'sizeof(wmGizmo)' or larger for instances of this type,
296          * use so we can cant to other types without the hassle of a custom-data pointer. */
297         uint struct_size;
298
299         /* Initialize struct (calloc'd 'struct_size' region). */
300         wmGizmoFnSetup setup;
301
302         /* draw gizmo */
303         wmGizmoFnDraw draw;
304
305         /* determines 3d intersection by rendering the gizmo in a selection routine. */
306         wmGizmoFnDrawSelect draw_select;
307
308         /* Determine if the mouse intersects with the gizmo.
309          * The calculation should be done in the callback itself, -1 for no seleciton. */
310         wmGizmoFnTestSelect test_select;
311
312         /* handler used by the gizmo. Usually handles interaction tied to a gizmo type */
313         wmGizmoFnModal modal;
314
315         /* gizmo-specific handler to update gizmo attributes based on the property value */
316         wmGizmoFnPropertyUpdate property_update;
317
318         /* Returns the final transformation which may be different from the 'matrix',
319          * depending on the gizmo.
320          * Notes:
321          * - Scale isn't applied (wmGizmo.scale/user_scale).
322          * - Offset isn't applied (wmGizmo.matrix_offset).
323          */
324         wmGizmoFnMatrixBasisGet matrix_basis_get;
325
326         /* activate a gizmo state when the user clicks on it */
327         wmGizmoFnInvoke invoke;
328
329         /* called when gizmo tweaking is done - used to free data and reset property when cancelling */
330         wmGizmoFnExit exit;
331
332         wmGizmoFnCursorGet cursor_get;
333
334         /* called when gizmo selection state changes */
335         wmGizmoFnSelectRefresh select_refresh;
336
337         /* Free data (not the gizmo it's self), use when the gizmo allocates it's own members. */
338         wmGizmoFnFree free;
339
340         /* RNA for properties */
341         struct StructRNA *srna;
342
343         /* RNA integration */
344         ExtensionRNA ext;
345
346         ListBase target_property_defs;
347         int target_property_defs_len;
348
349 } wmGizmoType;
350
351
352 /* -------------------------------------------------------------------- */
353 /* wmGizmoGroup */
354
355 /* factory class for a gizmo-group type, gets called every time a new area is spawned */
356 typedef struct wmGizmoGroupTypeRef {
357         struct wmGizmoGroupTypeRef *next, *prev;
358         struct wmGizmoGroupType *type;
359 } wmGizmoGroupTypeRef;
360
361 /* factory class for a gizmo-group type, gets called every time a new area is spawned */
362 typedef struct wmGizmoGroupType {
363         const char *idname;  /* MAX_NAME */
364         const char *name; /* gizmo-group name - displayed in UI (keymap editor) */
365         char owner_id[64];  /* MAX_NAME */
366
367         /* poll if gizmo-map should be visible */
368         wmGizmoGroupFnPoll poll;
369         /* initially create gizmos and set permanent data - stuff you only need to do once */
370         wmGizmoGroupFnInit setup;
371         /* refresh data, only called if recreate flag is set (WM_gizmomap_tag_refresh) */
372         wmGizmoGroupFnRefresh refresh;
373         /* refresh data for drawing, called before each redraw */
374         wmGizmoGroupFnDrawPrepare draw_prepare;
375         /* Initialize data for before invoke. */
376         wmGizmoGroupFnInvokePrepare invoke_prepare;
377
378         /* Keymap init callback for this gizmo-group (optional),
379          * will fall back to default tweak keymap when left NULL. */
380         wmGizmoGroupFnSetupKeymap setup_keymap;
381
382         /* Optionally subscribe to wmMsgBus events,
383          * these are calculated automatically from RNA properties,
384          * only needed if gizmos depend indirectly on properties. */
385         wmGizmoGroupFnMsgBusSubscribe message_subscribe;
386
387         /* keymap created with callback from above */
388         struct wmKeyMap *keymap;
389         /* Only for convenient removal. */
390         struct wmKeyConfig *keyconf;
391
392         /* Note: currently gizmo-group instances don't store properties,
393          * they're kept in the tool properties. */
394
395         /* RNA for properties */
396         struct StructRNA *srna;
397
398         /* RNA integration */
399         ExtensionRNA ext;
400
401         eWM_GizmoFlagGroupTypeFlag flag;
402
403         /* So we know which group type to update. */
404         eWM_GizmoFlagMapTypeUpdateFlag type_update_flag;
405
406         /* same as gizmo-maps, so registering/unregistering goes to the correct region */
407         struct wmGizmoMapType_Params gzmap_params;
408
409 } wmGizmoGroupType;
410
411 typedef struct wmGizmoGroup {
412         struct wmGizmoGroup *next, *prev;
413
414         struct wmGizmoGroupType *type;
415         ListBase gizmos;
416
417         struct wmGizmoMap *parent_gzmap;
418
419         void *py_instance;            /* python stores the class instance here */
420         struct ReportList *reports;   /* errors and warnings storage */
421
422         void *customdata;
423         void (*customdata_free)(void *); /* for freeing customdata from above */
424         eWM_GizmoFlagGroupInitFlag init_flag;
425 } wmGizmoGroup;
426
427 /* -------------------------------------------------------------------- */
428 /* wmGizmoMap */
429
430 /**
431  * Pass a value of this enum to #WM_gizmomap_draw to tell it what to draw.
432  */
433 typedef enum eWM_GizmoFlagMapDrawStep {
434         /** Draw 2D gizmo-groups (#WM_GIZMOGROUPTYPE_3D not set). */
435         WM_GIZMOMAP_DRAWSTEP_2D = 0,
436         /** Draw 3D gizmo-groups (#WM_GIZMOGROUPTYPE_3D set). */
437         WM_GIZMOMAP_DRAWSTEP_3D,
438 } eWM_GizmoFlagMapDrawStep;
439 #define WM_GIZMOMAP_DRAWSTEP_MAX 2
440
441 #endif  /* __WM_GIZMO_TYPES_H__ */