Revert "UI: Support persistent view state, write tree-view height to files"

This reverts commit e1b4610bf4.
This commit is contained in:
2025-09-27 09:23:33 -05:00
parent c394c36413
commit 8832af0d4b
26 changed files with 41 additions and 208 deletions
@@ -374,8 +374,6 @@ ARegion *BKE_area_region_copy(const SpaceType *st, const ARegion *region)
BLI_listbase_clear(&newar->ui_previews);
BLI_duplicatelist(&newar->ui_previews, &region->ui_previews);
BLI_listbase_clear(&newar->view_states);
BLI_duplicatelist(&newar->view_states, &region->view_states);
return newar;
}
@@ -599,7 +597,6 @@ void BKE_area_region_free(SpaceType *st, ARegion *region)
BLI_freelistN(&region->ui_previews);
BLI_freelistN(&region->panels_category);
BLI_freelistN(&region->panels_category_active);
BLI_freelistN(&region->view_states);
}
void BKE_screen_area_free(ScrArea *area)
@@ -1113,10 +1110,6 @@ static void write_area(BlendWriter *writer, ScrArea *area)
LISTBASE_FOREACH (uiPreview *, ui_preview, &region->ui_previews) {
BLO_write_struct(writer, uiPreview, ui_preview);
}
LISTBASE_FOREACH (uiViewStateLink *, view_state, &region->view_states) {
BLO_write_struct(writer, uiViewStateLink, view_state);
}
}
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
@@ -1175,7 +1168,6 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
BLO_read_list(reader, &region->panels_category_active);
BLO_read_list(reader, &region->ui_lists);
BLO_read_list(reader, &region->view_states);
/* The area's search filter is runtime only, so we need to clear the active flag on read. */
/* Clear runtime flags (e.g. search filter is runtime only). */
@@ -443,7 +443,8 @@ void region_layout(const bContext *C, ARegion *region)
0,
style);
build_asset_view(*layout, active_shelf->settings.asset_library_reference, *active_shelf, *C, *region);
build_asset_view(
*layout, active_shelf->settings.asset_library_reference, *active_shelf, *C, *region);
int layout_height;
UI_block_layout_resolve(block, nullptr, &layout_height);
@@ -266,7 +266,7 @@ void build_asset_view(uiLayout &layout,
*block, "asset shelf asset view", std::move(asset_view));
ui::GridViewBuilder builder(*block);
builder.build_grid_view(C, *grid_view, layout);
builder.build_grid_view(*grid_view, region.v2d, layout);
}
/* ---------------------------------------------------------------------- */
@@ -208,7 +208,7 @@ static void catalog_selector_panel_draw(const bContext *C, Panel *panel)
"asset catalog tree view",
std::make_unique<AssetCatalogSelectorTree>(*library, *shelf));
ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
void catalog_selector_panel_register(ARegionType *region_type)
@@ -25,7 +25,6 @@
#include "DNA_defs.h"
#include "DNA_vec_types.h"
#include "DNA_screen_types.h"
#include "BLI_span.hh"
#include "BLI_string_ref.hh"
@@ -99,20 +98,6 @@ class AbstractView {
virtual bool supports_scrolling() const;
virtual void scroll(ViewScrollDirection direction);
/**
* From the current view state, return certain state that will be written to files (stored in
* #ARegion.view_states) to preserve it over UI changes and file loading. The state can be
* restored using #persistent_state_apply().
*
* Return an empty value if there's no state to preserve (default implementation).
*/
virtual std::optional<uiViewState> persistent_state() const;
/**
* Restore a view state given in \a state, which was created by #persistent_state() for saving in
* files, and potentially loaded from a file.
*/
virtual void persistent_state_apply(const uiViewState &state);
/**
* Makes \a item valid for display in this view. Behavior is undefined for items not registered
* with this.
@@ -167,10 +167,9 @@ class GridViewBuilder {
public:
GridViewBuilder(uiBlock &block);
void build_grid_view(const bContext &C,
AbstractGridView &grid_view,
uiLayout &layout,
std::optional<StringRef> search_string = {});
/** Build \a grid_view into the previously provided block, clipped by \a view_bounds (view space,
* typically `View2D.cur`). */
void build_grid_view(AbstractGridView &grid_view, const View2D &v2d, uiLayout &layout);
};
/** \} */
@@ -252,8 +252,6 @@ void UI_list_filter_and_sort_items(uiList *ui_list,
/**
* Override this for all available view types.
* \param idname: Used for restoring persistent state of this view, potentially written to files.
* Must not be longer than #BKE_ST_MAXNAME (including 0 terminator).
*/
blender::ui::AbstractGridView *UI_block_add_view(
uiBlock &block,
@@ -2699,7 +2699,6 @@ void uiTemplateAssetView(uiLayout *layout,
PointerRNA *r_drag_op_properties);
void uiTemplateLightLinkingCollection(uiLayout *layout,
bContext *C,
uiLayout *context_layout,
PointerRNA *ptr,
const char *propname);
@@ -2710,7 +2709,7 @@ void uiTemplateBoneCollectionTree(uiLayout *layout, bContext *C);
void uiTemplateGreasePencilLayerTree(uiLayout *layout, bContext *C);
#endif
void uiTemplateNodeTreeInterface(uiLayout *layout, bContext *C, PointerRNA *ptr);
void uiTemplateNodeTreeInterface(uiLayout *layout, PointerRNA *ptr);
/**
* Draw all node buttons and socket default values with the same panel structure used by the node.
*/
@@ -146,9 +146,6 @@ class AbstractTreeView : public AbstractView, public TreeViewItemContainer {
protected:
virtual void build_tree() = 0;
std::optional<uiViewState> persistent_state() const override;
void persistent_state_apply(const uiViewState &state) override;
private:
void foreach_view_item(FunctionRef<void(AbstractViewItem &)> iter_fn) const final;
void update_children_from_old(const AbstractView &old_view) override;
@@ -404,11 +401,7 @@ class TreeViewItemDropTarget : public DropTargetInterface {
class TreeViewBuilder {
public:
static void build_tree_view(const bContext &C,
AbstractTreeView &tree_view,
uiLayout &layout,
std::optional<StringRef> search_string = {},
bool add_box = true);
static void build_tree_view(AbstractTreeView &tree_view, uiLayout &layout);
private:
static void ensure_min_rows_items(AbstractTreeView &tree_view);
@@ -2020,7 +2020,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
/* Update bounds of all views in this block. If this block is a panel, this will be done later in
* #UI_panels_end(), because buttons are offset there. */
if (!block->panel) {
ui_block_views_end(region, block);
ui_block_views_bounds_calc(block);
}
if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
@@ -18,7 +18,6 @@
#include "DNA_listBase.h"
#include "RNA_types.hh"
#include "UI_abstract_view.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"
@@ -1539,10 +1538,7 @@ void ui_interface_tag_script_reload_queries();
/* interface_view.cc */
void ui_block_free_views(uiBlock *block);
void ui_block_views_end(ARegion *region, const uiBlock *block);
void ui_block_view_persistent_state_restore(const ARegion &region,
const uiBlock &block,
blender::ui::AbstractView &view);
void ui_block_views_bounds_calc(const uiBlock *block);
void ui_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params);
void ui_block_views_draw_overlays(const ARegion *region, const uiBlock *block);
uiViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block,
@@ -1871,7 +1871,7 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
/* Update bounds for all "views" in this block. Usually this is done in #UI_block_end(), but
* that wouldn't work because of the offset applied above. */
ui_block_views_end(region, block);
ui_block_views_bounds_calc(block);
}
}
@@ -475,5 +475,5 @@ void uiTemplateBoneCollectionTree(uiLayout *layout, bContext *C)
std::make_unique<blender::ui::bonecollections::BoneCollectionTreeView>(*armature));
tree_view->set_default_rows(3);
ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
@@ -412,5 +412,5 @@ void uiTemplateGreasePencilLayerTree(uiLayout *layout, bContext *C)
std::make_unique<blender::ui::greasepencil::LayerTreeView>(grease_pencil));
tree_view->set_default_rows(3);
ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
@@ -355,8 +355,10 @@ class CollectionView : public AbstractTreeView {
} // namespace blender::ui::light_linking
void uiTemplateLightLinkingCollection(
uiLayout *layout, bContext *C, uiLayout *context_layout, PointerRNA *ptr, const char *propname)
void uiTemplateLightLinkingCollection(uiLayout *layout,
uiLayout *context_layout,
PointerRNA *ptr,
const char *propname)
{
if (!ptr->data) {
return;
@@ -399,5 +401,5 @@ void uiTemplateLightLinkingCollection(
std::make_unique<blender::ui::light_linking::CollectionView>(*context_layout, *collection));
tree_view->set_default_rows(3);
blender::ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
blender::ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
@@ -500,7 +500,7 @@ wmDragNodeTreeInterface *NodePanelDropTarget::get_drag_node_tree_declaration(
} // namespace blender::ui::nodes
void uiTemplateNodeTreeInterface(uiLayout *layout, bContext *C, PointerRNA *ptr)
void uiTemplateNodeTreeInterface(uiLayout *layout, PointerRNA *ptr)
{
if (!ptr->data) {
return;
@@ -519,5 +519,5 @@ void uiTemplateNodeTreeInterface(uiLayout *layout, bContext *C, PointerRNA *ptr)
std::make_unique<blender::ui::nodes::NodeTreeInterfaceView>(nodetree, interface));
tree_view->set_default_rows(3);
blender::ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
blender::ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
@@ -126,13 +126,6 @@ void AbstractView::scroll(ViewScrollDirection /*direction*/)
BLI_assert_msg(false, "Unsupported for this view type");
}
std::optional<uiViewState> AbstractView::persistent_state() const
{
return {};
}
void AbstractView::persistent_state_apply(const uiViewState & /*state*/) {}
/** \} */
/* ---------------------------------------------------------------------- */
@@ -11,7 +11,6 @@
#include <limits>
#include <stdexcept>
#include "BKE_context.hh"
#include "BKE_icons.h"
#include "BLI_index_range.hh"
@@ -226,15 +225,12 @@ class BuildOnlyVisibleButtonsHelper {
void add_spacer_button(uiBlock &block, int row_count) const;
};
BuildOnlyVisibleButtonsHelper::BuildOnlyVisibleButtonsHelper(
const View2D &v2d,
const AbstractGridView &grid_view,
int cols_per_row)
: grid_view_(grid_view), style_(grid_view.get_style()), cols_per_row_(cols_per_row), v2d_(v2d)
BuildOnlyVisibleButtonsHelper::BuildOnlyVisibleButtonsHelper(const View2D &v2d,
const AbstractGridView &grid_view,
const int cols_per_row)
: v2d_(v2d), grid_view_(grid_view), style_(grid_view.get_style()), cols_per_row_(cols_per_row)
{
if (v2d.flag & V2D_IS_INIT && grid_view.get_item_count_filtered()) {
visible_items_range_ = this->get_visible_range();
}
visible_items_range_ = this->get_visible_range();
}
IndexRange BuildOnlyVisibleButtonsHelper::get_visible_range() const
@@ -389,16 +385,12 @@ uiLayout *GridViewLayoutBuilder::current_layout() const
GridViewBuilder::GridViewBuilder(uiBlock & /*block*/) {}
void GridViewBuilder::build_grid_view(const bContext &C,
AbstractGridView &grid_view,
uiLayout &layout,
std::optional<StringRef> search_string)
void GridViewBuilder::build_grid_view(AbstractGridView &grid_view,
const View2D &v2d,
uiLayout &layout)
{
uiBlock &block = *uiLayoutGetBlock(&layout);
const ARegion *region = CTX_wm_region(&C);
ui_block_view_persistent_state_restore(*region, block, grid_view);
grid_view.build_items();
grid_view.update_from_old(block);
grid_view.change_state_delayed();
@@ -407,7 +399,7 @@ void GridViewBuilder::build_grid_view(const bContext &C,
UI_block_layout_set_current(&block, &layout);
GridViewLayoutBuilder builder(layout);
builder.build_from_view(grid_view, region->v2d);
builder.build_from_view(grid_view, v2d);
}
/* ---------------------------------------------------------------------- */
@@ -27,7 +27,6 @@
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_string.h"
#include "ED_screen.hh"
@@ -57,8 +56,6 @@ static T *ui_block_add_view_impl(uiBlock &block,
StringRef idname,
std::unique_ptr<AbstractView> view)
{
BLI_assert(idname.size() < int64_t(sizeof(uiViewStateLink::idname)));
ViewLink *view_link = MEM_new<ViewLink>(__func__);
BLI_addtail(&block.views, view_link);
@@ -129,58 +126,9 @@ void ViewLink::views_bounds_calc(const uiBlock &block)
}
}
void ui_block_view_persistent_state_restore(const ARegion &region,
const uiBlock &block,
ui::AbstractView &view)
{
StringRef idname = [&]() -> StringRef {
LISTBASE_FOREACH (ViewLink *, link, &block.views) {
if (link->view.get() == &view) {
return link->idname;
}
}
return "";
}();
if (idname.is_empty()) {
BLI_assert_unreachable();
return;
}
LISTBASE_FOREACH (uiViewStateLink *, stored_state, &region.view_states) {
if (stored_state->idname == idname) {
view.persistent_state_apply(stored_state->state);
}
}
}
static uiViewStateLink *ensure_view_state(ARegion &region, const ViewLink &link)
{
LISTBASE_FOREACH (uiViewStateLink *, stored_state, &region.view_states) {
if (link.idname == stored_state->idname) {
return stored_state;
}
}
uiViewStateLink *new_state = MEM_cnew<uiViewStateLink>(__func__);
link.idname.copy(new_state->idname, sizeof(new_state->idname));
BLI_addhead(&region.view_states, new_state);
return new_state;
}
void ui_block_views_end(ARegion *region, const uiBlock *block)
void ui_block_views_bounds_calc(const uiBlock *block)
{
ViewLink::views_bounds_calc(*block);
if (region && region->regiontype != RGN_TYPE_TEMPORARY) {
LISTBASE_FOREACH (const ViewLink *, link, &block->views) {
/* Ensure persistent view state storage for writing to files if needed. */
if (std::optional<uiViewState> temp_state = link->view->persistent_state()) {
uiViewStateLink *state_link = ensure_view_state(*region, *link);
state_link->state = *temp_state;
}
}
}
}
void ui_block_views_listen(const uiBlock *block, const wmRegionListenerParams *listener_params)
@@ -121,28 +121,6 @@ void AbstractTreeView::set_default_rows(int default_rows)
custom_height_ = std::make_unique<int>(default_rows * padded_item_height());
}
std::optional<uiViewState> AbstractTreeView::persistent_state() const
{
if (!custom_height_) {
return {};
}
uiViewState state{0};
if (custom_height_) {
state.custom_height = *custom_height_ * UI_INV_SCALE_FAC;
}
return state;
}
void AbstractTreeView::persistent_state_apply(const uiViewState &state)
{
if (state.custom_height) {
set_default_rows(round_fl_to_int(state.custom_height * UI_SCALE_FAC) / padded_item_height());
}
}
int AbstractTreeView::count_visible_descendants(const AbstractTreeViewItem &parent) const
{
if (parent.is_collapsed()) {
@@ -901,19 +879,10 @@ void TreeViewBuilder::ensure_min_rows_items(AbstractTreeView &tree_view)
}
}
void TreeViewBuilder::build_tree_view(const bContext &C,
AbstractTreeView &tree_view,
uiLayout &layout,
std::optional<StringRef> search_string,
const bool add_box)
void TreeViewBuilder::build_tree_view(AbstractTreeView &tree_view, uiLayout &layout)
{
uiBlock &block = *uiLayoutGetBlock(&layout);
const ARegion *region = CTX_wm_region(&C);
if (region) {
ui_block_view_persistent_state_restore(*region, block, tree_view);
}
tree_view.build_tree();
tree_view.update_from_old(block);
tree_view.change_state_delayed();
@@ -771,8 +771,7 @@ bool file_is_asset_visible_in_catalog_filter_settings(
/* ---------------------------------------------------------------------- */
void file_create_asset_catalog_tree_view_in_layout(const bContext *C,
asset_system::AssetLibrary *asset_library,
void file_create_asset_catalog_tree_view_in_layout(asset_system::AssetLibrary *asset_library,
uiLayout *layout,
SpaceFile *space_file,
FileAssetSelectParams *params)
@@ -787,5 +786,5 @@ void file_create_asset_catalog_tree_view_in_layout(const bContext *C,
std::make_unique<ed::asset_browser::AssetCatalogTreeView>(
asset_library, params, *space_file));
ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
@@ -230,11 +230,11 @@ void file_path_to_ui_path(const char *path, char *r_pathi, int max_size);
/* C-handle for #ed::asset_browser::AssetCatalogFilterSettings. */
struct FileAssetCatalogFilterSettingsHandle;
void file_create_asset_catalog_tree_view_in_layout(const bContext *C,
blender::asset_system::AssetLibrary *asset_library,
uiLayout *layout,
SpaceFile *space_file,
FileAssetSelectParams *params);
void file_create_asset_catalog_tree_view_in_layout(
blender::asset_system::AssetLibrary *asset_library,
uiLayout *layout,
SpaceFile *space_file,
FileAssetSelectParams *params);
namespace blender::asset_system {
class AssetLibrary;
@@ -252,8 +252,7 @@ static void file_panel_asset_catalog_buttons_draw(const bContext *C, Panel *pane
uiItemS(col);
file_create_asset_catalog_tree_view_in_layout(
C, asset_library, col, sfile, params);
file_create_asset_catalog_tree_view_in_layout(asset_library, col, sfile, params);
}
void file_tools_region_panels_register(ARegionType *art)
@@ -320,7 +320,7 @@ void spreadsheet_data_set_panel_draw(const bContext *C, Panel *panel)
std::make_unique<GeometryDataSetTreeView>(
spreadsheet_get_display_geometry_set(sspreadsheet, object), *C));
ui::TreeViewBuilder::build_tree_view(*C, *tree_view, *layout);
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
}
} // namespace blender::ed::spreadsheet
@@ -319,31 +319,6 @@ typedef struct uiList { /* some list UI data need to be saved in file */
uiListDyn *dyn_data;
} uiList;
/** See #uiViewStateLink. */
typedef struct uiViewState {
/**
* User set height of the view in unscaled pixels. A value of 0 means no custom height was set
* and the default should be used.
*/
int custom_height;
char _pad[4];
} uiViewState;
/**
* Persistent storage for some state of views (#ui::AbstractView), for storage in a region. The
* view state is matched to the view using the view's idname.
*
* The actual state is stored in #uiViewState, so views can manage this conveniently without having
* to care about the idname and listbase pointers themselves.
*/
typedef struct uiViewStateLink {
struct uiViewStateLink *next, *prev;
char idname[64]; /* #BKE_ST_MAXNAME */
uiViewState state;
} uiViewStateLink;
typedef struct TransformOrientation {
struct TransformOrientation *next, *prev;
/** MAX_NAME. */
@@ -542,11 +517,6 @@ typedef struct ARegion {
ListBase handlers;
/** Panel categories runtime. */
ListBase panels_category;
/**
* Permanent state storage of #ui::AbstractView instances, so hiding regions with views or
* loading files remembers the view state.
*/
ListBase view_states; /* #uiViewStateLink */
/** Gizmo-map of this region. */
struct wmGizmoMap *gizmo_map;
@@ -2202,7 +2202,6 @@ void RNA_api_ui_layout(StructRNA *srna)
srna, "template_light_linking_collection", "uiTemplateLightLinkingCollection");
RNA_def_function_ui_description(func,
"Visualization of a content of a light linking collection");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func,
"context_layout",
"UILayout",
@@ -2224,7 +2223,6 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_node_tree_interface", "uiTemplateNodeTreeInterface");
RNA_def_function_ui_description(func, "Show a node tree interface");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func,
"interface",
"NodeTreeInterface",