xref: /AOO41X/main/svtools/source/control/taskmisc.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #define _TASKBAR_CXX
28 
29 #include <tools/list.hxx>
30 #include <tools/debug.hxx>
31 #include <vcl/help.hxx>
32 #include <svtools/taskbar.hxx>
33 
34 // =======================================================================
35 
TaskButtonBar(Window * pParent,WinBits nWinStyle)36 TaskButtonBar::TaskButtonBar( Window* pParent, WinBits nWinStyle ) :
37     ToolBox( pParent, nWinStyle | WB_3DLOOK )
38 {
39     SetAlign( WINDOWALIGN_BOTTOM );
40     SetButtonType( BUTTON_SYMBOLTEXT );
41 }
42 
43 // -----------------------------------------------------------------------
44 
~TaskButtonBar()45 TaskButtonBar::~TaskButtonBar()
46 {
47 }
48 
49 // -----------------------------------------------------------------------
50 
RequestHelp(const HelpEvent & rHEvt)51 void TaskButtonBar::RequestHelp( const HelpEvent& rHEvt )
52 {
53     ToolBox::RequestHelp( rHEvt );
54 }
55 
56 // =======================================================================
57 
WindowArrange()58 WindowArrange::WindowArrange()
59 {
60     mpWinList = new List;
61 }
62 
63 // -----------------------------------------------------------------------
64 
~WindowArrange()65 WindowArrange::~WindowArrange()
66 {
67     delete mpWinList;
68 }
69 
70 // -----------------------------------------------------------------------
71 
ImplCeilSqareRoot(sal_uInt16 nVal)72 static sal_uInt16 ImplCeilSqareRoot( sal_uInt16 nVal )
73 {
74     sal_uInt16 i;
75 
76     // Ueberlauf verhindern
77     if ( nVal > 0xFE * 0xFE )
78         return 0xFE;
79 
80     for ( i=0; i*i < nVal; i++ )
81         {}
82 
83     return i;
84 }
85 
86 // -----------------------------------------------------------------------
87 
ImplPosSizeWindow(Window * pWindow,long nX,long nY,long nWidth,long nHeight)88 static void ImplPosSizeWindow( Window* pWindow,
89                                long nX, long nY, long nWidth, long nHeight )
90 {
91     if ( nWidth < 32 )
92         nWidth = 32;
93     if ( nHeight < 24 )
94         nHeight = 24;
95     pWindow->SetPosSizePixel( nX, nY, nWidth, nHeight );
96 }
97 
98 // -----------------------------------------------------------------------
99 
ImplTile(const Rectangle & rRect)100 void WindowArrange::ImplTile( const Rectangle& rRect )
101 {
102     sal_uInt16 nCount = (sal_uInt16)mpWinList->Count();
103     if ( nCount < 3 )
104     {
105         ImplVert( rRect );
106         return;
107     }
108 
109     sal_uInt16      i;
110     sal_uInt16      j;
111     sal_uInt16      nCols;
112     sal_uInt16      nRows;
113     sal_uInt16      nActRows;
114     sal_uInt16      nOffset;
115     long        nOverWidth;
116     long        nOverHeight;
117     Window*     pWindow;
118     long        nX = rRect.Left();
119     long        nY = rRect.Top();
120     long        nWidth = rRect.GetWidth();
121     long        nHeight = rRect.GetHeight();
122     long        nRectY = nY;
123     long        nRectWidth = nWidth;
124     long        nRectHeight = nHeight;
125     long        nTempWidth;
126     long        nTempHeight;
127 
128     nCols   = ImplCeilSqareRoot( nCount );
129     nOffset = (nCols*nCols) - nCount;
130     if ( nOffset >= nCols )
131     {
132         nRows    = nCols -1;
133         nOffset = nOffset - nCols;
134     }
135     else
136         nRows = nCols;
137 
138     nWidth /= nCols;
139     if ( nWidth < 1 )
140         nWidth = 1;
141     nOverWidth = nRectWidth-(nWidth*nCols);
142 
143     pWindow = (Window*)mpWinList->First();
144     for ( i = 0; i < nCols; i++ )
145     {
146         if ( i < nOffset )
147             nActRows = nRows - 1;
148         else
149             nActRows = nRows;
150 
151         nTempWidth = nWidth;
152         if ( nOverWidth > 0 )
153         {
154             nTempWidth++;
155             nOverWidth--;
156         }
157 
158         nHeight = nRectHeight / nActRows;
159         if ( nHeight < 1 )
160             nHeight = 1;
161         nOverHeight = nRectHeight-(nHeight*nActRows);
162         for ( j = 0; j < nActRows; j++ )
163         {
164             // Ueberhang verteilen
165             nTempHeight = nHeight;
166             if ( nOverHeight > 0 )
167             {
168                 nTempHeight++;
169                 nOverHeight--;
170             }
171             ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nTempHeight );
172             nY += nTempHeight;
173 
174             pWindow = (Window*)mpWinList->Next();
175             if ( !pWindow )
176                 break;
177         }
178 
179         nX += nWidth;
180         nY = nRectY;
181 
182         if ( !pWindow )
183             break;
184     }
185 }
186 
187 // -----------------------------------------------------------------------
188 
ImplHorz(const Rectangle & rRect)189 void WindowArrange::ImplHorz( const Rectangle& rRect )
190 {
191     long        nCount = (long)mpWinList->Count();
192     long        nX = rRect.Left();
193     long        nY = rRect.Top();
194     long        nWidth = rRect.GetWidth();
195     long        nHeight = rRect.GetHeight();
196     long        nRectHeight = nHeight;
197     long        nOver;
198     long        nTempHeight;
199     Window*     pWindow;
200 
201     nHeight /= nCount;
202     if ( nHeight < 1 )
203         nHeight = 1;
204     nOver = nRectHeight - (nCount*nHeight);
205     pWindow = (Window*)mpWinList->First();
206     while ( pWindow )
207     {
208         nTempHeight = nHeight;
209         if ( nOver > 0 )
210         {
211             nTempHeight++;
212             nOver--;
213         }
214         ImplPosSizeWindow( pWindow, nX, nY, nWidth, nTempHeight );
215         nY += nTempHeight;
216 
217         pWindow = (Window*)mpWinList->Next();
218     }
219 }
220 
221 // -----------------------------------------------------------------------
222 
ImplVert(const Rectangle & rRect)223 void WindowArrange::ImplVert( const Rectangle& rRect )
224 {
225     long        nCount = (long)mpWinList->Count();
226     long        nX = rRect.Left();
227     long        nY = rRect.Top();
228     long        nWidth = rRect.GetWidth();
229     long        nHeight = rRect.GetHeight();
230     long        nRectWidth = nWidth;
231     long        nOver;
232     long        nTempWidth;
233     Window*     pWindow;
234 
235     nWidth /= nCount;
236     if ( nWidth < 1 )
237         nWidth = 1;
238     nOver = nRectWidth - (nCount*nWidth);
239     pWindow = (Window*)mpWinList->First();
240     while ( pWindow )
241     {
242         nTempWidth = nWidth;
243         if ( nOver > 0 )
244         {
245             nTempWidth++;
246             nOver--;
247         }
248         ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nHeight );
249         nX += nTempWidth;
250 
251         pWindow = (Window*)mpWinList->Next();
252     }
253 }
254 
255 // -----------------------------------------------------------------------
256 
ImplCascade(const Rectangle & rRect)257 void WindowArrange::ImplCascade( const Rectangle& rRect )
258 {
259     long        nX = rRect.Left();
260     long        nY = rRect.Top();
261     long        nWidth = rRect.GetWidth();
262     long        nHeight = rRect.GetHeight();
263     long        nRectWidth = nWidth;
264     long        nRectHeight = nHeight;
265     long        nOff;
266     long        nCascadeWins;
267     sal_Int32   nLeftBorder;
268     sal_Int32   nTopBorder;
269     sal_Int32   nRightBorder;
270     sal_Int32   nBottomBorder;
271     long        nStartOverWidth;
272     long        nStartOverHeight;
273     long        nOverWidth = 0;
274     long        nOverHeight = 0;
275     long        nTempX;
276     long        nTempY;
277     long        nTempWidth;
278     long        nTempHeight;
279     long        i;
280     Window*     pWindow;
281     Window*     pTempWindow;
282 
283     // Border-Fenster suchen um den Versatz zu ermitteln
284     pTempWindow = (Window*)mpWinList->First();
285     pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
286     while ( !nTopBorder )
287     {
288         Window* pBrdWin = pTempWindow->GetWindow( WINDOW_REALPARENT );
289         if ( !pBrdWin || (pBrdWin->GetWindow( WINDOW_CLIENT ) != pTempWindow) )
290             break;
291         pTempWindow = pBrdWin;
292         pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
293     }
294     if ( !nTopBorder )
295         nTopBorder = 22;
296     nOff = nTopBorder;
297 
298     nCascadeWins = nRectHeight / 3 / nOff;
299     if ( !nCascadeWins )
300         nCascadeWins = 1;
301     nWidth   -= nCascadeWins*nOff;
302     nHeight  -= nCascadeWins*nOff;
303     if ( nWidth < 1 )
304         nWidth = 1;
305     if ( nHeight < 1 )
306         nHeight = 1;
307 
308     nStartOverWidth = nRectWidth-(nWidth+(nCascadeWins*nOff));
309     nStartOverHeight = nRectHeight-(nHeight+(nCascadeWins*nOff));
310 
311     i = 0;
312     pWindow = (Window*)mpWinList->First();
313     while ( pWindow )
314     {
315         if ( !i )
316         {
317             nOverWidth = nStartOverWidth;
318             nOverHeight = nStartOverHeight;
319         }
320 
321         // Position
322         nTempX = nX + (i*nOff);
323         nTempY = nY + (i*nOff);
324 
325         // Ueberhang verteilen
326         nTempWidth = nWidth;
327         if ( nOverWidth > 0 )
328         {
329             nTempWidth++;
330             nOverWidth--;
331         }
332         nTempHeight = nHeight;
333         if ( nOverHeight > 0 )
334         {
335             nTempHeight++;
336             nOverHeight--;
337         }
338 
339         ImplPosSizeWindow( pWindow, nTempX, nTempY, nTempWidth, nTempHeight );
340 
341         if ( i < nCascadeWins )
342             i++;
343         else
344             i = 0;
345 
346         pWindow = (Window*)mpWinList->Next();
347     }
348 }
349 
350 // -----------------------------------------------------------------------
351 
Arrange(sal_uInt16 nType,const Rectangle & rRect)352 void WindowArrange::Arrange( sal_uInt16 nType, const Rectangle& rRect )
353 {
354     if ( !mpWinList->Count() )
355         return;
356 
357     switch ( nType )
358     {
359         case WINDOWARRANGE_TILE:
360             ImplTile( rRect );
361             break;
362         case WINDOWARRANGE_HORZ:
363             ImplHorz( rRect );
364             break;
365         case WINDOWARRANGE_VERT:
366             ImplVert( rRect );
367             break;
368         case WINDOWARRANGE_CASCADE:
369             ImplCascade( rRect );
370             break;
371     }
372 }
373 
374