Tabs to activate a catalog

The tabs should be fully working themselves, however we don't filter
the asset shelf contents based on the active catalog (well, catalog
path) yet.

Includes the changes from D17164.
This commit is contained in:
Julian Eisel 2023-02-01 12:47:52 +01:00
parent 3700b74476
commit d5c60f912f
7 changed files with 122 additions and 43 deletions

View File

@ -104,9 +104,23 @@ static void asset_shelf_settings_clear_enabled_catalogs(AssetShelfSettings &shel
BLI_assert(BLI_listbase_is_empty(&shelf_settings.enabled_catalog_paths));
}
static void asset_shelf_settings_set_active_catalog(AssetShelfSettings &shelf_settings,
const asset_system::AssetCatalogPath &path)
{
MEM_delete(shelf_settings.active_catalog_path);
shelf_settings.active_catalog_path = BLI_strdupn(path.c_str(), path.length());
}
static bool asset_shelf_settings_is_active_catalog(const AssetShelfSettings &shelf_settings,
const asset_system::AssetCatalogPath &path)
{
return shelf_settings.active_catalog_path && shelf_settings.active_catalog_path == path.str();
}
void ED_asset_shelf_settings_free(AssetShelfSettings *shelf_settings)
{
asset_shelf_settings_clear_enabled_catalogs(*shelf_settings);
MEM_delete(shelf_settings->active_catalog_path);
}
void ED_asset_shelf_settings_blend_write(BlendWriter *writer,
@ -373,6 +387,50 @@ static uiBlock *asset_shelf_catalog_selector_block_draw(bContext *C,
/** \} */
/* -------------------------------------------------------------------- */
/** \name Catalog toggle buttons
* \{ */
static void add_catalog_toggle_buttons(AssetShelfSettings &shelf_settings, uiLayout &layout)
{
uiBlock *block = uiLayoutGetBlock(&layout);
const uiStyle *style = UI_style_get_dpi();
asset_shelf_settings_foreach_enabled_catalog_path(
shelf_settings, [&shelf_settings, block, style](const asset_system::AssetCatalogPath &path) {
const char *name = path.name().c_str();
const int string_width = UI_fontstyle_string_width(&style->widget, name);
const int pad_x = UI_UNIT_X * 0.3f;
const int but_width = std::min(string_width + 2 * pad_x, UI_UNIT_X * 8);
uiBut *but = uiDefBut(
block,
UI_BTYPE_TAB,
0,
name,
0,
0,
but_width,
UI_UNIT_Y,
nullptr,
0,
0,
0,
0,
"Enable catalog, making contained assets visible in the asset shelf");
UI_but_drawflag_enable(but, UI_BUT_ALIGN_TOP);
UI_but_func_set(but, [&shelf_settings, path](bContext &) {
asset_shelf_settings_set_active_catalog(shelf_settings, path);
});
UI_but_func_pushed_state_set(but, [&shelf_settings, path](const uiBut &) -> bool {
return asset_shelf_settings_is_active_catalog(shelf_settings, path);
});
});
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Asset Shelf Footer
*
@ -399,10 +457,7 @@ static void asset_shelf_footer_draw(const bContext *C, Header *header)
AssetShelfSettings *shelf_settings = get_asset_shelf_settings_from_context(C);
if (shelf_settings) {
asset_shelf_settings_foreach_enabled_catalog_path(
*shelf_settings, [layout](const asset_system::AssetCatalogPath &path) {
uiItemL(layout, path.name().c_str(), ICON_NONE);
});
add_catalog_toggle_buttons(*shelf_settings, *layout);
}
}

View File

@ -1748,8 +1748,6 @@ void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but);
void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN);
void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg);
struct PointerRNA *UI_but_extra_operator_icon_add(uiBut *but,
const char *opname,
wmOperatorCallContext opcontext,

View File

@ -17,6 +17,7 @@ namespace blender::nodes::geo_eval_log {
struct GeometryAttributeInfo;
}
struct bContext;
struct StructRNA;
struct uiBlock;
struct uiBut;
@ -54,6 +55,9 @@ void attribute_search_add_items(StringRefNull str,
} // namespace blender::ui
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);
/**
* Override this for all available view types.
*/

View File

