diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/modules/juce_gui_basics/widgets/juce_TreeView.cpp index 38c2277740..75d261787b 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -747,9 +747,10 @@ public: enum class Async { yes, no }; - void recalculatePositions (Async useAsyncUpdate) + void recalculatePositions (Async useAsyncUpdate, std::optional> viewportPosition) { needsRecalculating = true; + viewportAfterRecalculation = std::move (viewportPosition); if (useAsyncUpdate == Async::yes) triggerAsyncUpdate(); @@ -765,15 +766,13 @@ private: void handleAsyncUpdate() override { - if (structureChanged) + if (std::exchange (structureChanged, false)) { if (auto* handler = owner.getAccessibilityHandler()) handler->notifyAccessibilityEvent (AccessibilityEvent::structureChanged); - - structureChanged = false; } - if (needsRecalculating) + if (std::exchange (needsRecalculating, false)) { if (auto* root = owner.rootItem) { @@ -790,7 +789,8 @@ private: updateComponents (false); - needsRecalculating = false; + if (const auto viewportPosition = std::exchange (viewportAfterRecalculation, {})) + setViewPosition (viewportPosition->getX(), viewportPosition->getY()); } } @@ -810,6 +810,7 @@ private: TreeView& owner; int lastX = -1; bool structureChanged = false, needsRecalculating = false; + std::optional> viewportAfterRecalculation; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeViewport) }; @@ -858,7 +859,7 @@ void TreeView::setRootItem (TreeViewItem* const newRootItem) rootItem->setOpen (true); } - viewport->recalculatePositions (TreeViewport::Async::no); + viewport->recalculatePositions (TreeViewport::Async::no, {}); } } @@ -1020,10 +1021,6 @@ void TreeView::restoreOpennessState (const XmlElement& newState, bool restoreSto { rootItem->restoreOpennessState (newState); - if (newState.hasAttribute ("scrollPos")) - viewport->setViewPosition (viewport->getViewPositionX(), - newState.getIntAttribute ("scrollPos")); - if (restoreStoredSelection) { clearSelectedItems(); @@ -1033,7 +1030,11 @@ void TreeView::restoreOpennessState (const XmlElement& newState, bool restoreSto item->setSelected (true, false); } - updateVisibleItems(); + const auto scrollPos = newState.hasAttribute ("scrollPos") + ? std::make_optional> (viewport->getViewPositionX(), newState.getIntAttribute ("scrollPos")) + : std::nullopt; + + updateVisibleItems (std::move (scrollPos)); } } @@ -1216,9 +1217,9 @@ bool TreeView::keyPressed (const KeyPress& key) return false; } -void TreeView::updateVisibleItems() +void TreeView::updateVisibleItems (std::optional> viewportPosition) { - viewport->recalculatePositions (TreeViewport::Async::yes); + viewport->recalculatePositions (TreeViewport::Async::yes, std::move (viewportPosition)); } //============================================================================== diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.h b/modules/juce_gui_basics/widgets/juce_TreeView.h index 0a40a90ff1..608b3542bb 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.h +++ b/modules/juce_gui_basics/widgets/juce_TreeView.h @@ -935,7 +935,7 @@ private: std::unique_ptr createAccessibilityHandler() override; void itemsChanged() noexcept; - void updateVisibleItems(); + void updateVisibleItems (std::optional> viewportPosition = {}); void updateButtonUnderMouse (const MouseEvent&); void showDragHighlight (const InsertPoint&) noexcept; void hideDragHighlight() noexcept;