1*6a606da0SAndre Fischer /**************************************************************
2*6a606da0SAndre Fischer  *
3*6a606da0SAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
4*6a606da0SAndre Fischer  * or more contributor license agreements.  See the NOTICE file
5*6a606da0SAndre Fischer  * distributed with this work for additional information
6*6a606da0SAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
7*6a606da0SAndre Fischer  * to you under the Apache License, Version 2.0 (the
8*6a606da0SAndre Fischer  * "License"); you may not use this file except in compliance
9*6a606da0SAndre Fischer  * with the License.  You may obtain a copy of the License at
10*6a606da0SAndre Fischer  *
11*6a606da0SAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
12*6a606da0SAndre Fischer  *
13*6a606da0SAndre Fischer  * Unless required by applicable law or agreed to in writing,
14*6a606da0SAndre Fischer  * software distributed under the License is distributed on an
15*6a606da0SAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6a606da0SAndre Fischer  * KIND, either express or implied.  See the License for the
17*6a606da0SAndre Fischer  * specific language governing permissions and limitations
18*6a606da0SAndre Fischer  * under the License.
19*6a606da0SAndre Fischer  *
20*6a606da0SAndre Fischer  *************************************************************/
21*6a606da0SAndre Fischer 
22*6a606da0SAndre Fischer #include "precompiled_sfx2.hxx"
23*6a606da0SAndre Fischer #include "sfx2/sidebar/GridLayouter.hxx"
24*6a606da0SAndre Fischer 
25*6a606da0SAndre Fischer #include <vcl/window.hxx>
26*6a606da0SAndre Fischer 
27*6a606da0SAndre Fischer namespace sfx2 { namespace sidebar {
28*6a606da0SAndre Fischer 
29*6a606da0SAndre Fischer typedef std::vector<CellDescriptor> CellData;
30*6a606da0SAndre Fischer typedef std::vector<CellData> ColumnData;
31*6a606da0SAndre Fischer 
32*6a606da0SAndre Fischer class GridLayouter::Implementation
33*6a606da0SAndre Fischer {
34*6a606da0SAndre Fischer public:
35*6a606da0SAndre Fischer     Implementation (Window& rParent);
36*6a606da0SAndre Fischer     ~Implementation (void);
37*6a606da0SAndre Fischer 
38*6a606da0SAndre Fischer     CellDescriptor& GetCell (
39*6a606da0SAndre Fischer         const sal_Int32 nRow,
40*6a606da0SAndre Fischer         const sal_Int32 nColumn,
41*6a606da0SAndre Fischer         const sal_Int32 nVariant);
42*6a606da0SAndre Fischer 
43*6a606da0SAndre Fischer     void Layout (void);
44*6a606da0SAndre Fischer     void LayoutColumn(
45*6a606da0SAndre Fischer         ColumnData& rColumn,
46*6a606da0SAndre Fischer         const sal_Int32 nX,
47*6a606da0SAndre Fischer         const sal_Int32 nColumnIndex);
48*6a606da0SAndre Fischer 
49*6a606da0SAndre Fischer     void DistributeWidth (const sal_Int32 nTotalWidth);
50*6a606da0SAndre Fischer     sal_Int32 GetMinimumColumnWidth (
51*6a606da0SAndre Fischer         ColumnData& rColumn,
52*6a606da0SAndre Fischer         const ColumnDescriptor& rDescriptor) const;
53*6a606da0SAndre Fischer 
54*6a606da0SAndre Fischer     void Paint (void);
55*6a606da0SAndre Fischer 
56*6a606da0SAndre Fischer     Window& mrParent;
57*6a606da0SAndre Fischer     ::std::vector<ColumnData> maColumns;
58*6a606da0SAndre Fischer     ::std::vector<ColumnDescriptor> maColumnDescriptors;
59*6a606da0SAndre Fischer };
60*6a606da0SAndre Fischer 
61*6a606da0SAndre Fischer #define ForAllColumnDescriptors(I)                              \
62*6a606da0SAndre Fischer     for (::std::vector<ColumnDescriptor>::iterator              \
63*6a606da0SAndre Fischer              I(maColumnDescriptors.begin()),                    \
64*6a606da0SAndre Fischer              iEnd(maColumnDescriptors.end());                   \
65*6a606da0SAndre Fischer          I!=iEnd;                                               \
66*6a606da0SAndre Fischer          ++I)
67*6a606da0SAndre Fischer 
68*6a606da0SAndre Fischer #define ForAllColumns(I,N)                                      \
69*6a606da0SAndre Fischer     sal_Int32 N (0);                                            \
70*6a606da0SAndre Fischer     for (::std::vector<ColumnData>::iterator                    \
71*6a606da0SAndre Fischer              I(maColumns.begin()),                              \
72*6a606da0SAndre Fischer              iEnd(maColumns.end());                             \
73*6a606da0SAndre Fischer          I!=iEnd;                                               \
74*6a606da0SAndre Fischer          ++I,++N)
75*6a606da0SAndre Fischer 
76*6a606da0SAndre Fischer #define ForAllRows(ColumnData,I)                                \
77*6a606da0SAndre Fischer     for (std::vector<CellData>::iterator                        \
78*6a606da0SAndre Fischer              I((ColumnData).begin()),                           \
79*6a606da0SAndre Fischer              iRowEnd((ColumnData).end());                       \
80*6a606da0SAndre Fischer          I!=iRowEnd;                                            \
81*6a606da0SAndre Fischer          ++I)
82*6a606da0SAndre Fischer 
83*6a606da0SAndre Fischer #define ForAllCells(CellData,I)                                 \
84*6a606da0SAndre Fischer     for (::std::vector<CellDescriptor>::iterator                \
85*6a606da0SAndre Fischer              I((CellData).begin()),                             \
86*6a606da0SAndre Fischer              iCellEnd((CellData).end());                        \
87*6a606da0SAndre Fischer          I!=iCellEnd;                                           \
88*6a606da0SAndre Fischer          ++I)
89*6a606da0SAndre Fischer 
90*6a606da0SAndre Fischer 
91*6a606da0SAndre Fischer //===== GridLayouter ==========================================================
92*6a606da0SAndre Fischer 
GridLayouter(Window & rParent)93*6a606da0SAndre Fischer GridLayouter::GridLayouter (Window& rParent)
94*6a606da0SAndre Fischer     : mpImplementation(new Implementation(rParent))
95*6a606da0SAndre Fischer {
96*6a606da0SAndre Fischer }
97*6a606da0SAndre Fischer 
98*6a606da0SAndre Fischer 
99*6a606da0SAndre Fischer 
100*6a606da0SAndre Fischer 
~GridLayouter(void)101*6a606da0SAndre Fischer GridLayouter::~GridLayouter (void)
102*6a606da0SAndre Fischer {
103*6a606da0SAndre Fischer }
104*6a606da0SAndre Fischer 
105*6a606da0SAndre Fischer 
106*6a606da0SAndre Fischer 
107*6a606da0SAndre Fischer 
GetCell(const sal_Int32 nRow,const sal_Int32 nColumn,const sal_Int32 nVariant)108*6a606da0SAndre Fischer CellDescriptor& GridLayouter::GetCell (
109*6a606da0SAndre Fischer     const sal_Int32 nRow,
110*6a606da0SAndre Fischer     const sal_Int32 nColumn,
111*6a606da0SAndre Fischer     const sal_Int32 nVariant)
112*6a606da0SAndre Fischer {
113*6a606da0SAndre Fischer     return mpImplementation->GetCell(nRow, nColumn, nVariant);
114*6a606da0SAndre Fischer }
115*6a606da0SAndre Fischer 
116*6a606da0SAndre Fischer 
117*6a606da0SAndre Fischer 
118*6a606da0SAndre Fischer 
GetColumn(const sal_Int32 nColumn)119*6a606da0SAndre Fischer ColumnDescriptor& GridLayouter::GetColumn (
120*6a606da0SAndre Fischer     const sal_Int32 nColumn)
121*6a606da0SAndre Fischer {
122*6a606da0SAndre Fischer     // Make sure that the specified column exists.
123*6a606da0SAndre Fischer     mpImplementation->GetCell(0, nColumn, 0);
124*6a606da0SAndre Fischer     return mpImplementation->maColumnDescriptors[nColumn];
125*6a606da0SAndre Fischer }
126*6a606da0SAndre Fischer 
127*6a606da0SAndre Fischer 
128*6a606da0SAndre Fischer 
129*6a606da0SAndre Fischer 
Layout(void)130*6a606da0SAndre Fischer void GridLayouter::Layout (void)
131*6a606da0SAndre Fischer {
132*6a606da0SAndre Fischer     mpImplementation->Layout();
133*6a606da0SAndre Fischer }
134*6a606da0SAndre Fischer 
135*6a606da0SAndre Fischer 
136*6a606da0SAndre Fischer 
137*6a606da0SAndre Fischer 
Paint(const Rectangle & rBox)138*6a606da0SAndre Fischer void GridLayouter::Paint (const Rectangle& rBox)
139*6a606da0SAndre Fischer {
140*6a606da0SAndre Fischer     (void)rBox;
141*6a606da0SAndre Fischer 
142*6a606da0SAndre Fischer     mpImplementation->Paint();
143*6a606da0SAndre Fischer }
144*6a606da0SAndre Fischer 
145*6a606da0SAndre Fischer 
146*6a606da0SAndre Fischer 
147*6a606da0SAndre Fischer 
148*6a606da0SAndre Fischer //===== CellDescriptor ========================================================
149*6a606da0SAndre Fischer 
CellDescriptor(void)150*6a606da0SAndre Fischer CellDescriptor::CellDescriptor (void)
151*6a606da0SAndre Fischer     : mpControl(NULL),
152*6a606da0SAndre Fischer       mnGridWidth(1),
153*6a606da0SAndre Fischer       mnMinimumWidth(-1),
154*6a606da0SAndre Fischer       mnMaximumWidth(-1),
155*6a606da0SAndre Fischer       mnOffset(0)
156*6a606da0SAndre Fischer {
157*6a606da0SAndre Fischer }
158*6a606da0SAndre Fischer 
159*6a606da0SAndre Fischer 
160*6a606da0SAndre Fischer 
161*6a606da0SAndre Fischer 
~CellDescriptor(void)162*6a606da0SAndre Fischer CellDescriptor::~CellDescriptor (void)
163*6a606da0SAndre Fischer {
164*6a606da0SAndre Fischer }
165*6a606da0SAndre Fischer 
166*6a606da0SAndre Fischer 
167*6a606da0SAndre Fischer 
168*6a606da0SAndre Fischer 
SetGridWidth(const sal_Int32 nColumnCount)169*6a606da0SAndre Fischer CellDescriptor& CellDescriptor::SetGridWidth (const sal_Int32 nColumnCount)
170*6a606da0SAndre Fischer {
171*6a606da0SAndre Fischer     mnGridWidth = nColumnCount;
172*6a606da0SAndre Fischer     return *this;
173*6a606da0SAndre Fischer }
174*6a606da0SAndre Fischer 
175*6a606da0SAndre Fischer 
176*6a606da0SAndre Fischer 
177*6a606da0SAndre Fischer 
SetControl(Window & rControl)178*6a606da0SAndre Fischer CellDescriptor& CellDescriptor::SetControl (Window& rControl)
179*6a606da0SAndre Fischer {
180*6a606da0SAndre Fischer     mpControl = &rControl;
181*6a606da0SAndre Fischer     return *this;
182*6a606da0SAndre Fischer }
183*6a606da0SAndre Fischer 
184*6a606da0SAndre Fischer 
185*6a606da0SAndre Fischer 
186*6a606da0SAndre Fischer 
SetFixedWidth(const sal_Int32 nWidth)187*6a606da0SAndre Fischer CellDescriptor& CellDescriptor::SetFixedWidth (const sal_Int32 nWidth)
188*6a606da0SAndre Fischer {
189*6a606da0SAndre Fischer     mnMinimumWidth = nWidth;
190*6a606da0SAndre Fischer     mnMaximumWidth = nWidth;
191*6a606da0SAndre Fischer     return *this;
192*6a606da0SAndre Fischer }
193*6a606da0SAndre Fischer 
194*6a606da0SAndre Fischer 
195*6a606da0SAndre Fischer 
SetOffset(const sal_Int32 nOffset)196*6a606da0SAndre Fischer CellDescriptor& CellDescriptor::SetOffset (const sal_Int32 nOffset)
197*6a606da0SAndre Fischer {
198*6a606da0SAndre Fischer     mnOffset = nOffset;
199*6a606da0SAndre Fischer     return *this;
200*6a606da0SAndre Fischer }
201*6a606da0SAndre Fischer 
202*6a606da0SAndre Fischer 
203*6a606da0SAndre Fischer 
204*6a606da0SAndre Fischer 
SetFixedWidth(void)205*6a606da0SAndre Fischer CellDescriptor& CellDescriptor::SetFixedWidth (void)
206*6a606da0SAndre Fischer {
207*6a606da0SAndre Fischer     sal_Int32 nMaxControlWidth (0);
208*6a606da0SAndre Fischer     if (mpControl != NULL)
209*6a606da0SAndre Fischer     {
210*6a606da0SAndre Fischer         const sal_Int32 nControlWidth (mpControl->GetSizePixel().Width());
211*6a606da0SAndre Fischer         if (nControlWidth > nMaxControlWidth)
212*6a606da0SAndre Fischer             nMaxControlWidth = nControlWidth;
213*6a606da0SAndre Fischer     }
214*6a606da0SAndre Fischer     mnMinimumWidth = nMaxControlWidth;
215*6a606da0SAndre Fischer     mnMaximumWidth = nMaxControlWidth;
216*6a606da0SAndre Fischer 
217*6a606da0SAndre Fischer     return *this;
218*6a606da0SAndre Fischer }
219*6a606da0SAndre Fischer 
220*6a606da0SAndre Fischer 
221*6a606da0SAndre Fischer 
222*6a606da0SAndre Fischer 
SetMinimumWidth(const sal_Int32 nWidth)223*6a606da0SAndre Fischer CellDescriptor& CellDescriptor::SetMinimumWidth (const sal_Int32 nWidth)
224*6a606da0SAndre Fischer {
225*6a606da0SAndre Fischer     mnMinimumWidth = nWidth;
226*6a606da0SAndre Fischer     return *this;
227*6a606da0SAndre Fischer }
228*6a606da0SAndre Fischer 
229*6a606da0SAndre Fischer 
230*6a606da0SAndre Fischer 
GetGridWidth(void) const231*6a606da0SAndre Fischer sal_Int32 CellDescriptor::GetGridWidth (void) const
232*6a606da0SAndre Fischer {
233*6a606da0SAndre Fischer     return mnGridWidth;
234*6a606da0SAndre Fischer }
235*6a606da0SAndre Fischer 
236*6a606da0SAndre Fischer 
237*6a606da0SAndre Fischer 
238*6a606da0SAndre Fischer 
GetControl(void) const239*6a606da0SAndre Fischer Window* CellDescriptor::GetControl (void) const
240*6a606da0SAndre Fischer {
241*6a606da0SAndre Fischer     return mpControl;
242*6a606da0SAndre Fischer }
243*6a606da0SAndre Fischer 
244*6a606da0SAndre Fischer 
245*6a606da0SAndre Fischer 
246*6a606da0SAndre Fischer 
GetMinimumWidth(void) const247*6a606da0SAndre Fischer sal_Int32 CellDescriptor::GetMinimumWidth (void) const
248*6a606da0SAndre Fischer {
249*6a606da0SAndre Fischer     return mnMinimumWidth + mnOffset;
250*6a606da0SAndre Fischer }
251*6a606da0SAndre Fischer 
252*6a606da0SAndre Fischer 
253*6a606da0SAndre Fischer 
254*6a606da0SAndre Fischer 
GetMaximumWidth(void) const255*6a606da0SAndre Fischer sal_Int32 CellDescriptor::GetMaximumWidth (void) const
256*6a606da0SAndre Fischer {
257*6a606da0SAndre Fischer     return mnMaximumWidth;
258*6a606da0SAndre Fischer }
259*6a606da0SAndre Fischer 
260*6a606da0SAndre Fischer 
261*6a606da0SAndre Fischer 
GetOffset(void) const262*6a606da0SAndre Fischer sal_Int32 CellDescriptor::GetOffset (void) const
263*6a606da0SAndre Fischer {
264*6a606da0SAndre Fischer     return mnOffset;
265*6a606da0SAndre Fischer }
266*6a606da0SAndre Fischer 
267*6a606da0SAndre Fischer 
268*6a606da0SAndre Fischer 
269*6a606da0SAndre Fischer 
270*6a606da0SAndre Fischer //===== GridLayouter::Implementation ==========================================
271*6a606da0SAndre Fischer 
Implementation(Window & rParent)272*6a606da0SAndre Fischer GridLayouter::Implementation::Implementation (Window& rParent)
273*6a606da0SAndre Fischer     : mrParent(rParent),
274*6a606da0SAndre Fischer       maColumns(),
275*6a606da0SAndre Fischer       maColumnDescriptors()
276*6a606da0SAndre Fischer {
277*6a606da0SAndre Fischer }
278*6a606da0SAndre Fischer 
279*6a606da0SAndre Fischer 
280*6a606da0SAndre Fischer 
281*6a606da0SAndre Fischer 
~Implementation(void)282*6a606da0SAndre Fischer GridLayouter::Implementation::~Implementation (void)
283*6a606da0SAndre Fischer {
284*6a606da0SAndre Fischer }
285*6a606da0SAndre Fischer 
286*6a606da0SAndre Fischer 
287*6a606da0SAndre Fischer 
288*6a606da0SAndre Fischer 
GetCell(const sal_Int32 nRow,const sal_Int32 nColumn,const sal_Int32 nVariant)289*6a606da0SAndre Fischer CellDescriptor& GridLayouter::Implementation::GetCell (
290*6a606da0SAndre Fischer     const sal_Int32 nRow,
291*6a606da0SAndre Fischer     const sal_Int32 nColumn,
292*6a606da0SAndre Fischer     const sal_Int32 nVariant)
293*6a606da0SAndre Fischer {
294*6a606da0SAndre Fischer     if (nColumn<0 || nRow<0 || nVariant<0)
295*6a606da0SAndre Fischer     {
296*6a606da0SAndre Fischer         OSL_ASSERT(nColumn>=0);
297*6a606da0SAndre Fischer         OSL_ASSERT(nRow>=0);
298*6a606da0SAndre Fischer         OSL_ASSERT(nVariant>=0);
299*6a606da0SAndre Fischer         return GetCell(0,0,0);
300*6a606da0SAndre Fischer     }
301*6a606da0SAndre Fischer 
302*6a606da0SAndre Fischer     // Provide missing columns.
303*6a606da0SAndre Fischer     if (maColumns.size() <= static_cast<size_t>(nColumn))
304*6a606da0SAndre Fischer     {
305*6a606da0SAndre Fischer         maColumns.resize(nColumn+1);
306*6a606da0SAndre Fischer         maColumnDescriptors.resize(nColumn+1);
307*6a606da0SAndre Fischer     }
308*6a606da0SAndre Fischer 
309*6a606da0SAndre Fischer     // Provide missing rows.
310*6a606da0SAndre Fischer     ColumnData& rColumn (maColumns[nColumn]);
311*6a606da0SAndre Fischer     if (rColumn.size() <= static_cast<size_t>(nRow))
312*6a606da0SAndre Fischer         rColumn.resize(nRow+1);
313*6a606da0SAndre Fischer 
314*6a606da0SAndre Fischer     // Provide missing variants.
315*6a606da0SAndre Fischer     CellData& rCellData (rColumn[nRow]);
316*6a606da0SAndre Fischer     if (rCellData.size() <= static_cast<size_t>(nVariant))
317*6a606da0SAndre Fischer         rCellData.resize(nVariant+1);
318*6a606da0SAndre Fischer 
319*6a606da0SAndre Fischer     return rCellData[nVariant];
320*6a606da0SAndre Fischer }
321*6a606da0SAndre Fischer 
322*6a606da0SAndre Fischer 
323*6a606da0SAndre Fischer 
324*6a606da0SAndre Fischer 
Layout(void)325*6a606da0SAndre Fischer void GridLayouter::Implementation::Layout (void)
326*6a606da0SAndre Fischer {
327*6a606da0SAndre Fischer     if (maColumns.empty())
328*6a606da0SAndre Fischer     {
329*6a606da0SAndre Fischer         // There are no columns and therefore no controls => nothing
330*6a606da0SAndre Fischer         // to do.
331*6a606da0SAndre Fischer         return;
332*6a606da0SAndre Fischer     }
333*6a606da0SAndre Fischer 
334*6a606da0SAndre Fischer     const Size aParentSize (mrParent.GetSizePixel());
335*6a606da0SAndre Fischer 
336*6a606da0SAndre Fischer     // Determine the total column weight.
337*6a606da0SAndre Fischer     sal_Int32 nTotalColumnWeight (0);
338*6a606da0SAndre Fischer     ForAllColumnDescriptors(iDescriptor)
339*6a606da0SAndre Fischer         nTotalColumnWeight += iDescriptor->GetWeight();
340*6a606da0SAndre Fischer     if (nTotalColumnWeight <= 0)
341*6a606da0SAndre Fischer     {
342*6a606da0SAndre Fischer         OSL_ASSERT(nTotalColumnWeight>0);
343*6a606da0SAndre Fischer         return;
344*6a606da0SAndre Fischer     }
345*6a606da0SAndre Fischer 
346*6a606da0SAndre Fischer     // Distribute the width of the parent window to the columns.
347*6a606da0SAndre Fischer     DistributeWidth(aParentSize.Width());
348*6a606da0SAndre Fischer 
349*6a606da0SAndre Fischer     // Set the new positions and widths.
350*6a606da0SAndre Fischer     sal_Int32 nX (0);
351*6a606da0SAndre Fischer     ForAllColumns(iColumn,nColumnIndex)
352*6a606da0SAndre Fischer     {
353*6a606da0SAndre Fischer         LayoutColumn(
354*6a606da0SAndre Fischer             *iColumn,
355*6a606da0SAndre Fischer             nX,
356*6a606da0SAndre Fischer             nColumnIndex);
357*6a606da0SAndre Fischer 
358*6a606da0SAndre Fischer         nX += maColumnDescriptors[nColumnIndex].GetWidth();
359*6a606da0SAndre Fischer     }
360*6a606da0SAndre Fischer }
361*6a606da0SAndre Fischer 
362*6a606da0SAndre Fischer 
363*6a606da0SAndre Fischer 
364*6a606da0SAndre Fischer 
LayoutColumn(ColumnData & rColumn,const sal_Int32 nX,const sal_Int32 nColumnIndex)365*6a606da0SAndre Fischer void GridLayouter::Implementation::LayoutColumn(
366*6a606da0SAndre Fischer     ColumnData& rColumn,
367*6a606da0SAndre Fischer     const sal_Int32 nX,
368*6a606da0SAndre Fischer     const sal_Int32 nColumnIndex)
369*6a606da0SAndre Fischer {
370*6a606da0SAndre Fischer     ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumnIndex]);
371*6a606da0SAndre Fischer     const sal_Int32 nLeft (nX + rDescriptor.GetLeftPadding());
372*6a606da0SAndre Fischer     const sal_Int32 nWidth (rDescriptor.GetWidth() - rDescriptor.GetLeftPadding() - rDescriptor.GetRightPadding());
373*6a606da0SAndre Fischer 
374*6a606da0SAndre Fischer     sal_Int32 nRow (-1);
375*6a606da0SAndre Fischer     ForAllRows(rColumn, iCell)
376*6a606da0SAndre Fischer     {
377*6a606da0SAndre Fischer         ++nRow;
378*6a606da0SAndre Fischer 
379*6a606da0SAndre Fischer         ForAllCells(*iCell, iCellDescriptor)
380*6a606da0SAndre Fischer         {
381*6a606da0SAndre Fischer             Window* pControl = iCellDescriptor->GetControl();
382*6a606da0SAndre Fischer             if (pControl==NULL || ! pControl->IsVisible())
383*6a606da0SAndre Fischer                 continue;
384*6a606da0SAndre Fischer 
385*6a606da0SAndre Fischer             sal_Int32 nCellWidth (nWidth);
386*6a606da0SAndre Fischer             const sal_Int32 nGridWidth (iCellDescriptor->GetGridWidth());
387*6a606da0SAndre Fischer             if (nGridWidth < 0)
388*6a606da0SAndre Fischer                 continue;
389*6a606da0SAndre Fischer             else if (nGridWidth > 1)
390*6a606da0SAndre Fischer             {
391*6a606da0SAndre Fischer                 // Cell spans more than one column.  Sum all their
392*6a606da0SAndre Fischer                 // widths.
393*6a606da0SAndre Fischer                 for (sal_Int32 nOffset=1;
394*6a606da0SAndre Fischer                      nOffset<nGridWidth && static_cast<size_t>(nColumnIndex+nOffset)<maColumnDescriptors.size();
395*6a606da0SAndre Fischer                      ++nOffset)
396*6a606da0SAndre Fischer                 {
397*6a606da0SAndre Fischer                     nCellWidth += maColumnDescriptors[nColumnIndex+nOffset].GetWidth();
398*6a606da0SAndre Fischer                 }
399*6a606da0SAndre Fischer                 nCellWidth -= maColumnDescriptors[nColumnIndex+nGridWidth-1].GetRightPadding();
400*6a606da0SAndre Fischer             }
401*6a606da0SAndre Fischer 
402*6a606da0SAndre Fischer             // Check width against valid range of cell.
403*6a606da0SAndre Fischer             if (iCellDescriptor->GetMinimumWidth() > 0)
404*6a606da0SAndre Fischer                 if (nCellWidth < iCellDescriptor->GetMinimumWidth())
405*6a606da0SAndre Fischer                     nCellWidth = iCellDescriptor->GetMinimumWidth();
406*6a606da0SAndre Fischer             if (iCellDescriptor->GetMaximumWidth() > 0)
407*6a606da0SAndre Fischer                 if (nCellWidth > iCellDescriptor->GetMaximumWidth())
408*6a606da0SAndre Fischer                     nCellWidth = iCellDescriptor->GetMaximumWidth();
409*6a606da0SAndre Fischer 
410*6a606da0SAndre Fischer             pControl->SetPosSizePixel(
411*6a606da0SAndre Fischer                 nLeft + iCellDescriptor->GetOffset(),
412*6a606da0SAndre Fischer                 0,
413*6a606da0SAndre Fischer                 nCellWidth,
414*6a606da0SAndre Fischer                 0,
415*6a606da0SAndre Fischer                 WINDOW_POSSIZE_X | WINDOW_POSSIZE_WIDTH);
416*6a606da0SAndre Fischer         }
417*6a606da0SAndre Fischer     }
418*6a606da0SAndre Fischer }
419*6a606da0SAndre Fischer 
420*6a606da0SAndre Fischer 
421*6a606da0SAndre Fischer 
422*6a606da0SAndre Fischer 
DistributeWidth(const sal_Int32 nTotalWidth)423*6a606da0SAndre Fischer void GridLayouter::Implementation::DistributeWidth (const sal_Int32 nTotalWidth)
424*6a606da0SAndre Fischer {
425*6a606da0SAndre Fischer     // Prepare width distribution:
426*6a606da0SAndre Fischer     // a) Setup minimum widths for all columns.
427*6a606da0SAndre Fischer     // b) Sum up the width of columns that have zero weight.
428*6a606da0SAndre Fischer     // c) Sum up the non-zero weights.
429*6a606da0SAndre Fischer     sal_Int32 nZeroWeightWidth (0);
430*6a606da0SAndre Fischer     sal_Int32 nTotalColumnWeight (0);
431*6a606da0SAndre Fischer     for (sal_uInt32 nColumn=0; nColumn<maColumns.size(); ++nColumn)
432*6a606da0SAndre Fischer     {
433*6a606da0SAndre Fischer         ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumn]);
434*6a606da0SAndre Fischer         ColumnData& rColumn (maColumns[nColumn]);
435*6a606da0SAndre Fischer 
436*6a606da0SAndre Fischer         const sal_Int32 nWidth (GetMinimumColumnWidth(rColumn, rDescriptor));
437*6a606da0SAndre Fischer 
438*6a606da0SAndre Fischer         rDescriptor.SetWidth(nWidth);
439*6a606da0SAndre Fischer 
440*6a606da0SAndre Fischer         if (rDescriptor.GetWeight() <= 0)
441*6a606da0SAndre Fischer             nZeroWeightWidth += nWidth;
442*6a606da0SAndre Fischer         else
443*6a606da0SAndre Fischer             nTotalColumnWeight += rDescriptor.GetWeight();
444*6a606da0SAndre Fischer     }
445*6a606da0SAndre Fischer 
446*6a606da0SAndre Fischer     sal_Int32 nRemainingWidth (nTotalWidth - nZeroWeightWidth);
447*6a606da0SAndre Fischer     if (nRemainingWidth < 0)
448*6a606da0SAndre Fischer         nRemainingWidth = 0;
449*6a606da0SAndre Fischer 
450*6a606da0SAndre Fischer 
451*6a606da0SAndre Fischer     // Distribute the remaining width between columns that have
452*6a606da0SAndre Fischer     // non-zero width.
453*6a606da0SAndre Fischer     const sal_Int32 nDistributableWidth (nRemainingWidth);
454*6a606da0SAndre Fischer     for (sal_uInt32 nColumn=0; nColumn<maColumns.size(); ++nColumn)
455*6a606da0SAndre Fischer     {
456*6a606da0SAndre Fischer         ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumn]);
457*6a606da0SAndre Fischer 
458*6a606da0SAndre Fischer         if (rDescriptor.GetWeight() > 0)
459*6a606da0SAndre Fischer         {
460*6a606da0SAndre Fischer             sal_Int32 nWidth (nDistributableWidth * rDescriptor.GetWeight() / nTotalColumnWeight);
461*6a606da0SAndre Fischer             // Make sure the width lies inside the valid range of
462*6a606da0SAndre Fischer             // column widths.
463*6a606da0SAndre Fischer             if (nWidth < rDescriptor.GetWidth())
464*6a606da0SAndre Fischer                 nWidth = rDescriptor.GetWidth();
465*6a606da0SAndre Fischer             if (rDescriptor.GetMaximumWidth()>0)
466*6a606da0SAndre Fischer                 if (nWidth > rDescriptor.GetTotalMaximumWidth())
467*6a606da0SAndre Fischer                     nWidth = rDescriptor.GetTotalMaximumWidth();
468*6a606da0SAndre Fischer 
469*6a606da0SAndre Fischer             rDescriptor.SetWidth(nWidth);
470*6a606da0SAndre Fischer             nRemainingWidth -= nWidth;
471*6a606da0SAndre Fischer         }
472*6a606da0SAndre Fischer     }
473*6a606da0SAndre Fischer 
474*6a606da0SAndre Fischer     // If there are some pixels left (due to rounding errors), then
475*6a606da0SAndre Fischer     // give them to the first column that has non-zero weight.
476*6a606da0SAndre Fischer     if (nRemainingWidth > 0)
477*6a606da0SAndre Fischer         for (sal_uInt32 nColumn=0; nColumn<maColumns.size(); ++nColumn)
478*6a606da0SAndre Fischer         {
479*6a606da0SAndre Fischer             ColumnDescriptor& rDescriptor (maColumnDescriptors[nColumn]);
480*6a606da0SAndre Fischer             if (rDescriptor.GetWeight() > 0)
481*6a606da0SAndre Fischer             {
482*6a606da0SAndre Fischer                 rDescriptor.SetWidth(rDescriptor.GetWidth() + nRemainingWidth);
483*6a606da0SAndre Fischer                 break;
484*6a606da0SAndre Fischer             }
485*6a606da0SAndre Fischer         }
486*6a606da0SAndre Fischer }
487*6a606da0SAndre Fischer 
488*6a606da0SAndre Fischer 
489*6a606da0SAndre Fischer 
490*6a606da0SAndre Fischer 
GetMinimumColumnWidth(ColumnData & rColumn,const ColumnDescriptor & rDescriptor) const491*6a606da0SAndre Fischer sal_Int32 GridLayouter::Implementation::GetMinimumColumnWidth (
492*6a606da0SAndre Fischer     ColumnData& rColumn,
493*6a606da0SAndre Fischer     const ColumnDescriptor& rDescriptor) const
494*6a606da0SAndre Fischer {
495*6a606da0SAndre Fischer     // Start with the minimum width of the whole column.
496*6a606da0SAndre Fischer     sal_Int32 nMinimumWidth (rDescriptor.GetMinimumWidth());
497*6a606da0SAndre Fischer 
498*6a606da0SAndre Fischer     // Take also into account the minimum widths of all cells in the column.
499*6a606da0SAndre Fischer     ForAllRows(rColumn, iCell)
500*6a606da0SAndre Fischer         ForAllCells(*iCell, iCellDescriptor)
501*6a606da0SAndre Fischer         {
502*6a606da0SAndre Fischer             if (iCellDescriptor->GetGridWidth() != 1)
503*6a606da0SAndre Fischer                 continue;
504*6a606da0SAndre Fischer             const sal_Int32 nMinimumCellWidth (iCellDescriptor->GetMinimumWidth());
505*6a606da0SAndre Fischer             if (nMinimumCellWidth > nMinimumWidth)
506*6a606da0SAndre Fischer                 nMinimumWidth = nMinimumCellWidth;
507*6a606da0SAndre Fischer         }
508*6a606da0SAndre Fischer 
509*6a606da0SAndre Fischer     // Make sure that the minimum width does not become larger than
510*6a606da0SAndre Fischer     // the maximum width of the column.
511*6a606da0SAndre Fischer     if (nMinimumWidth > rDescriptor.GetMaximumWidth() && rDescriptor.GetMaximumWidth()>0)
512*6a606da0SAndre Fischer         nMinimumWidth = rDescriptor.GetMaximumWidth();
513*6a606da0SAndre Fischer 
514*6a606da0SAndre Fischer     // Add the horizontal padding.
515*6a606da0SAndre Fischer     return  nMinimumWidth
516*6a606da0SAndre Fischer         + rDescriptor.GetLeftPadding()
517*6a606da0SAndre Fischer         + rDescriptor.GetRightPadding();
518*6a606da0SAndre Fischer }
519*6a606da0SAndre Fischer 
520*6a606da0SAndre Fischer 
521*6a606da0SAndre Fischer 
522*6a606da0SAndre Fischer 
Paint(void)523*6a606da0SAndre Fischer void GridLayouter::Implementation::Paint (void)
524*6a606da0SAndre Fischer {
525*6a606da0SAndre Fischer     const Size aParentSize (mrParent.GetSizePixel());
526*6a606da0SAndre Fischer 
527*6a606da0SAndre Fischer     static const Color aSeparatorColor (0x66cdaa);
528*6a606da0SAndre Fischer     static const Color aLeftPaddingColor (0x98fb98);
529*6a606da0SAndre Fischer     static const Color aRightPaddingColor (0xff69b4);
530*6a606da0SAndre Fischer     static const Color aControlOverlayColor (0xffff00);
531*6a606da0SAndre Fischer 
532*6a606da0SAndre Fischer     sal_Int32 nX (0);
533*6a606da0SAndre Fischer     mrParent.SetLineColor();
534*6a606da0SAndre Fischer     mrParent.SetFillColor(aLeftPaddingColor);
535*6a606da0SAndre Fischer     ForAllColumnDescriptors(iColumn)
536*6a606da0SAndre Fischer     {
537*6a606da0SAndre Fischer         if (iColumn->GetLeftPadding() > 0)
538*6a606da0SAndre Fischer         {
539*6a606da0SAndre Fischer             mrParent.DrawRect(Rectangle(
540*6a606da0SAndre Fischer                     nX,0,
541*6a606da0SAndre Fischer                     nX+iColumn->GetLeftPadding(),aParentSize.Height()));
542*6a606da0SAndre Fischer         }
543*6a606da0SAndre Fischer 
544*6a606da0SAndre Fischer         nX += iColumn->GetWidth();
545*6a606da0SAndre Fischer     }
546*6a606da0SAndre Fischer 
547*6a606da0SAndre Fischer     nX = 0;
548*6a606da0SAndre Fischer     mrParent.SetFillColor(aRightPaddingColor);
549*6a606da0SAndre Fischer     ForAllColumnDescriptors(iColumn)
550*6a606da0SAndre Fischer     {
551*6a606da0SAndre Fischer         if (iColumn->GetRightPadding() > 0)
552*6a606da0SAndre Fischer         {
553*6a606da0SAndre Fischer             const sal_Int32 nRight (nX + iColumn->GetWidth());
554*6a606da0SAndre Fischer             const sal_Int32 nLeft (nRight - iColumn->GetRightPadding());
555*6a606da0SAndre Fischer             mrParent.DrawRect(Rectangle(
556*6a606da0SAndre Fischer                     nLeft,0,
557*6a606da0SAndre Fischer                     nRight,aParentSize.Height()));
558*6a606da0SAndre Fischer         }
559*6a606da0SAndre Fischer 
560*6a606da0SAndre Fischer         nX += iColumn->GetWidth();
561*6a606da0SAndre Fischer     }
562*6a606da0SAndre Fischer 
563*6a606da0SAndre Fischer     nX = 0;
564*6a606da0SAndre Fischer     mrParent.SetFillColor();
565*6a606da0SAndre Fischer     mrParent.SetLineColor(aSeparatorColor);
566*6a606da0SAndre Fischer     ForAllColumnDescriptors(iColumn)
567*6a606da0SAndre Fischer     {
568*6a606da0SAndre Fischer         mrParent.DrawLine(Point(nX,0), Point(nX,aParentSize.Height()));
569*6a606da0SAndre Fischer         nX += iColumn->GetWidth();
570*6a606da0SAndre Fischer     }
571*6a606da0SAndre Fischer 
572*6a606da0SAndre Fischer     mrParent.SetFillColor();
573*6a606da0SAndre Fischer     mrParent.SetLineColor(aControlOverlayColor);
574*6a606da0SAndre Fischer     ForAllColumns(iColumn,nColumnIndex)
575*6a606da0SAndre Fischer         ForAllRows(*iColumn, iCell)
576*6a606da0SAndre Fischer             ForAllCells(*iCell, iCellDescriptor)
577*6a606da0SAndre Fischer             {
578*6a606da0SAndre Fischer                 Window* pControl (iCellDescriptor->GetControl());
579*6a606da0SAndre Fischer                 if (pControl!=NULL && pControl->IsVisible())
580*6a606da0SAndre Fischer                 {
581*6a606da0SAndre Fischer                     Rectangle aBox (
582*6a606da0SAndre Fischer                         pControl->GetPosPixel(),
583*6a606da0SAndre Fischer                         pControl->GetSizePixel());
584*6a606da0SAndre Fischer                     --aBox.Left();
585*6a606da0SAndre Fischer                     --aBox.Top();
586*6a606da0SAndre Fischer                     ++aBox.Right();
587*6a606da0SAndre Fischer                     ++aBox.Bottom();
588*6a606da0SAndre Fischer                     mrParent.DrawRect(aBox);
589*6a606da0SAndre Fischer                 }
590*6a606da0SAndre Fischer             }
591*6a606da0SAndre Fischer }
592*6a606da0SAndre Fischer 
593*6a606da0SAndre Fischer 
594*6a606da0SAndre Fischer 
595*6a606da0SAndre Fischer 
596*6a606da0SAndre Fischer //===== ColumnDescriptor ======================================================
597*6a606da0SAndre Fischer 
ColumnDescriptor(void)598*6a606da0SAndre Fischer ColumnDescriptor::ColumnDescriptor (void)
599*6a606da0SAndre Fischer     : mnWeight(1),
600*6a606da0SAndre Fischer       mnMinimumWidth(0),
601*6a606da0SAndre Fischer       mnMaximumWidth(-1),
602*6a606da0SAndre Fischer       mnLeftPadding(0),
603*6a606da0SAndre Fischer       mnRightPadding(0),
604*6a606da0SAndre Fischer       mnWidth(0)
605*6a606da0SAndre Fischer {
606*6a606da0SAndre Fischer }
607*6a606da0SAndre Fischer 
608*6a606da0SAndre Fischer 
609*6a606da0SAndre Fischer 
610*6a606da0SAndre Fischer 
~ColumnDescriptor(void)611*6a606da0SAndre Fischer ColumnDescriptor::~ColumnDescriptor (void)
612*6a606da0SAndre Fischer {
613*6a606da0SAndre Fischer }
614*6a606da0SAndre Fischer 
615*6a606da0SAndre Fischer 
616*6a606da0SAndre Fischer 
617*6a606da0SAndre Fischer 
SetWeight(const sal_Int32 nWeight)618*6a606da0SAndre Fischer ColumnDescriptor& ColumnDescriptor::SetWeight (const sal_Int32 nWeight)
619*6a606da0SAndre Fischer {
620*6a606da0SAndre Fischer     mnWeight = nWeight;
621*6a606da0SAndre Fischer 
622*6a606da0SAndre Fischer     return *this;
623*6a606da0SAndre Fischer }
624*6a606da0SAndre Fischer 
625*6a606da0SAndre Fischer 
626*6a606da0SAndre Fischer 
627*6a606da0SAndre Fischer 
SetMinimumWidth(const sal_Int32 nWidth)628*6a606da0SAndre Fischer ColumnDescriptor& ColumnDescriptor::SetMinimumWidth (const sal_Int32 nWidth)
629*6a606da0SAndre Fischer {
630*6a606da0SAndre Fischer     mnMinimumWidth = nWidth;
631*6a606da0SAndre Fischer 
632*6a606da0SAndre Fischer     return *this;
633*6a606da0SAndre Fischer }
634*6a606da0SAndre Fischer 
635*6a606da0SAndre Fischer 
636*6a606da0SAndre Fischer 
SetFixedWidth(const sal_Int32 nWidth)637*6a606da0SAndre Fischer ColumnDescriptor& ColumnDescriptor::SetFixedWidth (const sal_Int32 nWidth)
638*6a606da0SAndre Fischer {
639*6a606da0SAndre Fischer     mnMinimumWidth = nWidth;
640*6a606da0SAndre Fischer     mnMaximumWidth = nWidth;
641*6a606da0SAndre Fischer 
642*6a606da0SAndre Fischer     return *this;
643*6a606da0SAndre Fischer }
644*6a606da0SAndre Fischer 
645*6a606da0SAndre Fischer 
646*6a606da0SAndre Fischer 
SetLeftPadding(const sal_Int32 nPadding)647*6a606da0SAndre Fischer ColumnDescriptor& ColumnDescriptor::SetLeftPadding (const sal_Int32 nPadding)
648*6a606da0SAndre Fischer {
649*6a606da0SAndre Fischer     mnLeftPadding = nPadding;
650*6a606da0SAndre Fischer 
651*6a606da0SAndre Fischer     return *this;
652*6a606da0SAndre Fischer }
653*6a606da0SAndre Fischer 
654*6a606da0SAndre Fischer 
655*6a606da0SAndre Fischer 
656*6a606da0SAndre Fischer 
SetRightPadding(const sal_Int32 nPadding)657*6a606da0SAndre Fischer ColumnDescriptor& ColumnDescriptor::SetRightPadding (const sal_Int32 nPadding)
658*6a606da0SAndre Fischer {
659*6a606da0SAndre Fischer     mnRightPadding = nPadding;
660*6a606da0SAndre Fischer 
661*6a606da0SAndre Fischer     return *this;
662*6a606da0SAndre Fischer }
663*6a606da0SAndre Fischer 
664*6a606da0SAndre Fischer 
665*6a606da0SAndre Fischer 
666*6a606da0SAndre Fischer 
GetWeight(void) const667*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetWeight (void) const
668*6a606da0SAndre Fischer {
669*6a606da0SAndre Fischer     return mnWeight;
670*6a606da0SAndre Fischer }
671*6a606da0SAndre Fischer 
672*6a606da0SAndre Fischer 
673*6a606da0SAndre Fischer 
674*6a606da0SAndre Fischer 
GetMinimumWidth(void) const675*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetMinimumWidth (void) const
676*6a606da0SAndre Fischer {
677*6a606da0SAndre Fischer     return mnMinimumWidth;
678*6a606da0SAndre Fischer }
679*6a606da0SAndre Fischer 
680*6a606da0SAndre Fischer 
681*6a606da0SAndre Fischer 
682*6a606da0SAndre Fischer 
GetMaximumWidth(void) const683*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetMaximumWidth (void) const
684*6a606da0SAndre Fischer {
685*6a606da0SAndre Fischer     return mnMaximumWidth;
686*6a606da0SAndre Fischer }
687*6a606da0SAndre Fischer 
688*6a606da0SAndre Fischer 
689*6a606da0SAndre Fischer 
690*6a606da0SAndre Fischer 
GetTotalMaximumWidth(void) const691*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetTotalMaximumWidth (void) const
692*6a606da0SAndre Fischer {
693*6a606da0SAndre Fischer     return mnMaximumWidth + mnLeftPadding + mnRightPadding;
694*6a606da0SAndre Fischer }
695*6a606da0SAndre Fischer 
696*6a606da0SAndre Fischer 
697*6a606da0SAndre Fischer 
698*6a606da0SAndre Fischer 
GetLeftPadding(void) const699*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetLeftPadding (void) const
700*6a606da0SAndre Fischer {
701*6a606da0SAndre Fischer     return mnLeftPadding;
702*6a606da0SAndre Fischer }
703*6a606da0SAndre Fischer 
704*6a606da0SAndre Fischer 
705*6a606da0SAndre Fischer 
706*6a606da0SAndre Fischer 
GetRightPadding(void) const707*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetRightPadding (void) const
708*6a606da0SAndre Fischer {
709*6a606da0SAndre Fischer     return mnRightPadding;
710*6a606da0SAndre Fischer }
711*6a606da0SAndre Fischer 
712*6a606da0SAndre Fischer 
713*6a606da0SAndre Fischer 
714*6a606da0SAndre Fischer 
SetWidth(const sal_Int32 nWidth)715*6a606da0SAndre Fischer void ColumnDescriptor::SetWidth (const sal_Int32 nWidth)
716*6a606da0SAndre Fischer {
717*6a606da0SAndre Fischer     mnWidth = nWidth;
718*6a606da0SAndre Fischer }
719*6a606da0SAndre Fischer 
720*6a606da0SAndre Fischer 
721*6a606da0SAndre Fischer 
722*6a606da0SAndre Fischer 
GetWidth(void) const723*6a606da0SAndre Fischer sal_Int32 ColumnDescriptor::GetWidth (void) const
724*6a606da0SAndre Fischer {
725*6a606da0SAndre Fischer     return mnWidth;
726*6a606da0SAndre Fischer }
727*6a606da0SAndre Fischer 
728*6a606da0SAndre Fischer } } // end of namespace sfx2::sidebar
729