Blender V4.5
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.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"
32#include "UI_tree_view.hh"
33
34#include "WM_api.hh"
35
36#include "asset_shelf.hh"
37
39
41 AssetShelf &shelf_;
42 AssetShelfSettings &shelf_settings_;
44
45 public:
46 class Item;
47
49 : shelf_(shelf), shelf_settings_(shelf_.settings)
50 {
51 catalog_tree_ = build_filtered_catalog_tree(
52 library,
53 shelf_settings_.asset_library_reference,
55 return (!shelf_.type->asset_poll || shelf_.type->asset_poll(shelf_.type, &asset));
56 });
57 }
58
59 void build_tree() override
60 {
61 if (catalog_tree_.is_empty()) {
62 auto &item = add_tree_item<ui::BasicTreeViewItem>(RPT_("No applicable assets found"),
63 ICON_INFO);
64 item.disable_interaction();
65 return;
66 }
67
68 catalog_tree_.foreach_root_item(
69 [this](const asset_system::AssetCatalogTreeItem &catalog_item) {
70 Item &item = build_catalog_items_recursive(*this, catalog_item);
72 });
73 }
74
76 const asset_system::AssetCatalogTreeItem &catalog_item) const
77 {
78 Item &view_item = parent_view_item.add_tree_item<Item>(catalog_item, shelf_);
79
80 const int parent_count = view_item.count_parents() + 1;
81 catalog_item.foreach_child([&, this](const asset_system::AssetCatalogTreeItem &child) {
82 Item &child_item = build_catalog_items_recursive(view_item, child);
83
84 /* Uncollapse to some level (gives quick access, but don't let the tree get too big). */
85 if (parent_count < 2) {
86 child_item.uncollapse_by_default();
87 }
88 });
89
90 return view_item;
91 }
92
94
95 class Item : public ui::BasicTreeViewItem {
96 const asset_system::AssetCatalogTreeItem &catalog_item_;
97 /* Is the catalog path enabled in this redraw? Set on construction, updated by the UI (which
98 * gets a pointer to it). The UI needs it as char. */
99 char catalog_path_enabled_ = false;
100
101 public:
103 : ui::BasicTreeViewItem(catalog_item.get_name()),
104 catalog_item_(catalog_item),
105 catalog_path_enabled_(
107 {
109 }
110
112 {
113 return catalog_path_enabled_ != 0;
114 }
115
117 {
118 bool has_enabled = false;
119
121 [&has_enabled](const ui::AbstractTreeViewItem &abstract_item) {
122 const Item &item = dynamic_cast<const Item &>(abstract_item);
123 if (item.is_catalog_path_enabled()) {
124 has_enabled = true;
125 }
126 },
128
129 return has_enabled;
130 }
131
133 {
134 return catalog_item_.catalog_path();
135 }
136
137 void build_row(uiLayout &row) override
138 {
140 uiBlock *block = uiLayoutGetBlock(&row);
141
143
144 uiLayout *subrow = &row.row(false);
145 uiLayoutSetActive(subrow, catalog_path_enabled_);
146 subrow->label(catalog_item_.get_name(), ICON_NONE);
147 UI_block_layout_set_current(block, &row);
148
149 uiBut *toggle_but = uiDefButC(block,
151 0,
152 "",
153 0,
154 0,
155 UI_UNIT_X,
156 UI_UNIT_Y,
157 &catalog_path_enabled_,
158 0,
159 0,
160 TIP_("Toggle catalog visibility in the asset shelf"));
161 UI_but_func_set(toggle_but, [&tree](bContext &C) {
162 tree.update_shelf_settings_from_enabled_catalogs();
164 });
167 }
168 UI_but_flag_disable(toggle_but, UI_BUT_UNDO);
169 }
170 };
171};
172
174{
176 foreach_item([this](ui::AbstractTreeViewItem &view_item) {
177 const auto &selector_tree_item = dynamic_cast<AssetCatalogSelectorTree::Item &>(view_item);
178 if (selector_tree_item.is_catalog_path_enabled()) {
179 settings_set_catalog_path_enabled(shelf_, selector_tree_item.catalog_path());
180 }
181 });
182}
183
185{
187
189 &CTX_wm_screen(C)->id, &RNA_AssetShelf, &shelf);
190
191 uiLayout *row = &layout->row(true);
192 row->prop(&shelf_ptr, "asset_library_reference", UI_ITEM_NONE, "", ICON_NONE);
193 if (shelf.settings.asset_library_reference.type != ASSET_LIBRARY_LOCAL) {
194 row->op("ASSET_OT_library_refresh", "", ICON_FILE_REFRESH);
195 }
196}
197
198static void catalog_selector_panel_draw(const bContext *C, Panel *panel)
199{
201 if (!shelf) {
202 return;
203 }
204
205 uiLayout *layout = panel->layout;
206
207 library_selector_draw(C, layout, *shelf);
208
210 shelf->settings.asset_library_reference);
211 if (!library) {
212 return;
213 }
214
215 uiBlock *block = uiLayoutGetBlock(layout);
217 *block,
218 "asset catalog tree view",
219 std::make_unique<AssetCatalogSelectorTree>(*library, *shelf));
220 tree_view->set_context_menu_title("Catalog");
221 ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
222}
223
225{
226 /* Uses global paneltype registry to allow usage as popover. So only register this once (may be
227 * called from multiple spaces). */
228 if (WM_paneltype_find("ASSETSHELF_PT_catalog_selector", true)) {
229 return;
230 }
231
232 PanelType *pt = MEM_callocN<PanelType>(__func__);
233 STRNCPY(pt->idname, "ASSETSHELF_PT_catalog_selector");
234 STRNCPY(pt->label, N_("Catalog Selector"));
236 pt->description = N_(
237 "Select the asset library and the contained catalogs to display in the asset shelf");
240 BLI_addtail(&region_type->paneltypes, pt);
242}
243
244} // 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
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#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
void UI_but_drawflag_enable(uiBut *but, int flag)
uiBut * uiDefButC(uiBlock *block, int 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)
@ UI_BUT_INDETERMINATE
#define UI_UNIT_X
@ UI_BTYPE_CHECKBOX
@ UI_BUT_UNDO
void uiLayoutSetActive(uiLayout *layout, bool active)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
#define UI_ITEM_NONE
void uiLayoutSetEmboss(uiLayout *layout, blender::ui::EmbossType emboss)
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
void uiLayoutSetOperatorContext(uiLayout *layout, wmOperatorCallContext opcontext)
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:238
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:620
void foreach_item(ItemIterFn iter_fn, IterOptions options=IterOptions::None) const
Definition tree_view.cc:108
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, std::optional< StringRef > search_string={}, bool add_box=true)
Definition tree_view.cc:980
ItemT & add_tree_item(Args &&...args)
void foreach_item_recursive(ItemIterFn iter_fn, IterOptions options=IterOptions::None) const
Definition tree_view.cc:72
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
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
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
void label(blender::StringRef name, int icon)
uiLayout & row(bool align)
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)