e8b81e1a78cf6f8bcd5f5d2a012a5246278c1385
[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
186         /* Transformation of the manipulator in 2d or 3d space.
187          * - Matrix axis are expected to be unit length (scale is applied after).
188          * - Behavior when axis aren't orthogonal depends on each manipulator.
189          * - Typically the +Z is the primary axis for manipulators to use.
190          * - 'matrix[3]' must be used for location,
191          *   besides this it's up to the manipulators internal code how the
192          *   rotation components are used for drawing and interaction.
193          */
194
195         /* The space this manipulator is being modified in. */
196         float matrix_space[4][4];
197         /* Transformation of this manipulator. */
198         float matrix_basis[4][4];
199         /* custom offset from origin */
200         float matrix_offset[4][4];
201         /* runtime property, set the scale while drawing on the viewport */
202         float scale_final;
203         /* user defined scale, in addition to the original one */
204         float scale_basis;
205         /* user defined width for line drawing */
206         float line_width;
207         /* manipulator colors (uses default fallbacks if not defined) */
208         float color[4], color_hi[4];
209
210         /* data used during interaction */
211         void *interaction_data;
212
213         /* Operator to spawn when activating the manipulator (overrides property editing),
214          * an array of items (aligned with #wmManipulator.highlight_part). */
215         wmManipulatorOpElem *op_data;
216         int op_data_len;
217
218         struct IDProperty *properties;
219
220         /* over alloc target_properties after 'wmManipulatorType.struct_size' */
221 };
222
223 /* Similar to PropertyElemRNA, but has an identifier. */
224 typedef struct wmManipulatorProperty {
225         const struct wmManipulatorPropertyType *type;
226
227         PointerRNA ptr;
228         PropertyRNA *prop;
229         int index;
230
231
232         /* Optional functions for converting to/from RNA  */
233         struct {
234                 wmManipulatorPropertyFnGet value_get_fn;
235                 wmManipulatorPropertyFnSet value_set_fn;
236                 wmManipulatorPropertyFnRangeGet range_get_fn;
237                 wmManipulatorPropertyFnFree free_fn;
238                 void *user_data;
239         } custom_func;
240 } wmManipulatorProperty;
241
242 typedef struct wmManipulatorPropertyType {
243         struct wmManipulatorPropertyType *next, *prev;
244         /* PropertyType, typically 'PROP_FLOAT' */
245         int data_type;
246         int array_length;
247
248         /* index within 'wmManipulatorType' */
249         int index_in_type;
250
251         /* over alloc */
252         char idname[0];
253 } wmManipulatorPropertyType;
254
255
256 /**
257  * Simple utility wrapper for storing a single manipulator as wmManipulatorGroup.customdata (which gets freed).
258  */
259 typedef struct wmManipulatorWrapper {
260         struct wmManipulator *manipulator;
261 } wmManipulatorWrapper;
262
263 struct wmManipulatorMapType_Params {
264         short spaceid;
265         short regionid;
266 };
267
268 typedef struct wmManipulatorType {
269
270         const char *idname; /* MAX_NAME */
271
272         /* Set to 'sizeof(wmManipulator)' or larger for instances of this type,
273          * use so we can cant to other types without the hassle of a custom-data pointer. */
274         uint struct_size;
275
276         /* Initialize struct (calloc'd 'struct_size' region). */
277         wmManipulatorFnSetup setup;
278
279         /* draw manipulator */
280         wmManipulatorFnDraw draw;
281
282         /* determines 3d intersection by rendering the manipulator in a selection routine. */
283         wmManipulatorFnDrawSelect draw_select;
284
285         /* Determine if the mouse intersects with the manipulator.
286          * The calculation should be done in the callback itself, -1 for no seleciton. */
287         wmManipulatorFnTestSelect test_select;
288
289         /* handler used by the manipulator. Usually handles interaction tied to a manipulator type */
290         wmManipulatorFnModal modal;
291
292         /* manipulator-specific handler to update manipulator attributes based on the property value */
293         wmManipulatorFnPropertyUpdate property_update;
294
295         /* Returns the final transformation which may be different from the 'matrix',
296          * depending on the manipulator.
297          * Notes:
298          * - Scale isn't applied (wmManipulator.scale/user_scale).
299          * - Offset isn't applied (wmManipulator.matrix_offset).
300          */
301         wmManipulatorFnMatrixBasisGet matrix_basis_get;
302
303         /* activate a manipulator state when the user clicks on it */
304         wmManipulatorFnInvoke invoke;
305
306         /* called when manipulator tweaking is done - used to free data and reset property when cancelling */
307         wmManipulatorFnExit exit;
308
309         wmManipulatorFnCursorGet cursor_get;
310
311         /* called when manipulator selection state changes */
312         wmManipulatorFnSelectRefresh select_refresh;
313
314         /* RNA for properties */
315         struct StructRNA *srna;
316
317         /* RNA integration */
318         ExtensionRNA ext;
319
320         ListBase target_property_defs;
321         int target_property_defs_len;
322
323 } wmManipulatorType;
324
325
326 /* -------------------------------------------------------------------- */
327 /* wmManipulatorGroup */
328
329 /* factory class for a manipulator-group type, gets called every time a new area is spawned */
330 typedef struct wmManipulatorGroupTypeRef {
331         struct wmManipulatorGroupTypeRef *next, *prev;
332         struct wmManipulatorGroupType *type;
333 } wmManipulatorGroupTypeRef;
334
335 /* factory class for a manipulator-group type, gets called every time a new area is spawned */
336 typedef struct wmManipulatorGroupType {
337         const char *idname;  /* MAX_NAME */
338         const char *name; /* manipulator-group name - displayed in UI (keymap editor) */
339
340         /* poll if manipulator-map should be visible */
341         wmManipulatorGroupFnPoll poll;
342         /* initially create manipulators and set permanent data - stuff you only need to do once */
343         wmManipulatorGroupFnInit setup;
344         /* refresh data, only called if recreate flag is set (WM_manipulatormap_tag_refresh) */
345         wmManipulatorGroupFnRefresh refresh;
346         /* refresh data for drawing, called before each redraw */
347         wmManipulatorGroupFnDrawPrepare draw_prepare;
348
349         /* Keymap init callback for this manipulator-group (optional),
350          * will fall back to default tweak keymap when left NULL. */
351         wmManipulatorGroupFnSetupKeymap setup_keymap;
352
353         /* Optionally subscribe to wmMsgBus events,
354          * these are calculated automatically from RNA properties,
355          * only needed if manipulators depend indirectly on properties. */
356         wmManipulatorGroupFnMsgBusSubscribe message_subscribe;
357
358         /* keymap created with callback from above */
359         struct wmKeyMap *keymap;
360         /* Only for convenient removal. */
361         struct wmKeyConfig *keyconf;
362
363         /* Disable for now, maybe some day we want properties. */
364 #if 0
365         /* rna for properties */
366         struct StructRNA *srna;
367 #endif
368
369         /* RNA integration */
370         ExtensionRNA ext;
371
372         eWM_ManipulatorGroupTypeFlag flag;
373
374         /* So we know which group type to update. */
375         eWM_ManipulatorMapTypeUpdateFlag type_update_flag;
376
377         /* same as manipulator-maps, so registering/unregistering goes to the correct region */
378         struct wmManipulatorMapType_Params mmap_params;
379
380 } wmManipulatorGroupType;
381
382 typedef struct wmManipulatorGroup {
383         struct wmManipulatorGroup *next, *prev;
384
385         struct wmManipulatorGroupType *type;
386         ListBase manipulators;
387
388         struct wmManipulatorMap *parent_mmap;
389
390         void *py_instance;            /* python stores the class instance here */
391         struct ReportList *reports;   /* errors and warnings storage */
392
393         void *customdata;
394         void (*customdata_free)(void *); /* for freeing customdata from above */
395         eWM_ManipulatorGroupInitFlag init_flag;
396 } wmManipulatorGroup;
397
398 /* -------------------------------------------------------------------- */
399 /* wmManipulatorMap */
400
401 /**
402  * Pass a value of this enum to #WM_manipulatormap_draw to tell it what to draw.
403  */
404 typedef enum eWM_ManipulatorMapDrawStep {
405         /** Draw 2D manipulator-groups (#WM_MANIPULATORGROUPTYPE_3D not set). */
406         WM_MANIPULATORMAP_DRAWSTEP_2D = 0,
407         /** Draw 3D manipulator-groups (#WM_MANIPULATORGROUPTYPE_3D set). */
408         WM_MANIPULATORMAP_DRAWSTEP_3D,
409 } eWM_ManipulatorMapDrawStep;
410 #define WM_MANIPULATORMAP_DRAWSTEP_MAX 2
411
412 #endif  /* __WM_MANIPULATOR_TYPES_H__ */