include/sfx2/sidebar/Panel.hxx | 5 + sfx2/source/sidebar/Deck.cxx | 13 ++- sfx2/source/sidebar/DeckLayouter.cxx | 112 +++++++++++++++++++----------- sfx2/source/sidebar/Panel.cxx | 18 ++++ sfx2/source/sidebar/SidebarController.cxx | 1 5 files changed, 104 insertions(+), 45 deletions(-)
New commits: commit 39055f5e32fc0314353e95252ed54ae591881445 Author: Michael Meeks <[email protected]> AuthorDate: Sat Jan 4 22:37:31 2020 +0000 Commit: Michael Meeks <[email protected]> CommitDate: Mon Jan 6 14:27:36 2020 +0100 sidebar: improve invalidation tracking for Panels. Only emit an invalidation on panels that change position. Ensure we invalidate the ScrollContainerWindow for updated separators. Emit a single vcl::Region for an invalidation rather than per panel. Change-Id: I5452791ac9a7d1a9b8604c7704d24641160c275b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86234 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Meeks <[email protected]> diff --git a/sfx2/source/sidebar/Deck.cxx b/sfx2/source/sidebar/Deck.cxx index 074334c2e415..60ea6b71ebba 100644 --- a/sfx2/source/sidebar/Deck.cxx +++ b/sfx2/source/sidebar/Deck.cxx @@ -385,6 +385,7 @@ void Deck::ScrollContainerWindow::Paint(vcl::RenderContext& rRenderContext, cons void Deck::ScrollContainerWindow::SetSeparators (const ::std::vector<sal_Int32>& rSeparators) { maSeparators = rSeparators; + Invalidate(); } } } // end of namespace sfx2::sidebar diff --git a/sfx2/source/sidebar/DeckLayouter.cxx b/sfx2/source/sidebar/DeckLayouter.cxx index 33d6dc62f4b9..66f60f2ef03e 100644 --- a/sfx2/source/sidebar/DeckLayouter.cxx +++ b/sfx2/source/sidebar/DeckLayouter.cxx @@ -78,6 +78,8 @@ namespace { const sal_Int32 nHeightToDistribute, const sal_Int32 nContainerHeight, const bool bMinimumHeightIsBase); + bool MoveResizePixel(const VclPtr<vcl::Window> &pWindow, + const Point &rNewPos, const Size &rNewSize); sal_Int32 PlacePanels ( ::std::vector<LayoutItem>& rLayoutItems, const sal_Int32 nWidth, @@ -246,6 +248,17 @@ tools::Rectangle LayoutPanels ( return aBox; } +bool MoveResizePixel(const VclPtr<vcl::Window> &pWindow, + const Point &rNewPos, const Size &rNewSize) +{ + Point aCurPos = pWindow->GetPosPixel(); + Size aCurSize = pWindow->GetSizePixel(); + if (rNewPos == aCurPos && aCurSize == rNewSize) + return false; + pWindow->setPosSizePixel(rNewPos.X(), rNewPos.Y(), rNewSize.Width(), rNewSize.Height()); + return true; +} + sal_Int32 PlacePanels ( ::std::vector<LayoutItem>& rLayoutItems, const sal_Int32 nWidth, @@ -256,6 +269,8 @@ sal_Int32 PlacePanels ( const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight)); sal_Int32 nY (0); + vcl::Region aInvalidRegions; + // Assign heights and places. for(::std::vector<LayoutItem>::const_iterator iItem(rLayoutItems.begin()), iEnd(rLayoutItems.end()); @@ -268,8 +283,11 @@ sal_Int32 PlacePanels ( Panel& rPanel (*iItem->mpPanel); // Separator above the panel title bar. - aSeparators.push_back(nY); - nY += nDeckSeparatorHeight; + if (!rPanel.IsLurking()) + { + aSeparators.push_back(nY); + nY += nDeckSeparatorHeight; + } // Place the title bar. VclPtr<PanelTitleBar> pTitleBar = rPanel.GetTitleBar(); @@ -313,8 +331,15 @@ sal_Int32 PlacePanels ( } // Place the panel. - rPanel.setPosSizePixel(0, nY, nWidth, nPanelHeight); - rPanel.Invalidate(); + Point aNewPos(0, nY); + Size aNewSize(nWidth, nPanelHeight); + + // Only invalidate if we moved + if (MoveResizePixel(&rPanel, aNewPos, aNewSize)) + { + tools::Rectangle aRect(aNewPos, aNewSize); + aInvalidRegions.Union(rPanel.PixelToLogic(aRect)); + } nY += nPanelHeight; } @@ -338,6 +363,8 @@ sal_Int32 PlacePanels ( if (pScrollContainerWindow != nullptr) pScrollContainerWindow->SetSeparators(aSeparators); + rScrollContainer.Invalidate(aInvalidRegions); + return nY; } commit aacc5ed083b53a99719034ff3b87105741982609 Author: Michael Meeks <[email protected]> AuthorDate: Sat Jan 4 18:09:20 2020 +0000 Commit: Michael Meeks <[email protected]> CommitDate: Mon Jan 6 14:27:28 2020 +0100 sidebar: allow panels to lurk around instead of being disposed. Creating and destroying sidebar panels is done remarkably often - on changes of context eg. The process is remarkably expensive - loading UI XML files, processing them etc. and is un-necessary. Instead let panels lurk around for future use - particularly in the Properties deck which gets the most thrash. This gives a big speedup particularly noticable on mobile where it could take several seconds to load switch between panels for eg. shape vs. slide properties when tapping to edit text. Change-Id: I497e77432c11bbd1e35a8a8716519cabc3730e61 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86233 Tested-by: Michael Meeks <[email protected]> Reviewed-by: Michael Meeks <[email protected]> diff --git a/include/sfx2/sidebar/Panel.hxx b/include/sfx2/sidebar/Panel.hxx index 2beec47dfea6..7bcdfdcd8d4b 100644 --- a/include/sfx2/sidebar/Panel.hxx +++ b/include/sfx2/sidebar/Panel.hxx @@ -58,6 +58,10 @@ public: const OUString& GetId() const { return msPanelId;} void TriggerDeckLayouting() { maDeckLayoutTrigger(); } + /// Set whether a panel should be present but invisible / inactive + void SetLurkMode(bool bLurk); + bool IsLurking() const { return mbLurking; } + virtual void Resize() override; virtual void DataChanged (const DataChangedEvent& rEvent) override; virtual void ApplySettings(vcl::RenderContext& rRenderContext) override; @@ -70,6 +74,7 @@ private: css::uno::Reference<css::ui::XUIElement> mxElement; css::uno::Reference<css::ui::XSidebarPanel> mxPanelComponent; bool mbIsExpanded; + bool mbLurking; const std::function<void()> maDeckLayoutTrigger; const std::function<Context()> maContextAccess; diff --git a/sfx2/source/sidebar/Deck.cxx b/sfx2/source/sidebar/Deck.cxx index fba9f1330833..074334c2e415 100644 --- a/sfx2/source/sidebar/Deck.cxx +++ b/sfx2/source/sidebar/Deck.cxx @@ -209,17 +209,25 @@ bool Deck::ProcessWheelEvent(CommandEvent const * pCommandEvent) */ void Deck::ResetPanels(const SharedPanelContainer& rPanelContainer) { - // First dispose old panels we no longer need. + SharedPanelContainer aHiddens; + + // First hide old panels we don't need just now. for (VclPtr<Panel> & rpPanel : maPanels) { bool bFound = false; for (const auto & i : rPanelContainer) bFound = bFound || (rpPanel.get() == i.get()); if (!bFound) // this one didn't survive. - rpPanel.disposeAndClear(); + { + rpPanel->SetLurkMode(true); + aHiddens.push_back(rpPanel); + } } maPanels = rPanelContainer; + // Hidden ones always at the end + maPanels.insert(std::end(maPanels), std::begin(aHiddens), std::end(aHiddens)); + RequestLayoutInternal(); } diff --git a/sfx2/source/sidebar/DeckLayouter.cxx b/sfx2/source/sidebar/DeckLayouter.cxx index 0337c7cc46d6..33d6dc62f4b9 100644 --- a/sfx2/source/sidebar/DeckLayouter.cxx +++ b/sfx2/source/sidebar/DeckLayouter.cxx @@ -289,7 +289,7 @@ sal_Int32 PlacePanels ( } } - if (rPanel.IsExpanded()) + if (rPanel.IsExpanded() && !rPanel.IsLurking()) { rPanel.Show(); @@ -353,46 +353,51 @@ void GetRequestedSizes ( for (LayoutItem& item : rLayoutItems) { - ui::LayoutSize aLayoutSize (ui::LayoutSize(0,0,0)); - if (item.mpPanel != nullptr) + item.maLayoutSize = ui::LayoutSize(0,0,0); + + if (item.mpPanel == nullptr) + continue; + + if (item.mpPanel->IsLurking()) { - if (rLayoutItems.size() == 1 - && item.mpPanel->IsTitleBarOptional()) - { - // There is only one panel and its title bar is - // optional => hide it. - rAvailableHeight -= nDeckSeparatorHeight; - item.mbShowTitleBar = false; - } - else - { - // Show the title bar and a separator above and below - // the title bar. - const sal_Int32 nPanelTitleBarHeight( - Theme::GetInteger(Theme::Int_PanelTitleBarHeight) - * item.mpPanel->GetDPIScaleFactor()); - - rAvailableHeight -= nPanelTitleBarHeight; - rAvailableHeight -= nDeckSeparatorHeight; - } + item.mbShowTitleBar = false; + continue; + } - if (item.mpPanel->IsExpanded()) + if (rLayoutItems.size() == 1 + && item.mpPanel->IsTitleBarOptional()) + { + // There is only one panel and its title bar is + // optional => hide it. + rAvailableHeight -= nDeckSeparatorHeight; + item.mbShowTitleBar = false; + } + else + { + // Show the title bar and a separator above and below + // the title bar. + const sal_Int32 nPanelTitleBarHeight( + Theme::GetInteger(Theme::Int_PanelTitleBarHeight) + * item.mpPanel->GetDPIScaleFactor()); + + rAvailableHeight -= nPanelTitleBarHeight; + rAvailableHeight -= nDeckSeparatorHeight; + } + + if (item.mpPanel->IsExpanded()) + { + Reference<ui::XSidebarPanel> xPanel(item.mpPanel->GetPanelComponent()); + if (xPanel.is()) { - Reference<ui::XSidebarPanel> xPanel(item.mpPanel->GetPanelComponent()); - if (xPanel.is()) - { - aLayoutSize = xPanel->getHeightForWidth(rContentBox.GetWidth()); - - const sal_Int32 nWidth = xPanel->getMinimalWidth(); - if (nWidth > rMinimalWidth) - rMinimalWidth = nWidth; - } - else - aLayoutSize = ui::LayoutSize(MinimalPanelHeight, -1, 0); + item.maLayoutSize = xPanel->getHeightForWidth(rContentBox.GetWidth()); + + const sal_Int32 nWidth = xPanel->getMinimalWidth(); + if (nWidth > rMinimalWidth) + rMinimalWidth = nWidth; } + else + item.maLayoutSize = ui::LayoutSize(MinimalPanelHeight, -1, 0); } - - item.maLayoutSize = aLayoutSize; } } diff --git a/sfx2/source/sidebar/Panel.cxx b/sfx2/source/sidebar/Panel.cxx index 7968f667b92d..dc4ea895d26d 100644 --- a/sfx2/source/sidebar/Panel.cxx +++ b/sfx2/source/sidebar/Panel.cxx @@ -57,6 +57,7 @@ Panel::Panel(const PanelDescriptor& rPanelDescriptor, , mxElement() , mxPanelComponent() , mbIsExpanded(bIsInitiallyExpanded) + , mbLurking(false) , maDeckLayoutTrigger(rDeckLayoutTrigger) , maContextAccess(rContextAccess) , mxFrame(rxFrame) @@ -70,6 +71,12 @@ Panel::~Panel() assert(!mpTitleBar); } +void Panel::SetLurkMode(bool bLurk) +{ + // cf. DeckLayouter + mbLurking = bLurk; +} + void Panel::ApplySettings(vcl::RenderContext& rRenderContext) { rRenderContext.SetBackground(Theme::GetPaint(Theme::Paint_PanelBackground).GetWallpaper()); @@ -77,9 +84,14 @@ void Panel::ApplySettings(vcl::RenderContext& rRenderContext) boost::property_tree::ptree Panel::DumpAsPropertyTree() { - boost::property_tree::ptree aTree(vcl::Window::DumpAsPropertyTree()); - aTree.put("type", "panel"); - return aTree; + if (!IsLurking()) + { + boost::property_tree::ptree aTree(vcl::Window::DumpAsPropertyTree()); + aTree.put("type", "panel"); + return aTree; + } + else + return boost::property_tree::ptree(); } void Panel::dispose() diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx index 91405791c727..f11ce95e7213 100644 --- a/sfx2/source/sidebar/SidebarController.cxx +++ b/sfx2/source/sidebar/SidebarController.cxx @@ -716,6 +716,7 @@ void SidebarController::CreatePanels(const OUString& rDeckId, const Context& rCo Panel *const pPanel(pDeck->GetPanel(rPanelContexDescriptor.msId)); if (pPanel != nullptr) { + pPanel->SetLurkMode(false); aNewPanels[nWriteIndex] = pPanel; pPanel->SetExpanded( rPanelContexDescriptor.mbIsInitiallyVisible ); ++nWriteIndex; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
