UI: Asset Shelf (Experimental Feature) #104831
|
@ -521,7 +521,7 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
/* Keep this block, even when empty. */
|
||||
}
|
||||
|
||||
if (!DNA_struct_find(fd->filesdna, "AssetShelfHook")) {
|
||||
if (!DNA_struct_find(fd->filesdna, "RegionAssetShelf")) {
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
|
|
|
@ -35,7 +35,7 @@ set(SRC
|
|||
intern/asset_shelf.cc
|
||||
intern/asset_shelf_asset_view.cc
|
||||
intern/asset_shelf_catalog_selector.cc
|
||||
intern/asset_shelf_hook.cc
|
||||
intern/asset_shelf_regiondata.cc
|
||||
intern/asset_shelf_settings.cc
|
||||
intern/asset_temp_id_consumer.cc
|
||||
intern/asset_type.cc
|
||||
|
|
|
@ -60,9 +60,6 @@ void ED_asset_shelf_header_regiontype_register(struct ARegionType *region_type,
|
|||
int ED_asset_shelf_tile_width(const struct AssetShelfSettings &settings);
|
||||
int ED_asset_shelf_tile_height(const struct AssetShelfSettings &settings);
|
||||
|
||||
/**
|
||||
* Creates an `"asset_shelf"` context member, pointing to the active shelf in \a #shelf_hook.
|
||||
*/
|
||||
int ED_asset_shelf_context(const struct bContext *C,
|
||||
const char *member,
|
||||
struct bContextDataResult *result);
|
||||
|
|
|
@ -92,15 +92,15 @@ static AssetShelf *create_shelf_from_type(AssetShelfType &type)
|
|||
* \{ */
|
||||
|
||||
/**
|
||||
* Activating a shelf means assigning it to #AssetShelfHook.active_shelf and (re-)inserting it at
|
||||
* the beginning of the #AssetShelfHook.shelves list. This implies that after calling this, \a
|
||||
* Activating a shelf means assigning it to #RegionAssetShelf.active_shelf and (re-)inserting it at
|
||||
* the beginning of the #RegionAssetShelf.shelves list. This implies that after calling this, \a
|
||||
* shelf is guaranteed to be owned by the shelves list.
|
||||
*/
|
||||
static void activate_shelf(AssetShelfHook &hook, AssetShelf &shelf)
|
||||
static void activate_shelf(RegionAssetShelf &shelf_regiondata, AssetShelf &shelf)
|
||||
{
|
||||
hook.active_shelf = &shelf;
|
||||
BLI_remlink_safe(&hook.shelves, &shelf);
|
||||
BLI_addhead(&hook.shelves, &shelf);
|
||||
shelf_regiondata.active_shelf = &shelf;
|
||||
BLI_remlink_safe(&shelf_regiondata.shelves, &shelf);
|
||||
JulianEisel marked this conversation as resolved
Outdated
|
||||
BLI_addhead(&shelf_regiondata.shelves, &shelf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,13 +108,13 @@ static void activate_shelf(AssetShelfHook &hook, AssetShelf &shelf)
|
|||
*
|
||||
* The heuristic works as follows:
|
||||
* 1) If the currently active shelf is still valid (poll succeeds), keep it active.
|
||||
* 2) Otherwise, check for previously activated shelves in \a hook and activate the first valid one
|
||||
* (first with a succeeding poll).
|
||||
* 2) Otherwise, check for previously activated shelves in \a shelf_regiondata and activate the
|
||||
* first valid one (first with a succeeding poll).
|
||||
* 3) If none is valid, check all shelf-types available for \a space_type, create a new shelf for
|
||||
* the first type that is valid (poll succeeds), and activate it.
|
||||
* 4) If no shelf-type is valid, #AssetShelfHook.active_shelf is set to null.
|
||||
* 4) If no shelf-type is valid, #RegionAssetShelf.active_shelf is set to null.
|
||||
*
|
||||
* When activating a shelf, it is moved to the beginning of the #AssetShelfHook.shelves list, so
|
||||
* When activating a shelf, it is moved to the beginning of the #RegionAssetShelf.shelves list, so
|
||||
* that recently activated shelves are also the first ones to be reactivated.
|
||||
*
|
||||
* The returned shelf is guaranteed to have its #AssetShelf.type pointer set.
|
||||
|
@ -124,29 +124,30 @@ static void activate_shelf(AssetShelfHook &hook, AssetShelf &shelf)
|
|||
*/
|
||||
static AssetShelf *update_active_shelf(const bContext &C,
|
||||
const SpaceType &space_type,
|
||||
AssetShelfHook &hook)
|
||||
RegionAssetShelf &shelf_regiondata)
|
||||
{
|
||||
/* Note: Don't access #AssetShelf.type directly, use #asset_shelf_type_ensure(). */
|
||||
|
||||
/* Case 1: */
|
||||
if (hook.active_shelf &&
|
||||
asset_shelf_type_poll(C, asset_shelf_type_ensure(space_type, *hook.active_shelf)))
|
||||
if (shelf_regiondata.active_shelf &&
|
||||
asset_shelf_type_poll(C,
|
||||
asset_shelf_type_ensure(space_type, *shelf_regiondata.active_shelf)))
|
||||
{
|
||||
/* Not a strong precondition, but if this is wrong something weird might be going on. */
|
||||
BLI_assert(hook.active_shelf == hook.shelves.first);
|
||||
return hook.active_shelf;
|
||||
BLI_assert(shelf_regiondata.active_shelf == shelf_regiondata.shelves.first);
|
||||
return shelf_regiondata.active_shelf;
|
||||
}
|
||||
|
||||
/* Case 2 (no active shelf or the poll of it isn't succeeding anymore. Poll all shelf types to
|
||||
* determine a new active one): */
|
||||
LISTBASE_FOREACH (AssetShelf *, shelf, &hook.shelves) {
|
||||
if (shelf == hook.active_shelf) {
|
||||
LISTBASE_FOREACH (AssetShelf *, shelf, &shelf_regiondata.shelves) {
|
||||
if (shelf == shelf_regiondata.active_shelf) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (asset_shelf_type_poll(C, asset_shelf_type_ensure(space_type, *shelf))) {
|
||||
/* Found a valid previously activated shelf, reactivate it. */
|
||||
activate_shelf(hook, *shelf);
|
||||
activate_shelf(shelf_regiondata, *shelf);
|
||||
return shelf;
|
||||
}
|
||||
}
|
||||
|
@ -155,13 +156,13 @@ static AssetShelf *update_active_shelf(const bContext &C,
|
|||
LISTBASE_FOREACH (AssetShelfType *, shelf_type, &space_type.asset_shelf_types) {
|
||||
if (asset_shelf_type_poll(C, shelf_type)) {
|
||||
AssetShelf *new_shelf = create_shelf_from_type(*shelf_type);
|
||||
/* Moves ownership to the hook. */
|
||||
activate_shelf(hook, *new_shelf);
|
||||
/* Moves ownership to the regiondata. */
|
||||
activate_shelf(shelf_regiondata, *new_shelf);
|
||||
return new_shelf;
|
||||
}
|
||||
}
|
||||
|
||||
hook.active_shelf = nullptr;
|
||||
shelf_regiondata.active_shelf = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -173,19 +174,19 @@ static AssetShelf *update_active_shelf(const bContext &C,
|
|||
|
||||
void *ED_asset_shelf_region_duplicate(void *regiondata)
|
||||
{
|
||||
const AssetShelfHook *hook = static_cast<AssetShelfHook *>(regiondata);
|
||||
if (!hook) {
|
||||
const RegionAssetShelf *shelf_regiondata = static_cast<RegionAssetShelf *>(regiondata);
|
||||
if (!shelf_regiondata) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return shelf::hook_duplicate(hook);
|
||||
return shelf::regiondata_duplicate(shelf_regiondata);
|
||||
}
|
||||
|
||||
void ED_asset_shelf_region_free(ARegion *region)
|
||||
{
|
||||
AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*region);
|
||||
if (hook) {
|
||||
shelf::hook_free(&hook);
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
if (shelf_regiondata) {
|
||||
shelf::regiondata_free(&shelf_regiondata);
|
||||
}
|
||||
region->regiondata = nullptr;
|
||||
}
|
||||
|
@ -252,12 +253,12 @@ void ED_asset_shelf_region_listen(const wmRegionListenerParams *params)
|
|||
void ED_asset_shelf_region_init(wmWindowManager *wm, ARegion *region)
|
||||
{
|
||||
if (!region->regiondata) {
|
||||
region->regiondata = MEM_cnew<AssetShelfHook>("AssetShelfHook");
|
||||
region->regiondata = MEM_cnew<RegionAssetShelf>("RegionAssetShelf");
|
||||
}
|
||||
AssetShelfHook &hook = *AssetShelfHook::get_from_asset_shelf_region(*region);
|
||||
RegionAssetShelf &shelf_regiondata = *RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
|
||||
/* Active shelf is only set on draw, so this may be null! */
|
||||
AssetShelf *active_shelf = hook.active_shelf;
|
||||
AssetShelf *active_shelf = shelf_regiondata.active_shelf;
|
||||
|
||||
UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_PANELS_UI, region->winx, region->winy);
|
||||
|
||||
|
@ -296,8 +297,9 @@ int ED_asset_shelf_region_snap(const ARegion *region, const int size, const int
|
|||
return size;
|
||||
}
|
||||
|
||||
const AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*region);
|
||||
const AssetShelf *active_shelf = hook->active_shelf;
|
||||
const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
|
||||
*region);
|
||||
const AssetShelf *active_shelf = shelf_regiondata->active_shelf;
|
||||
|
||||
/* Using scaled values only simplifies things. Simply divide the result by the scale again. */
|
||||
const int size_scaled = size * UI_SCALE_FAC;
|
||||
|
@ -375,14 +377,14 @@ void ED_asset_shelf_region_layout(const bContext *C, ARegion *region)
|
|||
const SpaceLink *space = CTX_wm_space_data(C);
|
||||
const SpaceType *space_type = BKE_spacetype_from_id(space->spacetype);
|
||||
|
||||
AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*region);
|
||||
if (!hook) {
|
||||
/* Hook should've been created by a previously called ED_asset_shelf_region_init(). */
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
if (!shelf_regiondata) {
|
||||
/* Regiondata should've been created by a previously called ED_asset_shelf_region_init(). */
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
AssetShelf *active_shelf = update_active_shelf(*C, *space_type, *hook);
|
||||
AssetShelf *active_shelf = update_active_shelf(*C, *space_type, *shelf_regiondata);
|
||||
if (!active_shelf) {
|
||||
return;
|
||||
}
|
||||
|
@ -452,8 +454,9 @@ void ED_asset_shelf_header_region(const bContext *C, ARegion *region)
|
|||
const ARegion *main_shelf_region = BKE_area_find_region_type(CTX_wm_area(C),
|
||||
RGN_TYPE_ASSET_SHELF);
|
||||
|
||||
AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*main_shelf_region);
|
||||
update_active_shelf(*C, *space_type, *hook);
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
|
||||
*main_shelf_region);
|
||||
update_active_shelf(*C, *space_type, *shelf_regiondata);
|
||||
|
||||
ED_region_header(C, region);
|
||||
}
|
||||
|
@ -466,21 +469,21 @@ int ED_asset_shelf_header_region_size()
|
|||
|
||||
void ED_asset_shelf_region_blend_read_data(BlendDataReader *reader, ARegion *region)
|
||||
{
|
||||
AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*region);
|
||||
if (!hook) {
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
if (!shelf_regiondata) {
|
||||
return;
|
||||
}
|
||||
shelf::hook_blend_read_data(reader, &hook);
|
||||
region->regiondata = hook;
|
||||
shelf::regiondata_blend_read_data(reader, &shelf_regiondata);
|
||||
region->regiondata = shelf_regiondata;
|
||||
}
|
||||
|
||||
void ED_asset_shelf_region_blend_write(BlendWriter *writer, ARegion *region)
|
||||
{
|
||||
AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*region);
|
||||
if (!hook) {
|
||||
RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(*region);
|
||||
if (!shelf_regiondata) {
|
||||
return;
|
||||
}
|
||||
shelf::hook_blend_write(writer, hook);
|
||||
shelf::regiondata_blend_write(writer, shelf_regiondata);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -513,12 +516,13 @@ int ED_asset_shelf_context(const bContext *C, const char *member, bContextDataRe
|
|||
return CTX_RESULT_NO_DATA;
|
||||
}
|
||||
|
||||
const AssetShelfHook *hook = AssetShelfHook::get_from_asset_shelf_region(*shelf_region);
|
||||
if (!hook) {
|
||||
const RegionAssetShelf *shelf_regiondata = RegionAssetShelf::get_from_asset_shelf_region(
|
||||
*shelf_region);
|
||||
if (!shelf_regiondata) {
|
||||
return CTX_RESULT_NO_DATA;
|
||||
}
|
||||
|
||||
CTX_data_pointer_set(result, &screen->id, &RNA_AssetShelf, hook->active_shelf);
|
||||
CTX_data_pointer_set(result, &screen->id, &RNA_AssetShelf, shelf_regiondata->active_shelf);
|
||||
|
||||
return CTX_RESULT_OK;
|
||||
}
|
||||
|
|
|
@ -38,17 +38,16 @@ AssetShelf *active_shelf_from_context(const bContext *C);
|
|||
void send_redraw_notifier(const bContext &C);
|
||||
|
||||
/**
|
||||
* Deep-copies \a hook into newly allocated memory. Must be freed using
|
||||
* #ED_asset_shelf_hook_free().
|
||||
* Deep-copies \a shelf_regiondata into newly allocated memory. Must be freed using
|
||||
* #regiondata_free().
|
||||
*/
|
||||
struct AssetShelfHook *hook_duplicate(const AssetShelfHook *hook);
|
||||
/**
|
||||
* Frees the contained data and \a hook itself.
|
||||
*/
|
||||
void hook_free(AssetShelfHook **hook);
|
||||
|
||||
void hook_blend_write(struct BlendWriter *writer, const struct AssetShelfHook *hook);
|
||||
void hook_blend_read_data(struct BlendDataReader *reader, struct AssetShelfHook **hook);
|
||||
struct RegionAssetShelf *regiondata_duplicate(const RegionAssetShelf *shelf_regiondata);
|
||||
/** Frees the contained data and \a shelf_regiondata itself. */
|
||||
void regiondata_free(RegionAssetShelf **shelf_regiondata);
|
||||
void regiondata_blend_write(struct BlendWriter *writer,
|
||||
const struct RegionAssetShelf *shelf_regiondata);
|
||||
void regiondata_blend_read_data(struct BlendDataReader *reader,
|
||||
struct RegionAssetShelf **shelf_regiondata);
|
||||
|
||||
/**
|
||||
* Frees the contained data, not \a shelf_settings itself.
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edasset
|
||||
*/
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BLO_read_write.h"
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "asset_shelf.hh"
|
||||
|
||||
AssetShelfHook *AssetShelfHook::get_from_asset_shelf_region(const ARegion ®ion)
|
||||
{
|
||||
if (region.regiontype != RGN_TYPE_ASSET_SHELF) {
|
||||
/* Should only be called on main asset shelf region. */
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<AssetShelfHook *>(region.regiondata);
|
||||
}
|
||||
|
||||
namespace blender::ed::asset::shelf {
|
||||
|
||||
AssetShelfHook *hook_duplicate(const AssetShelfHook *hook)
|
||||
{
|
||||
static_assert(std::is_trivial_v<AssetShelfHook>,
|
||||
"AssetShelfHook needs to be trivial to allow freeing with MEM_freeN()");
|
||||
AssetShelfHook *new_hook = MEM_new<AssetShelfHook>(__func__, *hook);
|
||||
|
||||
BLI_listbase_clear(&new_hook->shelves);
|
||||
LISTBASE_FOREACH (const AssetShelf *, shelf, &hook->shelves) {
|
||||
AssetShelf *new_shelf = MEM_new<AssetShelf>("duplicate asset shelf",
|
||||
blender::dna::shallow_copy(*shelf));
|
||||
new_shelf->settings = shelf->settings;
|
||||
BLI_addtail(&new_hook->shelves, new_shelf);
|
||||
if (hook->active_shelf == shelf) {
|
||||
new_hook->active_shelf = new_shelf;
|
||||
}
|
||||
}
|
||||
|
||||
return new_hook;
|
||||
}
|
||||
|
||||
void hook_free(AssetShelfHook **hook)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (AssetShelf *, shelf, &(*hook)->shelves) {
|
||||
MEM_delete(shelf);
|
||||
}
|
||||
MEM_SAFE_FREE(*hook);
|
||||
}
|
||||
|
||||
void hook_blend_write(BlendWriter *writer, const AssetShelfHook *hook)
|
||||
{
|
||||
BLO_write_struct(writer, AssetShelfHook, hook);
|
||||
LISTBASE_FOREACH (const AssetShelf *, shelf, &hook->shelves) {
|
||||
BLO_write_struct(writer, AssetShelf, shelf);
|
||||
settings_blend_write(writer, shelf->settings);
|
||||
}
|
||||
}
|
||||
|
||||
void hook_blend_read_data(BlendDataReader *reader, AssetShelfHook **hook)
|
||||
{
|
||||
if (!*hook) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLO_read_data_address(reader, hook);
|
||||
if ((*hook)->active_shelf) {
|
||||
BLO_read_data_address(reader, &(*hook)->active_shelf);
|
||||
}
|
||||
|
||||
BLO_read_list(reader, &(*hook)->shelves);
|
||||
LISTBASE_FOREACH (AssetShelf *, shelf, &(*hook)->shelves) {
|
||||
shelf->type = nullptr;
|
||||
settings_blend_read_data(reader, shelf->settings);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::ed::asset::shelf
|
|
@ -0,0 +1,83 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edasset
|
||||
*/
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BLO_read_write.h"
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "asset_shelf.hh"
|
||||
|
||||
RegionAssetShelf *RegionAssetShelf::get_from_asset_shelf_region(const ARegion ®ion)
|
||||
{
|
||||
if (region.regiontype != RGN_TYPE_ASSET_SHELF) {
|
||||
/* Should only be called on main asset shelf region. */
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<RegionAssetShelf *>(region.regiondata);
|
||||
}
|
||||
|
||||
namespace blender::ed::asset::shelf {
|
||||
|
||||
RegionAssetShelf *regiondata_duplicate(const RegionAssetShelf *shelf_regiondata)
|
||||
{
|
||||
static_assert(std::is_trivial_v<RegionAssetShelf>,
|
||||
"RegionAssetShelf needs to be trivial to allow freeing with MEM_freeN()");
|
||||
RegionAssetShelf *new_shelf_regiondata = MEM_new<RegionAssetShelf>(__func__, *shelf_regiondata);
|
||||
|
||||
BLI_listbase_clear(&new_shelf_regiondata->shelves);
|
||||
LISTBASE_FOREACH (const AssetShelf *, shelf, &shelf_regiondata->shelves) {
|
||||
AssetShelf *new_shelf = MEM_new<AssetShelf>("duplicate asset shelf",
|
||||
blender::dna::shallow_copy(*shelf));
|
||||
new_shelf->settings = shelf->settings;
|
||||
BLI_addtail(&new_shelf_regiondata->shelves, new_shelf);
|
||||
if (shelf_regiondata->active_shelf == shelf) {
|
||||
new_shelf_regiondata->active_shelf = new_shelf;
|
||||
}
|
||||
}
|
||||
|
||||
return new_shelf_regiondata;
|
||||
}
|
||||
|
||||
void regiondata_free(RegionAssetShelf **shelf_regiondata)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (AssetShelf *, shelf, &(*shelf_regiondata)->shelves) {
|
||||
MEM_delete(shelf);
|
||||
}
|
||||
MEM_SAFE_FREE(*shelf_regiondata);
|
||||
}
|
||||
|
||||
void regiondata_blend_write(BlendWriter *writer, const RegionAssetShelf *shelf_regiondata)
|
||||
{
|
||||
BLO_write_struct(writer, RegionAssetShelf, shelf_regiondata);
|
||||
LISTBASE_FOREACH (const AssetShelf *, shelf, &shelf_regiondata->shelves) {
|
||||
BLO_write_struct(writer, AssetShelf, shelf);
|
||||
settings_blend_write(writer, shelf->settings);
|
||||
}
|
||||
}
|
||||
|
||||
void regiondata_blend_read_data(BlendDataReader *reader, RegionAssetShelf **shelf_regiondata)
|
||||
{
|
||||
if (!*shelf_regiondata) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLO_read_data_address(reader, shelf_regiondata);
|
||||
if ((*shelf_regiondata)->active_shelf) {
|
||||
BLO_read_data_address(reader, &(*shelf_regiondata)->active_shelf);
|
||||
}
|
||||
|
||||
BLO_read_list(reader, &(*shelf_regiondata)->shelves);
|
||||
LISTBASE_FOREACH (AssetShelf *, shelf, &(*shelf_regiondata)->shelves) {
|
||||
shelf->type = nullptr;
|
||||
settings_blend_read_data(reader, shelf->settings);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::ed::asset::shelf
|
|
@ -807,22 +807,22 @@ typedef struct AssetShelf {
|
|||
} AssetShelf;
|
||||
|
||||
/**
|
||||
* Helper for asset shelf integration into spaces. See #ED_asset_shelf.h for a corresponding API.
|
||||
* Region-data for the main asset shelf region (#RGN_TYPE_ASSET_SHELF). Managed by the asset shelf
|
||||
* internals.
|
||||
*
|
||||
* A space can keep multiple shelf instances in storage, only one is active at a time.
|
||||
*
|
||||
* Allocate with #MEM_cnew().
|
||||
* Contains storage for all previously activated asset shelf instances plus info on the currently
|
||||
* active one (only one can be active at any time).
|
||||
*/
|
||||
typedef struct AssetShelfHook {
|
||||
typedef struct RegionAssetShelf {
|
||||
/** Owning list of previously activated asset shelves. */
|
||||
ListBase shelves;
|
||||
/** The currently active shelf, if any. Updated on redraw, so that context changes are reflected.
|
||||
*/
|
||||
AssetShelf *active_shelf; /* Non-owning. */
|
||||
#ifdef __cplusplus
|
||||
static AssetShelfHook *get_from_asset_shelf_region(const ARegion ®ion);
|
||||
static RegionAssetShelf *get_from_asset_shelf_region(const ARegion ®ion);
|
||||
#endif
|
||||
} AssetShelfHook;
|
||||
} RegionAssetShelf;
|
||||
|
||||
/* #AssetShelfSettings.display_flag */
|
||||
typedef enum AssetShelfSettings_DisplayFlag {
|
||||
|
|
Loading…
Reference in New Issue
Suggestion: I find it reads baddy when it's the existence of data in a list is undefined.
In this case the caller can ensure it's in the list in the case it's just been created.