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
This commit is contained in:
parent
2e22cfd08a
commit
13f292d10d
Notes:
blender-bot
2023-02-14 02:52:36 +01:00
Referenced by issue #63996, Click over a Gizmo to select items underneath it
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue