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