Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-12-11 23:54:10 +0300
committerJulian Eisel <julian@blender.org>2020-12-12 01:08:29 +0300
commitaf008f553293d91ef624ab4950e6d5dcc91650fe (patch)
tree75bb105b579be7a6e9286972a337e87a7afb8724 /source/blender/editors
parentba83ad226d8c3b3d1a87ebbb13aacf5cfc27edfc (diff)
UI: Allow Outliners to pass selected data-blocks to operators via context
The way the Outliner integrates operations on selected tree elements is known to be quite problematic amongst developers. The context menu is generated in an unusual way and doesn't use the normal operator system. Instead, changes are applied via a recursive callback system. Things are quite ad-hoc, and the callbacks often implement logic that should not be in the Outliner, but in entirely different modules. Often these modules already contain the logic, but as proper operators. This commit is a step into a hopefully better direction that should allow us to put actual operators into Outliner context menus. It starts solving the problem of: How can the Outliner pass selected data to operators. It implements it for data-blocks only, but other data could do it in the same way. Idea is to keep doing what operators were initially designed to do: Operate on context. Operators can now query a "selected_ids" context member (`CTX_data_selected_ids()` in C, `bpy.context.selected_ids` in .py). If an Outliner is active, it will generate a list of selected data-blocks as a response, via its `SpaceType.context` callback. Any other editor could do the same. No user visible changes. This new design isn't actually used yet. It will be soon for asset operators. Reviewed as part of https://developer.blender.org/D9717. Reviewed by: Brecht Van Lommel
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_outliner/outliner_context.c73
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h7
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c1
4 files changed, 82 insertions, 0 deletions
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 8e989f5568e..e0262371559 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -34,6 +34,7 @@ set(INC
set(SRC
outliner_collections.c
+ outliner_context.c
outliner_dragdrop.c
outliner_draw.c
outliner_edit.c
diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c
new file mode 100644
index 00000000000..760fa8e4604
--- /dev/null
+++ b/source/blender/editors/space_outliner/outliner_context.c
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2017 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+
+#include "DNA_space_types.h"
+
+#include "RNA_access.h"
+
+#include "outliner_intern.h"
+
+static void outliner_context_selected_ids_recursive(const ListBase *subtree,
+ bContextDataResult *result)
+{
+ LISTBASE_FOREACH (const TreeElement *, te, subtree) {
+ const TreeStoreElem *tse = TREESTORE(te);
+ if ((tse->flag & TSE_SELECTED) && (ELEM(tse->type, 0, TSE_LAYER_COLLECTION))) {
+ CTX_data_id_list_add(result, tse->id);
+ }
+ outliner_context_selected_ids_recursive(&te->subtree, result);
+ }
+}
+
+static void outliner_context_selected_ids(const SpaceOutliner *space_outliner,
+ bContextDataResult *result)
+{
+ outliner_context_selected_ids_recursive(&space_outliner->tree, result);
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+}
+
+const char *outliner_context_dir[] = {"selected_ids", NULL};
+
+int /*eContextResult*/ outliner_context(const bContext *C,
+ const char *member,
+ bContextDataResult *result)
+{
+ SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
+
+ if (CTX_data_dir(member)) {
+ CTX_data_dir_set(result, outliner_context_dir);
+ return CTX_RESULT_OK;
+ }
+ else if (CTX_data_equals(member, "selected_ids")) {
+ outliner_context_selected_ids(space_outliner, result);
+ return CTX_RESULT_OK;
+ }
+ /* Note: Querying non-ID selection could also work if tree elements stored their matching RNA
+ * struct type. */
+
+ return CTX_RESULT_MEMBER_NOT_FOUND;
+}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 0294b4836c8..ccb481197e4 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -32,6 +32,7 @@ extern "C" {
/* internal exports only */
struct ARegion;
+struct bContextDataResult;
struct EditBone;
struct ID;
struct ListBase;
@@ -561,6 +562,12 @@ void outliner_tag_redraw_avoid_rebuild_on_open_change(const struct SpaceOutliner
void outliner_sync_selection(const struct bContext *C, struct SpaceOutliner *space_outliner);
+/* outliner_context.c ------------------------------------------- */
+
+int outliner_context(const struct bContext *C,
+ const char *member,
+ struct bContextDataResult *result);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 3d675fdd9e4..c7c207caca0 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -451,6 +451,7 @@ void ED_spacetype_outliner(void)
st->dropboxes = outliner_dropboxes;
st->id_remap = outliner_id_remap;
st->deactivate = outliner_deactivate;
+ st->context = outliner_context;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");