UI: Support showing superimposed icons as disabled (with disabled hint)

If the operator poll of a superimposed icon returned `false`, the
superimposed icon would just draw normally and fail silently. Instead it
will now be drawn grayed out, plus the tooltip of the icon can show the
usual "disabled hint" (a hint explaining why the button is disabled).
This commit is contained in:
Julian Eisel 2021-10-08 16:17:29 +02:00
parent 38c4888f09
commit ff57ce8617
Notes: blender-bot 2023-02-14 06:55:40 +01:00
Referenced by issue #97518, Regression: All properties with eyedropper in same panel get bright when any of them is hovered
4 changed files with 32 additions and 9 deletions

View File

@ -1701,6 +1701,7 @@ static PointerRNA *ui_but_extra_operator_icon_add_ptr(uiBut *but,
extra_op_icon->optype_params->optype);
extra_op_icon->optype_params->opcontext = opcontext;
extra_op_icon->highlighted = false;
extra_op_icon->disabled = false;
BLI_addtail(&but->extra_op_icons, extra_op_icon);
@ -1905,18 +1906,19 @@ static void ui_but_validate(const uiBut *but)
/**
* Check if the operator \a ot poll is successful with the context given by \a but (optionally).
* \param but: The button that might store context. Can be NULL for convenience (e.g. if there is
* no button to take context from, but we still want to poll the operator).
* no button to take context from, but we still want to poll the operator).
*/
bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *but)
bool ui_but_context_poll_operator_ex(bContext *C,
const uiBut *but,
const wmOperatorCallParams *optype_params)
{
bool result;
int opcontext = but ? but->opcontext : WM_OP_INVOKE_DEFAULT;
if (but && but->context) {
CTX_store_set(C, but->context);
}
result = WM_operator_poll_context(C, ot, opcontext);
result = WM_operator_poll_context(C, optype_params->optype, optype_params->opcontext);
if (but && but->context) {
CTX_store_set(C, NULL);
@ -1925,6 +1927,13 @@ bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *
return result;
}
bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *but)
{
const int opcontext = but ? but->opcontext : WM_OP_INVOKE_DEFAULT;
return ui_but_context_poll_operator_ex(
C, but, &(wmOperatorCallParams){.optype = ot, .opcontext = opcontext});
}
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
{
wmWindow *window = CTX_wm_window(C);
@ -1955,6 +1964,12 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
}
}
LISTBASE_FOREACH (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
if (!ui_but_context_poll_operator_ex((bContext *)C, but, op_icon->optype_params)) {
op_icon->disabled = true;
}
}
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
depsgraph, (scene) ? scene->r.cfra : 0.0f);
ui_but_anim_flag(but, &anim_eval_context);

View File

@ -407,6 +407,7 @@ typedef struct uiButExtraOpIcon {
struct wmOperatorCallParams *optype_params;
bool highlighted;
bool disabled;
} uiButExtraOpIcon;
typedef struct ColorPicker {
@ -694,6 +695,9 @@ void ui_but_range_set_hard(uiBut *but);
void ui_but_range_set_soft(uiBut *but);
bool ui_but_context_poll_operator(struct bContext *C, struct wmOperatorType *ot, const uiBut *but);
bool ui_but_context_poll_operator_ex(struct bContext *C,
const uiBut *but,
const struct wmOperatorCallParams *optype_params);
extern void ui_but_update(uiBut *but);
extern void ui_but_update_edited(uiBut *but);

View File

@ -954,18 +954,19 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
}
/* button is disabled, we may be able to tell user why */
if (but->flag & UI_BUT_DISABLED) {
if ((but->flag & UI_BUT_DISABLED) || extra_icon) {
const char *disabled_msg = NULL;
bool disabled_msg_free = false;
/* if operator poll check failed, it can give pretty precise info why */
if (but->optype) {
if (optype) {
CTX_wm_operator_poll_msg_clear(C);
WM_operator_poll_context(C, but->optype, but->opcontext);
WM_operator_poll_context(
C, optype, extra_icon ? extra_icon->optype_params->opcontext : but->opcontext);
disabled_msg = CTX_wm_operator_poll_msg_get(C, &disabled_msg_free);
}
/* alternatively, buttons can store some reasoning too */
else if (but->disabled_info) {
else if (!extra_icon && but->disabled_info) {
disabled_msg = TIP_(but->disabled_info);
}

View File

@ -2263,7 +2263,10 @@ static void widget_draw_extra_icons(const uiWidgetColors *wcol,
temp.xmin = temp.xmax - icon_size;
if (!op_icon->highlighted) {
if (op_icon->disabled) {
alpha_this *= 0.4f;
}
else if (!op_icon->highlighted) {
alpha_this *= 0.75f;
}