xref: /trunk/main/sfx2/source/sidebar/DeckLayouter.cxx (revision b12a77c9de73410d92ad280a3c79a4e8692534ea)
17a32b0c8SAndre Fischer /**************************************************************
27a32b0c8SAndre Fischer  *
37a32b0c8SAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
47a32b0c8SAndre Fischer  * or more contributor license agreements.  See the NOTICE file
57a32b0c8SAndre Fischer  * distributed with this work for additional information
67a32b0c8SAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
77a32b0c8SAndre Fischer  * to you under the Apache License, Version 2.0 (the
87a32b0c8SAndre Fischer  * "License"); you may not use this file except in compliance
97a32b0c8SAndre Fischer  * with the License.  You may obtain a copy of the License at
107a32b0c8SAndre Fischer  *
117a32b0c8SAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
127a32b0c8SAndre Fischer  *
137a32b0c8SAndre Fischer  * Unless required by applicable law or agreed to in writing,
147a32b0c8SAndre Fischer  * software distributed under the License is distributed on an
157a32b0c8SAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
167a32b0c8SAndre Fischer  * KIND, either express or implied.  See the License for the
177a32b0c8SAndre Fischer  * specific language governing permissions and limitations
187a32b0c8SAndre Fischer  * under the License.
197a32b0c8SAndre Fischer  *
207a32b0c8SAndre Fischer  *************************************************************/
217a32b0c8SAndre Fischer 
22*b12a77c9Smseidel 
23*b12a77c9Smseidel 
247a32b0c8SAndre Fischer #include "precompiled_sfx2.hxx"
257a32b0c8SAndre Fischer 
267a32b0c8SAndre Fischer #include "DeckLayouter.hxx"
277a32b0c8SAndre Fischer #include "sfx2/sidebar/Theme.hxx"
287a32b0c8SAndre Fischer #include "Panel.hxx"
298a1a651aSAndre Fischer #include "PanelTitleBar.hxx"
307a32b0c8SAndre Fischer #include "Deck.hxx"
317a32b0c8SAndre Fischer 
327a32b0c8SAndre Fischer #include <vcl/window.hxx>
337a32b0c8SAndre Fischer #include <vcl/scrbar.hxx>
347a32b0c8SAndre Fischer 
357a32b0c8SAndre Fischer using namespace ::com::sun::star;
367a32b0c8SAndre Fischer using namespace ::com::sun::star::uno;
377a32b0c8SAndre Fischer 
387a32b0c8SAndre Fischer 
397a32b0c8SAndre Fischer namespace sfx2 { namespace sidebar {
407a32b0c8SAndre Fischer 
417a32b0c8SAndre Fischer 
427a32b0c8SAndre Fischer namespace {
437a32b0c8SAndre Fischer     static const sal_Int32 MinimalPanelHeight (25);
447a32b0c8SAndre Fischer }
457a32b0c8SAndre Fischer 
467a32b0c8SAndre Fischer #define IterateLayoutItems(iterator_name,container)                     \
477a32b0c8SAndre Fischer     for(::std::vector<LayoutItem>::iterator                             \
487a32b0c8SAndre Fischer                    iterator_name(container.begin()),                    \
497a32b0c8SAndre Fischer                    iEnd(container.end());                               \
507a32b0c8SAndre Fischer         iterator_name!=iEnd;                                            \
517a32b0c8SAndre Fischer         ++iterator_name)
527a32b0c8SAndre Fischer 
537a32b0c8SAndre Fischer 
547a32b0c8SAndre Fischer 
LayoutDeck(const Rectangle aContentArea,SharedPanelContainer & rPanels,Window & rDeckTitleBar,Window & rScrollClipWindow,Window & rScrollContainer,Window & rFiller,ScrollBar & rVerticalScrollBar)557a32b0c8SAndre Fischer void DeckLayouter::LayoutDeck (
567a32b0c8SAndre Fischer     const Rectangle aContentArea,
57f120fe41SAndre Fischer     SharedPanelContainer& rPanels,
587a32b0c8SAndre Fischer     Window& rDeckTitleBar,
597a32b0c8SAndre Fischer     Window& rScrollClipWindow,
607a32b0c8SAndre Fischer     Window& rScrollContainer,
617a32b0c8SAndre Fischer     Window& rFiller,
627a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar)
637a32b0c8SAndre Fischer {
647a32b0c8SAndre Fischer     if (aContentArea.GetWidth()<=0 || aContentArea.GetHeight()<=0)
657a32b0c8SAndre Fischer         return;
667a32b0c8SAndre Fischer     Rectangle aBox (PlaceDeckTitle(rDeckTitleBar, aContentArea));
677a32b0c8SAndre Fischer 
687a32b0c8SAndre Fischer     if ( ! rPanels.empty())
697a32b0c8SAndre Fischer     {
707a32b0c8SAndre Fischer         // Prepare the layout item container.
717a32b0c8SAndre Fischer         ::std::vector<LayoutItem> aLayoutItems;
727a32b0c8SAndre Fischer         aLayoutItems.resize(rPanels.size());
737a32b0c8SAndre Fischer         for (sal_Int32 nIndex(0),nCount(rPanels.size()); nIndex<nCount; ++nIndex)
747a32b0c8SAndre Fischer         {
757a32b0c8SAndre Fischer             aLayoutItems[nIndex].mpPanel = rPanels[nIndex];
767a32b0c8SAndre Fischer             aLayoutItems[nIndex].mnPanelIndex = nIndex;
777a32b0c8SAndre Fischer         }
787a32b0c8SAndre Fischer         aBox = LayoutPanels(
797a32b0c8SAndre Fischer             aBox,
807a32b0c8SAndre Fischer             aLayoutItems,
817a32b0c8SAndre Fischer             rScrollClipWindow,
827a32b0c8SAndre Fischer             rScrollContainer,
837a32b0c8SAndre Fischer             rVerticalScrollBar,
847a32b0c8SAndre Fischer             false);
857a32b0c8SAndre Fischer     }
867a32b0c8SAndre Fischer     UpdateFiller(rFiller, aBox);
877a32b0c8SAndre Fischer }
887a32b0c8SAndre Fischer 
897a32b0c8SAndre Fischer 
907a32b0c8SAndre Fischer 
917a32b0c8SAndre Fischer 
LayoutPanels(const Rectangle aContentArea,::std::vector<LayoutItem> & rLayoutItems,Window & rScrollClipWindow,Window & rScrollContainer,ScrollBar & rVerticalScrollBar,const bool bShowVerticalScrollBar)927a32b0c8SAndre Fischer Rectangle DeckLayouter::LayoutPanels (
937a32b0c8SAndre Fischer     const Rectangle aContentArea,
947a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
957a32b0c8SAndre Fischer     Window& rScrollClipWindow,
967a32b0c8SAndre Fischer     Window& rScrollContainer,
977a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar,
987a32b0c8SAndre Fischer     const bool bShowVerticalScrollBar)
997a32b0c8SAndre Fischer {
1007a32b0c8SAndre Fischer     Rectangle aBox (PlaceVerticalScrollBar(rVerticalScrollBar, aContentArea, bShowVerticalScrollBar));
1017a32b0c8SAndre Fischer 
1027a32b0c8SAndre Fischer     const sal_Int32 nWidth (aBox.GetWidth());
10374c6bcd3SPavel Janík     // const sal_Int32 nPanelTitleBarHeight (Theme::GetInteger(Theme::Int_PanelTitleBarHeight));
1047a32b0c8SAndre Fischer 
1057a32b0c8SAndre Fischer     // Prepare the separators, horizontal lines above and below the
106*b12a77c9Smseidel     // panel titles.
10774c6bcd3SPavel Janík     // const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
1087a32b0c8SAndre Fischer 
1097a32b0c8SAndre Fischer     // Get the requested heights of the panels and the available
1107a32b0c8SAndre Fischer     // height that is left when all panel titles and separators are
1117a32b0c8SAndre Fischer     // taken into account.
1127a32b0c8SAndre Fischer     sal_Int32 nAvailableHeight (aBox.GetHeight());
1137a32b0c8SAndre Fischer     GetRequestedSizes(rLayoutItems, nAvailableHeight, aBox);
1147a32b0c8SAndre Fischer     const sal_Int32 nTotalDecorationHeight (aBox.GetHeight() - nAvailableHeight);
1157a32b0c8SAndre Fischer 
1167a32b0c8SAndre Fischer     // Analyze the requested heights.
1177a32b0c8SAndre Fischer     // Determine the height that is available for panel content
1187a32b0c8SAndre Fischer     // and count the different layouts.
1197a32b0c8SAndre Fischer     sal_Int32 nTotalPreferredHeight (0);
1207a32b0c8SAndre Fischer     sal_Int32 nTotalMinimumHeight (0);
1217a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
1227a32b0c8SAndre Fischer     {
1237a32b0c8SAndre Fischer         nTotalMinimumHeight += iItem->maLayoutSize.Minimum;
1247a32b0c8SAndre Fischer         nTotalPreferredHeight += iItem->maLayoutSize.Preferred;
1257a32b0c8SAndre Fischer     }
1267a32b0c8SAndre Fischer 
1277a32b0c8SAndre Fischer     if (nTotalMinimumHeight > nAvailableHeight
1287a32b0c8SAndre Fischer         && ! bShowVerticalScrollBar)
1297a32b0c8SAndre Fischer     {
1307a32b0c8SAndre Fischer         // Not enough space, even when all panels are shrunk to their
1317a32b0c8SAndre Fischer         // minimum height.
1327a32b0c8SAndre Fischer         // Show a vertical scrollbar.
1337a32b0c8SAndre Fischer         return LayoutPanels(
1347a32b0c8SAndre Fischer             aContentArea,
1357a32b0c8SAndre Fischer             rLayoutItems,
1367a32b0c8SAndre Fischer             rScrollClipWindow,
1377a32b0c8SAndre Fischer             rScrollContainer,
1387a32b0c8SAndre Fischer             rVerticalScrollBar,
1397a32b0c8SAndre Fischer             true);
1407a32b0c8SAndre Fischer     }
1417a32b0c8SAndre Fischer 
1427a32b0c8SAndre Fischer     // We are now in one of three modes.
1437a32b0c8SAndre Fischer     // - The preferred height fits into the available size:
144*b12a77c9Smseidel     //   Use the preferred size, distribute the remaining height by
1457a32b0c8SAndre Fischer     //   enlarging panels.
1467a32b0c8SAndre Fischer     // - The total minimum height fits into the available size:
147*b12a77c9Smseidel     //   Use the minimum size, distribute the remaining height by
1487a32b0c8SAndre Fischer     //   enlarging panels.
1497a32b0c8SAndre Fischer     // - The total minimum height does not fit into the available
1507a32b0c8SAndre Fischer     //   size:
1517a32b0c8SAndre Fischer     //   Use the unmodified preferred height for all panels.
1527a32b0c8SAndre Fischer 
1537a32b0c8SAndre Fischer     LayoutMode eMode (MinimumOrLarger);
1547a32b0c8SAndre Fischer     if (bShowVerticalScrollBar)
1557a32b0c8SAndre Fischer         eMode = Preferred;
1567a32b0c8SAndre Fischer     else if (nTotalPreferredHeight <= nAvailableHeight)
1577a32b0c8SAndre Fischer         eMode = PreferredOrLarger;
1587a32b0c8SAndre Fischer     else
1597a32b0c8SAndre Fischer         eMode = MinimumOrLarger;
1607a32b0c8SAndre Fischer 
1617a32b0c8SAndre Fischer     if (eMode != Preferred)
1627a32b0c8SAndre Fischer     {
1637a32b0c8SAndre Fischer         const sal_Int32 nTotalHeight (eMode==MinimumOrLarger ? nTotalMinimumHeight : nTotalPreferredHeight);
1647a32b0c8SAndre Fischer 
1657a32b0c8SAndre Fischer         DistributeHeights(
1667a32b0c8SAndre Fischer             rLayoutItems,
1677a32b0c8SAndre Fischer             nAvailableHeight-nTotalHeight,
1687a32b0c8SAndre Fischer             aBox.GetHeight(),
1697a32b0c8SAndre Fischer             eMode==MinimumOrLarger);
1707a32b0c8SAndre Fischer     }
1717a32b0c8SAndre Fischer 
1727a32b0c8SAndre Fischer     // Set position and size of the mpScrollClipWindow to the available
1737a32b0c8SAndre Fischer     // size. Its child, the mpScrollContainer, may have a bigger
1747a32b0c8SAndre Fischer     // height.
1757a32b0c8SAndre Fischer     rScrollClipWindow.SetPosSizePixel(aBox.Left(), aBox.Top(), aBox.GetWidth(), aBox.GetHeight());
1767a32b0c8SAndre Fischer 
1777a32b0c8SAndre Fischer     const sal_Int32 nContentHeight (
1787a32b0c8SAndre Fischer         eMode==Preferred
1797a32b0c8SAndre Fischer             ? nTotalPreferredHeight + nTotalDecorationHeight
1807a32b0c8SAndre Fischer             : aBox.GetHeight());
1818403f08eSAndre Fischer     sal_Int32 nY = rVerticalScrollBar.GetThumbPos();
1828403f08eSAndre Fischer     if (nContentHeight-nY < aBox.GetHeight())
1838403f08eSAndre Fischer         nY = nContentHeight-aBox.GetHeight();
1848403f08eSAndre Fischer     if (nY < 0)
1858403f08eSAndre Fischer         nY = 0;
1867a32b0c8SAndre Fischer     rScrollContainer.SetPosSizePixel(
1877a32b0c8SAndre Fischer         0,
1888403f08eSAndre Fischer         -nY,
1897a32b0c8SAndre Fischer         nWidth,
1907a32b0c8SAndre Fischer         nContentHeight);
1917a32b0c8SAndre Fischer 
1927a32b0c8SAndre Fischer     if (bShowVerticalScrollBar)
1937a32b0c8SAndre Fischer         SetupVerticalScrollBar(rVerticalScrollBar, nContentHeight, aBox.GetHeight());
1947a32b0c8SAndre Fischer 
1958403f08eSAndre Fischer     const sal_Int32 nUsedHeight (PlacePanels(rLayoutItems, nWidth, eMode, rScrollContainer));
1968403f08eSAndre Fischer     aBox.Top() += nUsedHeight;
1977a32b0c8SAndre Fischer     return aBox;
1987a32b0c8SAndre Fischer }
1997a32b0c8SAndre Fischer 
2007a32b0c8SAndre Fischer 
2017a32b0c8SAndre Fischer 
2027a32b0c8SAndre Fischer 
PlacePanels(::std::vector<LayoutItem> & rLayoutItems,const sal_Int32 nWidth,const LayoutMode eMode,Window & rScrollContainer)2037a32b0c8SAndre Fischer sal_Int32 DeckLayouter::PlacePanels (
2047a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
2057a32b0c8SAndre Fischer     const sal_Int32 nWidth,
2067a32b0c8SAndre Fischer     const LayoutMode eMode,
2077a32b0c8SAndre Fischer     Window& rScrollContainer)
2087a32b0c8SAndre Fischer {
2097a32b0c8SAndre Fischer     ::std::vector<sal_Int32> aSeparators;
2107a32b0c8SAndre Fischer     const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
2117a32b0c8SAndre Fischer     const sal_Int32 nPanelTitleBarHeight (Theme::GetInteger(Theme::Int_PanelTitleBarHeight));
2127a32b0c8SAndre Fischer     sal_Int32 nY (0);
2137a32b0c8SAndre Fischer 
2147a32b0c8SAndre Fischer     // Assign heights and places.
2157a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
2167a32b0c8SAndre Fischer     {
217b862c97cSHerbert Dürr         if( !bool(iItem->mpPanel))
2187a32b0c8SAndre Fischer             continue;
2197a32b0c8SAndre Fischer 
2207a32b0c8SAndre Fischer         Panel& rPanel (*iItem->mpPanel);
2217a32b0c8SAndre Fischer 
2227a32b0c8SAndre Fischer         // Separator above the panel title bar.
2237a32b0c8SAndre Fischer         aSeparators.push_back(nY);
2247a32b0c8SAndre Fischer         nY += nDeckSeparatorHeight;
2257a32b0c8SAndre Fischer 
2267a32b0c8SAndre Fischer         // Place the title bar.
2278a1a651aSAndre Fischer         PanelTitleBar* pTitleBar = rPanel.GetTitleBar();
22854eaaa32SAndre Fischer         if (pTitleBar != NULL)
22954eaaa32SAndre Fischer         {
23054eaaa32SAndre Fischer             if (iItem->mbShowTitleBar)
23154eaaa32SAndre Fischer             {
2327a32b0c8SAndre Fischer                 pTitleBar->SetPosSizePixel(0, nY, nWidth, nPanelTitleBarHeight);
2337a32b0c8SAndre Fischer                 pTitleBar->Show();
2347a32b0c8SAndre Fischer                 nY += nPanelTitleBarHeight;
23554eaaa32SAndre Fischer             }
23654eaaa32SAndre Fischer             else
23754eaaa32SAndre Fischer             {
23854eaaa32SAndre Fischer                 pTitleBar->Hide();
23954eaaa32SAndre Fischer             }
24054eaaa32SAndre Fischer         }
2417a32b0c8SAndre Fischer 
2427a32b0c8SAndre Fischer         if (rPanel.IsExpanded())
2437a32b0c8SAndre Fischer         {
2447a32b0c8SAndre Fischer             rPanel.Show();
2457a32b0c8SAndre Fischer 
2467a32b0c8SAndre Fischer             // Determine the height of the panel depending on layout
2477a32b0c8SAndre Fischer             // mode and distributed heights.
2487a32b0c8SAndre Fischer             sal_Int32 nPanelHeight (0);
2497a32b0c8SAndre Fischer             switch(eMode)
2507a32b0c8SAndre Fischer             {
2517a32b0c8SAndre Fischer                 case MinimumOrLarger:
2527a32b0c8SAndre Fischer                     nPanelHeight = iItem->maLayoutSize.Minimum + iItem->mnDistributedHeight;
2537a32b0c8SAndre Fischer                     break;
2547a32b0c8SAndre Fischer                 case PreferredOrLarger:
2557a32b0c8SAndre Fischer                     nPanelHeight = iItem->maLayoutSize.Preferred + iItem->mnDistributedHeight;
2567a32b0c8SAndre Fischer                     break;
2577a32b0c8SAndre Fischer                 case Preferred:
2587a32b0c8SAndre Fischer                     nPanelHeight = iItem->maLayoutSize.Preferred;
2597a32b0c8SAndre Fischer                     break;
2607a32b0c8SAndre Fischer                 default:
2617a32b0c8SAndre Fischer                     OSL_ASSERT(false);
2627a32b0c8SAndre Fischer                     break;
2637a32b0c8SAndre Fischer             }
2647a32b0c8SAndre Fischer 
2657a32b0c8SAndre Fischer             // Place the panel.
2667a32b0c8SAndre Fischer             rPanel.SetPosSizePixel(0, nY, nWidth, nPanelHeight);
267d288180bSAndre Fischer             rPanel.Invalidate();
2687a32b0c8SAndre Fischer 
2697a32b0c8SAndre Fischer             nY += nPanelHeight;
2707a32b0c8SAndre Fischer         }
2717a32b0c8SAndre Fischer         else
2727a32b0c8SAndre Fischer         {
2737a32b0c8SAndre Fischer             rPanel.Hide();
27465908a7eSAndre Fischer 
27565908a7eSAndre Fischer             // Add a separator below the collapsed panel, if it is the
27665908a7eSAndre Fischer             // last panel in the deck.
27765908a7eSAndre Fischer             if (iItem == rLayoutItems.end()-1)
27865908a7eSAndre Fischer             {
27965908a7eSAndre Fischer                 // Separator below the panel title bar.
28065908a7eSAndre Fischer                 aSeparators.push_back(nY);
28165908a7eSAndre Fischer                 nY += nDeckSeparatorHeight;
28265908a7eSAndre Fischer             }
2837a32b0c8SAndre Fischer         }
2847a32b0c8SAndre Fischer     }
2857a32b0c8SAndre Fischer 
2867a32b0c8SAndre Fischer     Deck::ScrollContainerWindow* pScrollContainerWindow
2877a32b0c8SAndre Fischer         = dynamic_cast<Deck::ScrollContainerWindow*>(&rScrollContainer);
2887a32b0c8SAndre Fischer     if (pScrollContainerWindow != NULL)
2897a32b0c8SAndre Fischer         pScrollContainerWindow->SetSeparators(aSeparators);
2907a32b0c8SAndre Fischer 
2917a32b0c8SAndre Fischer     return nY;
2927a32b0c8SAndre Fischer }
2937a32b0c8SAndre Fischer 
2947a32b0c8SAndre Fischer 
2957a32b0c8SAndre Fischer 
2967a32b0c8SAndre Fischer 
GetRequestedSizes(::std::vector<LayoutItem> & rLayoutItems,sal_Int32 & rAvailableHeight,const Rectangle & rContentBox)2977a32b0c8SAndre Fischer void DeckLayouter::GetRequestedSizes (
2987a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
2997a32b0c8SAndre Fischer     sal_Int32& rAvailableHeight,
3007a32b0c8SAndre Fischer     const Rectangle& rContentBox)
3017a32b0c8SAndre Fischer {
3027a32b0c8SAndre Fischer     rAvailableHeight = rContentBox.GetHeight();
3037a32b0c8SAndre Fischer 
3047a32b0c8SAndre Fischer     const sal_Int32 nPanelTitleBarHeight (Theme::GetInteger(Theme::Int_PanelTitleBarHeight));
3057a32b0c8SAndre Fischer     const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
3067a32b0c8SAndre Fischer 
3077a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
3087a32b0c8SAndre Fischer     {
3097a32b0c8SAndre Fischer         ui::LayoutSize aLayoutSize (ui::LayoutSize(0,0,0));
310b862c97cSHerbert Dürr         if( bool(iItem->mpPanel))
3117a32b0c8SAndre Fischer         {
31254eaaa32SAndre Fischer             if (rLayoutItems.size() == 1
31354eaaa32SAndre Fischer                 && iItem->mpPanel->IsTitleBarOptional())
31454eaaa32SAndre Fischer             {
31554eaaa32SAndre Fischer                 // There is only one panel and its title bar is
31654eaaa32SAndre Fischer                 // optional => hide it.
31754eaaa32SAndre Fischer                 rAvailableHeight -= nDeckSeparatorHeight;
31854eaaa32SAndre Fischer                 iItem->mbShowTitleBar = false;
31954eaaa32SAndre Fischer             }
32054eaaa32SAndre Fischer             else
32154eaaa32SAndre Fischer             {
32254eaaa32SAndre Fischer                 // Show the title bar and a separator above and below
32354eaaa32SAndre Fischer                 // the title bar.
3247a32b0c8SAndre Fischer                 rAvailableHeight -= nPanelTitleBarHeight;
3258403f08eSAndre Fischer                 rAvailableHeight -= nDeckSeparatorHeight;
32654eaaa32SAndre Fischer             }
3277a32b0c8SAndre Fischer 
3287a32b0c8SAndre Fischer             if (iItem->mpPanel->IsExpanded())
3297a32b0c8SAndre Fischer             {
3307a32b0c8SAndre Fischer                 Reference<ui::XSidebarPanel> xPanel (iItem->mpPanel->GetPanelComponent());
3317a32b0c8SAndre Fischer                 if (xPanel.is())
3327a32b0c8SAndre Fischer                     aLayoutSize = xPanel->getHeightForWidth(rContentBox.GetWidth());
3337a32b0c8SAndre Fischer                 else
334b358a5b6SAndre Fischer                     aLayoutSize = ui::LayoutSize(MinimalPanelHeight, -1, 0);
3357a32b0c8SAndre Fischer             }
3367a32b0c8SAndre Fischer         }
3377a32b0c8SAndre Fischer         iItem->maLayoutSize = aLayoutSize;
3387a32b0c8SAndre Fischer     }
3397a32b0c8SAndre Fischer }
3407a32b0c8SAndre Fischer 
3417a32b0c8SAndre Fischer 
3427a32b0c8SAndre Fischer 
3437a32b0c8SAndre Fischer 
DistributeHeights(::std::vector<LayoutItem> & rLayoutItems,const sal_Int32 nHeightToDistribute,const sal_Int32 nContainerHeight,const bool bMinimumHeightIsBase)3447a32b0c8SAndre Fischer void DeckLayouter::DistributeHeights (
3457a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
3467a32b0c8SAndre Fischer     const sal_Int32 nHeightToDistribute,
3477a32b0c8SAndre Fischer     const sal_Int32 nContainerHeight,
3487a32b0c8SAndre Fischer     const bool bMinimumHeightIsBase)
3497a32b0c8SAndre Fischer {
3507a32b0c8SAndre Fischer     if (nHeightToDistribute <= 0)
3517a32b0c8SAndre Fischer         return;
3527a32b0c8SAndre Fischer 
3537a32b0c8SAndre Fischer     sal_Int32 nRemainingHeightToDistribute (nHeightToDistribute);
3547a32b0c8SAndre Fischer 
3557a32b0c8SAndre Fischer     // Compute the weights as difference between panel base height
3567a32b0c8SAndre Fischer     // (either its minimum or preferred height) and the container height.
3577a32b0c8SAndre Fischer     sal_Int32 nTotalWeight (0);
3587a32b0c8SAndre Fischer     sal_Int32 nNoMaximumCount (0);
3597a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
3607a32b0c8SAndre Fischer     {
3617a32b0c8SAndre Fischer         if (iItem->maLayoutSize.Maximum == 0)
3627a32b0c8SAndre Fischer             continue;
3637a32b0c8SAndre Fischer         if (iItem->maLayoutSize.Maximum < 0)
3647a32b0c8SAndre Fischer             ++nNoMaximumCount;
3657a32b0c8SAndre Fischer 
3667a32b0c8SAndre Fischer         const sal_Int32 nBaseHeight (
3677a32b0c8SAndre Fischer             bMinimumHeightIsBase
3687a32b0c8SAndre Fischer                 ? iItem->maLayoutSize.Minimum
3697a32b0c8SAndre Fischer                 : iItem->maLayoutSize.Preferred);
3707a32b0c8SAndre Fischer         if (nBaseHeight < nContainerHeight)
3717a32b0c8SAndre Fischer         {
3727a32b0c8SAndre Fischer             iItem->mnWeight = nContainerHeight - nBaseHeight;
3737a32b0c8SAndre Fischer             nTotalWeight += iItem->mnWeight;
3747a32b0c8SAndre Fischer         }
3757a32b0c8SAndre Fischer     }
3767a32b0c8SAndre Fischer 
3777a32b0c8SAndre Fischer     if (nTotalWeight == 0)
3787a32b0c8SAndre Fischer         return;
3797a32b0c8SAndre Fischer 
3807a32b0c8SAndre Fischer     // First pass of height distribution.
3817a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
3827a32b0c8SAndre Fischer     {
3837a32b0c8SAndre Fischer         const sal_Int32 nBaseHeight (
3847a32b0c8SAndre Fischer             bMinimumHeightIsBase
3857a32b0c8SAndre Fischer                 ? iItem->maLayoutSize.Minimum
3867a32b0c8SAndre Fischer                 : iItem->maLayoutSize.Preferred);
3877a32b0c8SAndre Fischer         sal_Int32 nDistributedHeight (iItem->mnWeight * nHeightToDistribute / nTotalWeight);
3887a32b0c8SAndre Fischer         if (nBaseHeight+nDistributedHeight > iItem->maLayoutSize.Maximum
3897a32b0c8SAndre Fischer             && iItem->maLayoutSize.Maximum >= 0)
3907a32b0c8SAndre Fischer         {
3917a32b0c8SAndre Fischer             nDistributedHeight = ::std::max<sal_Int32>(0,iItem->maLayoutSize.Maximum - nBaseHeight);
3927a32b0c8SAndre Fischer         }
3937a32b0c8SAndre Fischer         iItem->mnDistributedHeight = nDistributedHeight;
3947a32b0c8SAndre Fischer         nRemainingHeightToDistribute -= nDistributedHeight;
3957a32b0c8SAndre Fischer     }
3967a32b0c8SAndre Fischer 
3977a32b0c8SAndre Fischer     if (nRemainingHeightToDistribute == 0)
3987a32b0c8SAndre Fischer         return;
3997a32b0c8SAndre Fischer     OSL_ASSERT(nRemainingHeightToDistribute > 0);
4007a32b0c8SAndre Fischer 
4017a32b0c8SAndre Fischer     // It is possible that not all of the height could be distributed
4027a32b0c8SAndre Fischer     // because of Maximum heights being smaller than expected.
4037a32b0c8SAndre Fischer     // Distribute the remaining height between the panels that have no
4047a32b0c8SAndre Fischer     // Maximum (ie Maximum==-1).
4057a32b0c8SAndre Fischer     if (nNoMaximumCount == 0)
4067a32b0c8SAndre Fischer     {
4077a32b0c8SAndre Fischer         // There are no panels with unrestricted height.
4087a32b0c8SAndre Fischer         return;
4097a32b0c8SAndre Fischer     }
4107a32b0c8SAndre Fischer     const sal_Int32 nAdditionalHeightPerPanel (nRemainingHeightToDistribute / nNoMaximumCount);
4117a32b0c8SAndre Fischer     // Handle rounding error.
4127a32b0c8SAndre Fischer     sal_Int32 nAdditionalHeightForFirstPanel (nRemainingHeightToDistribute
4137a32b0c8SAndre Fischer         - nNoMaximumCount*nAdditionalHeightPerPanel);
4147a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
4157a32b0c8SAndre Fischer     {
4167a32b0c8SAndre Fischer         if (iItem->maLayoutSize.Maximum < 0)
4177a32b0c8SAndre Fischer         {
4187a32b0c8SAndre Fischer             iItem->mnDistributedHeight += nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel;
4197a32b0c8SAndre Fischer             nRemainingHeightToDistribute -= nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel;
4207a32b0c8SAndre Fischer         }
4217a32b0c8SAndre Fischer     }
4227a32b0c8SAndre Fischer 
4237a32b0c8SAndre Fischer     OSL_ASSERT(nRemainingHeightToDistribute==0);
4247a32b0c8SAndre Fischer }
4257a32b0c8SAndre Fischer 
4267a32b0c8SAndre Fischer 
4277a32b0c8SAndre Fischer 
4287a32b0c8SAndre Fischer 
PlaceDeckTitle(Window & rDeckTitleBar,const Rectangle & rAvailableSpace)4297a32b0c8SAndre Fischer Rectangle DeckLayouter::PlaceDeckTitle (
4307a32b0c8SAndre Fischer     Window& rDeckTitleBar,
4317a32b0c8SAndre Fischer     const Rectangle& rAvailableSpace)
4327a32b0c8SAndre Fischer {
4337a32b0c8SAndre Fischer     if (static_cast<DockingWindow*>(rDeckTitleBar.GetParent()->GetParent())->IsFloatingMode())
4347a32b0c8SAndre Fischer     {
4357a32b0c8SAndre Fischer         // When the side bar is undocked then the outer system window displays the deck title.
4367a32b0c8SAndre Fischer         rDeckTitleBar.Hide();
4377a32b0c8SAndre Fischer         return rAvailableSpace;
4387a32b0c8SAndre Fischer     }
4397a32b0c8SAndre Fischer     else
4407a32b0c8SAndre Fischer     {
4417a32b0c8SAndre Fischer         const sal_Int32 nDeckTitleBarHeight (Theme::GetInteger(Theme::Int_DeckTitleBarHeight));
4427a32b0c8SAndre Fischer         rDeckTitleBar.SetPosSizePixel(
4437a32b0c8SAndre Fischer             rAvailableSpace.Left(),
4447a32b0c8SAndre Fischer             rAvailableSpace.Top(),
4457a32b0c8SAndre Fischer             rAvailableSpace.GetWidth(),
4467a32b0c8SAndre Fischer             nDeckTitleBarHeight);
4477a32b0c8SAndre Fischer         rDeckTitleBar.Show();
4487a32b0c8SAndre Fischer         return Rectangle(
4497a32b0c8SAndre Fischer             rAvailableSpace.Left(),
4507a32b0c8SAndre Fischer             rAvailableSpace.Top() + nDeckTitleBarHeight,
4517a32b0c8SAndre Fischer             rAvailableSpace.Right(),
4527a32b0c8SAndre Fischer             rAvailableSpace.Bottom());
4537a32b0c8SAndre Fischer     }
4547a32b0c8SAndre Fischer }
4557a32b0c8SAndre Fischer 
4567a32b0c8SAndre Fischer 
4577a32b0c8SAndre Fischer 
4587a32b0c8SAndre Fischer 
PlaceVerticalScrollBar(ScrollBar & rVerticalScrollBar,const Rectangle & rAvailableSpace,const bool bShowVerticalScrollBar)4597a32b0c8SAndre Fischer Rectangle DeckLayouter::PlaceVerticalScrollBar (
4607a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar,
4617a32b0c8SAndre Fischer     const Rectangle& rAvailableSpace,
4627a32b0c8SAndre Fischer     const bool bShowVerticalScrollBar)
4637a32b0c8SAndre Fischer {
4647a32b0c8SAndre Fischer     if (bShowVerticalScrollBar)
4657a32b0c8SAndre Fischer     {
4667a32b0c8SAndre Fischer         const sal_Int32 nScrollBarWidth (rVerticalScrollBar.GetSizePixel().Width());
4677a32b0c8SAndre Fischer         rVerticalScrollBar.SetPosSizePixel(
4687a32b0c8SAndre Fischer             rAvailableSpace.Right() - nScrollBarWidth + 1,
4697a32b0c8SAndre Fischer             rAvailableSpace.Top(),
4707a32b0c8SAndre Fischer             nScrollBarWidth,
4717a32b0c8SAndre Fischer             rAvailableSpace.GetHeight());
4727a32b0c8SAndre Fischer         rVerticalScrollBar.Show();
4737a32b0c8SAndre Fischer         return Rectangle(
4747a32b0c8SAndre Fischer             rAvailableSpace.Left(),
4757a32b0c8SAndre Fischer             rAvailableSpace.Top(),
4767a32b0c8SAndre Fischer             rAvailableSpace.Right() - nScrollBarWidth,
4777a32b0c8SAndre Fischer             rAvailableSpace.Bottom());
4787a32b0c8SAndre Fischer     }
4797a32b0c8SAndre Fischer     else
4807a32b0c8SAndre Fischer     {
4817a32b0c8SAndre Fischer         rVerticalScrollBar.Hide();
4827a32b0c8SAndre Fischer         return rAvailableSpace;
4837a32b0c8SAndre Fischer     }
4847a32b0c8SAndre Fischer }
4857a32b0c8SAndre Fischer 
4867a32b0c8SAndre Fischer 
4877a32b0c8SAndre Fischer 
4887a32b0c8SAndre Fischer 
SetupVerticalScrollBar(ScrollBar & rVerticalScrollBar,const sal_Int32 nContentHeight,const sal_Int32 nVisibleHeight)4897a32b0c8SAndre Fischer void DeckLayouter::SetupVerticalScrollBar(
4907a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar,
4917a32b0c8SAndre Fischer     const sal_Int32 nContentHeight,
4927a32b0c8SAndre Fischer     const sal_Int32 nVisibleHeight)
4937a32b0c8SAndre Fischer {
4947a32b0c8SAndre Fischer     OSL_ASSERT(nContentHeight > nVisibleHeight);
4957a32b0c8SAndre Fischer 
4967a32b0c8SAndre Fischer     rVerticalScrollBar.SetRangeMin(0);
4977a32b0c8SAndre Fischer     rVerticalScrollBar.SetRangeMax(nContentHeight-1);
4987a32b0c8SAndre Fischer     rVerticalScrollBar.SetVisibleSize(nVisibleHeight);
4997a32b0c8SAndre Fischer }
5007a32b0c8SAndre Fischer 
5017a32b0c8SAndre Fischer 
5027a32b0c8SAndre Fischer 
5037a32b0c8SAndre Fischer 
UpdateFiller(Window & rFiller,const Rectangle & rBox)5047a32b0c8SAndre Fischer void DeckLayouter::UpdateFiller (
5057a32b0c8SAndre Fischer     Window& rFiller,
5067a32b0c8SAndre Fischer     const Rectangle& rBox)
5077a32b0c8SAndre Fischer {
5087a32b0c8SAndre Fischer     if (rBox.GetHeight() > 0)
5097a32b0c8SAndre Fischer     {
5107a32b0c8SAndre Fischer         // Show the filler.
5117a32b0c8SAndre Fischer         rFiller.SetBackground(Theme::GetPaint(Theme::Paint_PanelBackground).GetWallpaper());
5127a32b0c8SAndre Fischer         rFiller.SetPosSizePixel(rBox.TopLeft(), rBox.GetSize());
5137a32b0c8SAndre Fischer         rFiller.Show();
5147a32b0c8SAndre Fischer     }
5157a32b0c8SAndre Fischer     else
5167a32b0c8SAndre Fischer     {
5177a32b0c8SAndre Fischer         // Hide the filler.
5187a32b0c8SAndre Fischer         rFiller.Hide();
5197a32b0c8SAndre Fischer     }
5207a32b0c8SAndre Fischer }
5217a32b0c8SAndre Fischer 
5227a32b0c8SAndre Fischer 
5237a32b0c8SAndre Fischer 
5247a32b0c8SAndre Fischer } } // end of namespace sfx2::sidebar
525