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