Blender V5.0
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
13
14#include <cstdlib>
15#include <cstring>
16
17#include "MEM_guardedalloc.h"
18
19#include "BLI_listbase.h"
20#include "BLI_rect.h"
21#include "BLI_string.h"
22#include "BLI_vector.hh"
23
24#include "BKE_context.hh"
25#include "BKE_main.hh"
26#include "BKE_screen.hh"
27#include "BKE_workspace.hh"
28
29#include "RNA_access.hh"
30
31#include "WM_api.hh"
32#include "WM_keymap.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
48
49/* -------------------------------------------------------------------- */
52
54{
55 wmGizmoGroup *gzgroup = MEM_callocN<wmGizmoGroup>("gizmo-group");
56
57 gzgroup->type = gzgt;
58 gzgroup->type->users += 1;
59
60 /* Keep back-link. */
61 gzgroup->parent_gzmap = gzmap;
62
63 BLI_addtail(&gzmap->groups, gzgroup);
64
65 return gzgroup;
66}
67
69{
70 return static_cast<wmGizmoGroup *>(
71 BLI_findptr(&gzmap->groups, gzgt, offsetof(wmGizmoGroup, type)));
72}
73
75{
76 wmGizmoMap *gzmap = gzgroup->parent_gzmap;
77
78 /* Similar to WM_gizmo_unlink, but only to keep gzmap state correct,
79 * we don't want to run callbacks. */
80 if (gzmap->gzmap_context.highlight && gzmap->gzmap_context.highlight->parent_gzgroup == gzgroup)
81 {
82 wm_gizmomap_highlight_set(gzmap, C, nullptr, 0);
83 }
84 if (gzmap->gzmap_context.modal && gzmap->gzmap_context.modal->parent_gzgroup == gzgroup) {
85 wm_gizmomap_modal_set(gzmap, C, gzmap->gzmap_context.modal, nullptr, false);
86 }
87
88 for (wmGizmo *gz = static_cast<wmGizmo *>(gzgroup->gizmos.first), *gz_next; gz; gz = gz_next) {
89 gz_next = gz->next;
90 if (gzmap->gzmap_context.select.len) {
91 WM_gizmo_select_unlink(gzmap, gz);
92 }
93 WM_gizmo_free(gz);
94 }
95 BLI_listbase_clear(&gzgroup->gizmos);
96
97#ifdef WITH_PYTHON
98 if (gzgroup->py_instance) {
99 /* Do this first in case there are any `__del__` functions or
100 * similar that use properties. */
102 }
103#endif
104
105 if (gzgroup->customdata_free) {
106 gzgroup->customdata_free(gzgroup->customdata);
107 }
108 else {
109 MEM_SAFE_FREE(gzgroup->customdata);
110 }
111
112 BLI_remlink(&gzmap->groups, gzgroup);
113
114 if (gzgroup->tag_remove == false) {
115 gzgroup->type->users -= 1;
116 }
117
118 MEM_freeN(gzgroup);
119}
120
122{
123 if (gzgroup->tag_remove == false) {
124 gzgroup->tag_remove = true;
125 gzgroup->type->users -= 1;
126 BLI_assert(gzgroup->type->users >= 0);
128 }
129}
130
132{
133 BLI_assert(BLI_findindex(&gzgroup->gizmos, gz) == -1);
134 BLI_addtail(&gzgroup->gizmos, gz);
135 gz->parent_gzgroup = gzgroup;
136}
137
138int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr)
139{
140 const wmGizmo *gz_a = static_cast<const wmGizmo *>(gz_a_ptr);
141 const wmGizmo *gz_b = static_cast<const wmGizmo *>(gz_b_ptr);
142 if (gz_a->temp.f < gz_b->temp.f) {
143 return -1;
144 }
145 if (gz_a->temp.f > gz_b->temp.f) {
146 return 1;
147 }
148 return 0;
149}
150
151int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
152{
153 const wmGizmo *gz_a = static_cast<const wmGizmo *>(gz_a_ptr);
154 const wmGizmo *gz_b = static_cast<const wmGizmo *>(gz_b_ptr);
155 if (gz_a->temp.f < gz_b->temp.f) {
156 return 1;
157 }
158 if (gz_a->temp.f > gz_b->temp.f) {
159 return -1;
160 }
161 return 0;
162}
163
165 const wmGizmoGroup *gzgroup,
166 wmGizmo *gz,
167 const int event_modifier,
168 int *r_gzgroup_keymap_uses_modifier)
169{
170 if (gz->keymap) {
171 wmKeyMap *keymap = WM_keymap_active(wm, gz->keymap);
172 if (!WM_keymap_uses_event_modifier(keymap, event_modifier)) {
173 return false;
174 }
175 }
176 else if (gzgroup->type->keymap) {
177 if (*r_gzgroup_keymap_uses_modifier == -1) {
178 wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap);
179 *r_gzgroup_keymap_uses_modifier = WM_keymap_uses_event_modifier(keymap, event_modifier);
180 }
181 if (*r_gzgroup_keymap_uses_modifier == 0) {
182 return false;
183 }
184 }
185 return true;
186}
187
189 const wmGizmoGroup *gzgroup,
190 bContext *C,
191 const int event_modifier,
192 const int mval[2],
193 int *r_part)
194{
195 int gzgroup_keymap_uses_modifier = -1;
196
197 LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
198 if (gz->type->test_select && (gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) {
199
201 wm, gzgroup, gz, event_modifier, &gzgroup_keymap_uses_modifier))
202 {
203 continue;
204 }
205
206 if ((*r_part = gz->type->test_select(C, gz, mval)) != -1) {
207 return gz;
208 }
209 }
210 }
211
212 return nullptr;
213}
214
216 const wmGizmoGroup *gzgroup,
217 const int event_modifier,
218 blender::Vector<wmGizmo *, 128> *r_visible_gizmos)
219{
220 int gzgroup_keymap_uses_modifier = -1;
221 LISTBASE_FOREACH_BACKWARD (wmGizmo *, gz, &gzgroup->gizmos) {
222 if ((gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) {
223 if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) &&
224 (gz->type->draw_select || gz->type->test_select)) ||
225 ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select))
226 {
227
229 wm, gzgroup, gz, event_modifier, &gzgroup_keymap_uses_modifier))
230 {
231 continue;
232 }
233
234 r_visible_gizmos->append(gz);
235 }
236 }
237 }
238}
239
241{
242 /* Prepare for first draw. */
243 if (UNLIKELY((gzgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0)) {
244
245 gzgroup->type->setup(C, gzgroup);
246
247 /* Not ideal, initialize keymap here, needed for RNA runtime generated gizmos. */
248 wmGizmoGroupType *gzgt = gzgroup->type;
249 if (gzgt->keymap == nullptr) {
251 wm_gizmogrouptype_setup_keymap(gzgt, wm->runtime->defaultconf);
252 BLI_assert(gzgt->keymap != nullptr);
253 }
255 }
256
257 /* Refresh may be called multiple times,
258 * this just ensures its called at least once before we draw. */
259 if (UNLIKELY((gzgroup->init_flag & WM_GIZMOGROUP_INIT_REFRESH) == 0)) {
260 /* Clear the flag before calling refresh so the callback
261 * can postpone the refresh by clearing this flag. */
263 WM_gizmo_group_refresh(C, gzgroup);
264 }
265}
266
268 Main *bmain,
269 const wmGizmoGroupType *gzgt,
270 const bToolRef *tref)
271{
273 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
274 screen = static_cast<bScreen *>(screen->id.next))
275 {
276 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
277 if (area->runtime.tool == tref) {
278 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
279 wmGizmoMap *gzmap = region->runtime->gizmo_map;
280 if (gzmap && gzmap->type == gzmap_type) {
281 wmGizmoGroup *gzgroup, *gzgroup_next;
282 for (gzgroup = static_cast<wmGizmoGroup *>(gzmap->groups.first); gzgroup;
283 gzgroup = gzgroup_next)
284 {
285 gzgroup_next = gzgroup->next;
286 if (gzgroup->type == gzgt) {
287 BLI_assert(gzgroup->parent_gzmap == gzmap);
288 wm_gizmogroup_free(C, gzgroup);
290 }
291 }
292 }
293 }
294 }
295 }
296 }
297}
298
300 const eWM_GizmoFlagMapDrawStep drawstep)
301{
302 switch (drawstep) {
304 return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0;
306 return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D);
307 default:
309 return false;
310 }
311}
312
314{
315 if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_SELECT) {
316 LISTBASE_FOREACH (const wmGizmo *, gz, &gzgroup->gizmos) {
317 if (gz->state & WM_GIZMO_STATE_SELECT) {
318 return true;
319 }
320 }
321 }
322 return false;
323}
324
326
327/* -------------------------------------------------------------------- */
332
334{
335 ARegion *region = CTX_wm_region(C);
336 wmGizmoMap *gzmap = region->runtime->gizmo_map;
338 wmGizmo *highlight = gzmap->gzmap_context.highlight;
339
340 bool extend = RNA_boolean_get(op->ptr, "extend");
341 bool deselect = RNA_boolean_get(op->ptr, "deselect");
342 bool toggle = RNA_boolean_get(op->ptr, "toggle");
343
344 /* Deselect all first. */
345 if (extend == false && deselect == false && toggle == false) {
347 BLI_assert(msel->items == nullptr && msel->len == 0);
348 UNUSED_VARS_NDEBUG(msel);
349 }
350
351 if (highlight) {
352 const bool is_selected = (highlight->state & WM_GIZMO_STATE_SELECT);
353 bool redraw = false;
354
355 if (toggle) {
356 /* Toggle: deselect if already selected, else select. */
357 deselect = is_selected;
358 }
359
360 if (deselect) {
361 if (is_selected && WM_gizmo_select_set(gzmap, highlight, false)) {
362 redraw = true;
363 }
364 }
365 else if (wm_gizmo_select_and_highlight(C, gzmap, highlight)) {
366 redraw = true;
367 }
368
369 if (redraw) {
371 }
372
373 return OPERATOR_FINISHED;
374 }
375
378}
379
381{
382 /* Identifiers. */
383 ot->name = "Gizmo Select";
384 ot->description = "Select the currently highlighted gizmo";
385 ot->idname = "GIZMOGROUP_OT_gizmo_select";
386
387 /* API callbacks. */
388 ot->invoke = gizmo_select_invoke;
390
391 ot->flag = OPTYPE_UNDO;
392
394}
395
400
401 int init_event; /* Initial event type. */
402 int flag; /* Tweak flags. */
403};
404
405static bool gizmo_tweak_start(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event)
406{
407 /* Activate highlighted gizmo. */
408 wm_gizmomap_modal_set(gzmap, C, gz, event, true);
409
410 return (gz->state & WM_GIZMO_STATE_MODAL);
411}
412
414 bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event, bool *r_is_modal)
415{
417 if (r_is_modal) {
418 *r_is_modal = false;
419 }
420 if (gzop && gzop->type) {
421
422 /* Undo/Redo. */
423 if (gzop->is_redo) {
426
427/* We may want to enable this, for now the gizmo can manage its own properties. */
428#if 0
429 IDP_MergeGroup(gzop->ptr.data, op->properties, false);
430#endif
431
433 ED_undo_pop_op(C, op);
434 }
435
436 /* XXX temporary workaround for modal gizmo operator
437 * conflicting with modal operator attached to gizmo. */
438 if (gzop->type->modal) {
439 /* Activate highlighted gizmo. */
440 wm_gizmomap_modal_set(gzmap, C, gz, event, true);
441 if (r_is_modal) {
442 *r_is_modal = true;
443 }
444 }
445 else {
447 gz->parent_gzgroup->type->invoke_prepare(C, gz->parent_gzgroup, gz, event);
448 }
449 /* Allow for 'button' gizmos, single click to run an action. */
450 WM_gizmo_operator_invoke(C, gz, gzop, event);
451 }
452 return true;
453 }
454 return false;
455}
456
457static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal)
458{
459 GizmoTweakData *mtweak = static_cast<GizmoTweakData *>(op->customdata);
460 if (mtweak->gz_modal->type->exit) {
461 mtweak->gz_modal->type->exit(C, mtweak->gz_modal, cancel);
462 }
463 if (clear_modal) {
464 /* The gizmo may have been removed. */
465 if ((BLI_findindex(&mtweak->gzmap->groups, mtweak->gzgroup) != -1) &&
466 (BLI_findindex(&mtweak->gzgroup->gizmos, mtweak->gz_modal) != -1))
467 {
468 wm_gizmomap_modal_set(mtweak->gzmap, C, mtweak->gz_modal, nullptr, false);
469 }
470 }
471 if (cancel == false) {
472 if (mtweak->gz_modal->flag & WM_GIZMO_NEEDS_UNDO) {
474 }
475 }
476 MEM_freeN(mtweak);
477}
478
480{
481 GizmoTweakData *mtweak = static_cast<GizmoTweakData *>(op->customdata);
482 wmGizmo *gz = mtweak->gz_modal;
484 bool clear_modal = true;
485
486 if (gz == nullptr) {
489 }
490
491 if (retval == OPERATOR_FINISHED) {
492 /* Pass. */
493 }
494 else if (event->type == mtweak->init_event && event->val == KM_RELEASE) {
495 retval = OPERATOR_FINISHED;
496 }
497 else if (event->type == EVT_MODAL_MAP) {
498 switch (event->val) {
500 retval = OPERATOR_CANCELLED;
501 break;
503 retval = OPERATOR_FINISHED;
504 break;
506 mtweak->flag |= WM_GIZMO_TWEAK_PRECISE;
507 break;
509 mtweak->flag &= ~WM_GIZMO_TWEAK_PRECISE;
510 break;
511
513 mtweak->flag |= WM_GIZMO_TWEAK_SNAP;
514 break;
516 mtweak->flag &= ~WM_GIZMO_TWEAK_SNAP;
517 break;
518 }
519 }
520
521 if (retval != OPERATOR_PASS_THROUGH) {
522 gizmo_tweak_finish(C, op, retval != OPERATOR_FINISHED, clear_modal);
523 return retval;
524 }
525
526 /* Handle gizmo. */
527 wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal;
528 if (modal_fn) {
529 /* Ugly hack to ensure Python won't get 'EVT_MODAL_MAP' which isn't supported, see #73727.
530 * note that we could move away from wrapping modal gizmos in a modal operator,
531 * since it's causing the need for code like this. */
532 wmEvent *evil_event = (wmEvent *)event;
533 short event_modal_val = 0;
534
535 if (event->type == EVT_MODAL_MAP) {
536 event_modal_val = evil_event->val;
537 evil_event->type = evil_event->prev_type;
538 evil_event->val = evil_event->prev_val;
539 }
540
541 const wmOperatorStatus modal_retval = modal_fn(C, gz, event, eWM_GizmoFlagTweak(mtweak->flag));
542 OPERATOR_RETVAL_CHECK(modal_retval);
543
544 if (event_modal_val != 0) {
545 evil_event->type = EVT_MODAL_MAP;
546 evil_event->val = event_modal_val;
547 }
548
549 if ((modal_retval & OPERATOR_RUNNING_MODAL) == 0) {
550 gizmo_tweak_finish(C, op, (modal_retval & OPERATOR_CANCELLED) != 0, true);
551 return OPERATOR_FINISHED;
552 }
553
554 /* Ugly hack to send gizmo events. */
555 evil_event->type = EVT_GIZMO_UPDATE;
556 }
557
558 /* Always return PASS_THROUGH so modal handlers
559 * with gizmos attached can update. */
562}
563
565{
566 ARegion *region = CTX_wm_region(C);
567 wmGizmoMap *gzmap = region->runtime->gizmo_map;
568 wmGizmo *gz = gzmap->gzmap_context.highlight;
569
570 /* Needed for single click actions which don't enter modal state. */
572
573 if (!gz) {
574 /* #wm_handlers_do_intern shouldn't let this happen. */
575 BLI_assert_msg(false, "the gizmo should never be null, this is a bug!");
577 }
578
580 /* The event-system should prevent this from happening, see: #137146.
581 * May be caused by the context changing without tagging #wmGizmoMap::tag_highlight_pending,
582 * typically via #WM_gizmomap_tag_refresh. */
583 BLI_assert_msg(false, "the gizmo-group's poll should always succeed, this is a bug!");
585 }
586
587 const int highlight_part_init = gz->highlight_part;
588
589 if (gz->drag_part != -1) {
590 if (WM_event_is_mouse_drag(event)) {
591 gz->highlight_part = gz->drag_part;
592 }
593 }
594
595 if (gizmo_tweak_start_and_finish(C, gzmap, gz, event, nullptr)) {
596 return OPERATOR_FINISHED;
597 }
598
599 if (!gizmo_tweak_start(C, gzmap, gz, event)) {
600 /* Failed to start. */
601 gz->highlight_part = highlight_part_init;
603 }
604
606
608 mtweak->gz_modal = gzmap->gzmap_context.highlight;
609 mtweak->gzgroup = mtweak->gz_modal->parent_gzgroup;
610 mtweak->gzmap = gzmap;
611 mtweak->flag = 0;
612
613 op->customdata = mtweak;
614
616
618}
619
621{
622 /* Identifiers. */
623 ot->name = "Gizmo Tweak";
624 ot->description = "Tweak the active gizmo";
625 ot->idname = "GIZMOGROUP_OT_gizmo_tweak";
626
627 /* API callbacks. */
628 ot->invoke = gizmo_tweak_invoke;
629 ot->modal = gizmo_tweak_modal;
631
632/* TODO(@ideasman42): This causes problems tweaking settings for operators,
633 * need to find a way to support this. May want to use #WM_GIZMO_NEEDS_UNDO instead. */
634#if 0
635 ot->flag = OPTYPE_UNDO;
636#endif
638}
639
641{
642 wmKeyMap *keymap;
643 char name[KMAP_MAX_NAME];
644
645 static const EnumPropertyItem modal_items[] = {
646 {TWEAK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
647 {TWEAK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
648 {TWEAK_MODAL_PRECISION_ON, "PRECISION_ON", 0, "Enable Precision", ""},
649 {TWEAK_MODAL_PRECISION_OFF, "PRECISION_OFF", 0, "Disable Precision", ""},
650 {TWEAK_MODAL_SNAP_ON, "SNAP_ON", 0, "Enable Snap", ""},
651 {TWEAK_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Disable Snap", ""},
652 {0, nullptr, 0, nullptr, nullptr},
653 };
654
655 STRNCPY(name, "Generic Gizmo Tweak Modal Map");
656 keymap = WM_modalkeymap_find(keyconf, name);
657
658 /* This function is called for each space-type, only needs to add map once. */
659 if (keymap && keymap->modal_items) {
660 return nullptr;
661 }
662
663 keymap = WM_modalkeymap_ensure(keyconf, name, modal_items);
664
665 /* Items for modal map. */
666 {
668 params.type = EVT_ESCKEY;
669 params.value = KM_PRESS;
670 params.modifier = KM_ANY;
671 params.direction = KM_ANY;
673 }
674 {
676 params.type = RIGHTMOUSE;
677 params.value = KM_PRESS;
678 params.modifier = KM_ANY;
679 params.direction = KM_ANY;
681 }
682 {
684 params.type = EVT_RETKEY;
685 params.value = KM_PRESS;
686 params.modifier = KM_ANY;
687 params.direction = KM_ANY;
689 }
690 {
692 params.type = EVT_PADENTER;
693 params.value = KM_PRESS;
694 params.modifier = KM_ANY;
695 params.direction = KM_ANY;
697 }
698 {
701 params.value = KM_PRESS;
702 params.modifier = KM_ANY;
703 params.direction = KM_ANY;
705 }
706 {
709 params.value = KM_RELEASE;
710 params.modifier = KM_ANY;
711 params.direction = KM_ANY;
713 }
714 {
717 params.value = KM_PRESS;
718 params.modifier = KM_ANY;
719 params.direction = KM_ANY;
721 }
722 {
725 params.value = KM_RELEASE;
726 params.modifier = KM_ANY;
727 params.direction = KM_ANY;
729 }
730 {
733 params.value = KM_PRESS;
734 params.modifier = KM_ANY;
735 params.direction = KM_ANY;
737 }
738 {
741 params.value = KM_RELEASE;
742 params.modifier = KM_ANY;
743 params.direction = KM_ANY;
745 }
746 {
748 params.type = EVT_LEFTCTRLKEY;
749 params.value = KM_PRESS;
750 params.modifier = KM_ANY;
751 params.direction = KM_ANY;
753 }
754 {
756 params.type = EVT_LEFTCTRLKEY;
757 params.value = KM_RELEASE;
758 params.modifier = KM_ANY;
759 params.direction = KM_ANY;
761 }
762
763 WM_modalkeymap_assign(keymap, "GIZMOGROUP_OT_gizmo_tweak");
764
765 return keymap;
766}
767 /* #wmGizmoGroup. */
769
770/* -------------------------------------------------------------------- */
773
778
784
790
800 const char *name,
802{
803 /* Use area and region id since we might have multiple gizmos
804 * with the same name in different areas/regions. */
805 wmKeyMap *km = WM_keymap_ensure(kc, name, params->spaceid, params->regionid);
806 const bool do_init = BLI_listbase_is_empty(&km->items);
807
808/* FIXME(@ideasman42): Currently hard coded. */
809#if 0
810 const int select_mouse = (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE;
811 const int select_tweak = (U.flag & USER_LMOUSESELECT) ? EVT_TWEAK_L : EVT_TWEAK_R;
812 const int action_mouse = (U.flag & USER_LMOUSESELECT) ? RIGHTMOUSE : LEFTMOUSE;
813#else
814 const int select_mouse = RIGHTMOUSE, select_mouse_val = KM_PRESS;
815 const int select_tweak = RIGHTMOUSE, select_tweak_val = KM_PRESS_DRAG;
816 const int action_mouse = LEFTMOUSE, action_mouse_val = KM_PRESS;
817#endif
818
819 if (do_init) {
820 {
822 params.type = action_mouse;
823 params.value = action_mouse_val;
824 params.modifier = KM_ANY;
825 params.direction = KM_ANY;
826 WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", &params);
827 }
828 {
830 params.type = select_tweak;
831 params.value = select_tweak_val;
832 params.modifier = 0;
833 params.direction = KM_ANY;
834 WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", &params);
835 }
836 }
837
838 if (do_init) {
839 {
841 params.type = select_mouse;
842 params.value = select_mouse_val;
843 params.modifier = 0;
844 params.direction = KM_ANY;
845 wmKeyMapItem *kmi = WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_select", &params);
846 RNA_boolean_set(kmi->ptr, "extend", false);
847 RNA_boolean_set(kmi->ptr, "deselect", false);
848 RNA_boolean_set(kmi->ptr, "toggle", false);
849 }
850 {
852 params.type = select_mouse;
853 params.value = select_mouse_val;
854 params.modifier = KM_SHIFT;
855 params.direction = KM_ANY;
856 wmKeyMapItem *kmi = WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_select", &params);
857 RNA_boolean_set(kmi->ptr, "extend", false);
858 RNA_boolean_set(kmi->ptr, "deselect", false);
859 RNA_boolean_set(kmi->ptr, "toggle", true);
860 }
861 }
862
863 return km;
864}
865
867 wmKeyConfig *kc)
868{
870 params.spaceid = SPACE_EMPTY;
871 params.regionid = RGN_TYPE_WINDOW;
872 return WM_gizmogroup_keymap_template_select_ex(kc, "Generic Gizmo Select", &params);
873}
874
876
877/* -------------------------------------------------------------------- */
882
884{
885 const char *idname = "Generic Gizmo";
886 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
887}
892
894{
895 const char *idname = "Generic Gizmo Select";
896 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
897}
902
904{
905 const char *idname = "Generic Gizmo Drag";
906 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
907}
912
914{
915 const char *idname = "Generic Gizmo Click Drag";
916 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
917}
922
924{
925 const char *idname = "Generic Gizmo Maybe Drag";
926 return WM_keymap_ensure(kc, idname, SPACE_EMPTY, RGN_TYPE_WINDOW);
927}
932
934
935/* -------------------------------------------------------------------- */
938
940 const wmGizmoGroupType *gzgt)
941{
942 /* Could use hash lookups as operator types do, for now simple search. */
943 LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
944 if (gzgt_ref->type == gzgt) {
945 return gzgt_ref;
946 }
947 }
948 return nullptr;
949}
950
952{
953 /* Could use hash lookups as operator types do, for now simple search. */
954 LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) {
955 if (idname == gzgt_ref->type->idname) {
956 return gzgt_ref;
957 }
958 }
959 return nullptr;
960}
961
963{
964 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
965 BLI_assert(gzgt != nullptr);
966 return WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt);
967}
968
970 wmGizmoGroupType *gzgt)
971{
972 wmGizmoGroupTypeRef *gzgt_ref = MEM_callocN<wmGizmoGroupTypeRef>("gizmo-group-ref");
973 gzgt_ref->type = gzgt;
974 BLI_addtail(&gzmap_type->grouptype_refs, gzgt_ref);
975 return gzgt_ref;
976}
977
979{
980 /* Initialize key-map.
981 * On startup there's an extra call to initialize keymaps for 'permanent' gizmo-groups. */
982 wm_gizmogrouptype_setup_keymap(gzgt, ((wmWindowManager *)bmain->wm.first)->runtime->defaultconf);
983}
984
986 wmGizmoMapType *gzmap_type,
987 wmGizmoGroupType *gzgt)
988{
989 /* Tools add themselves. */
990 if (gzgt->flag & WM_GIZMOGROUPTYPE_TOOL_INIT) {
991 return;
992 }
993
994 /* Now create a gizmo for all existing areas. */
995 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
996 screen = static_cast<bScreen *>(screen->id.next))
997 {
998 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
999 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1000 ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
1001 LISTBASE_FOREACH (ARegion *, region, lb) {
1002 wmGizmoMap *gzmap = region->runtime->gizmo_map;
1003 if (gzmap && gzmap->type == gzmap_type) {
1004 WM_gizmomaptype_group_init_runtime_with_region(gzmap_type, gzgt, region);
1005 }
1006 }
1007 }
1008 }
1009 }
1010}
1011
1013 wmGizmoGroupType *gzgt,
1014 ARegion *region)
1015{
1016 wmGizmoMap *gzmap = region->runtime->gizmo_map;
1017 BLI_assert(gzmap && gzmap->type == gzmap_type);
1018 UNUSED_VARS_NDEBUG(gzmap_type);
1019
1020 wmGizmoGroup *gzgroup = wm_gizmogroup_new_from_type(gzmap, gzgt);
1021
1022 /* Don't allow duplicates when switching modes for example. See: #66229. */
1023 LISTBASE_FOREACH (wmGizmoGroup *, gzgroup_iter, &gzmap->groups) {
1024 if (gzgroup_iter->type == gzgt) {
1025 if (gzgroup_iter != gzgroup) {
1026 WM_gizmo_group_tag_remove(gzgroup_iter);
1027 }
1028 }
1029 }
1030
1031 wm_gizmomap_highlight_set(gzmap, nullptr, nullptr, 0);
1032
1034
1035 return gzgroup;
1036}
1037
1039{
1040 MEM_freeN(gzgt_ref);
1041}
1042
1044 Main *bmain,
1045 wmGizmoMapType *gzmap_type,
1046 const wmGizmoGroupType *gzgt)
1047{
1048 /* Free instances. */
1049 for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen;
1050 screen = static_cast<bScreen *>(screen->id.next))
1051 {
1052 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1053 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
1054 ListBase *lb = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
1055 LISTBASE_FOREACH (ARegion *, region, lb) {
1056 wmGizmoMap *gzmap = region->runtime->gizmo_map;
1057 if (gzmap && gzmap->type == gzmap_type) {
1058 wmGizmoGroup *gzgroup, *gzgroup_next;
1059 for (gzgroup = static_cast<wmGizmoGroup *>(gzmap->groups.first); gzgroup;
1060 gzgroup = gzgroup_next)
1061 {
1062 gzgroup_next = gzgroup->next;
1063 if (gzgroup->type == gzgt) {
1064 BLI_assert(gzgroup->parent_gzmap == gzmap);
1065 wm_gizmogroup_free(C, gzgroup);
1067 }
1068 }
1069 }
1070 }
1071 }
1072 }
1073 }
1074
1075 /* Free types. */
1076 wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt);
1077 if (gzgt_ref) {
1078 BLI_remlink(&gzmap_type->grouptype_refs, gzgt_ref);
1080 }
1081
1082/* TODO(@ideasman42): Gizmos may share key-maps, for now don't
1083 * remove however we could flag them as temporary/owned by the gizmo. */
1084#if 0
1085 /* NOTE: we may want to keep this key-map for editing. */
1086 WM_keymap_remove(gzgt->keyconf, gzgt->keymap);
1087#endif
1088
1089 BLI_assert(WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt) == nullptr);
1090}
1091
1093{
1094 /* Use flag since setup_keymap may return nullptr,
1095 * in that case we better not keep calling it. */
1097 gzgt->keymap = gzgt->setup_keymap(gzgt, keyconf);
1098 gzgt->keyconf = keyconf;
1100 }
1101}
1102 /* #wmGizmoGroupType. */
1104
1105/* -------------------------------------------------------------------- */
1118
1120{
1121 WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt);
1122
1124}
1131{
1132 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1133 BLI_assert(gzgt != nullptr);
1135}
1136
1138{
1139 wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt);
1140 if (gzgt_ref == nullptr) {
1141 WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type);
1142 return true;
1143 }
1144 return false;
1145}
1147{
1149 return WM_gizmo_group_type_ensure_ptr_ex(gzgt, gzmap_type);
1150}
1152{
1153 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1154 BLI_assert(gzgt != nullptr);
1155 return WM_gizmo_group_type_ensure_ptr(gzgt);
1156}
1157
1159 wmGizmoGroupType *gzgt,
1160 wmGizmoMapType *gzmap_type)
1161{
1162 WM_gizmomaptype_group_unlink(nullptr, bmain, gzmap_type, gzgt);
1163}
1165{
1167 WM_gizmo_group_type_remove_ptr_ex(bmain, gzgt, gzmap_type);
1168}
1170{
1171 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1172 BLI_assert(gzgt != nullptr);
1173 WM_gizmo_group_type_remove_ptr(bmain, gzgt);
1174}
1175
1177 wmGizmoGroupType *gzgt,
1178 wmGizmoMapType *gzmap_type)
1179{
1180 wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt);
1181 BLI_assert(gzgt_ref != nullptr);
1182 UNUSED_VARS_NDEBUG(gzgt_ref);
1183 WM_gizmomaptype_group_unlink(nullptr, bmain, gzmap_type, gzgt);
1184 WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type);
1185}
1187{
1189 WM_gizmo_group_type_reinit_ptr_ex(bmain, gzgt, gzmap_type);
1190}
1192{
1193 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1194 BLI_assert(gzgt != nullptr);
1195 WM_gizmo_group_type_reinit_ptr(bmain, gzgt);
1196}
1197
1198/* Delayed versions. */
1199
1204
1210
1212{
1213 wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false);
1214 BLI_assert(gzgt != nullptr);
1216}
1217
1219 wmGizmoMapType *gzmap_type,
1220 ScrArea *area)
1221{
1222 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1223 wmGizmoMap *gzmap = region->runtime->gizmo_map;
1224 if (gzmap && gzmap->type == gzmap_type) {
1225 LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, &gzmap->groups) {
1226 if (gzgroup->type == gzgt) {
1228 }
1229 }
1230 }
1231 }
1232}
1233
1235
1236/* -------------------------------------------------------------------- */
1239
1241{
1242 /* If we're tagged, only use compatible. */
1243 if (gzgt->owner_id[0] != '\0') {
1244 const WorkSpace *workspace = CTX_wm_workspace(C);
1245 if (BKE_workspace_owner_id_check(workspace, gzgt->owner_id) == false) {
1246 return false;
1247 }
1248 }
1249 /* Check for poll function, if gizmo-group belongs to an operator,
1250 * also check if the operator is running. */
1251 return (!gzgt->poll || gzgt->poll(C, (wmGizmoGroupType *)gzgt));
1252}
1253
1255{
1256 const wmGizmoGroupType *gzgt = gzgroup->type;
1258 wmGizmoMap *gzmap = gzgroup->parent_gzmap;
1259 wmGizmo *gz = nullptr;
1260 /* Without the check for refresh, any highlighted gizmo will prevent hiding
1261 * when selecting with RMB when the cursor happens to be over a gizmo. */
1262 if ((gzgroup->init_flag & WM_GIZMOGROUP_INIT_REFRESH) == 0) {
1263 gz = wm_gizmomap_highlight_get(gzmap);
1264 }
1265 if (!gz || gz->parent_gzgroup != gzgroup) {
1266 wmWindow *win = CTX_wm_window(C);
1267 ARegion *region = CTX_wm_region(C);
1268 BLI_assert(region->runtime->gizmo_map == gzmap);
1269 /* Check if the tweak event originated from this region. */
1270 if ((win->eventstate != nullptr) && (win->event_queue_check_drag) &&
1272 {
1273 /* We need to run refresh again. */
1276 gzgroup->hide.delay_refresh_for_tweak = true;
1277 return;
1278 }
1279 }
1280 gzgroup->hide.delay_refresh_for_tweak = false;
1281 }
1282
1283 if (gzgroup->hide.any) {
1284 return;
1285 }
1286
1287 if (gzgt->refresh) {
1288 gzgt->refresh(C, gzgroup);
1289 }
1290}
1291
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:712
bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_id) ATTR_NONNULL()
Definition workspace.cc:537
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define UNUSED_VARS_NDEBUG(...)
#define UNLIKELY(x)
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
@ RGN_TYPE_WINDOW
@ SPACE_EMPTY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
#define OPERATOR_RETVAL_CHECK(ret)
#define KMAP_MAX_NAME
void ED_region_tag_redraw_editor_overlays(ARegion *region)
Definition area.cc:654
bool ED_operator_region_gizmo_active(bContext *C)
void ED_undo_push(bContext *C, const char *str)
Definition ed_undo.cc:98
void ED_undo_pop_op(bContext *C, wmOperator *op)
Definition ed_undo.cc:375
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition RandGen.cpp:29
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
@ KM_SHIFT
Definition WM_types.hh:278
@ KM_ANY
Definition WM_types.hh:309
@ KM_PRESS
Definition WM_types.hh:311
@ KM_PRESS_DRAG
Definition WM_types.hh:319
@ KM_RELEASE
Definition WM_types.hh:312
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_GRAB_CURSOR_XY
Definition WM_types.hh:188
#define U
void append(const T &value)
#define offsetof(t, d)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
const char * name
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
ARegionRuntimeHandle * runtime
wmGizmoGroup * gzgroup
wmGizmoMap * gzmap
void * first
ListBase wm
Definition BKE_main.hh:307
ListBase screens
Definition BKE_main.hh:292
void * data
Definition RNA_types.hh:53
ListBase regionbase
wmEventType prev_type
Definition WM_types.hh:812
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
short prev_val
Definition WM_types.hh:814
int prev_press_xy[2]
Definition WM_types.hh:830
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
eWM_GizmoFlagGroupInitFlag init_flag
wmGizmoMap * parent_gzmap
void(* customdata_free)(void *)
wmGizmoGroupType * type
union wmGizmoGroup::@064376176052321033251226316126272250076156203053 hide
wmGizmoGroup * next
uint delay_refresh_for_tweak
struct wmGizmo ** items
wmGizmoMapSelectState select
wmGizmo * modal
wmGizmoMapType * type
struct wmGizmoMap::@114263143030171315362141314326010164050332242157 gzmap_context
Gizmo map runtime context.
wmGizmo * highlight
wmOperatorType * type
wmGizmoFnModal modal
wmGizmoFnExit exit
wmGizmoGroup * parent_gzgroup
const wmGizmoType * type
eWM_GizmoFlagState state
union wmGizmo::@212020261060256366012217133260074053150351165313 temp
eWM_GizmoFlag flag
wmKeyMap * keymap
wmGizmoFnModal custom_modal
struct PointerRNA * ptr
const void * modal_items
wmOperatorStatus(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1081
IDProperty * properties
struct PointerRNA * ptr
WindowManagerRuntimeHandle * runtime
struct wmEvent * eventstate
#define USER_LMOUSESELECT
void WM_operator_free_all_after(wmWindowManager *wm, wmOperator *op)
Definition wm.cc:294
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:4237
wmGizmoOpElem * WM_gizmo_operator_get(wmGizmo *gz, int part_index)
Definition wm_gizmo.cc:195
wmOperatorStatus WM_gizmo_operator_invoke(bContext *C, wmGizmo *gz, wmGizmoOpElem *gzop, const wmEvent *event)
Definition wm_gizmo.cc:227
bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz)
Definition wm_gizmo.cc:410
void WM_gizmo_free(wmGizmo *gz)
Definition wm_gizmo.cc:130
bool WM_gizmo_select_unlink(wmGizmoMap *gzmap, wmGizmo *gz)
Definition wm_gizmo.cc:395
bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select)
Definition wm_gizmo.cc:400
wmOperatorStatus(*)(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)
wmKeyMap * WM_gizmo_keymap_generic_press_drag(wmWindowManager *wm)
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)
void WM_gizmo_group_type_add(const StringRef idname)
wmKeyMap * wm_gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf)
void wm_gizmogroup_intersectable_gizmos_to_list(wmWindowManager *wm, const wmGizmoGroup *gzgroup, const int event_modifier, blender::Vector< wmGizmo *, 128 > *r_visible_gizmos)
wmKeyMap * WM_gizmo_keymap_generic_drag_with_keyconfig(wmKeyConfig *kc)
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 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)
void WM_gizmo_group_type_unlink_delayed(const StringRef idname)
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(Main *bmain, const StringRef idname)
void WM_gizmo_group_type_remove_ptr(Main *bmain, wmGizmoGroupType *gzgt)
wmGizmoGroupTypeRef * WM_gizmomaptype_group_link(wmGizmoMapType *gzmap_type, const StringRef idname)
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)
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)
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)
static wmOperatorStatus gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmKeyMap * WM_gizmo_keymap_generic_select_with_keyconfig(wmKeyConfig *kc)
wmKeyMap * WM_gizmo_keymap_generic_press_drag_with_keyconfig(wmKeyConfig *kc)
wmKeyMap * WM_gizmo_keymap_generic(wmWindowManager *wm)
wmGizmoGroupTypeRef * WM_gizmomaptype_group_find(wmGizmoMapType *gzmap_type, const StringRef 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_ensure(const StringRef idname)
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)
bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *gzgroup)
void WM_gizmomaptype_group_unlink(bContext *C, Main *bmain, wmGizmoMapType *gzmap_type, const wmGizmoGroupType *gzgt)
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_reinit(Main *bmain, const StringRef idname)
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 StringRef idname, bool quiet)
@ TWEAK_MODAL_PRECISION_ON
@ TWEAK_MODAL_SNAP_ON
@ TWEAK_MODAL_PRECISION_OFF
@ TWEAK_MODAL_CONFIRM
@ TWEAK_MODAL_SNAP_OFF
@ TWEAK_MODAL_CANCEL
bool wm_gizmomap_deselect_all(wmGizmoMap *gzmap)
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:932
wmKeyMapItem * WM_modalkeymap_add_item(wmKeyMap *km, const KeyMapItem_Params *params, int value)
Definition wm_keymap.cc:972
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:959
wmKeyMapItem * WM_keymap_add_item(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
Definition wm_keymap.cc:548
void WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
Definition wm_keymap.cc:462
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:895
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:82