UI: Asset Shelf (Experimental Feature) #104831
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue