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/util | |
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/util')
-rw-r--r-- | source/blender/editors/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/util/ed_util.c | 21 | ||||
-rw-r--r-- | source/blender/editors/util/ed_util_ops.c | 155 |
3 files changed, 156 insertions, 21 deletions
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index bbaf5d5475a..0aab3810254 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -39,6 +39,7 @@ set(SRC ed_transverts.c ed_util.c ed_util_imbuf.c + ed_util_ops.c gizmo_utils.c numinput.c select_utils.c diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index d78758dcc1c..5d2584c566d 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -485,27 +485,6 @@ void ED_spacedata_id_remap(struct ScrArea *area, struct SpaceLink *sl, ID *old_i } } -static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main *bmain = CTX_data_main(C); - ED_editors_flush_edits(bmain); - return OPERATOR_FINISHED; -} - -void ED_OT_flush_edits(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Flush Edits"; - ot->description = "Flush edit data from active editing modes"; - ot->idname = "ED_OT_flush_edits"; - - /* api callbacks */ - ot->exec = ed_flush_edits_exec; - - /* flags */ - ot->flag = OPTYPE_INTERNAL; -} - static bool lib_id_preview_editing_poll(bContext *C) { const PointerRNA idptr = CTX_data_pointer_get(C, "id"); diff --git a/source/blender/editors/util/ed_util_ops.c b/source/blender/editors/util/ed_util_ops.c new file mode 100644 index 00000000000..d8d1a64c1ee --- /dev/null +++ b/source/blender/editors/util/ed_util_ops.c @@ -0,0 +1,155 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup edutil + * + * Utility operators for UI data or for the UI to use. + */ + +#include <string.h> + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" +#include "BKE_report.h" + +#include "DNA_windowmanager_types.h" + +#include "ED_util.h" + +#include "RNA_access.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +static int lib_fake_user_toggle_exec(bContext *C, wmOperator *op) +{ + PropertyPointerRNA pprop; + PointerRNA idptr = PointerRNA_NULL; + + UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop); + + if (pprop.prop) { + idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop); + } + + if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) { + BKE_report( + op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling"); + return OPERATOR_CANCELLED; + } + + ID *id = idptr.data; + + if ((id->lib != NULL) || (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) { + BKE_report(op->reports, RPT_ERROR, "Data-block type does not support fake user"); + return OPERATOR_CANCELLED; + } + + if (ID_FAKE_USERS(id)) { + id_fake_user_clear(id); + } + else { + id_fake_user_set(id); + } + + return OPERATOR_FINISHED; +} + +static void ED_OT_lib_fake_user_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle Fake User"; + ot->description = "Save this data-block even if it has no users"; + ot->idname = "ED_OT_lib_fake_user_toggle"; + + /* api callbacks */ + ot->exec = lib_fake_user_toggle_exec; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL; +} + +static int lib_unlink_exec(bContext *C, wmOperator *op) +{ + PropertyPointerRNA pprop; + PointerRNA idptr; + + UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop); + + if (pprop.prop) { + idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop); + } + + if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) { + BKE_report( + op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling"); + return OPERATOR_CANCELLED; + } + + memset(&idptr, 0, sizeof(idptr)); + RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, NULL); + RNA_property_update(C, &pprop.ptr, pprop.prop); + + return OPERATOR_FINISHED; +} + +static void ED_OT_lib_unlink(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unlink Data-Block"; + ot->description = "Remove a usage of a data-block, clearing the assignment"; + ot->idname = "ED_OT_lib_unlink"; + + /* api callbacks */ + ot->exec = lib_unlink_exec; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL; +} + +static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + ED_editors_flush_edits(bmain); + return OPERATOR_FINISHED; +} + +static void ED_OT_flush_edits(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Flush Edits"; + ot->description = "Flush edit data from active editing modes"; + ot->idname = "ED_OT_flush_edits"; + + /* api callbacks */ + ot->exec = ed_flush_edits_exec; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; +} + +void ED_operatortypes_edutils(void) +{ + WM_operatortype_append(ED_OT_lib_fake_user_toggle); + WM_operatortype_append(ED_OT_lib_unlink); + WM_operatortype_append(ED_OT_flush_edits); +} |