diff options
author | Julian Eisel <julian@blender.org> | 2022-05-13 16:55:11 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2022-05-13 16:55:11 +0300 |
commit | 4680331749aa716fe01445c473308f3ff80ec8c9 (patch) | |
tree | 6693ba80a1e4f3f1ef5c9f0b58ed9006c272ba73 /source/blender/editors/interface | |
parent | 6f3d1552936bb65bc94011ecb83ef9aaa574b0a0 (diff) |
Fix T97518: All buttons with eyedropper highlight if one is hovered
Issue is that the operator acts on the active button, and also uses that in the
poll. So the actually active button would affect the poll of a different
button. For the superimposed icons we need to be able to execute these polls
properly for non-active buttons.
This enables temporarily overriding the active button for lookups via context.
While a bit of a hack it makes sense conceptually.
Reviewed By: Campbell Barton
Maniphest Tasks: T97518
Differential Revision: https://developer.blender.org/D14880
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r-- | source/blender/editors/interface/interface.cc | 25 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 12 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 6 |
3 files changed, 38 insertions, 5 deletions
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 8774a177c7d..d6719f0aa9f 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -1861,15 +1861,32 @@ bool ui_but_context_poll_operator_ex(bContext *C, const wmOperatorCallParams *optype_params) { bool result; + int old_but_flag = 0; - if (but && but->context) { - CTX_store_set(C, but->context); + if (but) { + old_but_flag = but->flag; + + /* Temporarily make this button override the active one, in case the poll acts on the active + * button. */ + const_cast<uiBut *>(but)->flag |= UI_BUT_ACTIVE_OVERRIDE; + + if (but->context) { + CTX_store_set(C, but->context); + } } result = WM_operator_poll_context(C, optype_params->optype, optype_params->opcontext); - if (but && but->context) { - CTX_store_set(C, nullptr); + if (but) { + BLI_assert_msg((but->flag & ~UI_BUT_ACTIVE_OVERRIDE) == + (old_but_flag & ~UI_BUT_ACTIVE_OVERRIDE), + "Operator polls shouldn't change button flags"); + + const_cast<uiBut *>(but)->flag = old_but_flag; + + if (but->context) { + CTX_store_set(C, nullptr); + } } return result; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index ad354560183..3b5d8ce89f2 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -8717,13 +8717,23 @@ static uiBut *ui_context_button_active(const ARegion *region, bool (*but_check_c /* find active button */ LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { LISTBASE_FOREACH (uiBut *, but, &block->buttons) { + if (but->flag & UI_BUT_ACTIVE_OVERRIDE) { + activebut = but; + break; + } if (but->active) { activebut = but; + break; } - else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) { + if (but->flag & UI_BUT_LAST_ACTIVE) { activebut = but; + break; } } + + if (activebut) { + break; + } } if (activebut && (but_check_cb == NULL || but_check_cb(activebut))) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 7f6c568aec8..2fac7da0ecc 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -74,6 +74,12 @@ enum { UI_SELECT_DRAW = (1 << 5), /** Property search filter is active and the button does not match. */ UI_SEARCH_FILTER_NO_MATCH = (1 << 6), + + /** Temporarily override the active button for lookups in context, regions, etc. (everything + * using #ui_context_button_active()). For example, so that operators normally acting on the + * active button can be polled on non-active buttons to (e.g. for disabling). */ + UI_BUT_ACTIVE_OVERRIDE = (1 << 7), + /* WARNING: rest of #uiBut.flag in UI_interface.h */ }; |