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