Blender V5.0
asset_shelf_catalog_selector.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "AS_asset_catalog.hh"
13
14#include "BLI_string_utf8.h"
15
16#include "DNA_screen_types.h"
17
18#include "BLI_listbase.h"
19
20#include "BKE_context.hh"
21#include "BKE_screen.hh"
22
23#include "BLT_translation.hh"
24
25#include "ED_asset_filter.hh"
26#include "ED_asset_list.hh"
27
28#include "RNA_access.hh"
29#include "RNA_prototypes.hh"
30
31#include "UI_interface.hh"
33#include "UI_tree_view.hh"
34
35#include "WM_api.hh"
36
37#include "asset_shelf.hh"
38
40
42 AssetShelf &shelf_;
43 AssetShelfSettings &shelf_settings_;
45
46 public:
47 class Item;
48
50 : shelf_(shelf), shelf_settings_(shelf_.settings)
51 {
52 catalog_tree_ = build_filtered_catalog_tree(
53 library,
54 shelf_settings_.asset_library_reference,
56 return (!shelf_.type->asset_poll || shelf_.type->asset_poll(shelf_.type, &asset));
57 });
58 }
59
60 void build_tree() override
61 {
62 if (catalog_tree_.is_empty()) {
63 auto &item = add_tree_item<ui::BasicTreeViewItem>(RPT_("No applicable assets found"),
64 ICON_INFO);
65 item.disable_interaction();
66 return;
67 }
68
69 catalog_tree_.foreach_root_item(
70 [this](const asset_system::AssetCatalogTreeItem &catalog_item) {
71 Item &item = build_catalog_items_recursive(*this, catalog_item);
73 });
74 }
75
77 const asset_system::AssetCatalogTreeItem &catalog_item) const
78 {
79 Item &view_item = parent_view_item.add_tree_item<Item>(catalog_item, shelf_);
80
81 const int parent_count = view_item.count_parents() + 1;
82 catalog_item.foreach_child([&, this](const asset_system::AssetCatalogTreeItem &child) {
83 Item &child_item = build_catalog_items_recursive(view_item, child);
84
85 /* Uncollapse to some level (gives quick access, but don't let the tree get too big). */
86 if (parent_count < 2) {
87 child_item.uncollapse_by_default();
88 }
89 });
90
91 return view_item;
92 }
93
95
96 class Item : public ui::BasicTreeViewItem {
97 const asset_system::AssetCatalogTreeItem &catalog_item_;
98 /* Is the catalog path enabled in this redraw? Set on construction, updated by the UI (which
99 * gets a pointer to it). The UI needs it as char. */
100 char catalog_path_enabled_ = false;
101
102 public:
104 : ui::BasicTreeViewItem(catalog_item.get_name()),
105 catalog_item_(catalog_item),
106 catalog_path_enabled_(
108 {
110 }
111
113 {
114 return catalog_path_enabled_ != 0;
115 }
116
118 {
119 bool has_enabled = false;
120
122 [&has_enabled](const ui::AbstractTreeViewItem &abstract_item) {
123 const Item &item = dynamic_cast<const Item &>(abstract_item);
124 if (item.is_catalog_path_enabled()) {
125 has_enabled = true;
126 }
127 },
129
130 return has_enabled;
131 }
132
134 {
135 return catalog_item_.catalog_path();
136 }
137
138 void build_row(uiLayout &row) override
139 {
141 uiBlock *block = row.block();
142
144
145 uiLayout *subrow = &row.row(false);
146 subrow->active_set(catalog_path_enabled_);
147 subrow->label(catalog_item_.get_name(), ICON_NONE);
148 ui::block_layout_set_current(block, &row);
149
150 uiBut *toggle_but = uiDefButC(block,
152 0,
153 "",
154 0,
155 0,
156 UI_UNIT_X,
157 UI_UNIT_Y,
158 &catalog_path_enabled_,
159 0,
160 0,
161 TIP_("Toggle catalog visibility in the asset shelf"));
162 UI_but_func_set(toggle_but, [&tree](bContext &C) {
163 tree.update_shelf_settings_from_enabled_catalogs();
165 });
168 }
169 UI_but_flag_disable(toggle_but, UI_BUT_UNDO);
170 }
171 };
172};
173
175{
177 foreach_item([this](ui::AbstractTreeViewItem &view_item) {
178 const auto &selector_tree_item = dynamic_cast<AssetCatalogSelectorTree::Item &>(view_item);
179 if (selector_tree_item.is_catalog_path_enabled()) {
180 settings_set_catalog_path_enabled(shelf_, selector_tree_item.catalog_path());
181 }
182 });
183}
184
186{
188
190 &CTX_wm_screen(C)->id, &RNA_AssetShelf, &shelf);
191
192 uiLayout *row = &layout->row(true);
193 row->prop(&shelf_ptr, "asset_library_reference", UI_ITEM_NONE, "", ICON_NONE);
194 if (shelf.settings.asset_library_reference.type != ASSET_LIBRARY_LOCAL) {
195 row->op("ASSET_OT_library_refresh", "", ICON_FILE_REFRESH);
196 }
197}
198
199static void catalog_selector_panel_draw(const bContext *C, Panel *panel)
200{
202 if (!shelf) {
203 return;
204 }
205
206 uiLayout *layout = panel->layout;
207
208 library_selector_draw(C, layout, *shelf);
209
211 shelf->settings.asset_library_reference);
212 if (!library) {
213 return;
214 }
215
216 uiBlock *block = layout->block();
218 *block,
219 "asset catalog tree view",
220 std::make_unique<AssetCatalogSelectorTree>(*library, *shelf));
221 tree_view->set_context_menu_title("Catalog");
222 ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
223}
224
226{
227 /* Uses global paneltype registry to allow usage as popover. So only register this once (may be
228 * called from multiple spaces). */
229 if (WM_paneltype_find("ASSETSHELF_PT_catalog_selector", true)) {
230 return;
231 }
232
233 PanelType *pt = MEM_callocN<PanelType>(__func__);
234 STRNCPY_UTF8(pt->idname, "ASSETSHELF_PT_catalog_selector");
235 STRNCPY_UTF8(pt->label, N_("Catalog Selector"));
237 pt->description = N_(
238 "Select the asset library and the contained catalogs to display in the asset shelf");
241 BLI_addtail(&region_type->paneltypes, pt);
243}
244
245} // namespace blender::ed::asset::shelf
bScreen * CTX_wm_screen(const bContext *C)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
#define STRNCPY_UTF8(dst, src)
#define RPT_(msgid)
#define TIP_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
@ ASSET_LIBRARY_LOCAL
#define C
Definition RandGen.cpp:29
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
blender::ui::AbstractGridView * UI_block_add_view(uiBlock &block, blender::StringRef idname, std::unique_ptr< blender::ui::AbstractGridView > grid_view)
void UI_but_flag_disable(uiBut *but, int flag)
#define UI_UNIT_Y
@ UI_BUT_UNDO
void UI_but_drawflag_enable(uiBut *but, int flag)
#define UI_UNIT_X
@ UI_BUT_INDETERMINATE
uiBut * uiDefButC(uiBlock *block, ButType type, int retval, blender::StringRef str, int x, int y, short width, short height, char *poin, float min, float max, std::optional< blender::StringRef > tip)
#define UI_ITEM_NONE
void foreach_child(ItemIterFn callback) const
Item(const asset_system::AssetCatalogTreeItem &catalog_item, AssetShelf &shelf)
Item & build_catalog_items_recursive(ui::TreeViewOrItem &parent_view_item, const asset_system::AssetCatalogTreeItem &catalog_item) const
AssetCatalogSelectorTree(asset_system::AssetLibrary &library, AssetShelf &shelf)
Abstract base class for defining a customizable tree-view item.
AbstractTreeView & get_tree_view() const
Definition tree_view.cc:644
void foreach_item(ItemIterFn iter_fn, IterOptions options=IterOptions::None) const
Definition tree_view.cc:110
void set_context_menu_title(const std::string &title)
BasicTreeViewItem(StringRef label, BIFIconID icon=ICON_NONE)
static void build_tree_view(const bContext &C, AbstractTreeView &tree_view, uiLayout &layout, bool add_box=true)
ItemT & add_tree_item(Args &&...args)
void foreach_item_recursive(ItemIterFn iter_fn, IterOptions options=IterOptions::None) const
Definition tree_view.cc:74
KDTree_3d * tree
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
asset_system::AssetLibrary * library_get_once_available(const AssetLibraryReference &library_reference)
void asset_reading_region_listen_fn(const wmRegionListenerParams *params)
static void catalog_selector_panel_draw(const bContext *C, Panel *panel)
void settings_clear_enabled_catalogs(AssetShelf &shelf)
void library_selector_draw(const bContext *C, uiLayout *layout, AssetShelf &shelf)
void catalog_selector_panel_register(ARegionType *region_type)
AssetShelf * active_shelf_from_context(const bContext *C)
bool settings_is_catalog_path_enabled(const AssetShelf &shelf, const asset_system::AssetCatalogPath &path)
void send_redraw_notifier(const bContext &C)
void settings_set_catalog_path_enabled(AssetShelf &shelf, const asset_system::AssetCatalogPath &path)
asset_system::AssetCatalogTree build_filtered_catalog_tree(const asset_system::AssetLibrary &library, const AssetLibraryReference &library_ref, blender::FunctionRef< bool(const asset_system::AssetRepresentation &)> is_asset_visible_fn)
TreeViewItemContainer TreeViewOrItem
void block_layout_set_current(uiBlock *block, uiLayout *layout)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
ListBase paneltypes
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
void(* listener)(const wmRegionListenerParams *params)
char translation_context[BKE_ST_MAXNAME]
char label[BKE_ST_MAXNAME]
const char * description
struct uiLayout * layout
uiBlock * block() const
void operator_context_set(blender::wm::OpCallContext opcontext)
void label(blender::StringRef name, int icon)
void active_set(bool active)
uiLayout & row(bool align)
void emboss_set(blender::ui::EmbossType emboss)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
#define N_(msgid)
bool WM_paneltype_add(PanelType *pt)
PanelType * WM_paneltype_find(const StringRef idname, bool quiet)