Blender V5.0
asset_shelf.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 <algorithm>
12#include <cfloat>
13
15#include "AS_asset_library.hh"
16
17#include "BLI_function_ref.hh"
18#include "BLI_listbase.h"
19#include "BLI_string_utf8.h"
20
21#include "BKE_context.hh"
22#include "BKE_main.hh"
23#include "BKE_screen.hh"
24
25#include "BLT_translation.hh"
26
27#include "DNA_screen_types.h"
28
29#include "ED_asset_list.hh"
30#include "ED_screen.hh"
31
32#include "RNA_access.hh"
33#include "RNA_prototypes.hh"
34
35#include "UI_interface.hh"
37#include "UI_resources.hh"
38#include "UI_tree_view.hh"
39#include "UI_view2d.hh"
40
41#include "WM_api.hh"
42#include "WM_message.hh"
43
44#include "ED_asset_shelf.hh"
45#include "asset_shelf.hh"
46
48
50
55
56/* -------------------------------------------------------------------- */
59
61{
63 return shelf_types;
64}
65
66void type_register(std::unique_ptr<AssetShelfType> type)
67{
69 shelf_types.append(std::move(type));
70}
71
72void type_unregister(const AssetShelfType &shelf_type)
73{
75 auto *const it = std::find_if(shelf_types.begin(),
76 shelf_types.end(),
77 [&](const std::unique_ptr<AssetShelfType> &iter_type) {
78 return iter_type.get() == &shelf_type;
79 });
80 BLI_assert(it != shelf_types.end());
81
82 shelf_types.remove(it - shelf_types.begin());
83}
84
85static bool type_poll_no_spacetype_check(const bContext &C, const AssetShelfType *shelf_type)
86{
87 if (!shelf_type) {
88 return false;
89 }
90
91#ifndef NDEBUG
93 BLI_assert_msg(std::find_if(shelf_types.begin(),
94 shelf_types.end(),
95 [&](const std::unique_ptr<AssetShelfType> &type) {
96 return type.get() == shelf_type;
97 }) != shelf_types.end(),
98 "Asset shelf type is not registered");
99#endif
100
101 return !shelf_type->poll || shelf_type->poll(&C, shelf_type);
102}
103
104bool type_poll_for_popup(const bContext &C, const AssetShelfType *shelf_type)
105{
106 return type_poll_no_spacetype_check(C, shelf_type);
107}
108
116 const AssetShelfType *shelf_type,
117 const int space_type)
118{
119 if (!shelf_type) {
120 return false;
121 }
122 if (shelf_type->space_type && (space_type != shelf_type->space_type)) {
123 return false;
124 }
125
126 return type_poll_no_spacetype_check(C, shelf_type);
127}
128
130{
131 for (const std::unique_ptr<AssetShelfType> &shelf_type : static_shelf_types()) {
132 if (idname == shelf_type->idname) {
133 return shelf_type.get();
134 }
135 }
136 return nullptr;
137}
138
140{
141 if (shelf.type) {
142 return shelf.type;
143 }
144
145 for (const std::unique_ptr<AssetShelfType> &shelf_type : static_shelf_types()) {
146 if (STREQ(shelf.idname, shelf_type->idname)) {
147 shelf.type = shelf_type.get();
148 return shelf_type.get();
149 }
150 }
151
152 return nullptr;
153}
154
156{
157 AssetShelf *shelf = MEM_new<AssetShelf>(__func__);
158 *shelf = dna::shallow_zero_initialize();
159 shelf->settings.preview_size = type.default_preview_size ? type.default_preview_size :
161 shelf->settings.asset_library_reference = asset_system::all_library_reference();
162 shelf->type = &type;
163 shelf->preferred_row_count = 1;
164 STRNCPY_UTF8(shelf->idname, type.idname);
165 return shelf;
166}
167
169
170/* -------------------------------------------------------------------- */
173
179static void activate_shelf(RegionAssetShelf &shelf_regiondata, AssetShelf &shelf)
180{
181 shelf_regiondata.active_shelf = &shelf;
182 BLI_assert(BLI_findindex(&shelf_regiondata.shelves, &shelf) > -1);
183 BLI_remlink(&shelf_regiondata.shelves, &shelf);
184 BLI_addhead(&shelf_regiondata.shelves, &shelf);
185}
186
209 const eSpace_Type space_type,
210 RegionAssetShelf &shelf_regiondata,
211 FunctionRef<void(AssetShelf &new_shelf)> on_create,
212 FunctionRef<void(AssetShelf &shelf)> on_reactivate)
213{
214 /* NOTE: Don't access #AssetShelf.type directly, use #type_ensure(). */
215
216 /* Case 1: */
217 if (shelf_regiondata.active_shelf &&
219 C, ensure_shelf_has_type(*shelf_regiondata.active_shelf), space_type))
220 {
221 /* Not a strong precondition, but if this is wrong something weird might be going on. */
222 BLI_assert(shelf_regiondata.active_shelf == shelf_regiondata.shelves.first);
223 return shelf_regiondata.active_shelf;
224 }
225
226 /* Case 2 (no active shelf or the poll of it isn't succeeding anymore. Poll all shelf types to
227 * determine a new active one): */
228 LISTBASE_FOREACH (AssetShelf *, shelf, &shelf_regiondata.shelves) {
229 if (shelf == shelf_regiondata.active_shelf) {
230 continue;
231 }
232
234 /* Found a valid previously activated shelf, reactivate it. */
235 activate_shelf(shelf_regiondata, *shelf);
236 if (on_reactivate) {
237 on_reactivate(*shelf);
238 }
239 return shelf;
240 }
241 }
242
243 /* Case 3: */
244 for (const std::unique_ptr<AssetShelfType> &shelf_type : static_shelf_types()) {
245 if (type_poll_for_non_popup(C, shelf_type.get(), space_type)) {
246 AssetShelf *new_shelf = create_shelf_from_type(*shelf_type);
247 BLI_addhead(&shelf_regiondata.shelves, new_shelf);
248 /* Moves ownership to the regiondata. */
249 activate_shelf(shelf_regiondata, *new_shelf);
250 if (on_create) {
251 on_create(*new_shelf);
252 }
253 return new_shelf;
254 }
255 }
256
257 shelf_regiondata.active_shelf = nullptr;
258 return nullptr;
259}
260
262
263/* -------------------------------------------------------------------- */
266
267void *region_duplicate(void *regiondata)
268{
269 const RegionAssetShelf *shelf_regiondata = static_cast<RegionAssetShelf *>(regiondata);
270 if (!shelf_regiondata) {
271 return nullptr;
272 }
273
274 return regiondata_duplicate(shelf_regiondata);
275}
276
277void region_free(ARegion *region)
278{
279 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
280 if (shelf_regiondata) {
281 regiondata_free(shelf_regiondata);
282 }
283 region->regiondata = nullptr;
284}
285
290static bool asset_shelf_space_poll(const bContext *C, const SpaceLink *space_link)
291{
292 /* Is there any asset shelf type registered that returns true for it's poll? */
293 for (const std::unique_ptr<AssetShelfType> &shelf_type : static_shelf_types()) {
294 if (type_poll_for_non_popup(*C, shelf_type.get(), space_link->spacetype)) {
295 return true;
296 }
297 }
298
299 return false;
300}
301
303{
304 return asset_shelf_space_poll(params->context,
305 static_cast<SpaceLink *>(params->area->spacedata.first));
306}
307
309{
310 ARegion *region = params->region;
311 const wmNotifier *wmn = params->notifier;
312
313 switch (wmn->category) {
314 case NC_SPACE:
315 if (wmn->data == ND_REGIONS_ASSET_SHELF) {
316 ED_region_tag_redraw(region);
317 }
318 break;
319 case NC_SCENE:
320 /* Asset shelf polls typically check the mode. */
321 if (ELEM(wmn->data, ND_MODE)) {
322 ED_region_tag_redraw(region);
323 }
324 break;
325 case NC_ASSET:
326 ED_region_tag_redraw(region);
327 break;
328 }
329}
330
332{
333 if (list::listen(params->notifier)) {
335 }
336 /* If the asset list didn't catch the notifier, let the region itself listen. */
337 else {
339 }
340}
341
343{
344 wmMsgBus *mbus = params->message_bus;
345 WorkSpace *workspace = params->workspace;
346 ARegion *region = params->region;
347
348 wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
349 msg_sub_value_region_tag_redraw.owner = region;
350 msg_sub_value_region_tag_redraw.user_data = region;
351 msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
353 mbus, &workspace->id, workspace, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
354}
355
357{
358 /* Region-data should've been created by a previously called #region_on_poll_success(). */
359 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
361 shelf_regiondata,
362 "Region-data should've been created by a previously called `region_on_poll_success()`.");
363
364 AssetShelf *active_shelf = shelf_regiondata->active_shelf;
365
366 UI_view2d_region_reinit(&region->v2d, V2D_COMMONVIEW_PANELS_UI, region->winx, region->winy);
367
368 wmKeyMap *keymap = WM_keymap_ensure(
369 wm->runtime->defaultconf, "View2D Buttons List", SPACE_EMPTY, RGN_TYPE_WINDOW);
370 WM_event_add_keymap_handler(&region->runtime->handlers, keymap);
371
374 region->v2d.keepofs |= V2D_KEEPOFS_Y;
375 region->v2d.keeptot |= V2D_KEEPTOT_STRICT;
376
378 region->v2d.page_size_y = active_shelf ? tile_height(active_shelf->settings) :
380
381 /* Ensure the view is snapped to a page still, especially for DPI changes. */
383}
384
386{
387 const uiStyle *style = UI_style_get_dpi();
388 return style->buttonspacey / 2;
389}
390
392{
393 /* Use the same as the height, equal padding looks nice. */
394 return main_region_padding_y();
395}
396
397static int current_tile_draw_height(const ARegion *region)
398{
399 const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
400 *region);
401 const float aspect = BLI_rctf_size_y(&region->v2d.cur) /
402 (BLI_rcti_size_y(&region->v2d.mask) + 1);
403
404 /* It can happen that this function is called before the region is actually initialized, when
405 * user clicks & drags slightly on the 'up arrow' icon of the shelf. */
406 const AssetShelf *active_shelf = shelf_regiondata ? shelf_regiondata->active_shelf : nullptr;
407 return (active_shelf ? tile_height(active_shelf->settings) : asset_shelf_default_tile_height()) /
408 (IS_EQF(aspect, 0) ? 1.0f : aspect);
409}
410
414static int calculate_row_count_from_tile_draw_height(const int region_height_scaled,
415 const int tile_draw_height)
416{
417 return std::max(1, int((region_height_scaled - 2 * main_region_padding_y()) / tile_draw_height));
418}
419
421 const int tile_draw_height)
422{
423 return (row_count * tile_draw_height + 2 * main_region_padding_y());
424}
425
426int region_snap(const ARegion *region, const int size, const int axis)
427{
428 /* Only on Y axis. */
429 if (axis != 1) {
430 return size;
431 }
432
433 /* Using scaled values only simplifies things. Simply divide the result by the scale again. */
434
435 const int tile_height = current_tile_draw_height(region);
436
439
440 const int new_size_scaled = calculate_scaled_region_height_from_row_count(row_count,
442 return new_size_scaled / UI_SCALE_FAC;
443}
444
450static void region_resize_to_preferred(ScrArea *area, ARegion *region)
451{
452 const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
453 *region);
454 const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
455
456 BLI_assert(active_shelf->preferred_row_count > 0);
457 const int tile_height = current_tile_draw_height(region);
458
459 /* Prevent the AssetShelf from getting too high (and thus being hidden) in case many rows are
460 * used and preview size is increased. */
461 const int size_y_avail = ED_area_max_regionsize(area, region, AE_TOP_TO_BOTTOMRIGHT);
462 const short int max_row_count = calculate_row_count_from_tile_draw_height(
463 size_y_avail * UI_SCALE_FAC, tile_height);
464
466 std::min(max_row_count, active_shelf->preferred_row_count),
467 tile_height) /
469
470 if (region->sizey != new_size_y) {
471 region->sizey = new_size_y;
472 ED_area_tag_region_size_update(area, region);
473 }
474}
475
477{
478 const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
479 *region);
480 AssetShelf *active_shelf = shelf_regiondata->active_shelf;
481 if (!active_shelf) {
482 return;
483 }
484
485 const int tile_height = current_tile_draw_height(region);
487 region->sizey * UI_SCALE_FAC, tile_height);
488}
489
490int tile_width(const AssetShelfSettings &settings)
491{
492 return UI_preview_tile_size_x(settings.preview_size);
493}
494
495int tile_height(const AssetShelfSettings &settings)
496{
497 return (settings.display_flag & ASSETSHELF_SHOW_NAMES) ?
500}
501
506
508{
509 /* One row by default (plus padding). */
511}
512
513void region_layout(const bContext *C, ARegion *region)
514{
515 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
517 shelf_regiondata,
518 "Region-data should've been created by a previously called `region_on_poll_success()`.");
519
520 const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
521 if (!active_shelf) {
522 return;
523 }
524
525 uiBlock *block = UI_block_begin(C, region, __func__, ui::EmbossType::Emboss);
526
527 const uiStyle *style = UI_style_get_dpi();
528 const int padding_y = main_region_padding_y();
529 const int padding_x = main_region_padding_x();
530 uiLayout &layout = ui::block_layout(block,
533 padding_x,
534 -padding_y,
535 region->winx - 2 * padding_x,
536 0,
537 0,
538 style);
539
540 build_asset_view(layout, active_shelf->settings.asset_library_reference, *active_shelf, *C);
541
542 int layout_height = ui::block_layout_resolve(block).y;
543 BLI_assert(layout_height <= 0);
544 UI_view2d_totRect_set(&region->v2d, region->winx - 1, layout_height - padding_y);
546
548
549 /* View2D matrix might have changed due to dynamic sized regions.
550 * Without this, tooltips jump around, see #129347. Reason is that #UI_but_tooltip_refresh() is
551 * called as part of #UI_block_end(), so the block's window matrix needs to be up-to-date. */
552 {
553 UI_view2d_view_ortho(&region->v2d);
554 UI_blocklist_update_window_matrix(C, &region->runtime->uiblocks);
555 }
556
557 UI_block_end(C, block);
558}
559
560void region_draw(const bContext *C, ARegion *region)
561{
562 ED_region_clear(C, region, TH_BACK);
563
564 /* Set view2d view matrix for scrolling. */
565 UI_view2d_view_ortho(&region->v2d);
566
567 /* View2D matrix might have changed due to dynamic sized regions. */
568 UI_blocklist_update_window_matrix(C, &region->runtime->uiblocks);
569
570 UI_blocklist_draw(C, &region->runtime->uiblocks);
571
572 /* Restore view matrix. */
574
575 UI_view2d_scrollers_draw(&region->v2d, nullptr);
576}
577
579{
580 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::ensure_from_asset_shelf_region(*region);
581 if (!shelf_regiondata) {
583 return;
584 }
585
586 const int old_region_flag = region->flag;
587
588 ScrArea *area = CTX_wm_area(C);
590 *C,
591 eSpace_Type(area->spacetype),
592 *shelf_regiondata,
593 /*on_create=*/
594 [&](AssetShelf &new_shelf) {
595 /* Set region visibility for first time shelf is created (`'DEFAULT_VISIBLE'` option). */
596 SET_FLAG_FROM_TEST(region->flag,
597 (new_shelf.type->flag & ASSET_SHELF_TYPE_FLAG_DEFAULT_VISIBLE) == 0,
598 RGN_FLAG_HIDDEN);
599 },
600 /*on_reactivate=*/
601 [&](AssetShelf &shelf) {
602 /* Restore region visibility from previous asset shelf instantiation when reactivating. */
603 SET_FLAG_FROM_TEST(
604 region->flag, shelf.instance_flag & ASSETSHELF_REGION_IS_HIDDEN, RGN_FLAG_HIDDEN);
605 });
606
607 if (old_region_flag != region->flag) {
608 ED_region_visibility_change_update(const_cast<bContext *>(C), area, region);
609 }
610
611 if (shelf_regiondata->active_shelf) {
612 /* Remember current visibility state of the region in the shelf, so we can restore it on
613 * reactivation. */
617 }
618}
619
624
631
636
638{
639 /* Use a height that lets widgets sit just on top of the separator line drawn at the lower edge
640 * of the region (widgets will be centered).
641 *
642 * Note that this is usually a bit less than the header size. The asset shelf tends to look like
643 * a separate area, so making the shelf header smaller than a header helps. */
645}
646
648{
649 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
650 if (!shelf_regiondata) {
651 return;
652 }
653 regiondata_blend_read_data(reader, &shelf_regiondata);
654 region->regiondata = shelf_regiondata;
655}
656
658{
659 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
660 if (!shelf_regiondata) {
661 return;
662 }
663 regiondata_blend_write(writer, shelf_regiondata);
664}
665
667
668/* -------------------------------------------------------------------- */
671
673{
674 const ARegion *shelf_region = BKE_area_find_region_type(area, RGN_TYPE_ASSET_SHELF);
675 if (!shelf_region) {
676 /* Called in wrong context, area doesn't have a shelf. */
677 return nullptr;
678 }
679
680 if (shelf_region->flag & RGN_FLAG_POLL_FAILED) {
681 /* Don't return data when the region "doesn't exist" (poll failed). */
682 return nullptr;
683 }
684
685 const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
686 *shelf_region);
687 if (!shelf_regiondata) {
688 return nullptr;
689 }
690
691 return shelf_regiondata->active_shelf;
692}
693
694int context(const bContext *C, const char *member, bContextDataResult *result)
695{
696 static const char *context_dir[] = {
697 "asset_shelf",
698 "asset_library_reference",
699 "asset",
700 nullptr,
701 };
702
703 if (CTX_data_dir(member)) {
704 CTX_data_dir_set(result, context_dir);
705 return CTX_RESULT_OK;
706 }
707
708 bScreen *screen = CTX_wm_screen(C);
709
710 if (CTX_data_equals(member, "asset_shelf")) {
712 if (!active_shelf) {
713 return CTX_RESULT_NO_DATA;
714 }
715
716 CTX_data_pointer_set(result, &screen->id, &RNA_AssetShelf, active_shelf);
717 return CTX_RESULT_OK;
718 }
719
720 if (CTX_data_equals(member, "asset_library_reference")) {
722 if (!active_shelf) {
723 return CTX_RESULT_NO_DATA;
724 }
725
727 &screen->id,
728 &RNA_AssetLibraryReference,
729 &active_shelf->settings.asset_library_reference);
730 return CTX_RESULT_OK;
731 }
732
733 if (CTX_data_equals(member, "asset")) {
734 const ARegion *region = CTX_wm_region(C);
735 const uiBut *but = UI_region_views_find_active_item_but(region);
736 if (!but) {
737 return CTX_RESULT_NO_DATA;
738 }
739
740 const bContextStore *but_context = UI_but_context_get(but);
741 if (!but_context) {
742 return CTX_RESULT_NO_DATA;
743 }
744
745 const PointerRNA *asset_ptr = CTX_store_ptr_lookup(
746 but_context, "asset", &RNA_AssetRepresentation);
747 if (!asset_ptr) {
748 return CTX_RESULT_NO_DATA;
749 }
750
752 return CTX_RESULT_OK;
753 }
754
756}
757
759{
760 return CTX_data_pointer_get_type(C, "asset_shelf", &RNA_AssetShelf);
761}
762
764{
765 PointerRNA shelf_settings_ptr = active_shelf_ptr_from_context(C);
766 return static_cast<AssetShelf *>(shelf_settings_ptr.data);
767}
768
770
771/* -------------------------------------------------------------------- */
774
776{
777 const uiStyle *style = UI_style_get_dpi();
778 const int string_width = UI_fontstyle_string_width(&style->widget, name.c_str());
779 const int pad_x = UI_UNIT_X * 0.3f;
780 const int but_width = std::min(string_width + 2 * pad_x, UI_UNIT_X * 8);
781
782 uiBut *but = uiDefBut(
783 &block,
785 0,
786 name,
787 0,
788 0,
789 but_width,
790 UI_UNIT_Y,
791 nullptr,
792 0,
793 0,
794 TIP_("Enable catalog, making contained assets visible in the asset shelf"));
795
798
799 return but;
800}
801
803{
804 uiBlock *block = layout.block();
805 AssetShelfSettings &shelf_settings = shelf.settings;
806
807 /* "All" tab. */
808 {
809 uiBut *but = add_tab_button(*block, IFACE_("All"));
810 UI_but_func_set(but, [&shelf_settings](bContext &C) {
811 settings_set_all_catalog_active(shelf_settings);
813 });
814 UI_but_func_pushed_state_set(but, [&shelf_settings](const uiBut &) -> bool {
815 return settings_is_all_catalog_active(shelf_settings);
816 });
817 }
818
819 layout.separator();
820
821 /* Regular catalog tabs. */
823 uiBut *but = add_tab_button(*block, path.name());
824
825 UI_but_func_set(but, [&shelf_settings, path](bContext &C) {
826 settings_set_active_catalog(shelf_settings, path);
828 });
829 UI_but_func_pushed_state_set(but, [&shelf_settings, path](const uiBut &) -> bool {
830 return settings_is_active_catalog(shelf_settings, path);
831 });
832 });
833}
834
836
837/* -------------------------------------------------------------------- */
842
843static void asset_shelf_header_draw(const bContext *C, Header *header)
844{
845 uiLayout *layout = header->layout;
846 uiBlock *block = layout->block();
848
849 list::storage_fetch(library_ref, C);
850
852 layout->popover(C, "ASSETSHELF_PT_catalog_selector", "", ICON_COLLAPSEMENU);
854
855 layout->separator();
856
858 if (AssetShelf *shelf = static_cast<AssetShelf *>(shelf_ptr.data)) {
859 add_catalog_tabs(*shelf, *layout);
860 }
861
862 layout->separator_spacer();
863
864 layout->popover(C, "ASSETSHELF_PT_display", "", ICON_IMGDISPLAY);
865 uiLayout *sub = &layout->row(false);
866 /* Same as file/asset browser header. */
867 sub->ui_units_x_set(8);
868 sub->prop(&shelf_ptr, "search_filter", UI_ITEM_NONE, "", ICON_VIEWZOOM);
869}
870
871static void header_regiontype_register(ARegionType *region_type, const int space_type)
872{
873 HeaderType *ht = MEM_callocN<HeaderType>(__func__);
874 STRNCPY_UTF8(ht->idname, "ASSETSHELF_HT_settings");
875 ht->space_type = space_type;
878 ht->poll = [](const bContext *C, HeaderType *) {
880 };
881
882 BLI_addtail(&region_type->headertypes, ht);
883}
884
885void types_register(ARegionType *region_type, const int space_type)
886{
887 header_regiontype_register(region_type, space_type);
889 popover_panel_register(region_type);
890}
891
893
894/* -------------------------------------------------------------------- */
897
898void type_unlink(const Main &bmain, const AssetShelfType &shelf_type)
899{
900 LISTBASE_FOREACH (bScreen *, screen, &bmain.screens) {
901 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
902 LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
903 ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
904 LISTBASE_FOREACH (ARegion *, region, regionbase) {
905 if (region->regiontype != RGN_TYPE_ASSET_SHELF) {
906 continue;
907 }
908
909 RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
910 *region);
911 if (!shelf_regiondata) {
912 continue;
913 }
914 LISTBASE_FOREACH (AssetShelf *, shelf, &shelf_regiondata->shelves) {
915 if (shelf->type == &shelf_type) {
916 shelf->type = nullptr;
917 }
918 }
919
920 BLI_assert((shelf_regiondata->active_shelf == nullptr) ||
921 (shelf_regiondata->active_shelf->type != &shelf_type));
922 }
923 }
924 }
925 }
926
927 type_popup_unlink(shelf_type);
928}
929
931
932/* -------------------------------------------------------------------- */
935
937{
939 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
940 const bScreen *screen = WM_window_get_active_screen(win);
941 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
944 }
945 }
946 }
947}
948
950
951} // namespace blender::ed::asset::shelf
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
bool CTX_data_equals(const char *member, const char *str)
bScreen * CTX_wm_screen(const bContext *C)
void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
bool CTX_data_dir(const char *member)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
ScrArea * CTX_wm_area(const bContext *C)
const AssetLibraryReference * CTX_wm_asset_library_ref(const bContext *C)
const PointerRNA * CTX_store_ptr_lookup(const bContextStore *store, blender::StringRef name, const StructRNA *type=nullptr)
@ CTX_RESULT_MEMBER_NOT_FOUND
@ CTX_RESULT_OK
@ CTX_RESULT_NO_DATA
SpaceLink * CTX_wm_space_data(const bContext *C)
void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define ASSET_SHELF_PREVIEW_SIZE_DEFAULT
ARegion * BKE_area_find_region_type(const ScrArea *area, int region_type)
Definition screen.cc:846
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void BLI_addhead(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:91
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:206
#define STRNCPY_UTF8(dst, src)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define IS_EQF(a, b)
#define STREQ(a, b)
#define TIP_(msgid)
#define IFACE_(msgid)
@ RGN_SPLIT_SCALE_PREV
@ ASSETSHELF_SHOW_NAMES
@ RGN_TYPE_ASSET_SHELF_HEADER
@ RGN_TYPE_WINDOW
@ RGN_TYPE_ASSET_SHELF
@ RGN_FLAG_RESIZE_RESPECT_BUTTON_SECTIONS
@ RGN_FLAG_HIDDEN
@ RGN_FLAG_POLL_FAILED
@ RGN_FLAG_HIDDEN_BY_USER
@ ASSETSHELF_REGION_IS_HIDDEN
eSpace_Type
@ SPACE_EMPTY
#define UI_SCALE_FAC
@ V2D_KEEPOFS_Y
@ V2D_SNAP_TO_PAGESIZE_Y
@ V2D_KEEPTOT_STRICT
@ V2D_LOCKZOOM_X
@ V2D_LOCKZOOM_Y
@ V2D_SCROLL_VERTICAL_HIDE
@ V2D_SCROLL_RIGHT
int ED_area_max_regionsize(const ScrArea *area, const ARegion *scale_region, const AZEdge edge)
Definition area.cc:762
void ED_region_clear(const bContext *C, const ARegion *region, int colorid)
Definition area.cc:2933
void ED_region_header_init(ARegion *region)
Definition area.cc:3950
void ED_region_tag_redraw_no_rebuild(ARegion *region)
Definition area.cc:638
void ED_region_header_with_button_sections(const bContext *C, ARegion *region, uiButtonSectionsAlign align)
Definition area.cc:3942
void ED_area_tag_region_size_update(ScrArea *area, ARegion *changed_region)
Definition area.cc:729
void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *region)
Definition area.cc:2351
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:618
void ED_region_do_msg_notify_tag_redraw(bContext *C, wmMsgSubscribeKey *msg_key, wmMsgSubscribeValue *msg_val)
Definition area.cc:361
@ AE_TOP_TO_BOTTOMRIGHT
#define C
Definition RandGen.cpp:29
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
void UI_but_func_pushed_state_set(uiBut *but, std::function< bool(const uiBut &)> func)
void UI_but_flag_disable(uiBut *but, int flag)
void UI_blocklist_update_window_matrix(const bContext *C, const ListBase *lb)
#define UI_UNIT_Y
void UI_block_emboss_set(uiBlock *block, blender::ui::EmbossType emboss)
uiBlock * UI_block_begin(const bContext *C, ARegion *region, std::string name, blender::ui::EmbossType emboss)
@ UI_BUT_UNDO
const uiStyle * UI_style_get_dpi()
int UI_preview_tile_size_y(const int size_px=96)
void UI_but_drawflag_enable(uiBut *but, int flag)
int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void UI_blocklist_draw(const bContext *C, const ListBase *lb)
#define UI_BUTTON_SECTION_SEPERATOR_LINE_WITH
int UI_preview_tile_size_x(const int size_px=96)
#define UI_UNIT_X
const bContextStore * UI_but_context_get(const uiBut *but)
@ UI_BUT_ALIGN_DOWN
int UI_preview_tile_size_y_no_label(const int size_px=96)
void UI_block_end(const bContext *C, uiBlock *block)
uiBut * uiDefBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
uiBut * UI_region_views_find_active_item_but(const ARegion *region)
#define UI_ITEM_NONE
@ TH_BACK
void UI_view2d_curRect_validate(View2D *v2d)
Definition view2d.cc:828
void UI_view2d_scrollers_draw(View2D *v2d, const rcti *mask_custom)
Definition view2d.cc:1504
void UI_view2d_view_restore(const bContext *C)
Definition view2d.cc:1162
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
Definition view2d.cc:221
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
Definition view2d.cc:1036
void UI_view2d_view_ortho(const View2D *v2d)
Definition view2d.cc:1095
void UI_view2d_offset_y_snap_to_closest_page(View2D *v2d)
Definition view2d.cc:1980
@ V2D_COMMONVIEW_PANELS_UI
Definition UI_view2d.hh:41
#define ND_REGIONS_ASSET_SHELF
Definition WM_types.hh:543
#define ND_MODE
Definition WM_types.hh:445
#define NC_SCENE
Definition WM_types.hh:378
#define NC_ASSET
Definition WM_types.hh:404
#define NC_SPACE
Definition WM_types.hh:392
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
constexpr const char * c_str() const
void append(const T &value)
void remove(const int64_t index)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
AssetLibraryReference all_library_reference()
void storage_fetch(const AssetLibraryReference *library_reference, const bContext *C)
bool listen(const wmNotifier *notifier)
static bool asset_shelf_space_poll(const bContext *C, const SpaceLink *space_link)
static int asset_shelf_default_tile_height()
void header_region(const bContext *C, ARegion *region)
AssetShelfType * type_find_from_idname(StringRef idname)
void region_init(wmWindowManager *wm, ARegion *region)
void region_blend_read_data(BlendDataReader *reader, ARegion *region)
static int current_tile_draw_height(const ARegion *region)
bool settings_is_all_catalog_active(const AssetShelfSettings &settings)
AssetShelf * create_shelf_from_type(AssetShelfType &type)
void type_popup_unlink(const AssetShelfType &shelf_type)
void popover_panel_register(ARegionType *region_type)
void types_register(ARegionType *region_type, const int space_type)
static Vector< std::unique_ptr< AssetShelfType > > & static_shelf_types()
void regiondata_free(RegionAssetShelf *shelf_regiondata)
static void header_regiontype_register(ARegionType *region_type, const int space_type)
void region_listen(const wmRegionListenerParams *params)
static int calculate_row_count_from_tile_draw_height(const int region_height_scaled, const int tile_draw_height)
void settings_foreach_enabled_catalog_path(const AssetShelf &shelf, FunctionRef< void(const asset_system::AssetCatalogPath &catalog_path)> fn)
void region_on_poll_success(const bContext *C, ARegion *region)
void catalog_selector_panel_register(ARegionType *region_type)
void header_region_listen(const wmRegionListenerParams *params)
static void asset_shelf_header_draw(const bContext *C, Header *header)
void settings_set_all_catalog_active(AssetShelfSettings &settings)
void type_unregister(const AssetShelfType &shelf_type)
void region_blend_write(BlendWriter *writer, ARegion *region)
void type_unlink(const Main &bmain, const AssetShelfType &shelf_type)
int tile_height(const AssetShelfSettings &settings)
static uiBut * add_tab_button(uiBlock &block, StringRefNull name)
AssetShelf * active_shelf_from_context(const bContext *C)
static AssetShelf * update_active_shelf(const bContext &C, const eSpace_Type space_type, RegionAssetShelf &shelf_regiondata, FunctionRef< void(AssetShelf &new_shelf)> on_create, FunctionRef< void(AssetShelf &shelf)> on_reactivate)
void regiondata_blend_write(BlendWriter *writer, const RegionAssetShelf *shelf_regiondata)
static PointerRNA active_shelf_ptr_from_context(const bContext *C)
static bool type_poll_for_non_popup(const bContext &C, const AssetShelfType *shelf_type, const int space_type)
void region_on_user_resize(const ARegion *region)
AssetShelfType * ensure_shelf_has_type(AssetShelf &shelf)
int context(const bContext *C, const char *member, bContextDataResult *result)
int tile_width(const AssetShelfSettings &settings)
int region_snap(const ARegion *region, int size, int axis)
void type_register(std::unique_ptr< AssetShelfType > type)
bool settings_is_active_catalog(const AssetShelfSettings &settings, const asset_system::AssetCatalogPath &path)
void show_catalog_in_visible_shelves(const bContext &C, const StringRefNull catalog_path)
void * region_duplicate(void *regiondata)
void send_redraw_notifier(const bContext &C)
bool type_poll_for_popup(const bContext &C, const AssetShelfType *shelf_type)
static void asset_shelf_region_listen(const wmRegionListenerParams *params)
void settings_set_catalog_path_enabled(AssetShelf &shelf, const asset_system::AssetCatalogPath &path)
AssetShelf * active_shelf_from_area(const ScrArea *area)
bool regions_poll(const RegionPollParams *params)
static void region_resize_to_preferred(ScrArea *area, ARegion *region)
void header_region_init(wmWindowManager *wm, ARegion *region)
static bool type_poll_no_spacetype_check(const bContext &C, const AssetShelfType *shelf_type)
static int main_region_padding_y()
void regiondata_blend_read_data(BlendDataReader *reader, RegionAssetShelf **shelf_regiondata)
void settings_set_active_catalog(AssetShelfSettings &settings, const asset_system::AssetCatalogPath &path)
static int main_region_padding_x()
void build_asset_view(uiLayout &layout, const AssetLibraryReference &library_ref, const AssetShelf &shelf, const bContext &C)
void region_draw(const bContext *C, ARegion *region)
void region_message_subscribe(const wmRegionMessageSubscribeParams *params)
RegionAssetShelf * regiondata_duplicate(const RegionAssetShelf *shelf_regiondata)
static int calculate_scaled_region_height_from_row_count(const int row_count, const int tile_draw_height)
static void activate_shelf(RegionAssetShelf &shelf_regiondata, AssetShelf &shelf)
void region_layout(const bContext *C, ARegion *region)
static void add_catalog_tabs(AssetShelf &shelf, uiLayout &layout)
void region_free(ARegion *region)
int2 block_layout_resolve(uiBlock *block)
uiLayout & block_layout(uiBlock *block, LayoutDirection direction, LayoutType type, int x, int y, int size, int em, int padding, const uiStyle *style)
const char * name
ListBase headertypes
void * regiondata
ARegionRuntimeHandle * runtime
AssetLibraryReference asset_library_reference
short default_preview_size
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, const AssetShelfType *shelf_type)
struct AssetShelfType * type
AssetShelfSettings settings
short preferred_row_count
void(* draw)(const bContext *C, Header *header)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, HeaderType *ht)
uiLayout * layout
void * first
ListBase screens
Definition BKE_main.hh:292
void * data
Definition RNA_types.hh:53
AssetShelf * active_shelf
short keeptot
short keepzoom
short keepofs
float page_size_y
ListBase areabase
void popover(const bContext *C, PanelType *pt, std::optional< blender::StringRef > name_opt, int icon)
uiBlock * block() const
void separator_spacer()
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
void ui_units_x_set(float width)
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)
short buttonspacey
uiFontStyle widget
unsigned int data
Definition WM_types.hh:358
unsigned int category
Definition WM_types.hh:358
wmEventHandler_Keymap * WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:895
#define WM_msg_subscribe_rna_prop(mbus, id_, data_, type_, prop_, value)
bScreen * WM_window_get_active_screen(const wmWindow *win)