[Bf-blender-cvs] [272e0770a03] asset-browser: Proper implementation of "Make Asset" for button context menus
Julian Eisel
noreply at git.blender.org
Wed Nov 25 17:21:30 CET 2020
Commit: 272e0770a032805b5675dd317882fd7f81cd76e7
Author: Julian Eisel
Date: Wed Nov 25 16:58:20 2020 +0100
Branches: asset-browser
https://developer.blender.org/rB272e0770a032805b5675dd317882fd7f81cd76e7
Proper implementation of "Make Asset" for button context menus
Buttons or other UI elements can now set a "focused_id" context pointer. The
asset operators (and in future, general data-block operators) can use this
then. Further the UI code automatically sets it when a button represents a
data-block pointer. That way, data-block search menus or data-block selectors
also show "Make Asset" in the context menu.
This also works for material slots now, the material slot you right click will
properly set the "focused_id" context pointer, and "Make Asset" makes that
material an asset.
Had to add support for using custom context pointers to context menus and
UILists.
Addresses T82664.
===================================================================
M release/scripts/startup/bl_ui/properties_material.py
M source/blender/blenkernel/BKE_context.h
M source/blender/blenkernel/intern/context.c
M source/blender/editors/asset/CMakeLists.txt
M source/blender/editors/asset/asset_edit.c
M source/blender/editors/asset/asset_ops.c
M source/blender/editors/include/ED_asset.h
M source/blender/editors/include/UI_interface.h
M source/blender/editors/interface/interface.c
M source/blender/editors/interface/interface_context_menu.c
M source/blender/editors/interface/interface_layout.c
M source/blender/editors/interface/interface_templates.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 6aaec9940e8..cd6bebfea94 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -42,6 +42,9 @@ class MATERIAL_UL_matslots(UIList):
# ob = data
slot = item
ma = slot.material
+
+ layout.context_pointer_set("focused_id", ma)
+
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if ma:
layout.prop(ma, "name", text="", emboss=False, icon_value=icon)
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index af9a95e1753..94392dd78da 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -143,8 +143,9 @@ bContext *CTX_copy(const bContext *C);
/* Stored Context */
-bContextStore *CTX_store_add(ListBase *contexts, const char *name, PointerRNA *ptr);
+bContextStore *CTX_store_add(ListBase *contexts, const char *name, const PointerRNA *ptr);
bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context);
+bContextStore *CTX_store_get(bContext *C);
void CTX_store_set(bContext *C, bContextStore *store);
bContextStore *CTX_store_copy(bContextStore *store);
void CTX_store_free(bContextStore *store);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 2e4d3d62925..65accc66084 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -123,7 +123,7 @@ void CTX_free(bContext *C)
/* store */
-bContextStore *CTX_store_add(ListBase *contexts, const char *name, PointerRNA *ptr)
+bContextStore *CTX_store_add(ListBase *contexts, const char *name, const PointerRNA *ptr)
{
/* ensure we have a context to put the entry in, if it was already used
* we have to copy the context to ensure */
@@ -178,6 +178,11 @@ bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context)
return ctx;
}
+bContextStore *CTX_store_get(bContext *C)
+{
+ return C->wm.store;
+}
+
void CTX_store_set(bContext *C, bContextStore *store)
{
C->wm.store = store;
diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt
index 8ba15208afc..63a1761b264 100644
--- a/source/blender/editors/asset/CMakeLists.txt
+++ b/source/blender/editors/asset/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
../../makesdna
../../makesrna
../../windowmanager
+ ../../../../intern/guardedalloc
)
set(INC_SYS
diff --git a/source/blender/editors/asset/asset_edit.c b/source/blender/editors/asset/asset_edit.c
index 583fc66ef40..c52e8bc7062 100644
--- a/source/blender/editors/asset/asset_edit.c
+++ b/source/blender/editors/asset/asset_edit.c
@@ -27,6 +27,8 @@
#include "UI_interface_icons.h"
+#include "RNA_access.h"
+
#include "ED_asset.h"
bool ED_asset_make_for_id(const bContext *C, ID *id)
@@ -49,3 +51,9 @@ bool ED_asset_make_for_id(const bContext *C, ID *id)
return true;
}
+
+bool ED_asset_can_make_single_from_context(const bContext *C)
+{
+ /* Context needs a "focused_id" pointer to be set for #ASSET_OT_make() to use. */
+ return CTX_data_pointer_get_type_silent(C, "focused_id", &RNA_ID).data != NULL;
+}
diff --git a/source/blender/editors/asset/asset_ops.c b/source/blender/editors/asset/asset_ops.c
index 9d14fa72f49..fcd27f3a65a 100644
--- a/source/blender/editors/asset/asset_ops.c
+++ b/source/blender/editors/asset/asset_ops.c
@@ -29,27 +29,54 @@
#include "ED_asset.h"
+#include "MEM_guardedalloc.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
+/**
+ * Return the IDs to operate on as list of #CollectionPointerLink links. Needs freeing.
+ */
+static ListBase asset_make_get_ids_from_context(const bContext *C)
+{
+ ListBase list = {0};
+
+ PointerRNA idptr = CTX_data_pointer_get_type(C, "focused_id", &RNA_ID);
+
+ if (idptr.data) {
+ CollectionPointerLink *ctx_link = MEM_callocN(sizeof(*ctx_link), __func__);
+ ctx_link->ptr = idptr;
+ BLI_addtail(&list, ctx_link);
+ }
+ else {
+ CTX_data_selected_ids(C, &list);
+ }
+
+ return list;
+}
+
static bool asset_make_poll(bContext *C)
{
+ ListBase ids = asset_make_get_ids_from_context(C);
+
int tot_selected = 0;
bool can_make_asset = false;
/* Note that this isn't entirely cheap. Iterates over entire Outliner tree and allocates a link
* for each selected item. The button only shows in the context menu though, so acceptable. */
- CTX_DATA_BEGIN (C, ID *, id, selected_ids) {
+ LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, &ids) {
+ ID *id = ctx_id->ptr.data;
+
tot_selected++;
if (!id->asset_data) {
can_make_asset = true;
break;
}
}
- CTX_DATA_END;
+ BLI_freelistN(&ids);
if (!can_make_asset) {
if (tot_selected > 0) {
@@ -66,10 +93,14 @@ static bool asset_make_poll(bContext *C)
static int asset_make_exec(bContext *C, wmOperator *op)
{
+ ListBase ids = asset_make_get_ids_from_context(C);
+
ID *last_id = NULL;
int tot_created = 0;
- CTX_DATA_BEGIN (C, ID *, id, selected_ids) {
+ LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, &ids) {
+ ID *id = ctx_id->ptr.data;
+ BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type));
if (id->asset_data) {
continue;
}
@@ -78,7 +109,7 @@ static int asset_make_exec(bContext *C, wmOperator *op)
last_id = id;
tot_created++;
}
- CTX_DATA_END;
+ BLI_freelistN(&ids);
/* User feedback. */
if (tot_created < 1) {
diff --git a/source/blender/editors/include/ED_asset.h b/source/blender/editors/include/ED_asset.h
index 7b9f5087da8..672fd80a219 100644
--- a/source/blender/editors/include/ED_asset.h
+++ b/source/blender/editors/include/ED_asset.h
@@ -27,6 +27,8 @@ extern "C" {
bool ED_asset_make_for_id(const struct bContext *C, struct ID *id);
+bool ED_asset_can_make_single_from_context(const struct bContext *C);
+
void ED_operatortypes_asset(void);
#ifdef __cplusplus
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index f11f3546f8d..77db90ef11d 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1885,6 +1885,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout);
void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv);
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr);
+struct bContextStore *uiLayoutGetContextStore(uiLayout *layout);
void uiLayoutContextCopy(uiLayout *layout, struct bContextStore *context);
struct wmOperatorType *UI_but_operatortype_get_from_enum_menu(struct uiBut *but,
PropertyRNA **r_prop);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index c8d5049edec..02224e6f029 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -4552,6 +4552,15 @@ static uiBut *ui_def_but_rna(uiBlock *block,
UI_but_disable(but, info);
}
+ if (proptype == PROP_POINTER) {
+ /* If the button shows an ID, automatically set it as focused in context so operators can
+ * access it.*/
+ const PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
+ if (pptr.data && RNA_struct_is_ID(pptr.type)) {
+ but->context = CTX_store_add(&block->contexts, "focused_id", &pptr);
+ }
+ }
+
if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) {
but->flag &= ~UI_BUT_UNDO;
}
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 82b5d0a174a..e8fb2c4fd8e 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -38,6 +38,7 @@
#include "BKE_idprop.h"
#include "BKE_screen.h"
+#include "ED_asset.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
@@ -515,6 +516,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
uiPopupMenu *pup;
uiLayout *layout;
+ bContextStore *previous_ctx = CTX_store_get(C);
{
uiStringInfo label = {BUT_GET_LABEL, NULL};
@@ -527,6 +529,11 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
if (label.strinfo) {
MEM_freeN(label.strinfo);
}
+
+ if (but->context) {
+ uiLayoutContextCopy(layout, but->context);
+ CTX_store_set(C, uiLayoutGetContextStore(layout));
+ }
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
}
@@ -957,11 +964,12 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
ui_but_menu_add_path_operators(layout, ptr, prop);
uiItemS(layout);
}
+ }
- if (RNA_struct_is_ID(but->rnapoin.type)) {
- uiItemO(layout, NULL, ICON_NONE, "ASSET_OT_make");
- uiItemS(layout);
- }
+ /* If the button reprents an id, it can set the "focused_id" context pointer. */
+ if (ED_asset_can_make_single_from_context(C)) {
+ uiItemO(layout, NULL, ICON_NONE, "ASSET_OT_make");
+ uiItemS(layout);
}
/* Pointer properties and string properties with
@@ -1227,6 +1235,10 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
}
+ if (but->context) {
+ CTX_store_set(C, previous_ctx);
+ }
+
return UI_popup_menu_end_or_cancel(C, pup);
}
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index d61e80e6505..8eb8f461a1f 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5663,6 +5663,11 @@ void uiLayoutSetContextPointer(uiLayout *layout, const char *name, PointerRNA *p
layout->context = CTX_store_add(&block->contexts, name, ptr);
}
+bContextStore *uiLayoutGetContextStore(uiLayout *layout)
+{
+ return layout->context;
+}
+
void uiLayoutContex
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list