diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-05-28 07:33:13 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-05-28 07:40:12 +0300 |
commit | 13f292d10d3bb19aa9aa694cecbde499f93e7a54 (patch) | |
tree | b12dffe51f9649c24642f18131b47bedca169438 | |
parent | 2e22cfd08a0d589e8894e322ed29d5c3227ca04d (diff) |
Gizmo: only highlight when held modifier keys are used
Check the current events modifiers against the gizmo keymap,
only highlighting when keymap items match.
Needed to resolve T63996
7 files changed, 123 insertions, 8 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 4a7953d7a24..a5eb892841c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -599,6 +599,7 @@ bool WM_gesture_is_modal_first(const struct wmGesture *gesture); /* fileselecting support */ void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op); void WM_event_fileselect_event(struct wmWindowManager *wm, void *ophandle, int eventval); +int WM_event_modifier_flag(const struct wmEvent *event); void WM_event_print(const struct wmEvent *event); void WM_operator_region_active_win_set(struct bContext *C); diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index 53488cd1f71..4a9a9cf8705 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -114,6 +114,8 @@ void WM_keymap_add_context_enum_set_items(wmKeyMap *keymap, wmKeyMap *WM_keymap_guess_from_context(const struct bContext *C); wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname); +bool WM_keymap_uses_event_modifier(wmKeyMap *keymap, const int event_modifier); + void WM_keymap_fix_linking(void); /* Modal Keymap */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index e491b86ea18..1918fc952f1 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -168,13 +168,47 @@ int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr) } } -wmGizmo *wm_gizmogroup_find_intersected_gizmo(const wmGizmoGroup *gzgroup, +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) +{ + if (gz->keymap) { + wmKeyMap *keymap = WM_keymap_active(wm, gz->keymap); + if (!WM_keymap_uses_event_modifier(keymap, event_modifier)) { + return false; + } + } + else if (gzgroup->type->keymap) { + if (*r_gzgroup_keymap_uses_modifier == -1) { + wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap); + *r_gzgroup_keymap_uses_modifier = WM_keymap_uses_event_modifier(keymap, event_modifier); + } + if (*r_gzgroup_keymap_uses_modifier == 0) { + return false; + } + } + return true; +} + +wmGizmo *wm_gizmogroup_find_intersected_gizmo(wmWindowManager *wm, + const wmGizmoGroup *gzgroup, bContext *C, + const int event_modifier, const int mval[2], int *r_part) { + int gzgroup_keymap_uses_modifier = -1; + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { if (gz->type->test_select && (gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) { + + if (!wm_gizmo_keymap_uses_event_modifier( + wm, gzgroup, gz, event_modifier, &gzgroup_keymap_uses_modifier)) { + continue; + } + if ((*r_part = gz->type->test_select(C, gz, mval)) != -1) { return gz; } @@ -188,14 +222,23 @@ wmGizmo *wm_gizmogroup_find_intersected_gizmo(const wmGizmoGroup *gzgroup, * Adds all gizmos of \a gzgroup that can be selected to the head of \a listbase. * Added items need freeing! */ -void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup, +void wm_gizmogroup_intersectable_gizmos_to_list(wmWindowManager *wm, + const wmGizmoGroup *gzgroup, + const int event_modifier, BLI_Buffer *visible_gizmos) { + int gzgroup_keymap_uses_modifier = -1; for (wmGizmo *gz = gzgroup->gizmos.last; gz; gz = gz->prev) { if ((gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) { if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) && (gz->type->draw_select || gz->type->test_select)) || ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select)) { + + if (!wm_gizmo_keymap_uses_event_modifier( + wm, gzgroup, gz, event_modifier, &gzgroup_keymap_uses_modifier)) { + continue; + } + BLI_buffer_append(visible_gizmos, wmGizmo *, gz); } } diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h index 9874b0e12af..2a0233d79b1 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h @@ -61,11 +61,15 @@ struct wmGizmoGroup *wm_gizmogroup_new_from_type(struct wmGizmoMap *gzmap, struct wmGizmoGroupType *gzgt); void wm_gizmogroup_free(bContext *C, struct wmGizmoGroup *gzgroup); void wm_gizmogroup_gizmo_register(struct wmGizmoGroup *gzgroup, struct wmGizmo *gz); -struct wmGizmo *wm_gizmogroup_find_intersected_gizmo(const struct wmGizmoGroup *gzgroup, +struct wmGizmo *wm_gizmogroup_find_intersected_gizmo(wmWindowManager *wm, + const struct wmGizmoGroup *gzgroup, struct bContext *C, + const int event_modifier, const int mval[2], int *r_part); -void wm_gizmogroup_intersectable_gizmos_to_list(const struct wmGizmoGroup *gzgroup, +void wm_gizmogroup_intersectable_gizmos_to_list(wmWindowManager *wm, + const struct wmGizmoGroup *gzgroup, + const int event_modifier, struct BLI_Buffer *visible_gizmos); bool wm_gizmogroup_is_visible_in_drawstep(const struct wmGizmoGroup *gzgroup, const eWM_GizmoFlagMapDrawStep drawstep); diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 56de2202731..20fe9728be7 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -679,6 +679,7 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap, const wmEvent *event, int *r_part) { + wmWindowManager *wm = CTX_wm_manager(C); wmGizmo *gz = NULL; BLI_buffer_declare_static(wmGizmo *, visible_3d_gizmos, BLI_BUFFER_NOP, 128); bool do_step[WM_GIZMOMAP_DRAWSTEP_MAX]; @@ -696,6 +697,8 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap, do_step[i] = WM_gizmo_context_check_drawstep(C, i); } + const int event_modifier = WM_event_modifier_flag(event); + for (wmGizmoGroup *gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { /* If it were important we could initialize here, @@ -721,10 +724,12 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap, /* cleared below */ } if (step == WM_GIZMOMAP_DRAWSTEP_3D) { - wm_gizmogroup_intersectable_gizmos_to_list(gzgroup, &visible_3d_gizmos); + wm_gizmogroup_intersectable_gizmos_to_list( + wm, gzgroup, event_modifier, &visible_3d_gizmos); } else if (step == WM_GIZMOMAP_DRAWSTEP_2D) { - if ((gz = wm_gizmogroup_find_intersected_gizmo(gzgroup, C, mval, r_part))) { + if ((gz = wm_gizmogroup_find_intersected_gizmo( + wm, gzgroup, C, event_modifier, mval, r_part))) { break; } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 3312d402d2d..51b2ca6a3d0 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -732,6 +732,24 @@ void WM_operator_region_active_win_set(bContext *C) } } +int WM_event_modifier_flag(const wmEvent *event) +{ + int flag = 0; + if (event->ctrl) { + flag |= KM_CTRL; + } + if (event->alt) { + flag |= KM_ALT; + } + if (event->shift) { + flag |= KM_SHIFT; + } + if (event->oskey) { + flag |= KM_OSKEY; + } + return flag; +} + /* for debugging only, getting inspecting events manually is tedious */ void WM_event_print(const wmEvent *event) { @@ -2724,14 +2742,16 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers /* Drag events use the previous click location to highlight the gizmos, * Get the highlight again in case the user dragged off the gizmo. */ const bool is_event_drag = ISTWEAK(event->type) || (event->val == KM_CLICK_DRAG); + const bool is_event_modifier = ISKEYMODIFIER(event->type); bool handle_highlight = false; bool handle_keymap = false; /* handle gizmo highlighting */ - if (!wm_gizmomap_modal_get(gzmap) && ((event->type == MOUSEMOVE) || is_event_drag)) { + if (!wm_gizmomap_modal_get(gzmap) && + ((event->type == MOUSEMOVE) || is_event_modifier || is_event_drag)) { handle_highlight = true; - if (is_event_drag) { + if (is_event_modifier || is_event_drag) { handle_keymap = true; } } diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c index 626e9e88845..4603f14729d 100644 --- a/source/blender/windowmanager/intern/wm_keymap_utils.c +++ b/source/blender/windowmanager/intern/wm_keymap_utils.c @@ -451,6 +451,46 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) return km; } +static bool wm_keymap_item_uses_modifier(wmKeyMapItem *kmi, const int event_modifier) +{ + if (kmi->ctrl != KM_ANY) { + if ((kmi->ctrl == KM_NOTHING) != ((event_modifier & KM_CTRL) == 0)) { + return false; + } + } + + if (kmi->alt != KM_ANY) { + if ((kmi->alt == KM_NOTHING) != ((event_modifier & KM_ALT) == 0)) { + return false; + } + } + + if (kmi->shift != KM_ANY) { + if ((kmi->shift == KM_NOTHING) != ((event_modifier & KM_SHIFT) == 0)) { + return false; + } + } + + if (kmi->oskey != KM_ANY) { + if ((kmi->oskey == KM_NOTHING) != ((event_modifier & KM_OSKEY) == 0)) { + return false; + } + } + return true; +} + +bool WM_keymap_uses_event_modifier(wmKeyMap *keymap, const int event_modifier) +{ + for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { + if ((kmi->flag & KMI_INACTIVE) == 0) { + if (wm_keymap_item_uses_modifier(kmi, event_modifier)) { + return true; + } + } + } + return false; +} + void WM_keymap_fix_linking(void) { } |