Blender V4.3
wm_gizmo_group.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2014 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
14#include <cstdlib>
15#include <cstring>
16
17#include "MEM_guardedalloc.h"
18
19#include "BLI_buffer.h"
20#include "BLI_listbase.h"
21#include "BLI_rect.h"
22#include "BLI_string.h"
23
24#include "BKE_context.hh"
25#include "BKE_main.hh"
26#include "BKE_report.hh"
27#include "BKE_workspace.hh"
28
29#include "RNA_access.hh"
30#include "RNA_define.hh"
31
32#include "WM_api.hh"
33#include "WM_types.hh"
34#include "wm_event_system.hh"
35
36#include "ED_screen.hh"
37#include "ED_undo.hh"
38
39/* Own includes. */
40#include "wm_gizmo_intern.hh"
41#include "wm_gizmo_wmapi.hh"
42
43#ifdef WITH_PYTHON
44# include "BPY_extern.hh"
45#endif
46
47/* -------------------------------------------------------------------- */
52{
53 wmGizmoGroup *gzgroup = static_cast<wmGizmoGroup *>(
54 MEM_callocN(sizeof(*gzgroup), "gizmo-group"));
55
56 gzgroup->type = gzgt;
57 gzgroup->type->users += 1;
58
59 /* Keep back-link. */
60 gzgroup->parent_gzmap = gzmap;
61
62 BLI_addtail(&gzmap->groups, gzgroup);
63
64 return gzgroup;
65}
66
68{
69 return static_cast<wmGizmoGroup *>(
70 BLI_findptr(&gzmap->groups, gzgt, offsetof(wmGizmoGroup, type)));
71}
72
74{
75 wmGizmoMap *gzmap = gzgroup->parent_gzmap;
76
77 /* Similar to WM_gizmo_unlink, but only to keep gzmap state correct,
78 * we don't want to run callbacks. */
79 if (gzmap->gzmap_context.highlight && gzmap->gzmap_context.highlight->parent_gzgroup == gzgroup)
80 {
81 wm_gizmomap_highlight_set(gzmap, C, nullptr, 0);
82 }
83 if (gzmap->gzmap_context.modal && gzmap->gzmap_context.modal->parent_gzgroup == gzgroup) {
84 wm_gizmomap_modal_set(gzmap, C, gzmap->gzmap_context.modal, nullptr, false);
85 }
86
87 for (wmGizmo *gz = static_cast<wmGizmo *>(gzgroup->gizmos.first), *gz_next; gz; gz = gz_next) {
88 gz_next = gz->next;
89 if (gzmap->gzmap_context.select.len) {
90 WM_gizmo_select_unlink(gzmap, gz);
91 }
92 WM_gizmo_free(gz);
93 }
94 BLI_listbase_clear(&gzgroup->gizmos);
95
96#ifdef WITH_PYTHON
97 if (gzgroup->py_instance) {
98 /* Do this first in case there are any `__del__` functions or
99 * similar that use properties. */
101 }
102#endif
103
104 if (gzgroup->customdata_free) {
105 gzgroup->customdata_free(gzgroup->customdata);
106 }
107 else {
108 MEM_SAFE_FREE(gzgroup->customdata);
109 }
110
111 BLI_remlink(&gzmap->groups, gzgroup);
112
113 if (gzgroup->tag_remove == false) {
114 gzgroup->type->users -= 1;
115 }
116
117 MEM_freeN(gzgroup);
118}
119
121{
122 if (gzgroup->tag_remove == false) {
123 gzgroup->tag_remove = true;
124 gzgroup->type->users -= 1;
125 BLI_assert(gzgroup->type->users >= 0);
127 }
128}
129
131{
132 BLI_assert(BLI_findindex(&gzgroup->gizmos, gz) == -1);
133 BLI_addtail(&gzgroup->gizmos, gz);
134 gz->parent_gzgroup = gzgroup;
135}
136
137int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr)
138{
139 const wmGizmo *gz_a = static_cast<const wmGizmo *>(gz_a_ptr);
140 const wmGizmo *gz_b = static_cast<const wmGizmo *>(gz_b_ptr);
141 if (gz_a->temp.f < gz_b->temp.f) {
142 return -1;
143 }
144 if (gz_a->temp.f > gz_b->temp.f) {
145 return 1;
146 }
147 return 0;
148}
149
150int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
151{
152 const wmGizmo *gz_a = static_cast<const wmGizmo *>(gz_a_ptr);
153 const wmGizmo *gz_b = static_cast<const wmGizmo *>(gz_b_ptr);
154 if (gz_a->temp.f < gz_b->temp.f) {
155 return 1;
156 }
157 if (gz_a->temp.f > gz_b->temp.f) {
158 return -1;
159 }
160 return 0;
161}
162
164 const wmGizmoGroup *gzgroup,
165 wmGizmo *gz,
166 const int event_modifier,
167 int *r_gzgroup_keymap_uses_modifier)
168{
169 if (gz->keymap) {
170 wmKeyMap *keymap = WM_keymap_active(wm, gz->keymap);
171 if (!WM_keymap_uses_event_modifier(keymap, event_modifier)) {
172 return false;
173 }
174 }
175 else if (gzgroup->type->keymap) {
176 if (*r_gzgroup_keymap_uses_modifier == -1) {
177 wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap);
178 *r_gzgroup_keymap_uses_modifier = WM_keymap_uses_event_modifier(keymap, event_modifier);
179 }
180 if (*r_gzgroup_keymap_uses_modifier == 0) {
181 return false;
182 }
183 }
184 return true;
185}
186
188 const wmGizmoGroup *gzgroup,
189 bContext *C,
190 const int event_modifier,
191 const int mval[2],
192 int *r_part)
193{
194 int gzgroup_keymap_uses_modifier = -1;
195
196 LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
197 if (gz->type->test_select && (gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) {
198
200 wm, gzgroup, gz, event_modifier, &gzgroup_keymap_uses_modifier))
201 {
202 continue;
203 }
204
205 if ((*r_part = gz->type->test_select(C, gz, mval)) != -1) {
206 return gz;
207 }
208 }
209 }
210
211 return nullptr;
212}
213
215 const wmGizmoGroup *gzgroup,
216 const int event_modifier,
217 BLI_Buffer *visible_gizmos)
218{
219 int gzgroup_keymap_uses_modifier = -1;
220 LISTBASE_FOREACH_BACKWARD (wmGizmo *, gz, &gzgroup->gizmos) {
221 if ((gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) {
222 if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) &&
223 (gz->type->draw_select || gz->type->test_select)) ||
224 ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select))
225 {
226
228 wm, gzgroup, gz, event_modifier, &gzgroup_keymap_uses_modifier))
229 {
230 continue;
231 }
232
233 BLI_buffer_append(visible_gizmos, wmGizmo *, gz);
234 }
235 }
236 }
237}
238
240{
241 /* Prepare for first draw. */
242 if (UNLIKELY((gzgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0)) {
243
244 gzgroup->type->setup(C, gzgroup);
245
246 /* Not ideal, initialize keymap here, needed for RNA runtime generated gizmos. */
247 wmGizmoGroupType *gzgt = gzgroup->type;
248 if (gzgt->keymap == nullptr) {
251 BLI_assert(gzgt->keymap != nullptr);
252 }
254 }
255
256 /* Refresh may be called multiple times,
257 * this just ensures its called at least once before we draw. */
258 if (UNLIKELY((gzgroup->init_flag & WM_GIZMOGROUP_INIT_REFRESH) == 0)) {
259 /* Clear the flag before calling refresh so the callback
260 * can postpone the refresh by clearing this flag. */
262 WM_gizmo_group_refresh(C, gzgroup);
263 }
264}
265
267 Main *bmain,
268 const wmGizmoGroupType *gzgt,
269 const bToolRef *tref)
270{
272 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
273 screen = static_cast<bScreen *>(screen->id.next))
274 {
275 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
276 if (area->runtime.tool == tref) {
277 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
278 wmGizmoMap *gzmap = region->gizmo_map;
279 if (gzmap && gzmap->type == gzmap_type) {
280 wmGizmoGroup *gzgroup, *gzgroup_next;
281 for (gzgroup = static_cast<wmGizmoGroup *>(gzmap->groups.first); gzgroup;
282 gzgroup = gzgroup_next)
283 {
284 gzgroup_next = gzgroup->next;
285 if (gzgroup->type == gzgt) {
286 BLI_assert(gzgroup->parent_gzmap == gzmap);
287 wm_gizmogroup_free(C, gzgroup);
289 }
290 }
291 }
292 }
293 }
294 }
295 }
296}
297
299 const eWM_GizmoFlagMapDrawStep drawstep)
300{
301 switch (drawstep) {
303 return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
305 return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D);
306 default:
308 return false;
309 }
310}
311
313{
314 if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_SELECT) {
315 LISTBASE_FOREACH (const wmGizmo *, gz, &gzgroup->gizmos) {
316 if (gz->state & WM_GIZMO_STATE_SELECT) {
317 return true;
318 }
319 }
320 }
321 return false;
322}
323
326/* -------------------------------------------------------------------- */
332static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
333{
334 ARegion *region = CTX_wm_region(C);
335 wmGizmoMap *gzmap = region->gizmo_map;
337 wmGizmo *highlight = gzmap->gzmap_context.highlight;
338
339 bool extend = RNA_boolean_get(op->ptr, "extend");
340 bool deselect = RNA_boolean_get(op->ptr, "deselect");
341 bool toggle = RNA_boolean_get(op->ptr, "toggle");
342
343 /* Deselect all first. */
344 if (extend == false && deselect == false && toggle == false) {
346 BLI_assert(msel->items == nullptr && msel->len == 0);
347 UNUSED_VARS_NDEBUG(msel);
348 }
349
350 if (highlight) {
351 const bool is_selected = (highlight->state & WM_GIZMO_STATE_SELECT);
352 bool redraw = false;
353
354 if (toggle) {
355 /* Toggle: deselect if already selected, else select. */
356 deselect = is_selected;
357 }
358
359 if (deselect) {
360 if (is_selected && WM_gizmo_select_set(gzmap, highlight, false)) {
361 redraw = true;
362 }
363 }
364 else if (wm_gizmo_select_and_highlight(C, gzmap, highlight)) {
365 redraw = true;
366 }
367
368 if (redraw) {
370 }
371
372 return OPERATOR_FINISHED;
373 }
374
377}
378
380{
381 /* Identifiers. */
382 ot->name = "Gizmo Select";
383 ot->description = "Select the currently highlighted gizmo";
384 ot->idname = "GIZMOGROUP_OT_gizmo_select";
385
386 /* API callbacks. */
389
391
393}
394
399
400 int init_event; /* Initial event type. */
401 int flag; /* Tweak flags. */
402};
403
404static bool gizmo_tweak_start(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event)
405{
406 /* Activate highlighted gizmo. */
407 wm_gizmomap_modal_set(gzmap, C, gz, event, true);
408
409 return (gz->state & WM_GIZMO_STATE_MODAL);
410}
411
413 bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event, bool *r_is_modal)
414{
416 if (r_is_modal) {
417 *r_is_modal = false;
418 }
419 if (gzop && gzop->type) {
420
421 /* Undo/Redo. */
422 if (gzop->is_redo) {
425
426/* We may want to enable this, for now the gizmo can manage its own properties. */
427#if 0
428 IDP_MergeGroup(gzop->ptr.data, op->properties, false);
429#endif
430
432 ED_undo_pop_op(C, op);
433 }
434
435 /* XXX temporary workaround for modal gizmo operator
436 * conflicting with modal operator attached to gizmo. */
437 if (gzop->type->modal) {
438 /* Activate highlighted gizmo. */
439 wm_gizmomap_modal_set(gzmap, C, gz, event, true);
440 if (r_is_modal) {
441 *r_is_modal = true;
442 }
443 }
444 else {
446 gz->parent_gzgroup->type->invoke_prepare(C, gz->parent_gzgroup, gz, event);
447 }
448 /* Allow for 'button' gizmos, single click to run an action. */
449 WM_gizmo_operator_invoke(C, gz, gzop, event);
450 }
451 return true;
452 }
453 return false;
454}
455
456static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal)
457{
458 GizmoTweakData *mtweak = static_cast<GizmoTweakData *>(op->customdata);
459 if (mtweak->gz_modal->type->exit) {
460 mtweak->gz_modal->type->exit(C, mtweak->gz_modal, cancel);
461 }
462 if (clear_modal) {
463 /* The gizmo may have been removed. */
464 if ((BLI_findindex(&mtweak->gzmap->groups, mtweak->gzgroup) != -1) &&
465 (BLI_findindex(&mtweak->gzgroup->gizmos, mtweak->gz_modal) != -1))
466 {
467 wm_gizmomap_modal_set(mtweak->gzmap, C, mtweak->gz_modal, nullptr, false);
468 }
469 }
470 if (cancel == false) {
471 if (mtweak->gz_modal->flag & WM_GIZMO_NEEDS_UNDO) {
473 }
474 }
475 MEM_freeN(mtweak);
476}
477
478static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event)
479{
480 GizmoTweakData *mtweak = static_cast<GizmoTweakData *>(op->customdata);
481 wmGizmo *gz = mtweak->gz_modal;
482 int retval = OPERATOR_PASS_THROUGH;
483 bool clear_modal = true;
484
485 if (gz == nullptr) {
488 }
489
490 if (retval == OPERATOR_FINISHED) {
491 /* Pass. */
492 }
493 else if (event->type == mtweak->init_event && event->val == KM_RELEASE) {
494 retval = OPERATOR_FINISHED;
495 }
496 else if (event->type == EVT_MODAL_MAP) {
497 switch (event->val) {
499 retval = OPERATOR_CANCELLED;
500 break;
502 retval = OPERATOR_FINISHED;
503 break;
505 mtweak->flag |= WM_GIZMO_TWEAK_PRECISE;
506 break;
508 mtweak->flag &= ~WM_GIZMO_TWEAK_PRECISE;
509 break;
510
512 mtweak->flag |= WM_GIZMO_TWEAK_SNAP;
513 break;
515 mtweak->flag &= ~WM_GIZMO_TWEAK_SNAP;
516 break;
517 }
518 }
519
520 if (retval != OPERATOR_PASS_THROUGH) {
521 gizmo_tweak_finish(C, op, retval != OPERATOR_FINISHED, clear_modal);
522 return retval;
523 }
524
525 /* Handle gizmo. */
526 wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal;
527 if (modal_fn) {
528 /* Ugly hack to ensure Python won't get 'EVT_MODAL_MAP' which isn't supported, see #73727.
529 * note that we could move away from wrapping modal gizmos in a modal operator,
530 * since it's causing the need for code like this. */
531 wmEvent *evil_event = (wmEvent *)event;
532 short event_modal_val = 0;
533
534 if (event->type == EVT_MODAL_MAP) {
535 event_modal_val = evil_event->val;
536 evil_event->type = evil_event->prev_type;
537 evil_event->val = evil_event->prev_val;
538 }
539
540 int modal_retval = modal_fn(C, gz, event, eWM_GizmoFlagTweak(mtweak->flag));
541
542 if (event_modal_val != 0) {
543 evil_event->type = EVT_MODAL_MAP;
544 evil_event->val = event_modal_val;
545 }
546
547 if ((modal_retval & OPERATOR_RUNNING_MODAL) == 0) {
548 gizmo_tweak_finish(C, op, (modal_retval & OPERATOR_CANCELLED) != 0, true);
549 return OPERATOR_FINISHED;
550 }
551
552 /* Ugly hack to send gizmo events. */
553 evil_event->type = EVT_GIZMO_UPDATE;
554 }
555
556 /* Always return PASS_THROUGH so modal handlers
557 * with gizmos attached can update. */
560}
561
562static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event)
563{
564 ARegion *region = CTX_wm_region(C);
565 wmGizmoMap *gzmap = region->gizmo_map;
566 wmGizmo *gz = gzmap->gzmap_context.highlight;
567
568 /* Needed for single click actions which don't enter modal state. */
570
571 if (!gz) {
572 /* #wm_handlers_do_intern shouldn't let this happen. */
575 }
576
577 const int highlight_part_init = gz->highlight_part;
578
579 if (gz->drag_part != -1) {
580 if (WM_event_is_mouse_drag(event)) {
581 gz->highlight_part = gz->drag_part;
582 }
583 }
584
585 if (gizmo_tweak_start_and_finish(C, gzmap, gz, event, nullptr)) {
586 return OPERATOR_FINISHED;
587 }
588
589 if (!gizmo_tweak_start(C, gzmap, gz, event)) {
590 /* Failed to start. */
591 gz->highlight_part = highlight_part_init;
593 }
594
595 GizmoTweakData *mtweak = static_cast<GizmoTweakData *>(
596 MEM_mallocN(sizeof(GizmoTweakData), __func__));
597
599 mtweak->gz_modal = gzmap->gzmap_context.highlight;
600 mtweak->gzgroup = mtweak->gz_modal->parent_gzgroup;
601 mtweak->gzmap = gzmap;
602 mtweak->flag = 0;
603
604 op->customdata = mtweak;
605
607
609}
610
612{
613 /* Identifiers. */
614 ot->name = "Gizmo Tweak";
615 ot->description = "Tweak the active gizmo";
616 ot->idname = "GIZMOGROUP_OT_gizmo_tweak";
617
618 /* API callbacks. */
622
623/* TODO(@ideasman42): This causes problems tweaking settings for operators,
624 * need to find a way to support this. May want to use #WM_GIZMO_NEEDS_UNDO instead. */
625#if 0
627#endif
629}
630
632{
633 wmKeyMap *keymap;
634 char name[KMAP_MAX_NAME];
635
636 static const EnumPropertyItem modal_items[] = {
637 {TWEAK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
638 {TWEAK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
639 {TWEAK_MODAL_PRECISION_ON, "PRECISION_ON", 0, "Enable Precision", ""},
640 {TWEAK_MODAL_PRECISION_OFF, "PRECISION_OFF", 0, "Disable Precision", ""},
641 {TWEAK_MODAL_SNAP_ON, "SNAP_ON", 0, "Enable Snap", ""},
642 {TWEAK_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Disable Snap", ""},
643 {0, nullptr, 0, nullptr, nullptr},
644 };
645
646 STRNCPY(name, "Generic Gizmo Tweak Modal Map");
647 keymap = WM_modalkeymap_find(keyconf, name);
648
649 /* This function is called for each space-type, only needs to add map once. */
650 if (keymap && keymap->modal_items) {
651 return nullptr;
652 }
653
654 keymap = WM_modalkeymap_ensure(keyconf, name, modal_items);
655
656 /* Items for modal map. */
657 {
659 params.type = EVT_ESCKEY;
660 params.value = KM_PRESS;
661 params.modifier = KM_ANY;
662 params.direction = KM_ANY;
664 }
665 {
667 params.type = RIGHTMOUSE;
668 params.value = KM_PRESS;
669 params.modifier = KM_ANY;
670 params.direction = KM_ANY;
672 }
673 {
675 params.type = EVT_RETKEY;
676 params.value = KM_PRESS;
677 params.modifier = KM_ANY;
678 params.direction = KM_ANY;
680 }
681 {
683 params.type = EVT_PADENTER;
684 params.value = KM_PRESS;
685 params.modifier = KM_ANY;
686 params.direction = KM_ANY;
688 }
689 {
692 params.value = KM_PRESS;
693 params.modifier = KM_ANY;
694 params.direction = KM_ANY;
696 }
697 {
700 params.value = KM_RELEASE;
701 params.modifier = KM_ANY;
702 params.direction = KM_ANY;
704 }
705 {
708 params.value = KM_PRESS;
709 params.modifier = KM_ANY;
710 params.direction = KM_ANY;
712 }
713 {
716 params.value = KM_RELEASE;
717 params.modifier = KM_ANY;
718 params.direction = KM_ANY;
720 }
721 {
724 params.value = KM_PRESS;
725 params.modifier = KM_ANY;
726 params.direction = KM_ANY;
728 }
729 {
732 params.value = KM_RELEASE;
733 params.modifier = KM_ANY;
734 params.direction = KM_ANY;
736 }
737 {
739 params.type = EVT_LEFTCTRLKEY;
740 params.value = KM_PRESS;
741 params.modifier = KM_ANY;
742 params.direction = KM_ANY;
744 }
745 {
747 params.type = EVT_LEFTCTRLKEY;
748 params.value = KM_RELEASE;
749 params.modifier = KM_ANY;
750 params.direction = KM_ANY;
752 }
753
754 WM_modalkeymap_assign(keymap, "GIZMOGROUP_OT_gizmo_tweak");
755
756 return keymap;
757}
758
759 /* #wmGizmoGroup. */
760
761/* -------------------------------------------------------------------- */
769
775
781
791 const char *name,
793{
794 /* Use area and region id since we might have multiple gizmos
795 * with the same name in different areas/regions. */
796 wmKeyMap *km = WM_keymap_ensure(kc, name, params->spaceid, params->regionid);
797 const bool do_init = BLI_listbase_is_empty(&km->items);
798
799/* FIXME(@ideasman42): Currently hard coded. */
800#if 0
801 const int select_mouse = (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE;
802 const int select_tweak = (U.flag & USER_LMOUSESELECT) ? EVT_TWEAK_L : EVT_TWEAK_R;
803 const int action_mouse = (U.flag & USER_LMOUSESELECT) ? RIGHTMOUSE : LEFTMOUSE;
804#else
805 const int select_mouse = RIGHTMOUSE, select_mouse_val = KM_PRESS;
806 const int select_tweak = RIGHTMOUSE, select_tweak_val = KM_CLICK_DRAG;
807 const int action_mouse = LEFTMOUSE, action_mouse_val = KM_PRESS;
808#endif
809
810 if (do_init) {
811 {
813 params.type = action_mouse;
814 params.value = action_mouse_val;
815 params.modifier = KM_ANY;
816 params.direction = KM_ANY;
817 WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", &params);
818 }
819 {
821 params.type = select_tweak;
822 params.value = select_tweak_val;
823 params.modifier = 0;
824 params.direction = KM_ANY;
825 WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", &params);
826 }
827 }
828
829 if (do_init) {
830 {
832 params.type = select_mouse;
833 params.value = select_mouse_val;
834 params.modifier = 0;
835 params.direction = KM_ANY;
836 wmKeyMapItem *kmi = WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_select", &params);
837 RNA_boolean_set(kmi->ptr, "extend", false);
838 RNA_boolean_set(kmi->ptr, "deselect", false);
839 RNA_boolean_set(kmi->ptr, "toggle", false);
840 }
841 {
843 params.type = select_mouse;
844 params.value = select_mouse_val;
845 params.modifier = KM_SHIFT;
846 params.direction = KM_ANY;
847 wmKeyMapItem *kmi = WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_select", &params);
848 RNA_boolean_set(kmi->ptr, "extend", false);
849 RNA_boolean_set(kmi->ptr, "deselect", false);
850 RNA_boolean_set(kmi->ptr, "toggle", true);
851 }
852 }
853
854 return km;
855}
856
858 wmKeyConfig *kc)
859{
861 params.spaceid = SPACE_EMPTY;
862 params.regionid = RGN_TYPE_WINDOW;
863 return WM_gizmogroup_keymap_template_select_ex(kc, "Generic Gizmo Select", &params);
864}
865
868/* -------------------------------------------------------------------- */
875{
876 const char *idname = "Generic Gizmo";
877 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
878}
883
885{
886 const char *idname = "Generic Gizmo Select";
887 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
888}
893
895{
896 const char *idname = "Generic Gizmo Drag";
897 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
898}
903
905{
906 const char *idname = "Generic Gizmo Click Drag";
907 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
908}
913
915{
916 const char *idname = "Generic Gizmo Maybe Drag";
917 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
918}
923
926/* -------------------------------------------------------------------- */
931 const wmGizmoGroupType *gzgt)
932{
933 /* Could use hash lookups as operator types do, for now simple search. */
934 LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
935 if (gzgt_ref->type == gzgt) {
936 return gzgt_ref;
937 }
938 }
939 return nullptr;
940}
941
943{
944 /* Could use hash lookups as operator types do, for now simple search. */
945 LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
946 if (STREQ(idname, gzgt_ref->type->idname)) {
947 return gzgt_ref;
948 }
949 }
950 return nullptr;
951}
952
954{
955 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
956 BLI_assert(gzgt != nullptr);
957 return WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt);
958}
959
961 wmGizmoGroupType *gzgt)
962{
963 wmGizmoGroupTypeRef *gzgt_ref = static_cast<wmGizmoGroupTypeRef *>(
964 MEM_callocN(sizeof(wmGizmoGroupTypeRef), "gizmo-group-ref"));
965 gzgt_ref->type = gzgt;
966 BLI_addtail(&gzmap_type->grouptype_refs, gzgt_ref);
967 return gzgt_ref;
968}
969
971{
972 /* Initialize key-map.
973 * On startup there's an extra call to initialize keymaps for 'permanent' gizmo-groups. */
974 wm_gizmogrouptype_setup_keymap(gzgt, ((wmWindowManager *)bmain->wm.first)->defaultconf);
975}
976
978 wmGizmoMapType *gzmap_type,
979 wmGizmoGroupType *gzgt)
980{
981 /* Tools add themselves. */
982 if (gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_INIT) {
983 return;
984 }
985
986 /* Now create a gizmo for all existing areas. */
987 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
988 screen = static_cast<bScreen *>(screen->id.next))
989 {
990 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
991 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
992 ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
993 LISTBASE_FOREACH (ARegion *, region, lb) {
994 wmGizmoMap *gzmap = region->gizmo_map;
995 if (gzmap && gzmap->type == gzmap_type) {
996 WM_gizmomaptype_group_init_runtime_with_region(gzmap_type, gzgt, region);
997 }
998 }
999 }
1000 }
1001 }
1002}
1003
1005 wmGizmoGroupType *gzgt,
1006 ARegion *region)
1007{
1008 wmGizmoMap *gzmap = region->gizmo_map;
1009 BLI_assert(gzmap && gzmap->type == gzmap_type);
1010 UNUSED_VARS_NDEBUG(gzmap_type);
1011
1012 wmGizmoGroup *gzgroup = wm_gizmogroup_new_from_type(gzmap, gzgt);
1013
1014 /* Don't allow duplicates when switching modes for e.g. see: #66229. */
1015 LISTBASE_FOREACH (wmGizmoGroup *, gzgroup_iter, &gzmap->groups) {
1016 if (gzgroup_iter->type == gzgt) {
1017 if (gzgroup_iter != gzgroup) {
1018 WM_gizmo_group_tag_remove(gzgroup_iter);
1019 }
1020 }
1021 }
1022
1023 wm_gizmomap_highlight_set(gzmap, nullptr, nullptr, 0);
1024
1026
1027 return gzgroup;
1028}
1029
1031{
1032 MEM_freeN(gzgt_ref);
1033}
1034
1036 Main *bmain,
1037 wmGizmoMapType *gzmap_type,
1038 const wmGizmoGroupType *gzgt)
1039{
1040 /* Free instances. */
1041 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
1042 screen = static_cast<bScreen *>(screen->id.next))
1043 {
1044 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1045 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1046 ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
1047 LISTBASE_FOREACH (ARegion *, region, lb) {
1048 wmGizmoMap *gzmap = region->gizmo_map;
1049 if (gzmap && gzmap->type == gzmap_type) {
1050 wmGizmoGroup *gzgroup, *gzgroup_next;
1051 for (gzgroup = static_cast<wmGizmoGroup *>(gzmap->groups.first); gzgroup;
1052 gzgroup = gzgroup_next)
1053 {
1054 gzgroup_next = gzgroup->next;
1055 if (gzgroup->type == gzgt) {
1056 BLI_assert(gzgroup->parent_gzmap == gzmap);
1057 wm_gizmogroup_free(C, gzgroup);
1059 }
1060 }
1061 }
1062 }
1063 }
1064 }
1065 }
1066
1067 /* Free types. */
1068 wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt);
1069 if (gzgt_ref) {
1070 BLI_remlink(&gzmap_type->grouptype_refs, gzgt_ref);
1072 }
1073
1074/* TODO(@ideasman42): Gizmos may share key-maps, for now don't
1075 * remove however we could flag them as temporary/owned by the gizmo. */
1076#if 0
1077 /* NOTE: we may want to keep this key-map for editing. */
1078 WM_keymap_remove(gzgt->keyconf, gzgt->keymap);
1079#endif
1080
1081 BLI_assert(WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt) == nullptr);
1082}
1083
1085{
1086 /* Use flag since setup_keymap may return nullptr,
1087 * in that case we better not keep calling it. */
1089 gzgt->keymap = gzgt->setup_keymap(gzgt, keyconf);
1090 gzgt->keyconf = keyconf;
1091 gzgt->type_update_flag &= ~WM_GIZMOMAPTYPE_KEYMAP_INIT;
1092 }
1093}
1094
1095 /* #wmGizmoGroupType. */
1096
1097/* -------------------------------------------------------------------- */
1112{
1113 WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt);
1114
1116}
1122void WM_gizmo_group_type_add(const char *idname)
1123{
1124 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1125 BLI_assert(gzgt != nullptr);
1127}
1128
1130{
1131 wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt);
1132 if (gzgt_ref == nullptr) {
1133 WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type);
1134 return true;
1135 }
1136 return false;
1137}
1139{
1141 return WM_gizmo_group_type_ensure_ptr_ex(gzgt, gzmap_type);
1142}
1143bool WM_gizmo_group_type_ensure(const char *idname)
1144{
1145 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1146 BLI_assert(gzgt != nullptr);
1147 return WM_gizmo_group_type_ensure_ptr(gzgt);
1148}
1149
1151 wmGizmoGroupType *gzgt,
1152 wmGizmoMapType *gzmap_type)
1153{
1154 WM_gizmomaptype_group_unlink(nullptr, bmain, gzmap_type, gzgt);
1155}
1157{
1159 WM_gizmo_group_type_remove_ptr_ex(bmain, gzgt, gzmap_type);
1160}
1161void WM_gizmo_group_type_remove(Main *bmain, const char *idname)
1162{
1163 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1164 BLI_assert(gzgt != nullptr);
1165 WM_gizmo_group_type_remove_ptr(bmain, gzgt);
1166}
1167
1169 wmGizmoGroupType *gzgt,
1170 wmGizmoMapType *gzmap_type)
1171{
1172 wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt);
1173 BLI_assert(gzgt_ref != nullptr);
1174 UNUSED_VARS_NDEBUG(gzgt_ref);
1175 WM_gizmomaptype_group_unlink(nullptr, bmain, gzmap_type, gzgt);
1176 WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type);
1177}
1179{
1181 WM_gizmo_group_type_reinit_ptr_ex(bmain, gzgt, gzmap_type);
1182}
1183void WM_gizmo_group_type_reinit(Main *bmain, const char *idname)
1184{
1185 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1186 BLI_assert(gzgt != nullptr);
1187 WM_gizmo_group_type_reinit_ptr(bmain, gzgt);
1188}
1189
1190/* Delayed versions. */
1191
1196
1202
1204{
1205 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1206 BLI_assert(gzgt != nullptr);
1208}
1209
1211 wmGizmoMapType *gzmap_type,
1212 ScrArea *area)
1213{
1214 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1215 wmGizmoMap *gzmap = region->gizmo_map;
1216 if (gzmap && gzmap->type == gzmap_type) {
1217 LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
1218 if (gzgroup->type == gzgt) {
1220 }
1221 }
1222 }
1223 }
1224}
1225
1228/* -------------------------------------------------------------------- */
1233{
1234 /* If we're tagged, only use compatible. */
1235 if (gzgt->owner_id[0] != '\0') {
1236 const WorkSpace *workspace = CTX_wm_workspace(C);
1237 if (BKE_workspace_owner_id_check(workspace, gzgt->owner_id) == false) {
1238 return false;
1239 }
1240 }
1241 /* Check for poll function, if gizmo-group belongs to an operator,
1242 * also check if the operator is running. */
1243 return (!gzgt->poll || gzgt->poll(C, (wmGizmoGroupType *)gzgt));
1244}
1245
1247{
1248 const wmGizmoGroupType *gzgt = gzgroup->type;
1250 wmGizmoMap *gzmap = gzgroup->parent_gzmap;
1251 wmGizmo *gz = nullptr;
1252 /* Without the check for refresh, any highlighted gizmo will prevent hiding
1253 * when selecting with RMB when the cursor happens to be over a gizmo. */
1254 if ((gzgroup->init_flag & WM_GIZMOGROUP_INIT_REFRESH) == 0) {
1255 gz = wm_gizmomap_highlight_get(gzmap);
1256 }
1257 if (!gz || gz->parent_gzgroup != gzgroup) {
1258 wmWindow *win = CTX_wm_window(C);
1259 ARegion *region = CTX_wm_region(C);
1260 BLI_assert(region->gizmo_map == gzmap);
1261 /* Check if the tweak event originated from this region. */
1262 if ((win->eventstate != nullptr) && (win->event_queue_check_drag) &&
1263 BLI_rcti_isect_pt_v(&region->winrct, win->eventstate->prev_press_xy))
1264 {
1265 /* We need to run refresh again. */
1266 gzgroup->init_flag &= ~WM_GIZMOGROUP_INIT_REFRESH;
1268 gzgroup->hide.delay_refresh_for_tweak = true;
1269 return;
1270 }
1271 }
1272 gzgroup->hide.delay_refresh_for_tweak = false;
1273 }
1274
1275 if (gzgroup->hide.any) {
1276 return;
1277 }
1278
1279 if (gzgt->refresh) {
1280 gzgt->refresh(C, gzgroup);
1281 }
1282}
1283
WorkSpace * CTX_wm_workspace(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, bool do_overwrite) ATTR_NONNULL()
Definition idprop.cc:717
bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id) ATTR_NONNULL()
Definition workspace.cc:536
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_buffer_append(buffer_, type_, val_)
Definition BLI_buffer.h:52
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define UNUSED_VARS_NDEBUG(...)
#define UNLIKELY(x)
#define STREQ(a, b)
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
@ RGN_TYPE_WINDOW
@ SPACE_EMPTY
#define KMAP_MAX_NAME
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_region_tag_redraw_editor_overlays(ARegion *region)
Definition area.cc:669
bool ED_operator_region_gizmo_active(bContext *C)
void ED_undo_push(bContext *C, const char *str)
Definition ed_undo.cc:104
void ED_undo_pop_op(bContext *C, wmOperator *op)
Definition ed_undo.cc:397
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
eWM_GizmoFlagMapDrawStep
@ WM_GIZMOMAP_DRAWSTEP_3D
@ WM_GIZMOMAP_DRAWSTEP_2D
eWM_GizmoFlagTweak
Gizmo tweak flag. Bit-flag passed to gizmo while tweaking.
@ WM_GIZMO_TWEAK_PRECISE
@ WM_GIZMO_TWEAK_SNAP
@ WM_GIZMOMAPTYPE_KEYMAP_INIT
@ WM_GIZMOGROUP_INIT_REFRESH
@ WM_GIZMOGROUP_INIT_SETUP
@ WM_GIZMO_HIDDEN
@ WM_GIZMO_NEEDS_UNDO
@ WM_GIZMO_HIDDEN_SELECT
@ WM_GIZMOGROUPTYPE_TOOL_INIT
@ WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK
@ WM_GIZMOGROUPTYPE_3D
@ WM_GIZMOGROUPTYPE_SELECT
@ WM_GIZMO_STATE_MODAL
@ WM_GIZMO_STATE_SELECT
@ OPTYPE_BLOCKING
Definition WM_types.hh:164
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_GRAB_CURSOR_XY
Definition WM_types.hh:168
@ KM_ANY
Definition WM_types.hh:282
@ KM_PRESS
Definition WM_types.hh:284
@ KM_CLICK_DRAG
Definition WM_types.hh:292
@ KM_RELEASE
Definition WM_types.hh:285
@ KM_SHIFT
Definition WM_types.hh:255
unsigned int U
Definition btGjkEpa3.h:78
#define offsetof(t, d)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
wmGizmoGroup * gzgroup
wmGizmoMap * gzmap
void * first
ListBase wm
Definition BKE_main.hh:239
ListBase screens
Definition BKE_main.hh:225
void * data
Definition RNA_types.hh:42
short val
Definition WM_types.hh:724
short prev_type
Definition WM_types.hh:777
short prev_val
Definition WM_types.hh:779
int prev_press_xy[2]
Definition WM_types.hh:795
short type
Definition WM_types.hh:722
wmGizmoGroupType * type
wmKeyConfig * keyconf
wmGizmoGroupFnSetupKeymap setup_keymap
wmGizmoGroupFnRefresh refresh
wmGizmoGroupFnInit setup
wmGizmoGroupFnInvokePrepare invoke_prepare
wmGizmoMapType_Params gzmap_params
eWM_GizmoFlagGroupTypeFlag flag
eWM_GizmoFlagMapTypeUpdateFlag type_update_flag
wmGizmoGroupFnPoll poll
union wmGizmoGroup::@1374 hide
eWM_GizmoFlagGroupInitFlag init_flag
wmGizmoMap * parent_gzmap
void(* customdata_free)(void *)
wmGizmoGroupType * type
wmGizmoGroup * next
uint delay_refresh_for_tweak
struct wmGizmo ** items
wmGizmoMapSelectState select
struct wmGizmoMap::@1370 gzmap_context
Gizmo map runtime context.
wmGizmo * modal
ListBase groups
wmGizmoMapType * type
wmGizmo * highlight
wmOperatorType * type
wmGizmoFnModal modal
wmGizmoFnExit exit
wmGizmoGroup * parent_gzgroup
const wmGizmoType * type
eWM_GizmoFlagState state
union wmGizmo::@1372 temp
eWM_GizmoFlag flag
wmKeyMap * keymap
wmGizmoFnModal custom_modal
struct PointerRNA * ptr
const void * modal_items
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
const char * description
Definition WM_types.hh:996
IDProperty * properties
struct PointerRNA * ptr
struct wmKeyConfig * defaultconf
struct wmEvent * eventstate
#define USER_LMOUSESELECT
void WM_operator_free_all_after(wmWindowManager *wm, wmOperator *op)
Definition wm.cc:318
bool WM_event_is_mouse_drag(const wmEvent *event)
int WM_userdef_event_type_from_keymap_type(int kmitype)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
@ RIGHTMOUSE
@ EVT_MODAL_MAP
@ EVT_RIGHTCTRLKEY
@ EVT_LEFTCTRLKEY
@ EVT_PADENTER
@ LEFTMOUSE
@ EVT_ESCKEY
@ EVT_GIZMO_UPDATE
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
@ EVT_RETKEY
wmOperatorType * ot
Definition wm_files.cc:4125
wmGizmoOpElem * WM_gizmo_operator_get(wmGizmo *gz, int part_index)
Definition wm_gizmo.cc:195
bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz)
Definition wm_gizmo.cc:406
void WM_gizmo_free(wmGizmo *gz)
Definition wm_gizmo.cc:126
int WM_gizmo_operator_invoke(bContext *C, wmGizmo *gz, wmGizmoOpElem *gzop, const wmEvent *event)
Definition wm_gizmo.cc:227
bool WM_gizmo_select_unlink(wmGizmoMap *gzmap, wmGizmo *gz)
Definition wm_gizmo.cc:391
bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select)
Definition wm_gizmo.cc:396
int(*)(bContext *, wmGizmo *, const wmEvent *, eWM_GizmoFlagTweak) wmGizmoFnModal
void WM_gizmo_group_refresh(const bContext *C, wmGizmoGroup *gzgroup)
void WM_gizmomaptype_group_init_runtime_keymap(const Main *bmain, wmGizmoGroupType *gzgt)
int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
wmKeyMap * WM_gizmo_keymap_generic_with_keyconfig(wmKeyConfig *kc)
wmKeyMap * WM_gizmogroup_setup_keymap_generic(const wmGizmoGroupType *, wmKeyConfig *kc)
void WM_gizmomaptype_group_init_runtime(const Main *bmain, wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
wmKeyMap * WM_gizmogroup_setup_keymap_generic_drag(const wmGizmoGroupType *, wmKeyConfig *kc)
void wm_gizmogroup_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz)
void wm_gizmogrouptype_setup_keymap(wmGizmoGroupType *gzgt, wmKeyConfig *keyconf)
wmKeyMap * wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap * WM_gizmo_keymap_generic_drag_with_keyconfig(wmKeyConfig *kc)
wmGizmoGroupTypeRef * WM_gizmomaptype_group_find(wmGizmoMapType *gzmap_type, const char *idname)
void WM_gizmogroup_ensure_init(const bContext *C, wmGizmoGroup *gzgroup)
wmKeyMap * WM_gizmo_keymap_generic_maybe_drag_with_keyconfig(wmKeyConfig *kc)
bool WM_gizmo_group_type_ensure_ptr(wmGizmoGroupType *gzgt)
static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmGizmoGroupTypeRef * WM_gizmomaptype_group_link(wmGizmoMapType *gzmap_type, const char *idname)
static wmKeyMap * WM_gizmogroup_keymap_template_select_ex(wmKeyConfig *kc, const char *name, const wmGizmoMapType_Params *params)
wmGizmoGroup * wm_gizmogroup_new_from_type(wmGizmoMap *gzmap, wmGizmoGroupType *gzgt)
bool WM_gizmo_group_type_ensure_ptr_ex(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type)
wmKeyMap * WM_gizmogroup_setup_keymap_generic_maybe_drag(const wmGizmoGroupType *, wmKeyConfig *kc)
wmKeyMap * WM_gizmo_keymap_generic_maybe_drag(wmWindowManager *wm)
void WM_gizmo_group_type_unlink_delayed_ptr(wmGizmoGroupType *gzgt)
void WM_gizmo_group_remove_by_tool(bContext *C, Main *bmain, const wmGizmoGroupType *gzgt, const bToolRef *tref)
void WM_gizmo_group_type_add_ptr(wmGizmoGroupType *gzgt)
void WM_gizmo_group_type_remove_ptr(Main *bmain, wmGizmoGroupType *gzgt)
static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *)
wmGizmoGroupTypeRef * WM_gizmomaptype_group_link_ptr(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
bool wm_gizmogroup_is_visible_in_drawstep(const wmGizmoGroup *gzgroup, const eWM_GizmoFlagMapDrawStep drawstep)
static bool gizmo_tweak_start_and_finish(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event, bool *r_is_modal)
wmKeyMap * WM_gizmo_keymap_generic_click_drag_with_keyconfig(wmKeyConfig *kc)
void WM_gizmo_group_unlink_delayed_ptr_from_space(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type, ScrArea *area)
void WM_gizmomaptype_group_free(wmGizmoGroupTypeRef *gzgt_ref)
void WM_gizmo_group_type_reinit_ptr(Main *bmain, wmGizmoGroupType *gzgt)
void WM_gizmo_group_type_add(const char *idname)
static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool gizmo_tweak_start(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event)
wmGizmoGroup * wm_gizmogroup_find_by_type(const wmGizmoMap *gzmap, const wmGizmoGroupType *gzgt)
wmKeyMap * WM_gizmo_keymap_generic_select_with_keyconfig(wmKeyConfig *kc)
bool WM_gizmo_group_type_ensure(const char *idname)
wmKeyMap * WM_gizmo_keymap_generic_click_drag(wmWindowManager *wm)
wmKeyMap * WM_gizmo_keymap_generic(wmWindowManager *wm)
void wm_gizmogroup_intersectable_gizmos_to_list(wmWindowManager *wm, const wmGizmoGroup *gzgroup, const int event_modifier, BLI_Buffer *visible_gizmos)
void WM_gizmo_group_type_unlink_delayed(const char *idname)
void WM_gizmo_group_type_add_ptr_ex(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type)
wmGizmoGroup * WM_gizmomaptype_group_init_runtime_with_region(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt, ARegion *region)
void WM_gizmo_group_type_reinit_ptr_ex(Main *bmain, wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type)
wmGizmoGroupTypeRef * WM_gizmomaptype_group_find_ptr(wmGizmoMapType *gzmap_type, const wmGizmoGroupType *gzgt)
int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr)
wmKeyMap * WM_gizmo_keymap_generic_select(wmWindowManager *wm)
bool WM_gizmo_group_type_poll(const bContext *C, const wmGizmoGroupType *gzgt)
void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot)
void WM_gizmo_group_tag_remove(wmGizmoGroup *gzgroup)
void WM_gizmo_group_type_reinit(Main *bmain, const char *idname)
bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *gzgroup)
void WM_gizmomaptype_group_unlink(bContext *C, Main *bmain, wmGizmoMapType *gzmap_type, const wmGizmoGroupType *gzgt)
void WM_gizmo_group_type_remove(Main *bmain, const char *idname)
static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal)
static bool wm_gizmo_keymap_uses_event_modifier(wmWindowManager *wm, const wmGizmoGroup *gzgroup, wmGizmo *gz, const int event_modifier, int *r_gzgroup_keymap_uses_modifier)
wmKeyMap * WM_gizmogroup_setup_keymap_generic_select(const wmGizmoGroupType *, wmKeyConfig *kc)
wmGizmo * wm_gizmogroup_find_intersected_gizmo(wmWindowManager *wm, const wmGizmoGroup *gzgroup, bContext *C, const int event_modifier, const int mval[2], int *r_part)
void WM_gizmo_group_type_unlink_delayed_ptr_ex(wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type)
wmKeyMap * WM_gizmo_keymap_generic_drag(wmWindowManager *wm)
void WM_gizmo_group_type_remove_ptr_ex(Main *bmain, wmGizmoGroupType *gzgt, wmGizmoMapType *gzmap_type)
void wm_gizmogroup_free(bContext *C, wmGizmoGroup *gzgroup)
void GIZMOGROUP_OT_gizmo_tweak(wmOperatorType *ot)
wmGizmoGroupType * WM_gizmogrouptype_find(const char *idname, bool quiet)
bool wm_gizmomap_deselect_all(wmGizmoMap *gzmap)
@ TWEAK_MODAL_PRECISION_ON
@ TWEAK_MODAL_SNAP_ON
@ TWEAK_MODAL_PRECISION_OFF
@ TWEAK_MODAL_CONFIRM
@ TWEAK_MODAL_SNAP_OFF
@ TWEAK_MODAL_CANCEL
void wm_gizmomap_modal_set(wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event, bool enable)
eWM_GizmoFlagMapDrawStep WM_gizmomap_drawstep_from_gizmo_group(const wmGizmoGroup *gzgroup)
bool wm_gizmomap_highlight_set(wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz, int part)
void WM_gizmomap_tag_refresh_drawstep(wmGizmoMap *gzmap, const eWM_GizmoFlagMapDrawStep drawstep)
void WM_gizmoconfig_update_tag_group_type_init(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
wmGizmo * wm_gizmomap_highlight_get(wmGizmoMap *gzmap)
void WM_gizmoconfig_update_tag_group_type_remove(wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt)
wmGizmoMapType * WM_gizmomaptype_find(const wmGizmoMapType_Params *gzmap_params)
void WM_gizmoconfig_update_tag_group_remove(wmGizmoMap *gzmap)
wmGizmoMapType * WM_gizmomaptype_ensure(const wmGizmoMapType_Params *gzmap_params)
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition wm_keymap.cc:933
wmKeyMapItem * WM_modalkeymap_add_item(wmKeyMap *km, const KeyMapItem_Params *params, int value)
Definition wm_keymap.cc:973
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
wmKeyMap * WM_keymap_active(const wmWindowManager *wm, wmKeyMap *keymap)
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
Definition wm_keymap.cc:960
wmKeyMapItem * WM_keymap_add_item(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
Definition wm_keymap.cc:546
void WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
Definition wm_keymap.cc:461
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:897
bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier)
void WM_operator_properties_mouse_select(wmOperatorType *ot)
wmOperator * WM_operator_last_redo(const bContext *C)
void WM_tooltip_clear(bContext *C, wmWindow *win)
Definition wm_tooltip.cc:81