@ -51,6 +51,7 @@
#include "BLT_translation.h"
#include "UI_interface.h"
#include "UI_interface.hh"
#include "UI_interface_icons.h"
#include "UI_view2d.h"
@ -749,6 +750,10 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
if (but->func != oldbut->func) {
return false;
}
if (but->apply_func.target<void(bContext &)>() !=
oldbut->apply_func.target<void(bContext &)>()) {
return false;
}
if (but->funcN != oldbut->funcN) {
return false;
}
@ -2181,7 +2186,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
{
int is_push = 0;
if (but->pushed_state_func) {
return but->pushed_state_func(but, but->pushed_state_arg);
return but->pushed_state_func(*but);
}
if (but->bit) {
@ -6001,6 +6006,11 @@ void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
but->func_arg2 = arg2;
}
void UI_but_func_set(uiBut *but, std::function<void(bContext &)> func)
{
but->apply_func = func;
}
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
{
if (but->func_argN) {
@ -6033,10 +6043,9 @@ void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFre
but->tip_arg_free = free_arg;
}
void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg)
void UI_but_func_pushed_state_set(uiBut *but, std::function<bool(const uiBut &)> func)
{
but->pushed_state_func = func;
but->pushed_state_arg = arg;
ui_but_update(but);
}

View File

@ -457,45 +457,47 @@ struct uiHandleButtonData {
};
struct uiAfterFunc {
uiAfterFunc *next, *prev;
uiAfterFunc *next = nullptr, *prev = nullptr;
uiButHandleFunc func;
void *func_arg1;
void *func_arg2;
uiButHandleFunc func = nullptr;
void *func_arg1 = nullptr;
void *func_arg2 = nullptr;
/** C++ version of #func above, without need for void pointer arguments. */
std::function<void(bContext &)> apply_func;
uiButHandleNFunc funcN;
void *func_argN;
uiButHandleNFunc funcN = nullptr;
void *func_argN = nullptr;
uiButHandleRenameFunc rename_func;
void *rename_arg1;
void *rename_orig;
uiButHandleRenameFunc rename_func = nullptr;
void *rename_arg1 = nullptr;
void *rename_orig = nullptr;
uiBlockHandleFunc handle_func;
void *handle_func_arg;
int retval;
uiBlockHandleFunc handle_func = nullptr;
void *handle_func_arg = nullptr;
int retval = 0;
uiMenuHandleFunc butm_func;
void *butm_func_arg;
int a2;
uiMenuHandleFunc butm_func = nullptr;
void *butm_func_arg = nullptr;
int a2 = 0;
wmOperator *popup_op;
wmOperatorType *optype;
wmOperator *popup_op = nullptr;
wmOperatorType *optype = nullptr;
wmOperatorCallContext opcontext;
PointerRNA *opptr;
PointerRNA *opptr = nullptr;
PointerRNA rnapoin;
PropertyRNA *rnaprop;
PointerRNA rnapoin = {};
PropertyRNA *rnaprop = nullptr;
void *search_arg;
uiFreeArgFunc search_arg_free_fn;
void *search_arg = nullptr;
uiFreeArgFunc search_arg_free_fn = nullptr;
uiBlockInteraction_CallbackData custom_interaction_callbacks;
uiBlockInteraction_Handle *custom_interaction_handle;
uiBlockInteraction_CallbackData custom_interaction_callbacks = {};
uiBlockInteraction_Handle *custom_interaction_handle = nullptr;
bContextStore *context;
bContextStore *context = nullptr;
char undostr[BKE_UNDO_STR_MAX];
char drawstr[UI_MAX_DRAW_STR];
char undostr[BKE_UNDO_STR_MAX] = "";
char drawstr[UI_MAX_DRAW_STR] = "";
};
static void button_activate_init(bContext *C,
@ -743,7 +745,7 @@ static ListBase UIAfterFuncs = {nullptr, nullptr};
static uiAfterFunc *ui_afterfunc_new()
{
uiAfterFunc *after = MEM_cnew<uiAfterFunc>(__func__);
uiAfterFunc *after = MEM_new<uiAfterFunc>(__func__);
BLI_addtail(&UIAfterFuncs, after);
@ -800,8 +802,9 @@ static void popup_check(bContext *C, wmOperator *op)
*/
static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but)
{
return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop ||
block->handle_func || (but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
return (but->func || but->apply_func || but->funcN || but->rename_func || but->optype ||
but->rnaprop || block->handle_func ||
(but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
(block->handle && block->handle->popup_op));
}
@ -826,10 +829,11 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
else {
after->func = but->func;
}
after->func_arg1 = but->func_arg1;
after->func_arg2 = but->func_arg2;
after->apply_func = but->apply_func;
after->funcN = but->funcN;
after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : nullptr;
@ -998,7 +1002,8 @@ static void ui_apply_but_funcs_after(bContext *C)
LISTBASE_FOREACH_MUTABLE (uiAfterFunc *, afterf, &funcs) {
uiAfterFunc after = *afterf; /* Copy to avoid memory leak on exit(). */
BLI_freelinkN(&funcs, afterf);
BLI_remlink(&funcs, afterf);
MEM_delete(afterf);
if (after.context) {
CTX_store_set(C, after.context);
@ -1040,6 +1045,9 @@ static void ui_apply_but_funcs_after(bContext *C)
if (after.func) {
after.func(C, after.func_arg1, after.func_arg2);
}
if (after.apply_func) {
after.apply_func(*C);
}
if (after.funcN) {
after.funcN(C, after.func_argN, after.func_arg2);
}

View File

@ -7,6 +7,8 @@
#pragma once
#include <functional>
#include "BLI_compiler_attrs.h"
#include "BLI_rect.h"
#include "BLI_vector.hh"
@ -199,6 +201,9 @@ struct uiBut {
uiButHandleFunc func = nullptr;
void *func_arg1 = nullptr;
void *func_arg2 = nullptr;
/** C++ version of #func above. Allows storing arbitrary data in a type safe way, no void
* pointer arguments.*/
std::function<void(bContext &)> apply_func;
uiButHandleNFunc funcN = nullptr;
void *func_argN = nullptr;
@ -275,8 +280,7 @@ struct uiBut {
double *editval = nullptr;
float *editvec = nullptr;
uiButPushedStateFunc pushed_state_func = nullptr;
const void *pushed_state_arg = nullptr;
std::function<bool(const uiBut &)> pushed_state_func;
/** Little indicator (e.g., counter) displayed on top of some icons. */
IconTextOverlay icon_overlay_text = {};

View File

@ -749,6 +749,7 @@ enum {
typedef struct AssetShelfSettings {
/* TODO make this per mode? (or use a custom identifier?) */
ListBase enabled_catalog_paths; /* #LinkData */
const char *active_catalog_path;
} AssetShelfSettings;
#ifdef __cplusplus