xref: /AOO41X/main/sfx2/source/sidebar/DeckLayouter.cxx (revision 7a32b0c888def1bf84d1d657c48953bc10dc00c1)
1*7a32b0c8SAndre Fischer /**************************************************************
2*7a32b0c8SAndre Fischer  *
3*7a32b0c8SAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
4*7a32b0c8SAndre Fischer  * or more contributor license agreements.  See the NOTICE file
5*7a32b0c8SAndre Fischer  * distributed with this work for additional information
6*7a32b0c8SAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
7*7a32b0c8SAndre Fischer  * to you under the Apache License, Version 2.0 (the
8*7a32b0c8SAndre Fischer  * "License"); you may not use this file except in compliance
9*7a32b0c8SAndre Fischer  * with the License.  You may obtain a copy of the License at
10*7a32b0c8SAndre Fischer  *
11*7a32b0c8SAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
12*7a32b0c8SAndre Fischer  *
13*7a32b0c8SAndre Fischer  * Unless required by applicable law or agreed to in writing,
14*7a32b0c8SAndre Fischer  * software distributed under the License is distributed on an
15*7a32b0c8SAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*7a32b0c8SAndre Fischer  * KIND, either express or implied.  See the License for the
17*7a32b0c8SAndre Fischer  * specific language governing permissions and limitations
18*7a32b0c8SAndre Fischer  * under the License.
19*7a32b0c8SAndre Fischer  *
20*7a32b0c8SAndre Fischer  *************************************************************/
21*7a32b0c8SAndre Fischer 
22*7a32b0c8SAndre Fischer #include "precompiled_sfx2.hxx"
23*7a32b0c8SAndre Fischer 
24*7a32b0c8SAndre Fischer #include "DeckLayouter.hxx"
25*7a32b0c8SAndre Fischer #include "sfx2/sidebar/Theme.hxx"
26*7a32b0c8SAndre Fischer #include "Panel.hxx"
27*7a32b0c8SAndre Fischer #include "TitleBar.hxx"
28*7a32b0c8SAndre Fischer #include "Deck.hxx"
29*7a32b0c8SAndre Fischer 
30*7a32b0c8SAndre Fischer #include <vcl/window.hxx>
31*7a32b0c8SAndre Fischer #include <vcl/scrbar.hxx>
32*7a32b0c8SAndre Fischer 
33*7a32b0c8SAndre Fischer using namespace ::com::sun::star;
34*7a32b0c8SAndre Fischer using namespace ::com::sun::star::uno;
35*7a32b0c8SAndre Fischer 
36*7a32b0c8SAndre Fischer 
37*7a32b0c8SAndre Fischer namespace sfx2 { namespace sidebar {
38*7a32b0c8SAndre Fischer 
39*7a32b0c8SAndre Fischer 
40*7a32b0c8SAndre Fischer namespace {
41*7a32b0c8SAndre Fischer     static const sal_Int32 MinimalPanelHeight (25);
42*7a32b0c8SAndre Fischer }
43*7a32b0c8SAndre Fischer 
44*7a32b0c8SAndre Fischer #define IterateLayoutItems(iterator_name,container)                     \
45*7a32b0c8SAndre Fischer     for(::std::vector<LayoutItem>::iterator                             \
46*7a32b0c8SAndre Fischer                    iterator_name(container.begin()),                    \
47*7a32b0c8SAndre Fischer                    iEnd(container.end());                               \
48*7a32b0c8SAndre Fischer         iterator_name!=iEnd;                                            \
49*7a32b0c8SAndre Fischer         ++iterator_name)
50*7a32b0c8SAndre Fischer 
51*7a32b0c8SAndre Fischer 
52*7a32b0c8SAndre Fischer 
53*7a32b0c8SAndre Fischer void DeckLayouter::LayoutDeck (
54*7a32b0c8SAndre Fischer     const Rectangle aContentArea,
55*7a32b0c8SAndre Fischer     ::std::vector<Panel*>& rPanels,
56*7a32b0c8SAndre Fischer     Window& rDeckTitleBar,
57*7a32b0c8SAndre Fischer     Window& rScrollClipWindow,
58*7a32b0c8SAndre Fischer     Window& rScrollContainer,
59*7a32b0c8SAndre Fischer     Window& rFiller,
60*7a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar)
61*7a32b0c8SAndre Fischer {
62*7a32b0c8SAndre Fischer     if (aContentArea.GetWidth()<=0 || aContentArea.GetHeight()<=0)
63*7a32b0c8SAndre Fischer         return;
64*7a32b0c8SAndre Fischer     Rectangle aBox (PlaceDeckTitle(rDeckTitleBar, aContentArea));
65*7a32b0c8SAndre Fischer 
66*7a32b0c8SAndre Fischer     if ( ! rPanels.empty())
67*7a32b0c8SAndre Fischer     {
68*7a32b0c8SAndre Fischer         // Prepare the layout item container.
69*7a32b0c8SAndre Fischer         ::std::vector<LayoutItem> aLayoutItems;
70*7a32b0c8SAndre Fischer         aLayoutItems.resize(rPanels.size());
71*7a32b0c8SAndre Fischer         for (sal_Int32 nIndex(0),nCount(rPanels.size()); nIndex<nCount; ++nIndex)
72*7a32b0c8SAndre Fischer         {
73*7a32b0c8SAndre Fischer             aLayoutItems[nIndex].mpPanel = rPanels[nIndex];
74*7a32b0c8SAndre Fischer             aLayoutItems[nIndex].mnPanelIndex = nIndex;
75*7a32b0c8SAndre Fischer         }
76*7a32b0c8SAndre Fischer         aBox = LayoutPanels(
77*7a32b0c8SAndre Fischer             aBox,
78*7a32b0c8SAndre Fischer             aLayoutItems,
79*7a32b0c8SAndre Fischer             rScrollClipWindow,
80*7a32b0c8SAndre Fischer             rScrollContainer,
81*7a32b0c8SAndre Fischer             rVerticalScrollBar,
82*7a32b0c8SAndre Fischer             false);
83*7a32b0c8SAndre Fischer     }
84*7a32b0c8SAndre Fischer     UpdateFiller(rFiller, aBox);
85*7a32b0c8SAndre Fischer }
86*7a32b0c8SAndre Fischer 
87*7a32b0c8SAndre Fischer 
88*7a32b0c8SAndre Fischer 
89*7a32b0c8SAndre Fischer 
90*7a32b0c8SAndre Fischer Rectangle DeckLayouter::LayoutPanels (
91*7a32b0c8SAndre Fischer     const Rectangle aContentArea,
92*7a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
93*7a32b0c8SAndre Fischer     Window& rScrollClipWindow,
94*7a32b0c8SAndre Fischer     Window& rScrollContainer,
95*7a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar,
96*7a32b0c8SAndre Fischer     const bool bShowVerticalScrollBar)
97*7a32b0c8SAndre Fischer {
98*7a32b0c8SAndre Fischer     Rectangle aBox (PlaceVerticalScrollBar(rVerticalScrollBar, aContentArea, bShowVerticalScrollBar));
99*7a32b0c8SAndre Fischer 
100*7a32b0c8SAndre Fischer     const sal_Int32 nWidth (aBox.GetWidth());
101*7a32b0c8SAndre Fischer     const sal_Int32 nPanelTitleBarHeight (Theme::GetInteger(Theme::Int_PanelTitleBarHeight));
102*7a32b0c8SAndre Fischer 
103*7a32b0c8SAndre Fischer     // Prepare the separators, horizontal lines above and below the
104*7a32b0c8SAndre Fischer     // panel titels.
105*7a32b0c8SAndre Fischer     const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
106*7a32b0c8SAndre Fischer 
107*7a32b0c8SAndre Fischer     // Get the requested heights of the panels and the available
108*7a32b0c8SAndre Fischer     // height that is left when all panel titles and separators are
109*7a32b0c8SAndre Fischer     // taken into account.
110*7a32b0c8SAndre Fischer     sal_Int32 nAvailableHeight (aBox.GetHeight());
111*7a32b0c8SAndre Fischer     GetRequestedSizes(rLayoutItems, nAvailableHeight, aBox);
112*7a32b0c8SAndre Fischer     const sal_Int32 nTotalDecorationHeight (aBox.GetHeight() - nAvailableHeight);
113*7a32b0c8SAndre Fischer 
114*7a32b0c8SAndre Fischer     // Analyze the requested heights.
115*7a32b0c8SAndre Fischer     // Determine the height that is available for panel content
116*7a32b0c8SAndre Fischer     // and count the different layouts.
117*7a32b0c8SAndre Fischer     sal_Int32 nTotalPreferredHeight (0);
118*7a32b0c8SAndre Fischer     sal_Int32 nTotalMinimumHeight (0);
119*7a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
120*7a32b0c8SAndre Fischer     {
121*7a32b0c8SAndre Fischer         nTotalMinimumHeight += iItem->maLayoutSize.Minimum;
122*7a32b0c8SAndre Fischer         nTotalPreferredHeight += iItem->maLayoutSize.Preferred;
123*7a32b0c8SAndre Fischer     }
124*7a32b0c8SAndre Fischer 
125*7a32b0c8SAndre Fischer     if (nTotalMinimumHeight > nAvailableHeight
126*7a32b0c8SAndre Fischer         && ! bShowVerticalScrollBar)
127*7a32b0c8SAndre Fischer     {
128*7a32b0c8SAndre Fischer         // Not enough space, even when all panels are shrunk to their
129*7a32b0c8SAndre Fischer         // minimum height.
130*7a32b0c8SAndre Fischer         // Show a vertical scrollbar.
131*7a32b0c8SAndre Fischer         return LayoutPanels(
132*7a32b0c8SAndre Fischer             aContentArea,
133*7a32b0c8SAndre Fischer             rLayoutItems,
134*7a32b0c8SAndre Fischer             rScrollClipWindow,
135*7a32b0c8SAndre Fischer             rScrollContainer,
136*7a32b0c8SAndre Fischer             rVerticalScrollBar,
137*7a32b0c8SAndre Fischer             true);
138*7a32b0c8SAndre Fischer     }
139*7a32b0c8SAndre Fischer 
140*7a32b0c8SAndre Fischer     // We are now in one of three modes.
141*7a32b0c8SAndre Fischer     // - The preferred height fits into the available size:
142*7a32b0c8SAndre Fischer     //   Use the preferred size, distribute the remaining height bei
143*7a32b0c8SAndre Fischer     //   enlarging panels.
144*7a32b0c8SAndre Fischer     // - The total minimum height fits into the available size:
145*7a32b0c8SAndre Fischer     //   Use the minimum size, distribute the remaining height bei
146*7a32b0c8SAndre Fischer     //   enlarging panels.
147*7a32b0c8SAndre Fischer     // - The total minimum height does not fit into the available
148*7a32b0c8SAndre Fischer     //   size:
149*7a32b0c8SAndre Fischer     //   Use the unmodified preferred height for all panels.
150*7a32b0c8SAndre Fischer 
151*7a32b0c8SAndre Fischer     LayoutMode eMode (MinimumOrLarger);
152*7a32b0c8SAndre Fischer     if (bShowVerticalScrollBar)
153*7a32b0c8SAndre Fischer         eMode = Preferred;
154*7a32b0c8SAndre Fischer     else if (nTotalPreferredHeight <= nAvailableHeight)
155*7a32b0c8SAndre Fischer         eMode = PreferredOrLarger;
156*7a32b0c8SAndre Fischer     else
157*7a32b0c8SAndre Fischer         eMode = MinimumOrLarger;
158*7a32b0c8SAndre Fischer 
159*7a32b0c8SAndre Fischer     if (eMode != Preferred)
160*7a32b0c8SAndre Fischer     {
161*7a32b0c8SAndre Fischer         const sal_Int32 nTotalHeight (eMode==MinimumOrLarger ? nTotalMinimumHeight : nTotalPreferredHeight);
162*7a32b0c8SAndre Fischer 
163*7a32b0c8SAndre Fischer         DistributeHeights(
164*7a32b0c8SAndre Fischer             rLayoutItems,
165*7a32b0c8SAndre Fischer             nAvailableHeight-nTotalHeight,
166*7a32b0c8SAndre Fischer             aBox.GetHeight(),
167*7a32b0c8SAndre Fischer             eMode==MinimumOrLarger);
168*7a32b0c8SAndre Fischer     }
169*7a32b0c8SAndre Fischer 
170*7a32b0c8SAndre Fischer     // Set position and size of the mpScrollClipWindow to the available
171*7a32b0c8SAndre Fischer     // size.  Its child, the mpScrollContainer, may have a bigger
172*7a32b0c8SAndre Fischer     // height.
173*7a32b0c8SAndre Fischer     rScrollClipWindow.SetPosSizePixel(aBox.Left(), aBox.Top(), aBox.GetWidth(), aBox.GetHeight());
174*7a32b0c8SAndre Fischer 
175*7a32b0c8SAndre Fischer     const sal_Int32 nContentHeight (
176*7a32b0c8SAndre Fischer         eMode==Preferred
177*7a32b0c8SAndre Fischer             ? nTotalPreferredHeight + nTotalDecorationHeight
178*7a32b0c8SAndre Fischer             : aBox.GetHeight());
179*7a32b0c8SAndre Fischer     rScrollContainer.SetPosSizePixel(
180*7a32b0c8SAndre Fischer         0,
181*7a32b0c8SAndre Fischer         0,
182*7a32b0c8SAndre Fischer         nWidth,
183*7a32b0c8SAndre Fischer         nContentHeight);
184*7a32b0c8SAndre Fischer 
185*7a32b0c8SAndre Fischer     if (bShowVerticalScrollBar)
186*7a32b0c8SAndre Fischer         SetupVerticalScrollBar(rVerticalScrollBar, nContentHeight, aBox.GetHeight());
187*7a32b0c8SAndre Fischer 
188*7a32b0c8SAndre Fischer     aBox.Top() += PlacePanels(rLayoutItems, nWidth, eMode, rScrollContainer);
189*7a32b0c8SAndre Fischer     return aBox;
190*7a32b0c8SAndre Fischer }
191*7a32b0c8SAndre Fischer 
192*7a32b0c8SAndre Fischer 
193*7a32b0c8SAndre Fischer 
194*7a32b0c8SAndre Fischer 
195*7a32b0c8SAndre Fischer sal_Int32 DeckLayouter::PlacePanels (
196*7a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
197*7a32b0c8SAndre Fischer     const sal_Int32 nWidth,
198*7a32b0c8SAndre Fischer     const LayoutMode eMode,
199*7a32b0c8SAndre Fischer     Window& rScrollContainer)
200*7a32b0c8SAndre Fischer {
201*7a32b0c8SAndre Fischer     ::std::vector<sal_Int32> aSeparators;
202*7a32b0c8SAndre Fischer     const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
203*7a32b0c8SAndre Fischer     const sal_Int32 nPanelTitleBarHeight (Theme::GetInteger(Theme::Int_PanelTitleBarHeight));
204*7a32b0c8SAndre Fischer     sal_Int32 nY (0);
205*7a32b0c8SAndre Fischer 
206*7a32b0c8SAndre Fischer     // Assign heights and places.
207*7a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
208*7a32b0c8SAndre Fischer     {
209*7a32b0c8SAndre Fischer 		if (iItem->mpPanel == NULL)
210*7a32b0c8SAndre Fischer 			continue;
211*7a32b0c8SAndre Fischer 
212*7a32b0c8SAndre Fischer         Panel& rPanel (*iItem->mpPanel);
213*7a32b0c8SAndre Fischer 
214*7a32b0c8SAndre Fischer         // Separator above the panel title bar.
215*7a32b0c8SAndre Fischer         aSeparators.push_back(nY);
216*7a32b0c8SAndre Fischer         nY += nDeckSeparatorHeight;
217*7a32b0c8SAndre Fischer 
218*7a32b0c8SAndre Fischer         // Place the title bar.
219*7a32b0c8SAndre Fischer         TitleBar* pTitleBar = rPanel.GetTitleBar();
220*7a32b0c8SAndre Fischer         pTitleBar->SetPosSizePixel(0, nY, nWidth, nPanelTitleBarHeight);
221*7a32b0c8SAndre Fischer         pTitleBar->Show();
222*7a32b0c8SAndre Fischer         nY += nPanelTitleBarHeight;
223*7a32b0c8SAndre Fischer 
224*7a32b0c8SAndre Fischer         // Separator below the panel title bar.
225*7a32b0c8SAndre Fischer         aSeparators.push_back(nY);
226*7a32b0c8SAndre Fischer         nY += nDeckSeparatorHeight;
227*7a32b0c8SAndre Fischer 
228*7a32b0c8SAndre Fischer         if (rPanel.IsExpanded())
229*7a32b0c8SAndre Fischer         {
230*7a32b0c8SAndre Fischer             rPanel.Show();
231*7a32b0c8SAndre Fischer 
232*7a32b0c8SAndre Fischer             // Determine the height of the panel depending on layout
233*7a32b0c8SAndre Fischer             // mode and distributed heights.
234*7a32b0c8SAndre Fischer             sal_Int32 nPanelHeight (0);
235*7a32b0c8SAndre Fischer             switch(eMode)
236*7a32b0c8SAndre Fischer             {
237*7a32b0c8SAndre Fischer                 case MinimumOrLarger:
238*7a32b0c8SAndre Fischer                     nPanelHeight = iItem->maLayoutSize.Minimum + iItem->mnDistributedHeight;
239*7a32b0c8SAndre Fischer                     break;
240*7a32b0c8SAndre Fischer                 case PreferredOrLarger:
241*7a32b0c8SAndre Fischer                     nPanelHeight = iItem->maLayoutSize.Preferred + iItem->mnDistributedHeight;
242*7a32b0c8SAndre Fischer                     break;
243*7a32b0c8SAndre Fischer                 case Preferred:
244*7a32b0c8SAndre Fischer                     nPanelHeight = iItem->maLayoutSize.Preferred;
245*7a32b0c8SAndre Fischer                     break;
246*7a32b0c8SAndre Fischer                 default:
247*7a32b0c8SAndre Fischer                     OSL_ASSERT(false);
248*7a32b0c8SAndre Fischer                     break;
249*7a32b0c8SAndre Fischer             }
250*7a32b0c8SAndre Fischer 
251*7a32b0c8SAndre Fischer             // Place the panel.
252*7a32b0c8SAndre Fischer             OSL_TRACE("panel %d: placing @%d +%d", iItem->mnPanelIndex, nY, nPanelHeight);
253*7a32b0c8SAndre Fischer             rPanel.SetPosSizePixel(0, nY, nWidth, nPanelHeight);
254*7a32b0c8SAndre Fischer 
255*7a32b0c8SAndre Fischer             nY += nPanelHeight;
256*7a32b0c8SAndre Fischer         }
257*7a32b0c8SAndre Fischer         else
258*7a32b0c8SAndre Fischer         {
259*7a32b0c8SAndre Fischer             rPanel.Hide();
260*7a32b0c8SAndre Fischer         }
261*7a32b0c8SAndre Fischer     }
262*7a32b0c8SAndre Fischer 
263*7a32b0c8SAndre Fischer     Deck::ScrollContainerWindow* pScrollContainerWindow
264*7a32b0c8SAndre Fischer         = dynamic_cast<Deck::ScrollContainerWindow*>(&rScrollContainer);
265*7a32b0c8SAndre Fischer     if (pScrollContainerWindow != NULL)
266*7a32b0c8SAndre Fischer         pScrollContainerWindow->SetSeparators(aSeparators);
267*7a32b0c8SAndre Fischer 
268*7a32b0c8SAndre Fischer     return nY;
269*7a32b0c8SAndre Fischer }
270*7a32b0c8SAndre Fischer 
271*7a32b0c8SAndre Fischer 
272*7a32b0c8SAndre Fischer 
273*7a32b0c8SAndre Fischer 
274*7a32b0c8SAndre Fischer void DeckLayouter::GetRequestedSizes (
275*7a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
276*7a32b0c8SAndre Fischer     sal_Int32& rAvailableHeight,
277*7a32b0c8SAndre Fischer     const Rectangle& rContentBox)
278*7a32b0c8SAndre Fischer {
279*7a32b0c8SAndre Fischer     rAvailableHeight = rContentBox.GetHeight();
280*7a32b0c8SAndre Fischer 
281*7a32b0c8SAndre Fischer     const sal_Int32 nPanelTitleBarHeight (Theme::GetInteger(Theme::Int_PanelTitleBarHeight));
282*7a32b0c8SAndre Fischer     const sal_Int32 nDeckSeparatorHeight (Theme::GetInteger(Theme::Int_DeckSeparatorHeight));
283*7a32b0c8SAndre Fischer 
284*7a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
285*7a32b0c8SAndre Fischer     {
286*7a32b0c8SAndre Fischer         ui::LayoutSize aLayoutSize (ui::LayoutSize(0,0,0));
287*7a32b0c8SAndre Fischer 		if (iItem->mpPanel != NULL)
288*7a32b0c8SAndre Fischer         {
289*7a32b0c8SAndre Fischer             rAvailableHeight -= nPanelTitleBarHeight;
290*7a32b0c8SAndre Fischer             rAvailableHeight -= 2*nDeckSeparatorHeight;
291*7a32b0c8SAndre Fischer 
292*7a32b0c8SAndre Fischer             if (iItem->mpPanel->IsExpanded())
293*7a32b0c8SAndre Fischer             {
294*7a32b0c8SAndre Fischer                 Reference<ui::XSidebarPanel> xPanel (iItem->mpPanel->GetPanelComponent());
295*7a32b0c8SAndre Fischer                 if (xPanel.is())
296*7a32b0c8SAndre Fischer                     aLayoutSize = xPanel->getHeightForWidth(rContentBox.GetWidth());
297*7a32b0c8SAndre Fischer                 else
298*7a32b0c8SAndre Fischer                     aLayoutSize = ui::LayoutSize(MinimalPanelHeight, 0, -1);
299*7a32b0c8SAndre Fischer             }
300*7a32b0c8SAndre Fischer         }
301*7a32b0c8SAndre Fischer         iItem->maLayoutSize = aLayoutSize;
302*7a32b0c8SAndre Fischer     }
303*7a32b0c8SAndre Fischer }
304*7a32b0c8SAndre Fischer 
305*7a32b0c8SAndre Fischer 
306*7a32b0c8SAndre Fischer 
307*7a32b0c8SAndre Fischer 
308*7a32b0c8SAndre Fischer void DeckLayouter::DistributeHeights (
309*7a32b0c8SAndre Fischer     ::std::vector<LayoutItem>& rLayoutItems,
310*7a32b0c8SAndre Fischer     const sal_Int32 nHeightToDistribute,
311*7a32b0c8SAndre Fischer     const sal_Int32 nContainerHeight,
312*7a32b0c8SAndre Fischer     const bool bMinimumHeightIsBase)
313*7a32b0c8SAndre Fischer {
314*7a32b0c8SAndre Fischer     if (nHeightToDistribute <= 0)
315*7a32b0c8SAndre Fischer         return;
316*7a32b0c8SAndre Fischer 
317*7a32b0c8SAndre Fischer     sal_Int32 nRemainingHeightToDistribute (nHeightToDistribute);
318*7a32b0c8SAndre Fischer 
319*7a32b0c8SAndre Fischer     // Compute the weights as difference between panel base height
320*7a32b0c8SAndre Fischer     // (either its minimum or preferred height) and the container height.
321*7a32b0c8SAndre Fischer     sal_Int32 nTotalWeight (0);
322*7a32b0c8SAndre Fischer     sal_Int32 nNoMaximumCount (0);
323*7a32b0c8SAndre Fischer     sal_Int32 nIndex (0);
324*7a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
325*7a32b0c8SAndre Fischer     {
326*7a32b0c8SAndre Fischer         if (iItem->maLayoutSize.Maximum == 0)
327*7a32b0c8SAndre Fischer             continue;
328*7a32b0c8SAndre Fischer         if (iItem->maLayoutSize.Maximum < 0)
329*7a32b0c8SAndre Fischer             ++nNoMaximumCount;
330*7a32b0c8SAndre Fischer 
331*7a32b0c8SAndre Fischer         const sal_Int32 nBaseHeight (
332*7a32b0c8SAndre Fischer             bMinimumHeightIsBase
333*7a32b0c8SAndre Fischer                 ? iItem->maLayoutSize.Minimum
334*7a32b0c8SAndre Fischer                 : iItem->maLayoutSize.Preferred);
335*7a32b0c8SAndre Fischer         if (nBaseHeight < nContainerHeight)
336*7a32b0c8SAndre Fischer         {
337*7a32b0c8SAndre Fischer             iItem->mnWeight = nContainerHeight - nBaseHeight;
338*7a32b0c8SAndre Fischer             nTotalWeight += iItem->mnWeight;
339*7a32b0c8SAndre Fischer         }
340*7a32b0c8SAndre Fischer         OSL_TRACE("panel %d: base height is %d, weight is %d, min/max/pref are %d/%d/%d",
341*7a32b0c8SAndre Fischer             nIndex, nBaseHeight, iItem->mnWeight,
342*7a32b0c8SAndre Fischer             iItem->maLayoutSize.Minimum, iItem->maLayoutSize.Maximum, iItem->maLayoutSize.Preferred);
343*7a32b0c8SAndre Fischer     }
344*7a32b0c8SAndre Fischer 
345*7a32b0c8SAndre Fischer 	if (nTotalWeight == 0)
346*7a32b0c8SAndre Fischer 		return;
347*7a32b0c8SAndre Fischer 
348*7a32b0c8SAndre Fischer     // First pass of height distribution.
349*7a32b0c8SAndre Fischer     nIndex = 0;
350*7a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
351*7a32b0c8SAndre Fischer     {
352*7a32b0c8SAndre Fischer         const sal_Int32 nBaseHeight (
353*7a32b0c8SAndre Fischer             bMinimumHeightIsBase
354*7a32b0c8SAndre Fischer                 ? iItem->maLayoutSize.Minimum
355*7a32b0c8SAndre Fischer                 : iItem->maLayoutSize.Preferred);
356*7a32b0c8SAndre Fischer         sal_Int32 nDistributedHeight (iItem->mnWeight * nHeightToDistribute / nTotalWeight);
357*7a32b0c8SAndre Fischer         if (nBaseHeight+nDistributedHeight > iItem->maLayoutSize.Maximum
358*7a32b0c8SAndre Fischer             && iItem->maLayoutSize.Maximum >= 0)
359*7a32b0c8SAndre Fischer         {
360*7a32b0c8SAndre Fischer             nDistributedHeight = ::std::max<sal_Int32>(0,iItem->maLayoutSize.Maximum - nBaseHeight);
361*7a32b0c8SAndre Fischer         }
362*7a32b0c8SAndre Fischer         iItem->mnDistributedHeight = nDistributedHeight;
363*7a32b0c8SAndre Fischer         OSL_TRACE("panel %d: distributed height is %d", nIndex, nDistributedHeight);
364*7a32b0c8SAndre Fischer         nRemainingHeightToDistribute -= nDistributedHeight;
365*7a32b0c8SAndre Fischer     }
366*7a32b0c8SAndre Fischer 
367*7a32b0c8SAndre Fischer     if (nRemainingHeightToDistribute == 0)
368*7a32b0c8SAndre Fischer         return;
369*7a32b0c8SAndre Fischer     OSL_ASSERT(nRemainingHeightToDistribute > 0);
370*7a32b0c8SAndre Fischer 
371*7a32b0c8SAndre Fischer     // It is possible that not all of the height could be distributed
372*7a32b0c8SAndre Fischer     // because of Maximum heights being smaller than expected.
373*7a32b0c8SAndre Fischer     // Distribute the remaining height between the panels that have no
374*7a32b0c8SAndre Fischer     // Maximum (ie Maximum==-1).
375*7a32b0c8SAndre Fischer     if (nNoMaximumCount == 0)
376*7a32b0c8SAndre Fischer     {
377*7a32b0c8SAndre Fischer         // There are no panels with unrestricted height.
378*7a32b0c8SAndre Fischer         return;
379*7a32b0c8SAndre Fischer     }
380*7a32b0c8SAndre Fischer     const sal_Int32 nAdditionalHeightPerPanel (nRemainingHeightToDistribute / nNoMaximumCount);
381*7a32b0c8SAndre Fischer     // Handle rounding error.
382*7a32b0c8SAndre Fischer     sal_Int32 nAdditionalHeightForFirstPanel (nRemainingHeightToDistribute
383*7a32b0c8SAndre Fischer         - nNoMaximumCount*nAdditionalHeightPerPanel);
384*7a32b0c8SAndre Fischer     nIndex = 0;
385*7a32b0c8SAndre Fischer     IterateLayoutItems(iItem,rLayoutItems)
386*7a32b0c8SAndre Fischer     {
387*7a32b0c8SAndre Fischer         if (iItem->maLayoutSize.Maximum < 0)
388*7a32b0c8SAndre Fischer         {
389*7a32b0c8SAndre Fischer             iItem->mnDistributedHeight += nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel;
390*7a32b0c8SAndre Fischer             OSL_TRACE("panel %d: additionl height is %d",
391*7a32b0c8SAndre Fischer                 iItem->mnPanelIndex,
392*7a32b0c8SAndre Fischer                 nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel);
393*7a32b0c8SAndre Fischer             nRemainingHeightToDistribute -= nAdditionalHeightPerPanel + nAdditionalHeightForFirstPanel;
394*7a32b0c8SAndre Fischer         }
395*7a32b0c8SAndre Fischer     }
396*7a32b0c8SAndre Fischer 
397*7a32b0c8SAndre Fischer     OSL_ASSERT(nRemainingHeightToDistribute==0);
398*7a32b0c8SAndre Fischer }
399*7a32b0c8SAndre Fischer 
400*7a32b0c8SAndre Fischer 
401*7a32b0c8SAndre Fischer 
402*7a32b0c8SAndre Fischer 
403*7a32b0c8SAndre Fischer Rectangle DeckLayouter::PlaceDeckTitle (
404*7a32b0c8SAndre Fischer     Window& rDeckTitleBar,
405*7a32b0c8SAndre Fischer     const Rectangle& rAvailableSpace)
406*7a32b0c8SAndre Fischer {
407*7a32b0c8SAndre Fischer     if (static_cast<DockingWindow*>(rDeckTitleBar.GetParent()->GetParent())->IsFloatingMode())
408*7a32b0c8SAndre Fischer     {
409*7a32b0c8SAndre Fischer         // When the side bar is undocked then the outer system window displays the deck title.
410*7a32b0c8SAndre Fischer         rDeckTitleBar.Hide();
411*7a32b0c8SAndre Fischer         return rAvailableSpace;
412*7a32b0c8SAndre Fischer     }
413*7a32b0c8SAndre Fischer     else
414*7a32b0c8SAndre Fischer     {
415*7a32b0c8SAndre Fischer         const sal_Int32 nDeckTitleBarHeight (Theme::GetInteger(Theme::Int_DeckTitleBarHeight));
416*7a32b0c8SAndre Fischer         rDeckTitleBar.SetPosSizePixel(
417*7a32b0c8SAndre Fischer             rAvailableSpace.Left(),
418*7a32b0c8SAndre Fischer             rAvailableSpace.Top(),
419*7a32b0c8SAndre Fischer             rAvailableSpace.GetWidth(),
420*7a32b0c8SAndre Fischer             nDeckTitleBarHeight);
421*7a32b0c8SAndre Fischer         rDeckTitleBar.Show();
422*7a32b0c8SAndre Fischer         return Rectangle(
423*7a32b0c8SAndre Fischer             rAvailableSpace.Left(),
424*7a32b0c8SAndre Fischer             rAvailableSpace.Top() + nDeckTitleBarHeight,
425*7a32b0c8SAndre Fischer             rAvailableSpace.Right(),
426*7a32b0c8SAndre Fischer             rAvailableSpace.Bottom());
427*7a32b0c8SAndre Fischer     }
428*7a32b0c8SAndre Fischer }
429*7a32b0c8SAndre Fischer 
430*7a32b0c8SAndre Fischer 
431*7a32b0c8SAndre Fischer 
432*7a32b0c8SAndre Fischer 
433*7a32b0c8SAndre Fischer Rectangle DeckLayouter::PlaceVerticalScrollBar (
434*7a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar,
435*7a32b0c8SAndre Fischer     const Rectangle& rAvailableSpace,
436*7a32b0c8SAndre Fischer     const bool bShowVerticalScrollBar)
437*7a32b0c8SAndre Fischer {
438*7a32b0c8SAndre Fischer     if (bShowVerticalScrollBar)
439*7a32b0c8SAndre Fischer     {
440*7a32b0c8SAndre Fischer         const sal_Int32 nScrollBarWidth (rVerticalScrollBar.GetSizePixel().Width());
441*7a32b0c8SAndre Fischer         rVerticalScrollBar.SetPosSizePixel(
442*7a32b0c8SAndre Fischer             rAvailableSpace.Right() - nScrollBarWidth + 1,
443*7a32b0c8SAndre Fischer             rAvailableSpace.Top(),
444*7a32b0c8SAndre Fischer             nScrollBarWidth,
445*7a32b0c8SAndre Fischer             rAvailableSpace.GetHeight());
446*7a32b0c8SAndre Fischer         rVerticalScrollBar.Show();
447*7a32b0c8SAndre Fischer         return Rectangle(
448*7a32b0c8SAndre Fischer             rAvailableSpace.Left(),
449*7a32b0c8SAndre Fischer             rAvailableSpace.Top(),
450*7a32b0c8SAndre Fischer             rAvailableSpace.Right() - nScrollBarWidth,
451*7a32b0c8SAndre Fischer             rAvailableSpace.Bottom());
452*7a32b0c8SAndre Fischer     }
453*7a32b0c8SAndre Fischer     else
454*7a32b0c8SAndre Fischer     {
455*7a32b0c8SAndre Fischer         rVerticalScrollBar.Hide();
456*7a32b0c8SAndre Fischer         return rAvailableSpace;
457*7a32b0c8SAndre Fischer     }
458*7a32b0c8SAndre Fischer }
459*7a32b0c8SAndre Fischer 
460*7a32b0c8SAndre Fischer 
461*7a32b0c8SAndre Fischer 
462*7a32b0c8SAndre Fischer 
463*7a32b0c8SAndre Fischer void DeckLayouter::SetupVerticalScrollBar(
464*7a32b0c8SAndre Fischer     ScrollBar& rVerticalScrollBar,
465*7a32b0c8SAndre Fischer     const sal_Int32 nContentHeight,
466*7a32b0c8SAndre Fischer     const sal_Int32 nVisibleHeight)
467*7a32b0c8SAndre Fischer {
468*7a32b0c8SAndre Fischer     OSL_ASSERT(nContentHeight > nVisibleHeight);
469*7a32b0c8SAndre Fischer 
470*7a32b0c8SAndre Fischer     rVerticalScrollBar.SetRangeMin(0);
471*7a32b0c8SAndre Fischer     rVerticalScrollBar.SetRangeMax(nContentHeight-1);
472*7a32b0c8SAndre Fischer     rVerticalScrollBar.SetVisibleSize(nVisibleHeight);
473*7a32b0c8SAndre Fischer }
474*7a32b0c8SAndre Fischer 
475*7a32b0c8SAndre Fischer 
476*7a32b0c8SAndre Fischer 
477*7a32b0c8SAndre Fischer 
478*7a32b0c8SAndre Fischer void DeckLayouter::UpdateFiller (
479*7a32b0c8SAndre Fischer     Window& rFiller,
480*7a32b0c8SAndre Fischer     const Rectangle& rBox)
481*7a32b0c8SAndre Fischer {
482*7a32b0c8SAndre Fischer     if (rBox.GetHeight() > 0)
483*7a32b0c8SAndre Fischer     {
484*7a32b0c8SAndre Fischer         // Show the filler.
485*7a32b0c8SAndre Fischer         rFiller.SetBackground(Theme::GetPaint(Theme::Paint_PanelBackground).GetWallpaper());
486*7a32b0c8SAndre Fischer         rFiller.SetPosSizePixel(rBox.TopLeft(), rBox.GetSize());
487*7a32b0c8SAndre Fischer         rFiller.Show();
488*7a32b0c8SAndre Fischer     }
489*7a32b0c8SAndre Fischer     else
490*7a32b0c8SAndre Fischer     {
491*7a32b0c8SAndre Fischer         // Hide the filler.
492*7a32b0c8SAndre Fischer         rFiller.Hide();
493*7a32b0c8SAndre Fischer     }
494*7a32b0c8SAndre Fischer }
495*7a32b0c8SAndre Fischer 
496*7a32b0c8SAndre Fischer 
497*7a32b0c8SAndre Fischer 
498*7a32b0c8SAndre Fischer } } // end of namespace sfx2::sidebar
499