diff options
author | Julian Eisel <julian@blender.org> | 2020-12-18 20:12:11 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-12-18 20:28:04 +0300 |
commit | 2250b5cefee7f7cce31e388cb83515543ffe60f0 (patch) | |
tree | cbac53205d453f4b1c7ec221b6377a672d9eaa09 /source/blender/editors/interface/interface.c | |
parent | 7bee1489c1d81ecf2634df96ba039549c64313c3 (diff) |
UI: Redesigned data-block selectors
The previous design is rather old and has a couple of problems:
* Scalability: The current solution of adding little icon buttons next to the
data-block name field doesn't scale well. It only works if there's a small
number of operations. We need to be able to place more items there for better
data-block management. Especially with the introduction of library overrides.
* Discoverability: It's not obvious what some of the icons do. They appear and
disappear, but it's not obvious why some are available at times and others
not.
* Unclear Status: Currently their library status (linked, indirectly linked,
broken link, library override) isn't really clear.
* Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to
invoke alternative behaviors. This is not a usual pattern in Blender.
This patch does the following changes:
* Adds a menu to the right of the name button to access all kinds of operations
(create, delete, unlink, user management, library overrides, etc).
* Make good use of the "disabled hint" for tooltips, to explain why buttons are
disabled. The UI team wants to establish this as a good practise.
* Use superimposed icons for duplicate and unlink, rather than extra buttons
(uses less space, looks less distracting and is a nice + consistent design
language).
* Remove fake user and user count button, they are available from the menu now.
* Support tooltips for superimposed icons (committed mouse hover feedback to
master already).
* Slightly increase size of the name button - it was already a bit small
before, and the move from real buttons to superimposed icons reduces usable
space for the name itself.
* More clearly differentiate between duplicate and creating a new data-block.
The latter is only available in the menu.
* Display library status icon on the left (linked, missing library, overridden,
asset)
* Disables "Make Single User" button - in review we weren't sure if there are
good use-cases for it, so better to see if we can remove it.
Note that I do expect some aspects of this design to change still. I think some
changes are problematic, but others disagreed. I will open a feedback thread on
devtalk to see what others think.
Differential Revision: https://developer.blender.org/D8554
Reviewed by: Bastien Montagne
Design discussed and agreed on with the UI team, also see T79959.
Diffstat (limited to 'source/blender/editors/interface/interface.c')
-rw-r--r-- | source/blender/editors/interface/interface.c | 143 |
1 files changed, 86 insertions, 57 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index c5c2f0e55c4..26fd75cc74c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1167,16 +1167,21 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str * \{ */ static bool ui_but_event_operator_string_from_operator(const bContext *C, - uiBut *but, + wmOperatorCallParams *op_call_params, char *buf, const size_t buf_len) { - BLI_assert(but->optype != NULL); + BLI_assert(op_call_params->optype != NULL); bool found = false; - IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; - - if (WM_key_event_operator_string( - C, but->optype->idname, but->opcontext, prop, true, buf, buf_len)) { + IDProperty *prop = (op_call_params->opptr) ? op_call_params->opptr->data : NULL; + + if (WM_key_event_operator_string(C, + op_call_params->optype->idname, + op_call_params->opcontext, + prop, + true, + buf, + buf_len)) { found = true; } return found; @@ -1253,15 +1258,22 @@ static bool ui_but_event_operator_string_from_panel(const bContext *C, return found; } -static bool ui_but_event_operator_string(const bContext *C, - uiBut *but, - char *buf, - const size_t buf_len) +static bool ui_but_event_operator_string( + const bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon, char *buf, const size_t buf_len) { bool found = false; + wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon); - if (but->optype != NULL) { - found = ui_but_event_operator_string_from_operator(C, but, buf, buf_len); + if (extra_icon_optype) { + found = ui_but_event_operator_string_from_operator(C, extra_icon->optype_params, buf, buf_len); + } + else if (but->optype != NULL) { + found = ui_but_event_operator_string_from_operator( + C, + &(wmOperatorCallParams){ + .optype = but->optype, .opptr = but->opptr, .opcontext = but->opcontext}, + buf, + buf_len); } else if (UI_but_menutype_get(but) != NULL) { found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len); @@ -1564,7 +1576,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) continue; } - if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { + if (ui_but_event_operator_string(C, but, NULL, buf, sizeof(buf))) { ui_but_add_shortcut(but, buf, false); } else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { @@ -1605,12 +1617,12 @@ typedef enum PredefinedExtraOpIconType { PREDEFINED_EXTRA_OP_ICON_EYEDROPPER, } PredefinedExtraOpIconType; -static PointerRNA *ui_but_extra_operator_icon_add_ptr(uiBut *but, - wmOperatorType *optype, - short opcontext, - int icon) +static uiButExtraOpIcon *ui_but_extra_operator_icon_add_ptr(uiBut *but, + wmOperatorType *optype, + short opcontext, + int icon) { - uiButExtraOpIcon *extra_op_icon = MEM_mallocN(sizeof(*extra_op_icon), __func__); + uiButExtraOpIcon *extra_op_icon = MEM_callocN(sizeof(*extra_op_icon), __func__); extra_op_icon->icon = (BIFIconID)icon; extra_op_icon->optype_params = MEM_callocN(sizeof(*extra_op_icon->optype_params), @@ -1625,13 +1637,15 @@ static PointerRNA *ui_but_extra_operator_icon_add_ptr(uiBut *but, BLI_addtail(&but->extra_op_icons, extra_op_icon); - return extra_op_icon->optype_params->opptr; + return extra_op_icon; } static void ui_but_extra_operator_icon_free(uiButExtraOpIcon *extra_icon) { - WM_operator_properties_free(extra_icon->optype_params->opptr); - MEM_freeN(extra_icon->optype_params->opptr); + if (extra_icon->optype_params->opptr) { + WM_operator_properties_free(extra_icon->optype_params->opptr); + MEM_freeN(extra_icon->optype_params->opptr); + } MEM_freeN(extra_icon->optype_params); MEM_freeN(extra_icon); } @@ -1644,18 +1658,25 @@ void ui_but_extra_operator_icons_free(uiBut *but) BLI_listbase_clear(&but->extra_op_icons); } -PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, - const char *opname, - short opcontext, - int icon) +uiButExtraOpIcon *UI_but_extra_operator_icon_add(uiBut *but, + const char *opname, + short opcontext, + int icon) { wmOperatorType *optype = WM_operatortype_find(opname, false); - if (optype) { - return ui_but_extra_operator_icon_add_ptr(but, optype, opcontext, icon); - } + BLI_assert(optype); + return ui_but_extra_operator_icon_add_ptr(but, optype, opcontext, icon); +} - return NULL; +PointerRNA *UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon) +{ + return extra_icon->optype_params->opptr; +} + +wmOperatorType *UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon) +{ + return extra_icon ? extra_icon->optype_params->optype : NULL; } static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but) @@ -6818,7 +6839,7 @@ void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN) but->hold_argN = argN; } -void UI_but_string_info_get(bContext *C, uiBut *but, ...) +void UI_but_string_info_get(bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon, ...) { va_list args; uiStringInfo *si; @@ -6827,13 +6848,19 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) int totitems; bool free_items = false; - va_start(args, but); + wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon); + wmOperatorType *optype = extra_icon ? extra_icon_optype : but->optype; + + /* Don't query RNA data when the extra-icon overrides the button. */ + PropertyRNA *rnaprop = extra_icon ? NULL : but->rnaprop; + + va_start(args, extra_icon); while ((si = (uiStringInfo *)va_arg(args, void *))) { uiStringInfoType type = si->type; char *tmp = NULL; if (type == BUT_GET_LABEL) { - if (but->str && but->str[0]) { + if (but->str && but->str[0] && !extra_icon) { const char *str_sep; size_t str_len; @@ -6863,16 +6890,16 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } if (type == BUT_GET_RNAPROP_IDENTIFIER) { - if (but->rnaprop) { - tmp = BLI_strdup(RNA_property_identifier(but->rnaprop)); + if (rnaprop) { + tmp = BLI_strdup(RNA_property_identifier(rnaprop)); } } else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) { - if (but->rnaprop && but->rnapoin.data) { + if (rnaprop && but->rnapoin.data) { tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type)); } - else if (but->optype) { - tmp = BLI_strdup(but->optype->idname); + else if (optype) { + tmp = BLI_strdup(optype->idname); } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { MenuType *mt = UI_but_menutype_get(but); @@ -6888,23 +6915,25 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) { - if (but->rnaprop) { + if (rnaprop) { if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(RNA_property_ui_name(but->rnaprop)); + tmp = BLI_strdup(RNA_property_ui_name(rnaprop)); } else { - const char *t = RNA_property_ui_description(but->rnaprop); + const char *t = RNA_property_ui_description(rnaprop); if (t && t[0]) { tmp = BLI_strdup(t); } } } - else if (but->optype) { + else if (optype) { + PointerRNA *opptr = extra_icon_optype ? UI_but_extra_operator_icon_opptr_get(extra_icon) : + but->opptr; if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(WM_operatortype_name(but->optype, but->opptr)); + tmp = BLI_strdup(WM_operatortype_name(optype, opptr)); } else { - tmp = WM_operatortype_description(C, but->optype, but->opptr); + tmp = WM_operatortype_description(C, optype, opptr); } } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { @@ -6956,11 +6985,11 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } else if (type == BUT_GET_RNA_LABEL_CONTEXT) { const char *_tmp = BLT_I18NCONTEXT_DEFAULT; - if (but->rnaprop) { - _tmp = RNA_property_translation_context(but->rnaprop); + if (rnaprop) { + _tmp = RNA_property_translation_context(rnaprop); } - else if (but->optype) { - _tmp = RNA_struct_translation_context(but->optype->srna); + else if (optype) { + _tmp = RNA_struct_translation_context(optype->srna); } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { MenuType *mt = UI_but_menutype_get(but); @@ -6979,16 +7008,16 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) int value = 0; /* get the enum property... */ - if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { + if (rnaprop && RNA_property_type(rnaprop) == PROP_ENUM) { /* enum property */ ptr = &but->rnapoin; - prop = but->rnaprop; + prop = rnaprop; value = (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB)) ? (int)but->hardmax : (int)ui_but_value_get(but); } - else if (but->optype) { - PointerRNA *opptr = UI_but_operator_ptr_get(but); - wmOperatorType *ot = but->optype; + else if (optype) { + PointerRNA *opptr = extra_icon_optype ? UI_but_extra_operator_icon_opptr_get(extra_icon) : + UI_but_operator_ptr_get(but); /* so the context is passed to itemf functions */ WM_operator_properties_sanitize(opptr, false); @@ -6998,11 +7027,11 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) * operator menus in the Anim Editors will show tooltips for the different * operations instead of the meaningless generic operator tooltip */ - if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { - if (RNA_struct_contains_property(opptr, ot->prop)) { + if (optype->prop && RNA_property_type(optype->prop) == PROP_ENUM) { + if (RNA_struct_contains_property(opptr, optype->prop)) { ptr = opptr; - prop = ot->prop; - value = RNA_property_enum_get(opptr, ot->prop); + prop = optype->prop; + value = RNA_property_enum_get(opptr, optype->prop); } } } @@ -7035,7 +7064,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) else if (type == BUT_GET_OP_KEYMAP) { if (!ui_block_is_menu(but->block)) { char buf[128]; - if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { + if (ui_but_event_operator_string(C, but, extra_icon, buf, sizeof(buf))) { tmp = BLI_strdup(buf); } } |