UI: Remember scroll offset for tree-views

f0db870822 added support for tree-views to remember state, but only to
remember their custom height for the start. This change makes the scroll
offset be remembered too.

Not remembering the scroll offset can be very annoying in some cases,
e.g. when working with bone collections and changing the active tab in
the properties editor often. In realistic, non-trivial bone collection
set ups this can lead to a lot of repeated scrolling.

Cherry-picked for the 4.4 release since this solves a real usability
issue with trivial changes. Discussed with Thomas and others.
This commit is contained in:
Julian Eisel
2025-02-10 15:50:00 +01:00
parent d9ea0e0a29
commit ed0d01c5af
3 changed files with 15 additions and 2 deletions

View File

@@ -117,6 +117,8 @@ class AbstractTreeView : public AbstractView, public TreeViewItemContainer {
*/
/* TODO support region zoom. */
std::shared_ptr<int> custom_height_ = nullptr;
/** Scroll offset in items, also see #uiViewState.scroll_offset. Clamped before creating the
* button layout. */
std::shared_ptr<int> scroll_value_ = nullptr;
friend class AbstractTreeViewItem;

View File

@@ -134,7 +134,7 @@ void AbstractTreeView::set_default_rows(int default_rows)
std::optional<uiViewState> AbstractTreeView::persistent_state() const
{
if (!custom_height_) {
if (!custom_height_ && !scroll_value_) {
return {};
}
@@ -143,6 +143,9 @@ std::optional<uiViewState> AbstractTreeView::persistent_state() const
if (custom_height_) {
state.custom_height = *custom_height_ * UI_INV_SCALE_FAC;
}
if (scroll_value_) {
state.scroll_offset = *scroll_value_;
}
return state;
}
@@ -152,6 +155,9 @@ 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());
}
if (state.scroll_offset) {
scroll_value_ = std::make_shared<int>(state.scroll_offset);
}
}
int AbstractTreeView::count_visible_descendants(const AbstractTreeViewItem &parent) const

View File

@@ -329,7 +329,12 @@ typedef struct uiViewState {
* and the default should be used.
*/
int custom_height;
char _pad[4];
/**
* Amount of vertical scrolling. View types decide on the unit:
* - Tree views: Number of items scrolled out of view (#scroll_offset of 5 means 5 items are
* scrolled out of view).
*/
int scroll_offset;
} uiViewState;
/**