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