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