xref: /trunk/main/vcl/source/window/splitwin.cxx (revision 27b8d3b4)
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_vcl.hxx"
26 
27 #include <string.h>
28 
29 #include <tools/list.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/rcid.h>
32 
33 #include <vcl/event.hxx>
34 #include <vcl/wall.hxx>
35 #include <vcl/bitmap.hxx>
36 #include <vcl/decoview.hxx>
37 #include <vcl/symbol.hxx>
38 #include <vcl/image.hxx>
39 #include <vcl/help.hxx>
40 #include <vcl/splitwin.hxx>
41 
42 #include <svdata.hxx>
43 #include <svids.hrc>
44 
45 
46 // =======================================================================
47 
48 // Attention: Must not contain non-PODs because array is enlarged/copied
49 // with the use of memmove/memcpy.
50 struct ImplSplitItem
51 {
52 	long				mnSize;
53 	long				mnPixSize;
54 	long				mnLeft;
55 	long				mnTop;
56 	long				mnWidth;
57 	long				mnHeight;
58 	long				mnSplitPos;
59 	long				mnSplitSize;
60 	long				mnOldSplitPos;
61 	long				mnOldSplitSize;
62 	long				mnOldWidth;
63 	long				mnOldHeight;
64 	ImplSplitSet*		mpSet;
65 	Window* 			mpWindow;
66 	Window* 			mpOrgParent;
67 	sal_uInt16			mnId;
68 	SplitWindowItemBits mnBits;
69 	sal_Bool			mbFixed;
70 	sal_Bool			mbSubSize;
71 	/// Minimal width or height of the item. -1 means no restriction.
72 	long				mnMinSize;
73 	/// Maximal width or height of the item. -1 means no restriction.
74 	long				mnMaxSize;
75 };
76 
77 struct ImplSplitSet
78 {
79 	ImplSplitItem*		mpItems;
80 	Wallpaper*			mpWallpaper;
81 	Bitmap* 			mpBitmap;
82 	long				mnLastSize;
83 	long				mnSplitSize;
84 	sal_uInt16			mnItems;
85 	sal_uInt16			mnId;
86 	sal_Bool			mbCalcPix;
87 };
88 
89 
90 
91 /** Check whether the given size is inside the valid range defined by
92     [rItem.mnMinSize,rItem.mnMaxSize]. When it is not inside it then return
93     the upper or lower bound, respectively. Otherwise return the given size
94     unmodified.
95     Note that either mnMinSize and/or mnMaxSize can be -1 in which case the
96     size has not lower or upper bound.
97 */
98 namespace {
ValidateSize(const long nSize,const ImplSplitItem & rItem)99 	long ValidateSize (const long nSize, const ImplSplitItem& rItem)
100 	{
101 		if (rItem.mnMinSize>=0 && nSize<rItem.mnMinSize)
102 			return rItem.mnMinSize;
103 		else if (rItem.mnMaxSize>0 && nSize>rItem.mnMaxSize)
104 			return rItem.mnMaxSize;
105 		else
106 			return nSize;
107 	}
108 }
109 
110 
111 #define SPLITWIN_SPLITSIZE				3
112 #define SPLITWIN_SPLITSIZEEX			4
113 #define SPLITWIN_SPLITSIZEEXLN			6
114 #define SPLITWIN_SPLITSIZEAUTOHIDE		36
115 #define SPLITWIN_SPLITSIZEFADE			36
116 
117 #define SPLIT_HORZ				((sal_uInt16)0x0001)
118 #define SPLIT_VERT				((sal_uInt16)0x0002)
119 #define SPLIT_WINDOW			((sal_uInt16)0x0004)
120 #define SPLIT_NOSPLIT			((sal_uInt16)0x8000)
121 
122 // -----------------------------------------------------------------------
123 
DECLARE_LIST(ImplSplitList,SplitWindow *)124 DECLARE_LIST( ImplSplitList, SplitWindow* )
125 
126 // =======================================================================
127 
128 static void ImplCalcBorder( WindowAlign eAlign, sal_Bool bNoAlign,
129 							long& rLeft, long& rTop,
130 							long& rRight, long& rBottom )
131 {
132 	if ( bNoAlign )
133 	{
134 		rLeft	= 2;
135 		rTop	= 2;
136 		rRight	= 2;
137 		rBottom = 2;
138 	}
139 	else
140 	{
141 		if ( eAlign == WINDOWALIGN_TOP )
142 		{
143 			rLeft	= 2;
144 			rTop	= 2;
145 			rRight	= 2;
146 			rBottom = 0;
147 		}
148 		else if ( eAlign == WINDOWALIGN_LEFT )
149 		{
150 			rLeft	= 2;
151 			rTop	= 2;
152 			rRight	= 0;
153 			rBottom = 2;
154 		}
155 		else if ( eAlign == WINDOWALIGN_BOTTOM )
156 		{
157 			rLeft	= 2;
158 			rTop	= 0;
159 			rRight	= 2;
160 			rBottom = 2;
161 		}
162 		else
163 		{
164 			rLeft	= 0;
165 			rTop	= 2;
166 			rRight	= 2;
167 			rBottom = 2;
168 		}
169 	}
170 }
171 
172 // -----------------------------------------------------------------------
173 
ImplDrawBorder(SplitWindow * pWin)174 void SplitWindow::ImplDrawBorder( SplitWindow* pWin )
175 {
176 	const StyleSettings&	rStyleSettings = pWin->GetSettings().GetStyleSettings();
177 	long					nDX = pWin->mnDX;
178 	long					nDY = pWin->mnDY;
179 
180 	if ( pWin->mbNoAlign )
181 	{
182 		DecorationView	aDecoView( pWin );
183 		Point			aTmpPoint;
184 		Rectangle		aRect( aTmpPoint, Size( nDX, nDY ) );
185 		aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
186 	}
187 	else
188 	{/*
189 		if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
190 		{
191 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
192 			pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
193 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
194 			pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
195 		}
196 		else
197 		{
198 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
199 			pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
200 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
201 			pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
202 			if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
203 			{
204 				if ( pWin->meAlign == WINDOWALIGN_LEFT )
205 				{
206 					pWin->SetLineColor( rStyleSettings.GetShadowColor() );
207 					pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
208 					pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
209 					pWin->SetLineColor( rStyleSettings.GetLightColor() );
210 					pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
211 					pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
212 				}
213 				else
214 				{
215 					pWin->SetLineColor( rStyleSettings.GetShadowColor() );
216 					pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
217 					pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
218 					pWin->SetLineColor( rStyleSettings.GetLightColor() );
219 					pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
220 					pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
221 				}
222 			}
223 		}*/
224 		if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
225 		{
226 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
227 			pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
228 			pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
229 			pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
230 
231 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
232 			pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
233 			pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
234 			pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
235 		}
236 		else if ( pWin->meAlign == WINDOWALIGN_TOP )
237 		{
238 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
239 			pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
240 			pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
241 			pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
242 
243 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
244 			pWin->DrawLine( Point( 1, 1 ), Point( nDX-3, 1 ) );
245 			pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-1 ) );
246 			pWin->DrawLine( Point( nDX-1, 1 ), Point( nDX-1, nDY-1 ) );
247 		}
248 		else if ( pWin->meAlign == WINDOWALIGN_LEFT )
249 		{
250 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
251 			pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
252 			pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
253 			pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
254 
255 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
256 			pWin->DrawLine( Point( 1, 1 ), Point( nDX-1, 1 ) );
257 			pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
258 			pWin->DrawLine( Point( 1, nDY-1 ), Point( nDX-1, nDY-1 ) );
259 		}
260 		else
261 		{
262 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
263 			pWin->DrawLine( Point( 0, 0 ), Point( nDX-2, 0 ) );
264 			pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
265 			pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
266 
267 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
268 			pWin->DrawLine( Point( 0, 1 ), Point( nDX-3, 1 ) );
269 			pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
270 			pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
271 		}
272 	}
273 }
274 
275 // -----------------------------------------------------------------------
276 
ImplDrawBorderLine(SplitWindow * pWin)277 void SplitWindow::ImplDrawBorderLine( SplitWindow* pWin )
278 {
279 	if ( pWin->mbFadeOut || pWin->mbAutoHide )
280 	{
281 		const StyleSettings&	rStyleSettings = pWin->GetSettings().GetStyleSettings();
282 		long					nDX = pWin->mnDX;
283 		long					nDY = pWin->mnDY;
284 
285 		if ( pWin->meAlign == WINDOWALIGN_LEFT )
286 		{
287 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
288 			pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, nDY-3 ) );
289 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
290 			pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN, nDY-4 ) );
291 		}
292 		else if ( pWin->meAlign == WINDOWALIGN_RIGHT )
293 		{
294 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
295 			pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN-1, nDY-3 ) );
296 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
297 			pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN, 1 ), Point( SPLITWIN_SPLITSIZEEXLN, nDY-4 ) );
298 		}
299 		else if ( pWin->meAlign == WINDOWALIGN_TOP )
300 		{
301 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
302 			pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-3, nDY-SPLITWIN_SPLITSIZEEXLN-1 ) );
303 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
304 			pWin->DrawLine( Point( 1, nDY-SPLITWIN_SPLITSIZEEXLN ), Point( nDX-4, nDY-SPLITWIN_SPLITSIZEEXLN ) );
305 		}
306 		else if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
307 		{
308 			pWin->SetLineColor( rStyleSettings.GetShadowColor() );
309 			pWin->DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-3, SPLITWIN_SPLITSIZEEXLN-1 ) );
310 			pWin->SetLineColor( rStyleSettings.GetLightColor() );
311 			pWin->DrawLine( Point( 1, SPLITWIN_SPLITSIZEEXLN ), Point( nDX-4, SPLITWIN_SPLITSIZEEXLN ) );
312 		}
313 	}
314 }
315 
316 // -----------------------------------------------------------------------
317 
ImplFindSet(ImplSplitSet * pSet,sal_uInt16 nId)318 static ImplSplitSet* ImplFindSet( ImplSplitSet* pSet, sal_uInt16 nId )
319 {
320 	if ( pSet->mnId == nId )
321 		return pSet;
322 
323 	sal_uInt16			i;
324 	sal_uInt16			nItems = pSet->mnItems;
325 	ImplSplitItem*	pItems = pSet->mpItems;
326 
327 	for ( i = 0; i < nItems; i++ )
328 	{
329 		if ( pItems[i].mnId == nId )
330 			return pItems[i].mpSet;
331 	}
332 
333 	for ( i = 0; i < nItems; i++ )
334 	{
335 		if ( pItems[i].mpSet )
336 		{
337 			ImplSplitSet* pFindSet = ImplFindSet( pItems[i].mpSet, nId );
338 			if ( pFindSet )
339 				return pFindSet;
340 		}
341 	}
342 
343 	return NULL;
344 }
345 
346 // -----------------------------------------------------------------------
347 
ImplFindItem(ImplSplitSet * pSet,sal_uInt16 nId,sal_uInt16 & rPos)348 static ImplSplitSet* ImplFindItem( ImplSplitSet* pSet, sal_uInt16 nId, sal_uInt16& rPos )
349 {
350 	sal_uInt16			i;
351 	sal_uInt16			nItems = pSet->mnItems;
352 	ImplSplitItem*	pItems = pSet->mpItems;
353 
354 	for ( i = 0; i < nItems; i++ )
355 	{
356 		if ( pItems[i].mnId == nId )
357 		{
358 			rPos = i;
359 			return pSet;
360 		}
361 	}
362 
363 	for ( i = 0; i < nItems; i++ )
364 	{
365 		if ( pItems[i].mpSet )
366 		{
367 			ImplSplitSet* pFindSet = ImplFindItem( pItems[i].mpSet, nId, rPos );
368 			if ( pFindSet )
369 				return pFindSet;
370 		}
371 	}
372 
373 	return NULL;
374 }
375 
376 // -----------------------------------------------------------------------
377 
ImplFindItem(ImplSplitSet * pSet,Window * pWindow)378 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, Window* pWindow )
379 {
380 	sal_uInt16			i;
381 	sal_uInt16			nItems = pSet->mnItems;
382 	ImplSplitItem*	pItems = pSet->mpItems;
383 
384 	for ( i = 0; i < nItems; i++ )
385 	{
386 		if ( pItems[i].mpWindow == pWindow )
387 			return pItems[i].mnId;
388 		else
389 		{
390 			if ( pItems[i].mpSet )
391 			{
392 				sal_uInt16 nId = ImplFindItem( pItems[i].mpSet, pWindow );
393 				if ( nId )
394 					return nId;
395 			}
396 		}
397 	}
398 
399 	return 0;
400 }
401 
402 // -----------------------------------------------------------------------
403 
ImplFindItem(ImplSplitSet * pSet,const Point & rPos,sal_Bool bRows,sal_Bool bDown=sal_True)404 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, const Point& rPos,
405 							sal_Bool bRows, sal_Bool bDown = sal_True )
406 {
407 	sal_uInt16			i;
408 	sal_uInt16			nItems = pSet->mnItems;
409 	ImplSplitItem*	pItems = pSet->mpItems;
410 
411 	for ( i = 0; i < nItems; i++ )
412 	{
413 		if ( pItems[i].mnWidth && pItems[i].mnHeight )
414 		{
415 			// Wegen ICC auftrennen
416 			Point		aPoint( pItems[i].mnLeft, pItems[i].mnTop );
417 			Size		aSize( pItems[i].mnWidth, pItems[i].mnHeight );
418 			Rectangle	aRect( aPoint, aSize );
419 			if ( bRows )
420 			{
421 				if ( bDown )
422 					aRect.Bottom() += pSet->mnSplitSize;
423 				else
424 					aRect.Top() -= pSet->mnSplitSize;
425 			}
426 			else
427 			{
428 				if ( bDown )
429 					aRect.Right() += pSet->mnSplitSize;
430 				else
431 					aRect.Left() -= pSet->mnSplitSize;
432 			}
433 
434 			if ( aRect.IsInside( rPos ) )
435 			{
436 				if ( pItems[i].mpSet && pItems[i].mpSet->mpItems )
437 				{
438 					return ImplFindItem( pItems[i].mpSet, rPos,
439 										((pItems[i].mnBits & SWIB_COLSET) == 0) );
440 				}
441 				else
442 					return pItems[i].mnId;
443 			}
444 		}
445 	}
446 
447 	return 0;
448 }
449 
450 // -----------------------------------------------------------------------
451 
ImplDeleteSet(ImplSplitSet * pSet)452 static void ImplDeleteSet( ImplSplitSet* pSet )
453 {
454 	sal_uInt16			i;
455 	sal_uInt16			nItems = pSet->mnItems;
456 	ImplSplitItem*	pItems = pSet->mpItems;
457 
458 	for ( i = 0; i < nItems; i++ )
459 	{
460 		if ( pItems[i].mpSet )
461 			ImplDeleteSet( pItems[i].mpSet );
462 	}
463 
464 	if ( pSet->mpWallpaper )
465 		delete pSet->mpWallpaper;
466 
467 	if ( pSet->mpBitmap )
468 		delete pSet->mpBitmap;
469 
470 	delete [] pItems;
471 	delete pSet;
472 }
473 
474 // -----------------------------------------------------------------------
475 
ImplSetSplitSize(ImplSplitSet * pSet,long nNewSize)476 static void ImplSetSplitSize( ImplSplitSet* pSet, long nNewSize )
477 {
478 	pSet->mnSplitSize = nNewSize;
479 	for ( sal_uInt16 i = 0; i < pSet->mnItems; i++ )
480 	{
481 		if ( pSet->mpItems[i].mpSet )
482 			ImplSetSplitSize( pSet->mpItems[i].mpSet, nNewSize );
483 	}
484 }
485 
486 // -----------------------------------------------------------------------
487 
ImplCalcSet(ImplSplitSet * pSet,long nSetLeft,long nSetTop,long nSetWidth,long nSetHeight,sal_Bool bRows,sal_Bool bDown=sal_True)488 static void ImplCalcSet( ImplSplitSet* pSet,
489 						 long nSetLeft, long nSetTop,
490 						 long nSetWidth, long nSetHeight,
491 						 sal_Bool bRows, sal_Bool bDown = sal_True )
492 {
493 	if ( !pSet->mpItems )
494 		return;
495 
496 	sal_uInt16				i;
497 	sal_uInt16				j;
498 	sal_uInt16				nMins;
499 	sal_uInt16				nCalcItems;
500 	sal_uInt16				nItems = pSet->mnItems;
501 	sal_uInt16				nVisItems;
502 	sal_uInt16				nAbsItems;
503 	long				nCalcSize;
504 	long				nSizeDelta;
505 	long				nCurSize;
506 	long				nSizeWinSize;
507 	long				nNewSizeWinSize;
508 	long				nTemp;
509 	long				nTempErr;
510 	long				nErrorSum;
511 	long				nCurSizeDelta;
512 	long				nPos;
513 	long				nMaxPos;
514 	long*				pSize;
515 	ImplSplitItem*		pItems = pSet->mpItems;
516 	sal_Bool				bEmpty;
517 
518 	// Anzahl sichtbarer Items ermitteln
519 	nVisItems = 0;
520 	for ( i = 0; i < nItems; i++ )
521 	{
522 		if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
523 			nVisItems++;
524 	}
525 
526 	// Groessen berechnen
527 	if ( bRows )
528 		nCalcSize = nSetHeight;
529 	else
530 		nCalcSize = nSetWidth;
531 	nCalcSize -= (nVisItems-1)*pSet->mnSplitSize;
532 	nCurSize   = 0;
533 	if ( pSet->mbCalcPix || (pSet->mnLastSize != nCalcSize) )
534 	{
535 		long nPercentFactor = 10;
536 		long nRelCount		= 0;
537 		long nPercent		= 0;
538 		long nRelPercent	= 0;
539 		long nAbsSize		= 0;
540 		for ( i = 0; i < nItems; i++ )
541 		{
542 			if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
543 			{
544 				if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
545 					nRelCount += pItems[i].mnSize;
546 				else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
547 					nPercent += pItems[i].mnSize;
548 				else
549 					nAbsSize += pItems[i].mnSize;
550 			}
551 		}
552 		// Relative-Werte auf prozentual mappen (Percent bei uns 10tel Prozent)
553 		nPercent *= nPercentFactor;
554 		if ( nRelCount )
555 		{
556 			long nRelPercentBase = 1000;
557 			while ( (nRelCount > nRelPercentBase) && (nPercentFactor < 100000) )
558 			{
559 				nRelPercentBase *= 10;
560 				nPercentFactor *= 10;
561 			}
562 			if ( nPercent < nRelPercentBase )
563 			{
564 				nRelPercent = (nRelPercentBase-nPercent)/nRelCount;
565 				nPercent += nRelPercent*nRelCount;
566 			}
567 			else
568 				nRelPercent = 0;
569 		}
570 		if ( !nPercent )
571 			nPercent = 1;
572 		nSizeDelta = nCalcSize-nAbsSize;
573 		for ( i = 0; i < nItems; i++ )
574 		{
575 			if ( pItems[i].mnBits & SWIB_INVISIBLE )
576 				pItems[i].mnPixSize = 0;
577 			else if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
578 			{
579 				if ( nSizeDelta <= 0 )
580 					pItems[i].mnPixSize = 0;
581 				else
582 					pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nRelPercent)/nPercent;
583 			}
584 			else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
585 			{
586 				if ( nSizeDelta <= 0 )
587 					pItems[i].mnPixSize = 0;
588 				else
589 					pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nPercentFactor)/nPercent;
590 			}
591 			else
592 				pItems[i].mnPixSize = pItems[i].mnSize;
593 			nCurSize += pItems[i].mnPixSize;
594 		}
595 
596 		pSet->mbCalcPix  = sal_False;
597 		pSet->mnLastSize = nCalcSize;
598 
599 		// Fenster einpassen
600 		nSizeDelta	= nCalcSize-nCurSize;
601 		if ( nSizeDelta )
602 		{
603 			nAbsItems		= 0;
604 			nSizeWinSize	= 0;
605 			nNewSizeWinSize = 0;
606 
607 			// Zuerst die absoluten Items relativ resizen
608 			for ( i = 0; i < nItems; i++ )
609 			{
610 				if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
611 				{
612 					if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
613 					{
614 						nAbsItems++;
615 						nSizeWinSize += pItems[i].mnPixSize;
616 					}
617 				}
618 			}
619 			// Rundungsfehler werden hier nicht ausgeglichen
620 			if ( (nAbsItems < (sal_uInt16)(Abs( nSizeDelta ))) && nSizeWinSize )
621 			{
622 				for ( i = 0; i < nItems; i++ )
623 				{
624 					if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
625 					{
626 						if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
627 						{
628 							pItems[i].mnPixSize += (nSizeDelta*pItems[i].mnPixSize)/nSizeWinSize;
629 							nNewSizeWinSize += pItems[i].mnPixSize;
630 						}
631 					}
632 				}
633 				nSizeDelta -= nNewSizeWinSize-nSizeWinSize;
634 			}
635 
636 			// Jetzt die Rundungsfehler ausgleichen
637 			j			= 0;
638 			nMins		= 0;
639 			while ( nSizeDelta && (nItems != nMins) )
640 			{
641 				// Feststellen, welche Items berechnet werden duerfen
642 				nCalcItems = 0;
643 				while ( !nCalcItems )
644 				{
645 					for ( i = 0; i < nItems; i++ )
646 					{
647 						pItems[i].mbSubSize = sal_False;
648 
649 						if ( j >= 2 )
650 							pItems[i].mbSubSize = sal_True;
651 						else
652 						{
653 							if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
654 							{
655 								if ( (nSizeDelta > 0) || pItems[i].mnPixSize )
656 								{
657 									if ( j >= 1 )
658 										pItems[i].mbSubSize = sal_True;
659 									else
660 									{
661 										if ( (j == 0) && (pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
662 											pItems[i].mbSubSize = sal_True;
663 									}
664 								}
665 							}
666 						}
667 
668 						if ( pItems[i].mbSubSize )
669 							nCalcItems++;
670 					}
671 
672 					j++;
673 				}
674 
675 				// Groessen von den einzelnen Items abziehen
676 				nErrorSum		= nSizeDelta % nCalcItems;
677 				nCurSizeDelta	= nSizeDelta / nCalcItems;
678 				nMins			= 0;
679 				for ( i = 0; i < nItems; i++ )
680 				{
681 					if ( pItems[i].mnBits & SWIB_INVISIBLE )
682 						nMins++;
683 					else if ( pItems[i].mbSubSize )
684 					{
685 						pSize = &(pItems[i].mnPixSize);
686 
687 						if ( nErrorSum )
688 						{
689 							if ( nErrorSum < 0 )
690 								nTempErr = -1;
691 							else
692 								nTempErr = 1;
693 						}
694 						else
695 							nTempErr = 0;
696 
697 						if ( (*pSize+nCurSizeDelta+nTempErr) <= 0 )
698 						{
699 							nTemp = *pSize;
700 							if ( nTemp )
701 							{
702 								*pSize -= nTemp;
703 								nSizeDelta += nTemp;
704 							}
705 							nMins++;
706 						}
707 						else
708 						{
709 							*pSize += nCurSizeDelta;
710 							nSizeDelta -= nCurSizeDelta;
711 							if ( nTempErr && (*pSize || (nTempErr > 0)) )
712 							{
713 								*pSize += nTempErr;
714 								nSizeDelta -= nTempErr;
715 								nErrorSum -= nTempErr;
716 							}
717 						}
718 					}
719 				}
720 			}
721 		}
722 	}
723 	else
724 	{
725 		for ( i = 0; i < nItems; i++ )
726 		{
727 			if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
728 				nCurSize += pItems[i].mnPixSize;
729 		}
730 	}
731 
732 	// Maximale Groesse berechnen
733 	if ( bRows )
734 	{
735 		nPos = nSetTop;
736 		if ( !bDown )
737 			nMaxPos = nSetTop-nSetHeight;
738 		else
739 			nMaxPos = nSetTop+nSetHeight;
740 	}
741 	else
742 	{
743 		nPos = nSetLeft;
744 		if ( !bDown )
745 			nMaxPos = nSetLeft-nSetWidth;
746 		else
747 			nMaxPos = nSetLeft+nSetWidth;
748 	}
749 
750 	// Fenster anordnen und Werte anpassen
751 	for ( i = 0; i < nItems; i++ )
752 	{
753 		pItems[i].mnOldSplitPos    = pItems[i].mnSplitPos;
754 		pItems[i].mnOldSplitSize   = pItems[i].mnSplitSize;
755 		pItems[i].mnOldWidth	   = pItems[i].mnWidth;
756 		pItems[i].mnOldHeight	   = pItems[i].mnHeight;
757 
758 		if ( pItems[i].mnBits & SWIB_INVISIBLE )
759 			bEmpty = sal_True;
760 		else
761 		{
762 			bEmpty = sal_False;
763 			if ( bDown )
764 			{
765 				if ( nPos+pItems[i].mnPixSize > nMaxPos )
766 					bEmpty = sal_True;
767 			}
768 			else
769 			{
770 				nPos -= pItems[i].mnPixSize;
771 				if ( nPos < nMaxPos )
772 					bEmpty = sal_True;
773 			}
774 		}
775 
776 		if ( bEmpty )
777 		{
778 			pItems[i].mnWidth	  = 0;
779 			pItems[i].mnHeight	  = 0;
780 			pItems[i].mnSplitSize = 0;
781 		}
782 		else
783 		{
784 			if ( bRows )
785 			{
786 				pItems[i].mnLeft   = nSetLeft;
787 				pItems[i].mnTop    = nPos;
788 				pItems[i].mnWidth  = nSetWidth;
789 				pItems[i].mnHeight = pItems[i].mnPixSize;
790 			}
791 			else
792 			{
793 				pItems[i].mnLeft   = nPos;
794 				pItems[i].mnTop    = nSetTop;
795 				pItems[i].mnWidth  = pItems[i].mnPixSize;
796 				pItems[i].mnHeight = nSetHeight;
797 			}
798 
799 			if ( i > nItems-1 )
800 				pItems[i].mnSplitSize = 0;
801 			else
802 			{
803 				pItems[i].mnSplitSize = pSet->mnSplitSize;
804 				if ( bDown )
805 				{
806 					pItems[i].mnSplitPos = nPos+pItems[i].mnPixSize;
807 					if ( pItems[i].mnSplitPos+pItems[i].mnSplitSize > nMaxPos )
808 						pItems[i].mnSplitSize = nMaxPos-pItems[i].mnSplitPos;
809 				}
810 				else
811 				{
812 					pItems[i].mnSplitPos = nPos-pSet->mnSplitSize;
813 					if ( pItems[i].mnSplitPos < nMaxPos )
814 						pItems[i].mnSplitSize = pItems[i].mnSplitPos+pSet->mnSplitSize-nMaxPos;
815 				}
816 			}
817 		}
818 
819 		if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
820 		{
821 			if ( !bDown )
822 				nPos -= pSet->mnSplitSize;
823 			else
824 				nPos += pItems[i].mnPixSize+pSet->mnSplitSize;
825 		}
826 	}
827 
828 	// Sub-Set's berechnen
829 	for ( i = 0; i < nItems; i++ )
830 	{
831 		if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
832 		{
833 			ImplCalcSet( pItems[i].mpSet,
834 						 pItems[i].mnLeft, pItems[i].mnTop,
835 						 pItems[i].mnWidth, pItems[i].mnHeight,
836 						 ((pItems[i].mnBits & SWIB_COLSET) == 0) );
837 		}
838 	}
839 
840 	// Fixed setzen
841 	for ( i = 0; i < nItems; i++ )
842 	{
843 		pItems[i].mbFixed = sal_False;
844 		if ( pItems[i].mnBits & SWIB_FIXED )
845 			pItems[i].mbFixed = sal_True;
846 		else
847 		{
848 			// Wenn Child-Set vorhanden, ist dieses Item auch Fixed, wenn
849 			// ein Child fixed ist
850 			if ( pItems[i].mpSet )
851 			{
852 				for ( j = 0; j < pItems[i].mpSet->mnItems; j++ )
853 				{
854 					if ( pItems[i].mpSet->mpItems[j].mbFixed )
855 					{
856 						pItems[i].mbFixed = sal_True;
857 						break;
858 					}
859 				}
860 			}
861 		}
862 	}
863 }
864 
865 // -----------------------------------------------------------------------
866 
ImplCalcSet2(SplitWindow * pWindow,ImplSplitSet * pSet,sal_Bool bHide,sal_Bool bRows,sal_Bool)867 void SplitWindow::ImplCalcSet2( SplitWindow* pWindow, ImplSplitSet* pSet, sal_Bool bHide,
868 						        sal_Bool bRows, sal_Bool /*bDown*/ )
869 {
870 	sal_uInt16			i;
871 	sal_uInt16			nItems = pSet->mnItems;
872 	ImplSplitItem*	pItems = pSet->mpItems;
873 
874 	if ( pWindow->IsReallyVisible() && pWindow->IsUpdateMode() && pWindow->mbInvalidate )
875 	{
876 		for ( i = 0; i < nItems; i++ )
877 		{
878 			if ( pItems[i].mnSplitSize )
879 			{
880 				// Evt. alles invalidieren oder nur einen kleinen Teil
881 				if ( (pItems[i].mnOldSplitPos  != pItems[i].mnSplitPos)  ||
882 					 (pItems[i].mnOldSplitSize != pItems[i].mnSplitSize) ||
883 					 (pItems[i].mnOldWidth	   != pItems[i].mnWidth)	 ||
884 					 (pItems[i].mnOldHeight    != pItems[i].mnHeight) )
885 				{
886 					Rectangle aRect;
887 
888 					// Old Rect invalidieren
889 					if ( bRows )
890 					{
891 						aRect.Left()	= pItems[i].mnLeft;
892 						aRect.Right()	= pItems[i].mnLeft+pItems[i].mnOldWidth-1;
893 						aRect.Top() 	= pItems[i].mnOldSplitPos;
894 						aRect.Bottom()	= aRect.Top() + pItems[i].mnOldSplitSize;
895 					}
896 					else
897 					{
898 						aRect.Top() 	= pItems[i].mnTop;
899 						aRect.Bottom()	= pItems[i].mnTop+pItems[i].mnOldHeight-1;
900 						aRect.Left()	= pItems[i].mnOldSplitPos;
901 						aRect.Right()	= aRect.Left() + pItems[i].mnOldSplitSize;
902 					}
903 					pWindow->Invalidate( aRect );
904 					// New Rect invalidieren
905 					if ( bRows )
906 					{
907 						aRect.Left()	= pItems[i].mnLeft;
908 						aRect.Right()	= pItems[i].mnLeft+pItems[i].mnWidth-1;
909 						aRect.Top() 	= pItems[i].mnSplitPos;
910 						aRect.Bottom()	= aRect.Top() + pItems[i].mnSplitSize;
911 					}
912 					else
913 					{
914 						aRect.Top() 	= pItems[i].mnTop;
915 						aRect.Bottom()	= pItems[i].mnTop+pItems[i].mnHeight-1;
916 						aRect.Left()	= pItems[i].mnSplitPos;
917 						aRect.Right()	= aRect.Left() + pItems[i].mnSplitSize;
918 					}
919 					pWindow->Invalidate( aRect );
920 
921 					// Leere Sets komplett invalidieren, da diese Flaechen
922 					// nicht von Fenstern ueberladen werden
923 					if ( pItems[i].mpSet && !pItems[i].mpSet->mpItems )
924 					{
925 						aRect.Left()	= pItems[i].mnLeft;
926 						aRect.Top() 	= pItems[i].mnTop;
927 						aRect.Right()	= pItems[i].mnLeft+pItems[i].mnWidth-1;
928 						aRect.Bottom()	= pItems[i].mnTop+pItems[i].mnHeight-1;
929 						pWindow->Invalidate( aRect );
930 					}
931 				}
932 			}
933 		}
934 	}
935 
936 	// Fenster positionieren
937 	for ( i = 0; i < nItems; i++ )
938 	{
939 		if ( pItems[i].mpSet )
940 		{
941 			sal_Bool bTempHide = bHide;
942 			if ( !pItems[i].mnWidth || !pItems[i].mnHeight )
943 				bTempHide = sal_True;
944 			ImplCalcSet2( pWindow, pItems[i].mpSet, bTempHide,
945 						  ((pItems[i].mnBits & SWIB_COLSET) == 0) );
946 		}
947 		else
948 		{
949 			if ( pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
950 			{
951 				Point aPos( pItems[i].mnLeft, pItems[i].mnTop );
952 				Size  aSize( pItems[i].mnWidth, pItems[i].mnHeight );
953 				pItems[i].mpWindow->SetPosSizePixel( aPos, aSize );
954 			}
955 			else
956 				pItems[i].mpWindow->Hide();
957 		}
958 	}
959 
960 	// Fenster anzeigen und Flag zuruecksetzen
961 	for ( i = 0; i < nItems; i++ )
962 	{
963 		if ( pItems[i].mpWindow && pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
964 			pItems[i].mpWindow->Show();
965 	}
966 }
967 
968 // -----------------------------------------------------------------------
969 
ImplCalcLogSize(ImplSplitItem * pItems,sal_uInt16 nItems)970 static void ImplCalcLogSize( ImplSplitItem* pItems, sal_uInt16 nItems )
971 {
972 	// Original-Groessen updaten
973 	sal_uInt16	i;
974 	long	nRelSize = 0;
975 	long	nPerSize = 0;
976 	for ( i = 0; i < nItems; i++ )
977 	{
978 		if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
979 			nRelSize += pItems[i].mnPixSize;
980 		else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
981 			nPerSize += pItems[i].mnPixSize;
982 	}
983 	nPerSize += nRelSize;
984 	for ( i = 0; i < nItems; i++ )
985 	{
986 		if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
987 		{
988 			if ( nRelSize )
989 				pItems[i].mnSize = (pItems[i].mnPixSize+(nRelSize/2))/nRelSize;
990 			else
991 				pItems[i].mnSize = 1;
992 		}
993 		else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
994 		{
995 			if ( nPerSize )
996 				pItems[i].mnSize = (pItems[i].mnPixSize*100)/nPerSize;
997 			else
998 				pItems[i].mnSize = 1;
999 		}
1000 		else
1001 			pItems[i].mnSize = pItems[i].mnPixSize;
1002 	}
1003 }
1004 
1005 // -----------------------------------------------------------------------
1006 
ImplDrawBack(SplitWindow * pWindow,const Rectangle & rRect,const Wallpaper * pWall,const Bitmap * pBitmap)1007 void SplitWindow::ImplDrawBack( SplitWindow* pWindow, const Rectangle& rRect,
1008                                 const Wallpaper* pWall, const Bitmap* pBitmap )
1009 {
1010 	if ( pBitmap )
1011 	{
1012 		Point	aPos = rRect.TopLeft();
1013 		Size	aBmpSize = pBitmap->GetSizePixel();
1014 		pWindow->Push( PUSH_CLIPREGION );
1015 		pWindow->IntersectClipRegion( rRect );
1016 		do
1017 		{
1018 			aPos.X() = rRect.Left();
1019 			do
1020 			{
1021 				pWindow->DrawBitmap( aPos, *pBitmap );
1022 				aPos.X() += aBmpSize.Width();
1023 			}
1024 			while ( aPos.X() < rRect.Right() );
1025 			aPos.Y() += aBmpSize.Height();
1026 		}
1027 		while ( aPos.Y() < rRect.Bottom() );
1028 		pWindow->Pop();
1029 	}
1030 	else
1031 		pWindow->DrawWallpaper( rRect, *pWall );
1032 }
1033 
1034 // -----------------------------------------------------------------------
1035 
ImplDrawBack(SplitWindow * pWindow,ImplSplitSet * pSet)1036 void SplitWindow::ImplDrawBack( SplitWindow* pWindow, ImplSplitSet* pSet )
1037 {
1038 	sal_uInt16			i;
1039 	sal_uInt16			nItems = pSet->mnItems;
1040 	ImplSplitItem*	pItems = pSet->mpItems;
1041 
1042 	// Beim Mainset auch den Hintergrund zeichnen
1043 	if ( pSet->mnId == 0 )
1044 	{
1045 		if ( pSet->mpBitmap )
1046 		{
1047 			Rectangle aRect( pWindow->mnLeftBorder,
1048 							 pWindow->mnTopBorder,
1049 							 pWindow->mnDX-pWindow->mnRightBorder-1,
1050 							 pWindow->mnDY-pWindow->mnBottomBorder-1 );
1051 			ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
1052 		}
1053 	}
1054 
1055 	for ( i = 0; i < nItems; i++ )
1056 	{
1057 		pSet = pItems[i].mpSet;
1058 		if ( pSet )
1059 		{
1060 			if ( pSet->mpBitmap || pSet->mpWallpaper )
1061 			{
1062 				// Wegen ICC auftrennen
1063 				Point		aPoint( pItems[i].mnLeft, pItems[i].mnTop );
1064 				Size		aSize( pItems[i].mnWidth, pItems[i].mnHeight );
1065 				Rectangle	aRect( aPoint, aSize );
1066 				ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
1067 			}
1068 		}
1069 	}
1070 
1071 	for ( i = 0; i < nItems; i++ )
1072 	{
1073 		if ( pItems[i].mpSet )
1074 			ImplDrawBack( pWindow, pItems[i].mpSet );
1075 	}
1076 }
1077 
1078 // -----------------------------------------------------------------------
1079 
ImplDrawSplit(SplitWindow * pWindow,ImplSplitSet * pSet,sal_Bool bRows,sal_Bool bDown=sal_True)1080 static void ImplDrawSplit( SplitWindow* pWindow, ImplSplitSet* pSet,
1081 						   sal_Bool bRows, sal_Bool bDown = sal_True )
1082 {
1083 	if ( !pSet->mpItems )
1084 		return;
1085 
1086 	sal_uInt16					i;
1087 	sal_uInt16					nItems = pSet->mnItems;
1088 	long					nPos;
1089 	long					nTop;
1090 	long					nBottom;
1091 	ImplSplitItem*			pItems = pSet->mpItems;
1092 	const StyleSettings&	rStyleSettings = pWindow->GetSettings().GetStyleSettings();
1093 
1094 	sal_Bool bFlat = (pWindow->GetStyle() & WB_FLATSPLITDRAW) == WB_FLATSPLITDRAW;
1095 
1096 	for ( i = 0; i < nItems-1; i++ )
1097 	{
1098 		if ( pItems[i].mnSplitSize )
1099 		{
1100 			nPos = pItems[i].mnSplitPos;
1101 
1102 			long nItemSplitSize = pItems[i].mnSplitSize;
1103 			long nSplitSize = pSet->mnSplitSize;
1104 			if ( bRows )
1105 			{
1106 				nTop	= pItems[i].mnLeft;
1107 				nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
1108 
1109 				if ( bFlat ) nPos--;
1110 
1111 				if ( bDown || (nItemSplitSize >= nSplitSize) )
1112 				{
1113 					pWindow->SetLineColor( rStyleSettings.GetLightColor() );
1114 					pWindow->DrawLine( Point( nTop, nPos+1 ), Point( nBottom, nPos+1 ) );
1115 				}
1116 				nPos += nSplitSize-2;
1117 				if ( bFlat ) nPos+=2;
1118 				if ( (!bDown && (nItemSplitSize >= 2)) ||
1119 					 (bDown  && (nItemSplitSize >= nSplitSize-1)) )
1120 				{
1121 					pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
1122 					pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
1123 				}
1124 				if ( !bFlat )
1125 				{
1126 					nPos++;
1127 					if ( !bDown || (nItemSplitSize >= nSplitSize) )
1128 					{
1129 						pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
1130 						pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
1131 					}
1132 				}
1133 			}
1134 			else
1135 			{
1136 				nTop	= pItems[i].mnTop;
1137 				nBottom = pItems[i].mnTop+pSet->mpItems[i].mnHeight-1;
1138 
1139 				if ( bFlat ) nPos--;
1140 				if ( bDown || (nItemSplitSize >= nSplitSize) )
1141 				{
1142 					pWindow->SetLineColor( rStyleSettings.GetLightColor() );
1143 					pWindow->DrawLine( Point( nPos+1, nTop ), Point( nPos+1, nBottom ) );
1144 				}
1145 				nPos += pSet->mnSplitSize-2;
1146 				if ( bFlat ) nPos+=2;
1147 				if ( (!bDown && (nItemSplitSize >= 2)) ||
1148 					 (bDown  && (nItemSplitSize >= nSplitSize-1)) )
1149 				{
1150 					pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
1151 					pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
1152 				}
1153 				if( !bFlat )
1154 				{
1155 					nPos++;
1156 					if ( !bDown || (nItemSplitSize >= nSplitSize) )
1157 					{
1158 						pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
1159 						pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
1160 					}
1161 				}
1162 			}
1163 		}
1164 	}
1165 
1166 	for ( i = 0; i < nItems; i++ )
1167 	{
1168 		if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
1169 			ImplDrawSplit( pWindow, pItems[i].mpSet, ((pItems[i].mnBits & SWIB_COLSET) == 0) );
1170 	}
1171 }
1172 
1173 // -----------------------------------------------------------------------
1174 
ImplTestSplit(ImplSplitSet * pSet,const Point & rPos,long & rMouseOff,ImplSplitSet ** ppFoundSet,sal_uInt16 & rFoundPos,sal_Bool bRows,sal_Bool)1175 sal_uInt16 SplitWindow::ImplTestSplit( ImplSplitSet* pSet, const Point& rPos,
1176                                    long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos,
1177                                    sal_Bool bRows, sal_Bool /*bDown*/ )
1178 {
1179 	if ( !pSet->mpItems )
1180 		return 0;
1181 
1182 	sal_uInt16			i;
1183 	sal_uInt16			nSplitTest;
1184 	sal_uInt16			nItems = pSet->mnItems;
1185 	long			nMPos1;
1186 	long			nMPos2;
1187 	long			nPos;
1188 	long			nTop;
1189 	long			nBottom;
1190 	ImplSplitItem*	 pItems = pSet->mpItems;
1191 
1192 	if ( bRows )
1193 	{
1194 		nMPos1 = rPos.X();
1195 		nMPos2 = rPos.Y();
1196 	}
1197 	else
1198 	{
1199 		nMPos1 = rPos.Y();
1200 		nMPos2 = rPos.X();
1201 	}
1202 
1203 	for ( i = 0; i < nItems-1; i++ )
1204 	{
1205 		if ( pItems[i].mnSplitSize )
1206 		{
1207 			if ( bRows )
1208 			{
1209 				nTop	= pItems[i].mnLeft;
1210 				nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
1211 			}
1212 			else
1213 			{
1214 				nTop	= pItems[i].mnTop;
1215 				nBottom = pItems[i].mnTop+pItems[i].mnHeight-1;
1216 			}
1217 			nPos = pItems[i].mnSplitPos;
1218 
1219 			if ( (nMPos1 >= nTop) && (nMPos1 <= nBottom) &&
1220 				 (nMPos2 >= nPos) && (nMPos2 <= nPos+pItems[i].mnSplitSize) )
1221 			{
1222 				if ( !pItems[i].mbFixed && !pItems[i+1].mbFixed )
1223 				{
1224 					rMouseOff = nMPos2-nPos;
1225 					*ppFoundSet = pSet;
1226 					rFoundPos = i;
1227 					if ( bRows )
1228 						return SPLIT_VERT;
1229 					else
1230 						return SPLIT_HORZ;
1231 				}
1232 				else
1233 					return SPLIT_NOSPLIT;
1234 			}
1235 		}
1236 	}
1237 
1238 	for ( i = 0; i < nItems; i++ )
1239 	{
1240 		if ( pItems[i].mpSet )
1241 		{
1242 			nSplitTest = ImplTestSplit( pItems[i].mpSet, rPos,
1243 									   rMouseOff, ppFoundSet, rFoundPos,
1244 									   ((pItems[i].mnBits & SWIB_COLSET) == 0) );
1245 			if ( nSplitTest )
1246 				return nSplitTest;
1247 		}
1248 	}
1249 
1250 	return 0;
1251 }
1252 
1253 // -----------------------------------------------------------------------
1254 
ImplTestSplit(SplitWindow * pWindow,const Point & rPos,long & rMouseOff,ImplSplitSet ** ppFoundSet,sal_uInt16 & rFoundPos)1255 sal_uInt16 SplitWindow::ImplTestSplit( SplitWindow* pWindow, const Point& rPos,
1256                                    long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos )
1257 {
1258 	// Resizeable SplitWindow muss anders behandelt werden
1259 	if ( pWindow->mnWinStyle & WB_SIZEABLE )
1260 	{
1261 		long	nTPos;
1262 		long	nPos;
1263 		long	nBorder;
1264 
1265 		if ( pWindow->mbHorz )
1266 		{
1267 			if ( pWindow->mbBottomRight )
1268 			{
1269 				nBorder = pWindow->mnBottomBorder;
1270 				nPos = 0;
1271 			}
1272 			else
1273 			{
1274 				nBorder = pWindow->mnTopBorder;
1275 				nPos = pWindow->mnDY-nBorder;
1276 			}
1277 			nTPos = rPos.Y();
1278 		}
1279 		else
1280 		{
1281 			if ( pWindow->mbBottomRight )
1282 			{
1283 				nBorder = pWindow->mnRightBorder;
1284 				nPos = 0;
1285 			}
1286 			else
1287 			{
1288 				nBorder = pWindow->mnLeftBorder;
1289 				nPos = pWindow->mnDX-nBorder;
1290 			}
1291 			nTPos = rPos.X();
1292 		}
1293 		long nSplitSize = pWindow->mpMainSet->mnSplitSize-2;
1294 		if ( pWindow->mbAutoHide || pWindow->mbFadeOut )
1295 			nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1296 		if ( !pWindow->mbBottomRight )
1297 			nPos -= nSplitSize;
1298 		if ( (nTPos >= nPos) && (nTPos <= nPos+nSplitSize+nBorder) )
1299 		{
1300 			rMouseOff = nTPos-nPos;
1301 			*ppFoundSet = pWindow->mpMainSet;
1302 			if ( pWindow->mpMainSet->mpItems )
1303 				rFoundPos = pWindow->mpMainSet->mnItems-1;
1304 			else
1305 				rFoundPos = 0;
1306 			if ( pWindow->mbHorz )
1307 				return SPLIT_VERT | SPLIT_WINDOW;
1308 			else
1309 				return SPLIT_HORZ | SPLIT_WINDOW;
1310 		}
1311 	}
1312 
1313 	return ImplTestSplit( pWindow->mpMainSet, rPos, rMouseOff, ppFoundSet, rFoundPos,
1314 						 pWindow->mbHorz, !pWindow->mbBottomRight );
1315 }
1316 
1317 // -----------------------------------------------------------------------
1318 
ImplDrawSplitTracking(SplitWindow * pThis,const Point & rPos)1319 void SplitWindow::ImplDrawSplitTracking( SplitWindow* pThis, const Point& rPos )
1320 {
1321 	Rectangle aRect;
1322 
1323 	if ( pThis->mnSplitTest & SPLIT_HORZ )
1324 	{
1325 		aRect.Top()    = pThis->maDragRect.Top();
1326 		aRect.Bottom() = pThis->maDragRect.Bottom();
1327 		aRect.Left()   = rPos.X();
1328 		aRect.Right()  = aRect.Left()+pThis->mpSplitSet->mnSplitSize-1;
1329 		if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
1330 			aRect.Right()--;
1331 		if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
1332 			 (pThis->mbAutoHide || pThis->mbFadeOut) )
1333 		{
1334 			aRect.Left()  += SPLITWIN_SPLITSIZEEXLN;
1335 			aRect.Right() += SPLITWIN_SPLITSIZEEXLN;
1336 		}
1337 	}
1338 	else
1339 	{
1340 		aRect.Left()	= pThis->maDragRect.Left();
1341 		aRect.Right()	= pThis->maDragRect.Right();
1342 		aRect.Top() 	= rPos.Y();
1343 		aRect.Bottom()	= aRect.Top()+pThis->mpSplitSet->mnSplitSize-1;
1344 		if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
1345 			aRect.Bottom()--;
1346 		if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
1347 			 (pThis->mbAutoHide || pThis->mbFadeOut) )
1348 		{
1349 			aRect.Top()    += SPLITWIN_SPLITSIZEEXLN;
1350 			aRect.Bottom() += SPLITWIN_SPLITSIZEEXLN;
1351 		}
1352 	}
1353 	pThis->ShowTracking( aRect, SHOWTRACK_SPLIT );
1354 }
1355 
1356 // -----------------------------------------------------------------------
1357 
ImplInit(Window * pParent,WinBits nStyle)1358 void SplitWindow::ImplInit( Window* pParent, WinBits nStyle )
1359 {
1360 	ImplSplitSet* pNewSet	= new ImplSplitSet;
1361 	pNewSet->mpItems		= NULL;
1362 	pNewSet->mpWallpaper	= NULL;
1363 	pNewSet->mpBitmap		= NULL;
1364 	pNewSet->mnLastSize 	= 0;
1365 	pNewSet->mnItems		= 0;
1366 	pNewSet->mnId			= 0;
1367 	pNewSet->mnSplitSize	= SPLITWIN_SPLITSIZE;
1368 	pNewSet->mbCalcPix		= sal_True;
1369 
1370 	mpMainSet				= pNewSet;
1371 	mpBaseSet				= pNewSet;
1372 	mpSplitSet				= NULL;
1373 	mpLastSizes 			= NULL;
1374 	mnDX					= 0;
1375 	mnDY					= 0;
1376 	mnLeftBorder			= 0;
1377 	mnTopBorder 			= 0;
1378 	mnRightBorder			= 0;
1379 	mnBottomBorder			= 0;
1380 	mnMaxSize				= 0;
1381 	mnMouseOff				= 0;
1382 	meAlign 				= WINDOWALIGN_TOP;
1383 	mnWinStyle				= nStyle;
1384 	mnSplitTest 			= 0;
1385 	mnSplitPos				= 0;
1386 	mnMouseModifier 		= 0;
1387 	mnMStartPos 			= 0;
1388 	mnMSplitPos 			= 0;
1389 	mbDragFull				= sal_False;
1390 	mbHorz					= sal_True;
1391 	mbBottomRight			= sal_False;
1392 	mbCalc					= sal_False;
1393 	mbRecalc				= sal_True;
1394 	mbInvalidate			= sal_True;
1395 	mbAutoHide				= sal_False;
1396 	mbFadeIn				= sal_False;
1397 	mbFadeOut				= sal_False;
1398 	mbAutoHideIn			= sal_False;
1399 	mbAutoHideDown			= sal_False;
1400 	mbFadeInDown			= sal_False;
1401 	mbFadeOutDown			= sal_False;
1402 	mbAutoHidePressed		= sal_False;
1403 	mbFadeInPressed 		= sal_False;
1404 	mbFadeOutPressed		= sal_False;
1405 	mbFadeNoButtonMode		= sal_False;
1406 	mbNoAlign				= sal_False;
1407 
1408 	if ( nStyle & WB_NOSPLITDRAW )
1409 	{
1410 		pNewSet->mnSplitSize -= 2;
1411 		mbInvalidate = sal_False;
1412 	}
1413 
1414 	if ( nStyle & WB_BORDER )
1415 	{
1416 		ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
1417 						mnRightBorder, mnBottomBorder );
1418 	}
1419 	else
1420 	{
1421 		mnLeftBorder   = 0;
1422 		mnTopBorder    = 0;
1423 		mnRightBorder  = 0;
1424 		mnBottomBorder = 0;
1425 	}
1426 
1427 	DockingWindow::ImplInit( pParent, (nStyle | WB_CLIPCHILDREN) & ~(WB_BORDER | WB_SIZEABLE) );
1428 
1429 	ImplInitSettings();
1430 }
1431 
1432 // -----------------------------------------------------------------------
1433 
ImplInitSettings()1434 void SplitWindow::ImplInitSettings()
1435 {
1436 	// Wenn fuer das MainSet eine Bitmap gesetzt wird, dann
1437 	// brauchen wir nicht mehr den Hintergrund loeschen
1438 	// Wenn MainSet Wallpaper hat, dann ist das der Hintergrund, ansonsten
1439 	// sind es die Standard-Farben
1440 	if ( mpMainSet->mpBitmap )
1441 		SetBackground();
1442 	else if ( mpMainSet->mpWallpaper )
1443 		SetBackground( *mpMainSet->mpWallpaper );
1444 	else
1445 	{
1446 		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1447 
1448 		Color aColor;
1449 		if ( IsControlBackground() )
1450 			aColor = GetControlBackground();
1451 		else if ( Window::GetStyle() & WB_3DLOOK )
1452 			aColor = rStyleSettings.GetFaceColor();
1453 		else
1454 			aColor = rStyleSettings.GetWindowColor();
1455 		SetBackground( aColor );
1456 	}
1457 }
1458 
1459 // =======================================================================
1460 
SplitWindow(Window * pParent,WinBits nStyle)1461 SplitWindow::SplitWindow( Window* pParent, WinBits nStyle ) :
1462 	DockingWindow( WINDOW_SPLITWINDOW )
1463 {
1464 	ImplInit( pParent, nStyle );
1465 }
1466 
1467 // -----------------------------------------------------------------------
1468 
SplitWindow(Window * pParent,const ResId & rResId)1469 SplitWindow::SplitWindow( Window* pParent, const ResId& rResId ) :
1470 	DockingWindow( WINDOW_SPLITWINDOW )
1471 {
1472 	rResId.SetRT( RSC_SPLITWINDOW );
1473 	WinBits nStyle = ImplInitRes( rResId );
1474 	ImplInit( pParent, nStyle );
1475 	ImplLoadRes( rResId );
1476 
1477 	if ( !(nStyle & WB_HIDE) )
1478 		Show();
1479 }
1480 
1481 // -----------------------------------------------------------------------
1482 
~SplitWindow()1483 SplitWindow::~SplitWindow()
1484 {
1485 	// Sets loeschen
1486 	ImplDeleteSet( mpMainSet );
1487 }
1488 
1489 // -----------------------------------------------------------------------
1490 
ImplSetWindowSize(long nDelta)1491 void SplitWindow::ImplSetWindowSize( long nDelta )
1492 {
1493 	if ( !nDelta )
1494 		return;
1495 
1496 	Size aSize = GetSizePixel();
1497 	if ( meAlign == WINDOWALIGN_TOP )
1498 	{
1499 		aSize.Height() += nDelta;
1500 		SetSizePixel( aSize );
1501 	}
1502 	else if ( meAlign == WINDOWALIGN_BOTTOM )
1503 	{
1504 		maDragRect.Top() += nDelta;
1505 		Point aPos = GetPosPixel();
1506 		aPos.Y() -= nDelta;
1507 		aSize.Height() += nDelta;
1508 		SetPosSizePixel( aPos, aSize );
1509 	}
1510 	else if ( meAlign == WINDOWALIGN_LEFT )
1511 	{
1512 		aSize.Width() += nDelta;
1513 		SetSizePixel( aSize );
1514 	}
1515 	else // meAlign == WINDOWALIGN_RIGHT
1516 	{
1517 		maDragRect.Left() += nDelta;
1518 		Point aPos = GetPosPixel();
1519 		aPos.X() -= nDelta;
1520 		aSize.Width() += nDelta;
1521 		SetPosSizePixel( aPos, aSize );
1522 	}
1523 
1524 	SplitResize();
1525 }
1526 
1527 // -----------------------------------------------------------------------
1528 
CalcLayoutSizePixel(const Size & aNewSize)1529 Size SplitWindow::CalcLayoutSizePixel( const Size& aNewSize )
1530 {
1531 	Size aSize( aNewSize );
1532 	long nSplitSize = mpMainSet->mnSplitSize-2;
1533 
1534 	if ( mbAutoHide || mbFadeOut )
1535 		nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1536 
1537 	// Wenn Fenster sizeable ist, wird die Groesse automatisch nach
1538 	// dem MainSet festgelegt, wenn kein relatives Fenster enthalten
1539 	// ist
1540 	if ( mnWinStyle & WB_SIZEABLE )
1541 	{
1542 		long	nCurSize;
1543 		long	nCalcSize = 0;
1544 		sal_uInt16	i;
1545 
1546 		for ( i = 0; i < mpMainSet->mnItems; i++ )
1547 		{
1548 			if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
1549 				break;
1550 			else
1551 				nCalcSize += mpMainSet->mpItems[i].mnSize;
1552 		}
1553 
1554 		if ( i == mpMainSet->mnItems )
1555 		{
1556 			long	nDelta = 0;
1557 			Point	aPos = GetPosPixel();
1558 
1559 			if ( mbHorz )
1560 				nCurSize = aNewSize.Height()-mnTopBorder-mnBottomBorder;
1561 			else
1562 				nCurSize = aNewSize.Width()-mnLeftBorder-mnRightBorder;
1563 			nCurSize -= nSplitSize;
1564 			nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
1565 
1566 			nDelta = nCalcSize-nCurSize;
1567 			if ( !nDelta )
1568 				return aSize;
1569 
1570 			if ( meAlign == WINDOWALIGN_TOP )
1571 			{
1572 				aSize.Height() += nDelta;
1573 			}
1574 			else if ( meAlign == WINDOWALIGN_BOTTOM )
1575 			{
1576 				aPos.Y() -= nDelta;
1577 				aSize.Height() += nDelta;
1578 			}
1579 			else if ( meAlign == WINDOWALIGN_LEFT )
1580 			{
1581 				aSize.Width() += nDelta;
1582 			}
1583 			else // meAlign == WINDOWALIGN_RIGHT
1584 			{
1585 				aPos.X() -= nDelta;
1586 				aSize.Width() += nDelta;
1587 			}
1588 		}
1589 	}
1590 
1591 	return aSize;
1592 }
1593 
1594 // -----------------------------------------------------------------------
1595 
ImplCalcLayout()1596 void SplitWindow::ImplCalcLayout()
1597 {
1598 	if ( !mbCalc || !mbRecalc || !mpMainSet->mpItems )
1599 		return;
1600 
1601 	long nSplitSize = mpMainSet->mnSplitSize-2;
1602 	if ( mbAutoHide || mbFadeOut )
1603 		nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1604 
1605 	// Wenn Fenster sizeable ist, wird die Groesse automatisch nach
1606 	// dem MainSet festgelegt, wenn kein relatives Fenster enthalten
1607 	// ist
1608 	if ( mnWinStyle & WB_SIZEABLE )
1609 	{
1610 		long	nCurSize;
1611 		long	nCalcSize = 0;
1612 		sal_uInt16	i;
1613 
1614 		for ( i = 0; i < mpMainSet->mnItems; i++ )
1615 		{
1616 			if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
1617 				break;
1618 			else
1619 				nCalcSize += mpMainSet->mpItems[i].mnSize;
1620 		}
1621 
1622 		if ( i == mpMainSet->mnItems )
1623 		{
1624 			if ( mbHorz )
1625 				nCurSize = mnDY-mnTopBorder-mnBottomBorder;
1626 			else
1627 				nCurSize = mnDX-mnLeftBorder-mnRightBorder;
1628 			nCurSize -= nSplitSize;
1629 			nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
1630 
1631 			mbRecalc = sal_False;
1632 			ImplSetWindowSize( nCalcSize-nCurSize );
1633 			mbRecalc = sal_True;
1634 		}
1635 	}
1636 
1637 	if ( (mnDX <= 0) || (mnDY <= 0) )
1638 		return;
1639 
1640 	// Groessen/Position vorberechnen
1641 	long	nL;
1642 	long	nT;
1643 	long	nW;
1644 	long	nH;
1645 
1646 	if ( mbHorz )
1647 	{
1648 		if ( mbBottomRight )
1649 			nT = mnDY-mnBottomBorder;
1650 		else
1651 			nT = mnTopBorder;
1652 		nL = mnLeftBorder;
1653 	}
1654 	else
1655 	{
1656 		if ( mbBottomRight )
1657 			nL = mnDX-mnRightBorder;
1658 		else
1659 			nL = mnLeftBorder;
1660 		nT = mnTopBorder;
1661 	}
1662 	nW = mnDX-mnLeftBorder-mnRightBorder;
1663 	nH = mnDY-mnTopBorder-mnBottomBorder;
1664 	if ( mnWinStyle & WB_SIZEABLE )
1665 	{
1666 		if ( mbHorz )
1667 			nH -= nSplitSize;
1668 		else
1669 			nW -= nSplitSize;
1670 	}
1671 
1672 	// Sets rekursiv berechnen
1673 	ImplCalcSet( mpMainSet, nL, nT, nW, nH, mbHorz, !mbBottomRight );
1674 	ImplCalcSet2( this, mpMainSet, sal_False, mbHorz, !mbBottomRight );
1675 	mbCalc = sal_False;
1676 }
1677 
1678 // -----------------------------------------------------------------------
1679 
ImplUpdate()1680 void SplitWindow::ImplUpdate()
1681 {
1682 	mbCalc = sal_True;
1683 
1684 	if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
1685 	{
1686 		if ( mpMainSet->mpItems )
1687 			ImplCalcLayout();
1688 		else
1689 			Invalidate();
1690 	}
1691 }
1692 
1693 // -----------------------------------------------------------------------
1694 
ImplUpdateSet(ImplSplitSet * pSet)1695 void SplitWindow::ImplUpdateSet( ImplSplitSet* pSet )
1696 {
1697 	if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
1698 	{
1699 		// Wenn wir noch berechnen muessen, dann alles invalidieren.
1700 		if ( mbCalc )
1701 		{
1702 			// Wenn nicht NOSPLITDRAW gesetzt ist, koennen wir uns das
1703 			// invalidieren sparen, da bei ImplCalcSet2() die freien Flaechen
1704 			// sowieso invalidiert werden
1705 			if ( !mpMainSet->mpItems || (mnWinStyle & WB_NOSPLITDRAW) )
1706 				pSet = mpMainSet;
1707 			else
1708 				return;
1709 		}
1710 
1711 		Rectangle aRect;
1712 		if ( pSet == mpMainSet )
1713 		{
1714 			aRect.Left()	= mnLeftBorder;
1715 			aRect.Top() 	= mnTopBorder;
1716 			aRect.Right()	= mnDX-mnRightBorder-1;
1717 			aRect.Bottom()	= mnDY-mnBottomBorder-1;
1718 		}
1719 		else
1720 		{
1721 			ImplSplitItem*	pItem;
1722 			sal_uInt16			nPos;
1723 
1724 			pSet = ImplFindItem( mpMainSet, pSet->mnId, nPos );
1725 			pItem = &(pSet->mpItems[nPos]);
1726 			aRect.Left()	= pItem->mnLeft;
1727 			aRect.Top() 	= pItem->mnTop;
1728 			aRect.Right()	= aRect.Left()+pItem->mnWidth;
1729 			aRect.Bottom()	= aRect.Top()+pItem->mnHeight;
1730 		}
1731 		Invalidate( aRect );
1732 	}
1733 }
1734 
1735 // -----------------------------------------------------------------------
1736 
ImplSplitMousePos(Point & rMousePos)1737 void SplitWindow::ImplSplitMousePos( Point& rMousePos )
1738 {
1739 	if ( mnSplitTest & SPLIT_HORZ )
1740 	{
1741 		rMousePos.X() -= mnMouseOff;
1742 		if ( rMousePos.X() < maDragRect.Left() )
1743 			rMousePos.X() = maDragRect.Left();
1744 		else if ( rMousePos.X()+mpSplitSet->mnSplitSize+1 > maDragRect.Right() )
1745 			rMousePos.X() = maDragRect.Right()-mpSplitSet->mnSplitSize+1;
1746 		// Wegen FullDrag in Screen-Koordinaaten merken
1747 		mnMSplitPos = OutputToScreenPixel( rMousePos ).X();
1748 	}
1749 	else
1750 	{
1751 		rMousePos.Y() -= mnMouseOff;
1752 		if ( rMousePos.Y() < maDragRect.Top() )
1753 			rMousePos.Y() = maDragRect.Top();
1754 		else if ( rMousePos.Y()+mpSplitSet->mnSplitSize+1 > maDragRect.Bottom() )
1755 			rMousePos.Y() = maDragRect.Bottom()-mpSplitSet->mnSplitSize+1;
1756 		mnMSplitPos = OutputToScreenPixel( rMousePos ).Y();
1757 	}
1758 }
1759 
1760 // -----------------------------------------------------------------------
1761 
ImplGetButtonRect(Rectangle & rRect,long nEx,sal_Bool bTest) const1762 void SplitWindow::ImplGetButtonRect( Rectangle& rRect, long nEx, sal_Bool bTest ) const
1763 {
1764 	long nSplitSize = mpMainSet->mnSplitSize-2;
1765 	if ( mbAutoHide || mbFadeOut || mbFadeIn )
1766 		nSplitSize += SPLITWIN_SPLITSIZEEX;
1767 
1768 	long nButtonSize = 0;
1769 	if ( mbFadeIn )
1770 		nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1771 	if ( mbFadeOut )
1772 		nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1773 	if ( mbAutoHide )
1774 		nButtonSize += SPLITWIN_SPLITSIZEAUTOHIDE+1;
1775 	long nCenterEx = 0;
1776 	if ( mbHorz )
1777 		nCenterEx += ((mnDX-mnLeftBorder-mnRightBorder)-nButtonSize)/2;
1778 	else
1779 		nCenterEx += ((mnDY-mnTopBorder-mnBottomBorder)-nButtonSize)/2;
1780 	if ( nCenterEx > 0 )
1781 		nEx += nCenterEx;
1782 
1783 	if ( meAlign == WINDOWALIGN_TOP )
1784 	{
1785 		rRect.Left()	= mnLeftBorder+nEx;
1786 		rRect.Top() 	= mnDY-mnBottomBorder-nSplitSize;
1787 		rRect.Right()	= rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
1788 		rRect.Bottom()	= mnDY-mnBottomBorder-1;
1789 		if ( bTest )
1790 		{
1791 			rRect.Top() 	-= mnTopBorder;
1792 			rRect.Bottom()	+= mnBottomBorder;
1793 		}
1794 	}
1795 	else if ( meAlign == WINDOWALIGN_BOTTOM )
1796 	{
1797 		rRect.Left()	= mnLeftBorder+nEx;
1798 		rRect.Top() 	= mnTopBorder;
1799 		rRect.Right()	= rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
1800 		rRect.Bottom()	= mnTopBorder+nSplitSize-1;
1801 		if ( bTest )
1802 		{
1803 			rRect.Top() 	-= mnTopBorder;
1804 			rRect.Bottom()	+= mnBottomBorder;
1805 		}
1806 	}
1807 	else if ( meAlign == WINDOWALIGN_LEFT )
1808 	{
1809 		rRect.Left()	= mnDX-mnRightBorder-nSplitSize;
1810 		rRect.Top() 	= mnTopBorder+nEx;
1811 		rRect.Right()	= mnDX-mnRightBorder-1;
1812 		rRect.Bottom()	= rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
1813 		if ( bTest )
1814 		{
1815 			rRect.Left()	-= mnLeftBorder;
1816 			rRect.Right()	+= mnRightBorder;
1817 		}
1818 	}
1819 	else if ( meAlign == WINDOWALIGN_RIGHT )
1820 	{
1821 		rRect.Left()	= mnLeftBorder;
1822 		rRect.Top() 	= mnTopBorder+nEx;
1823 		rRect.Right()	= mnLeftBorder+nSplitSize-1;
1824 		rRect.Bottom()	= rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
1825 		if ( bTest )
1826 		{
1827 			rRect.Left()	-= mnLeftBorder;
1828 			rRect.Right()	+= mnRightBorder;
1829 		}
1830 	}
1831 }
1832 
1833 // -----------------------------------------------------------------------
1834 
ImplGetAutoHideRect(Rectangle & rRect,sal_Bool bTest) const1835 void SplitWindow::ImplGetAutoHideRect( Rectangle& rRect, sal_Bool bTest ) const
1836 {
1837 	Rectangle aRect;
1838 
1839 	if ( mbAutoHide )
1840 	{
1841 		long nEx = 0;
1842 		if ( mbFadeIn || mbFadeOut )
1843 			nEx = SPLITWIN_SPLITSIZEFADE+1;
1844 		ImplGetButtonRect( aRect, nEx, bTest && mbFadeIn );
1845 	}
1846 
1847 	rRect = aRect;
1848 }
1849 
1850 // -----------------------------------------------------------------------
1851 
ImplGetFadeInRect(Rectangle & rRect,sal_Bool bTest) const1852 void SplitWindow::ImplGetFadeInRect( Rectangle& rRect, sal_Bool bTest ) const
1853 {
1854 	Rectangle aRect;
1855 
1856 	if ( mbFadeIn )
1857 		ImplGetButtonRect( aRect, 0, bTest );
1858 
1859 	rRect = aRect;
1860 }
1861 
1862 // -----------------------------------------------------------------------
1863 
ImplGetFadeOutRect(Rectangle & rRect,sal_Bool) const1864 void SplitWindow::ImplGetFadeOutRect( Rectangle& rRect, sal_Bool ) const
1865 {
1866 	Rectangle aRect;
1867 
1868 	if ( mbFadeOut )
1869 		ImplGetButtonRect( aRect, 0, sal_False );
1870 
1871 	rRect = aRect;
1872 }
1873 
1874 // -----------------------------------------------------------------------
1875 
ImplDrawButtonRect(const Rectangle & rRect,long nSize)1876 void SplitWindow::ImplDrawButtonRect( const Rectangle& rRect, long nSize )
1877 {
1878 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1879 
1880 	if ( mbHorz )
1881 	{
1882 		long nLeft = rRect.Left();
1883 		long nRight = rRect.Right();
1884 		long nCenter = rRect.Center().Y();
1885 		long nEx1 = nLeft+((rRect.GetWidth()-nSize)/2)-2;
1886 		long nEx2 = nEx1+nSize+3;
1887 		SetLineColor( rStyleSettings.GetLightColor() );
1888 		DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
1889 		DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
1890 		SetLineColor( rStyleSettings.GetShadowColor() );
1891 		DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
1892 		DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
1893 		long i = nLeft+2;
1894 		while ( i < nRight-3 )
1895 		{
1896 			if ( (i < nEx1) || (i > nEx2 ) )
1897 			{
1898 				DrawPixel( Point( i, nCenter-2 ), rStyleSettings.GetLightColor() );
1899 				DrawPixel( Point( i+1, nCenter-2+1 ), rStyleSettings.GetShadowColor() );
1900 			}
1901 			i++;
1902 			if ( (i < nEx1) || ((i > nEx2 ) && (i < nRight-3)) )
1903 			{
1904 				DrawPixel( Point( i, nCenter+2 ), rStyleSettings.GetLightColor() );
1905 				DrawPixel( Point( i+1, nCenter+2+1 ), rStyleSettings.GetShadowColor() );
1906 			}
1907 			i += 2;
1908 		}
1909 	}
1910 	else
1911 	{
1912 		long nTop = rRect.Top();
1913 		long nBottom = rRect.Bottom();
1914 		long nCenter = rRect.Center().X();
1915 		long nEx1 = nTop+((rRect.GetHeight()-nSize)/2)-2;
1916 		long nEx2 = nEx1+nSize+3;
1917 		SetLineColor( rStyleSettings.GetLightColor() );
1918 		DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
1919 		DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
1920 		SetLineColor( rStyleSettings.GetShadowColor() );
1921 		DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
1922 		DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
1923 		long i = nTop+2;
1924 		while ( i < nBottom-3 )
1925 		{
1926 			if ( (i < nEx1) || (i > nEx2 ) )
1927 			{
1928 				DrawPixel( Point( nCenter-2, i ), rStyleSettings.GetLightColor() );
1929 				DrawPixel( Point( nCenter-2+1, i+1 ), rStyleSettings.GetShadowColor() );
1930 			}
1931 			i++;
1932 			if ( (i < nEx1) || ((i > nEx2 ) && (i < nBottom-3)) )
1933 			{
1934 				DrawPixel( Point( nCenter+2, i ), rStyleSettings.GetLightColor() );
1935 				DrawPixel( Point( nCenter+2+1, i+1 ), rStyleSettings.GetShadowColor() );
1936 			}
1937 			i += 2;
1938 		}
1939 	}
1940 }
1941 
1942 // -----------------------------------------------------------------------
1943 
ImplDrawAutoHide(sal_Bool bInPaint)1944 void SplitWindow::ImplDrawAutoHide( sal_Bool bInPaint )
1945 {
1946 	if ( mbAutoHide )
1947 	{
1948 		Rectangle aTempRect;
1949 		ImplGetAutoHideRect( aTempRect );
1950 
1951 		if ( !bInPaint )
1952 			Erase( aTempRect );
1953 
1954 		// ImageListe laden, wenn noch nicht vorhanden
1955 		ImplSVData* pSVData = ImplGetSVData();
1956 		ImageList*	pImageList;
1957 		if ( mbHorz )
1958 		{
1959 			if ( !pSVData->maCtrlData.mpSplitHPinImgList )
1960 			{
1961 				ResMgr* pResMgr = ImplGetResMgr();
1962 				if( pResMgr )
1963 				{
1964 					Color aNonAlphaMask( 0x00, 0x00, 0xFF );
1965 					pSVData->maCtrlData.mpSplitHPinImgList = new ImageList(4);
1966 					pSVData->maCtrlData.mpSplitHPinImgList->InsertFromHorizontalBitmap
1967 						( ResId( SV_RESID_BITMAP_SPLITHPIN, *pResMgr ), 4, &aNonAlphaMask );
1968 				}
1969 			}
1970 			pImageList = pSVData->maCtrlData.mpSplitHPinImgList;
1971 		}
1972 		else
1973 		{
1974 			if ( !pSVData->maCtrlData.mpSplitVPinImgList )
1975 			{
1976 				ResMgr* pResMgr = ImplGetResMgr();
1977 				pSVData->maCtrlData.mpSplitVPinImgList = new ImageList(4);
1978 				if( pResMgr )
1979 				{
1980 					Color aNonAlphaMask( 0x00, 0x00, 0xFF );
1981 					pSVData->maCtrlData.mpSplitVPinImgList->InsertFromHorizontalBitmap
1982 						( ResId( SV_RESID_BITMAP_SPLITVPIN, *pResMgr ), 4, &aNonAlphaMask );
1983 				}
1984 			}
1985 			pImageList = pSVData->maCtrlData.mpSplitVPinImgList;
1986 		}
1987 
1988 		// Image ermitteln und zurueckgeben
1989 		sal_uInt16 nId;
1990 		if ( mbAutoHidePressed )
1991 		{
1992 			if ( mbAutoHideIn )
1993 				nId = 3;
1994 			else
1995 				nId = 4;
1996 		}
1997 		else
1998 		{
1999 			if ( mbAutoHideIn )
2000 				nId = 1;
2001 			else
2002 				nId = 2;
2003 		}
2004 
2005 		Image	aImage = pImageList->GetImage( nId );
2006 		Size	aImageSize = aImage.GetSizePixel();
2007 		Point	aPos( aTempRect.Left()+((aTempRect.GetWidth()-aImageSize.Width())/2),
2008 					  aTempRect.Top()+((aTempRect.GetHeight()-aImageSize.Height())/2) );
2009 		long	nSize;
2010 		if ( mbHorz )
2011 			nSize = aImageSize.Width();
2012 		else
2013 			nSize = aImageSize.Height();
2014 		ImplDrawButtonRect( aTempRect, nSize );
2015 		DrawImage( aPos, aImage );
2016 	}
2017 }
2018 
2019 // -----------------------------------------------------------------------
2020 
ImplDrawFadeArrow(const Point & rPt,sal_Bool bHorz,sal_Bool bLeft)2021 void SplitWindow::ImplDrawFadeArrow( const Point& rPt, sal_Bool bHorz, sal_Bool bLeft )
2022 {
2023 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2024 
2025 	int x( rPt.X() );
2026 	int y( rPt.Y() );
2027 
2028     Color aCol;
2029     if( !bHorz )
2030     {
2031         int dx = 1;
2032         if( bLeft )
2033         {
2034             x = x+3;
2035             dx = -1;
2036         }
2037 
2038         x = x-1;
2039         aCol = rStyleSettings.GetDarkShadowColor();
2040         DrawPixel( Point(x, y), aCol );
2041         DrawPixel( Point(x, y+6), aCol );
2042         DrawPixel( Point(x+dx, y+1), aCol );
2043         DrawPixel( Point(x+dx, y+5), aCol );
2044         DrawPixel( Point(x+dx+dx, y+2), aCol );
2045         DrawPixel( Point(x+dx+dx, y+4), aCol );
2046         DrawPixel( Point(x+dx+dx+dx, y+3), aCol );
2047 
2048         aCol = rStyleSettings.GetShadowColor();
2049         DrawPixel( Point(x, y+1), aCol );
2050         DrawPixel( Point(x, y+5), aCol );
2051         DrawPixel( Point(x+dx, y+2), aCol );
2052         DrawPixel( Point(x+dx, y+4), aCol );
2053         DrawPixel( Point(x+dx+dx, y+3), aCol );
2054     }
2055     else
2056     {
2057         int dy = 1;
2058         if( bLeft )
2059         {
2060             y = y+3;
2061             dy = -1;
2062         }
2063 
2064         y = y-1;
2065         aCol = rStyleSettings.GetDarkShadowColor();
2066         DrawPixel( Point(x, y), aCol );
2067         DrawPixel( Point(x+6, y), aCol );
2068         DrawPixel( Point(x+1, y+dy), aCol );
2069         DrawPixel( Point(x+5, y+dy), aCol );
2070         DrawPixel( Point(x+2, y+dy+dy), aCol );
2071         DrawPixel( Point(x+4, y+dy+dy), aCol );
2072         DrawPixel( Point(x+3, y+dy+dy+dy), aCol );
2073 
2074         aCol = rStyleSettings.GetShadowColor();
2075         DrawPixel( Point(x+1, y), aCol );
2076         DrawPixel( Point(x+5, y), aCol );
2077         DrawPixel( Point(x+2, y+dy), aCol );
2078         DrawPixel( Point(x+4, y+dy), aCol );
2079         DrawPixel( Point(x+3, y+dy+dy), aCol );
2080     }
2081 }
2082 
ImplDrawGrip(const Rectangle & rRect,sal_Bool bHorz,sal_Bool bLeft)2083 void SplitWindow::ImplDrawGrip( const Rectangle& rRect, sal_Bool bHorz, sal_Bool bLeft )
2084 {
2085     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2086 
2087     if( rRect.IsInside( GetPointerPosPixel() ) )
2088     {
2089         DrawWallpaper( rRect, Wallpaper( Color( COL_WHITE ) ) );
2090         DrawSelectionBackground( rRect, 2, sal_False, sal_False, sal_False );
2091     }
2092 
2093     if( bHorz )
2094     {
2095         int width = (int) (0.5 * rRect.getWidth() + 0.5);
2096         int i = rRect.nLeft + (rRect.getWidth() - width) / 2;
2097         width += i;
2098         const int y = rRect.nTop + 1;
2099         ImplDrawFadeArrow( Point( i-9, y), bHorz, bLeft );
2100         while( i <= width )
2101         {
2102 
2103             DrawPixel( Point(i, y), rStyleSettings.GetDarkShadowColor() );
2104             DrawPixel( Point(i+1, y), rStyleSettings.GetDarkShadowColor() );
2105 
2106             DrawPixel( Point(i, y+1), rStyleSettings.GetShadowColor() );
2107             DrawPixel( Point(i+1, y+1), rStyleSettings.GetShadowColor() );
2108             i+=4;
2109         }
2110         ImplDrawFadeArrow( Point( i, y), bHorz, bLeft );
2111     }
2112     else
2113     {
2114         int height = (int) (0.5 * rRect.getHeight() + 0.5);
2115         int i = rRect.nTop + (rRect.getHeight() - height) / 2;
2116         height += i;
2117         const int x = rRect.nLeft + 1;
2118         ImplDrawFadeArrow( Point( x, i-9), bHorz, bLeft );
2119         while( i <= height )
2120         {
2121 
2122             DrawPixel( Point(x, i), rStyleSettings.GetDarkShadowColor() );
2123             DrawPixel( Point(x+1, i), rStyleSettings.GetDarkShadowColor() );
2124 
2125             DrawPixel( Point(x, i+1), rStyleSettings.GetShadowColor() );
2126             DrawPixel( Point(x+1, i+1), rStyleSettings.GetShadowColor() );
2127             i+=4;
2128         }
2129         ImplDrawFadeArrow( Point( x, i), bHorz, bLeft );
2130     }
2131 }
2132 
ImplDrawFadeIn(sal_Bool bInPaint)2133 void SplitWindow::ImplDrawFadeIn( sal_Bool bInPaint )
2134 {
2135 	if ( mbFadeIn )
2136 	{
2137 		Rectangle		aTempRect;
2138 		Image			aImage;
2139 		ImplGetFadeInRect( aTempRect );
2140 
2141 		sal_Bool bLeft;
2142 		if ( meAlign == WINDOWALIGN_TOP )
2143 			bLeft	= sal_False;
2144 		else if ( meAlign == WINDOWALIGN_BOTTOM )
2145 			bLeft	= sal_True;
2146 		else if ( meAlign == WINDOWALIGN_LEFT )
2147 			bLeft	= sal_False;
2148 		else if ( meAlign == WINDOWALIGN_RIGHT )
2149 			bLeft	= sal_True;
2150 		else
2151 			bLeft	= sal_True;
2152 
2153 		if ( !bInPaint )
2154 			Erase( aTempRect );
2155 
2156 		ImplDrawGrip( aTempRect, (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM), bLeft );
2157 	}
2158 }
2159 
2160 // -----------------------------------------------------------------------
2161 
ImplDrawFadeOut(sal_Bool bInPaint)2162 void SplitWindow::ImplDrawFadeOut( sal_Bool bInPaint )
2163 {
2164 	if ( mbFadeOut )
2165 	{
2166 		Rectangle		aTempRect;
2167 		Image			aImage;
2168 		ImplGetFadeOutRect( aTempRect );
2169 
2170 		sal_Bool bLeft;
2171 		if ( meAlign == WINDOWALIGN_TOP )
2172 			bLeft	= sal_True;
2173 		else if ( meAlign == WINDOWALIGN_BOTTOM )
2174 			bLeft	= sal_False;
2175 		else if ( meAlign == WINDOWALIGN_LEFT )
2176 			bLeft	= sal_True;
2177 		else if ( meAlign == WINDOWALIGN_RIGHT )
2178 			bLeft	= sal_False;
2179 		else
2180 			bLeft	= sal_True;
2181 
2182 		if ( !bInPaint )
2183 			Erase( aTempRect );
2184 
2185 		ImplDrawGrip( aTempRect, (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM), bLeft );
2186 	}
2187 }
2188 
2189 // -----------------------------------------------------------------------
ImplStartSplit(const MouseEvent & rMEvt)2190 void SplitWindow::ImplStartSplit( const MouseEvent& rMEvt )
2191 {
2192 	Point aMousePosPixel = rMEvt.GetPosPixel();
2193 	mnSplitTest = ImplTestSplit( this, aMousePosPixel, mnMouseOff, &mpSplitSet, mnSplitPos );
2194 
2195 	if ( mnSplitTest && !(mnSplitTest & SPLIT_NOSPLIT) )
2196 	{
2197 		ImplSplitItem*	pSplitItem;
2198 		long			nCurMaxSize;
2199 		sal_uInt16			nTemp;
2200 		sal_Bool			bDown;
2201 		sal_Bool			bPropSmaller;
2202 
2203 		mnMouseModifier = rMEvt.GetModifier();
2204 		if ( !(mnMouseModifier & KEY_SHIFT) || (mnSplitPos+1 >= mpSplitSet->mnItems) )
2205 			bPropSmaller = sal_False;
2206 		else
2207 			bPropSmaller = sal_True;
2208 
2209 		// Hier kann noch die maximale Groesse gesetzt werden
2210 		StartSplit();
2211 
2212 		if ( mnMaxSize )
2213 			nCurMaxSize = mnMaxSize;
2214 		else
2215 		{
2216 			Size aSize = GetParent()->GetOutputSizePixel();
2217 			if ( mbHorz )
2218 				nCurMaxSize = aSize.Height();
2219 			else
2220 				nCurMaxSize = aSize.Width();
2221 		}
2222 
2223 		if ( mpSplitSet->mpItems )
2224 		{
2225 			bDown = sal_True;
2226 			if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2227 				bDown = sal_False;
2228 
2229             pSplitItem			= &(mpSplitSet->mpItems[mnSplitPos]);
2230             maDragRect.Left()	= pSplitItem->mnLeft;
2231             maDragRect.Top()	= pSplitItem->mnTop;
2232             maDragRect.Right()	= pSplitItem->mnLeft+pSplitItem->mnWidth-1;
2233             maDragRect.Bottom() = pSplitItem->mnTop+pSplitItem->mnHeight-1;
2234 
2235             if ( mnSplitTest & SPLIT_HORZ )
2236             {
2237                 if ( bDown )
2238                     maDragRect.Right() += mpSplitSet->mnSplitSize;
2239                 else
2240                     maDragRect.Left() -= mpSplitSet->mnSplitSize;
2241             }
2242             else
2243             {
2244                 if ( bDown )
2245                     maDragRect.Bottom() += mpSplitSet->mnSplitSize;
2246                 else
2247                     maDragRect.Top() -= mpSplitSet->mnSplitSize;
2248             }
2249 
2250             if ( mnSplitPos )
2251             {
2252                 nTemp = mnSplitPos;
2253                 while ( nTemp )
2254                 {
2255                     pSplitItem = &(mpSplitSet->mpItems[nTemp-1]);
2256                     if ( pSplitItem->mbFixed )
2257                         break;
2258                     else
2259                     {
2260                         if ( mnSplitTest & SPLIT_HORZ )
2261                         {
2262                             if ( bDown )
2263                                 maDragRect.Left() -= pSplitItem->mnPixSize;
2264                             else
2265                                 maDragRect.Right() += pSplitItem->mnPixSize;
2266                         }
2267                         else
2268                         {
2269                             if ( bDown )
2270                                 maDragRect.Top() -= pSplitItem->mnPixSize;
2271                             else
2272                                 maDragRect.Bottom() += pSplitItem->mnPixSize;
2273                         }
2274                     }
2275                     nTemp--;
2276                 }
2277             }
2278 
2279             if ( (mpSplitSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) && !bPropSmaller )
2280             {
2281                 if ( bDown )
2282                 {
2283                     if ( mbHorz )
2284                         maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
2285                     else
2286                         maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
2287                 }
2288                 else
2289                 {
2290                     if ( mbHorz )
2291                         maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
2292                     else
2293                         maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
2294                 }
2295             }
2296             else
2297             {
2298                 nTemp = mnSplitPos+1;
2299                 while ( nTemp < mpSplitSet->mnItems )
2300                 {
2301                     pSplitItem = &(mpSplitSet->mpItems[nTemp]);
2302                     if ( pSplitItem->mbFixed )
2303                         break;
2304                     else
2305                     {
2306                         if ( mnSplitTest & SPLIT_HORZ )
2307                         {
2308                             if ( bDown )
2309                                 maDragRect.Right() += pSplitItem->mnPixSize;
2310                             else
2311                                 maDragRect.Left() -= pSplitItem->mnPixSize;
2312                         }
2313                         else
2314                         {
2315                             if ( bDown )
2316                                 maDragRect.Bottom() += pSplitItem->mnPixSize;
2317                             else
2318                                 maDragRect.Top() -= pSplitItem->mnPixSize;
2319                         }
2320                     }
2321                     nTemp++;
2322                 }
2323             }
2324 		}
2325 		else
2326 		{
2327             maDragRect.Left()	= mnLeftBorder;
2328             maDragRect.Top()	= mnTopBorder;
2329             maDragRect.Right()	= mnDX-mnRightBorder-1;
2330             maDragRect.Bottom() = mnDY-mnBottomBorder-1;
2331             if ( mbHorz )
2332             {
2333                 if ( mbBottomRight )
2334                     maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
2335                 else
2336                     maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
2337             }
2338             else
2339             {
2340                 if ( mbBottomRight )
2341                     maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
2342                 else
2343                     maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
2344             }
2345 		}
2346 
2347 		StartTracking();
2348 
2349 		mbDragFull = (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0;
2350 
2351 		ImplSplitMousePos( aMousePosPixel );
2352 
2353 		if ( !mbDragFull )
2354 			ImplDrawSplitTracking( this, aMousePosPixel );
2355 		else
2356 		{
2357 			ImplSplitItem*	pItems = mpSplitSet->mpItems;
2358 			sal_uInt16			nItems = mpSplitSet->mnItems;
2359 			mpLastSizes = new long[nItems*2];
2360 			for ( sal_uInt16 i = 0; i < nItems; i++ )
2361 			{
2362 				mpLastSizes[i*2]   = pItems[i].mnSize;
2363 				mpLastSizes[i*2+1] = pItems[i].mnPixSize;
2364 			}
2365 		}
2366 		mnMStartPos = mnMSplitPos;
2367 
2368 		PointerStyle eStyle = POINTER_ARROW;
2369 		if ( mnSplitTest & SPLIT_HORZ )
2370 			eStyle = POINTER_HSPLIT;
2371 		else if ( mnSplitTest & SPLIT_VERT )
2372 			eStyle = POINTER_VSPLIT;
2373 
2374 		Pointer aPtr( eStyle );
2375 		SetPointer( aPtr );
2376 	}
2377 }
2378 
2379 
2380 // -----------------------------------------------------------------------
2381 
StartSplit()2382 void SplitWindow::StartSplit()
2383 {
2384 	maStartSplitHdl.Call( this );
2385 }
2386 
2387 // -----------------------------------------------------------------------
2388 
Split()2389 void SplitWindow::Split()
2390 {
2391 	maSplitHdl.Call( this );
2392 }
2393 
2394 // -----------------------------------------------------------------------
2395 
SplitResize()2396 void SplitWindow::SplitResize()
2397 {
2398 	maSplitResizeHdl.Call( this );
2399 }
2400 
2401 // -----------------------------------------------------------------------
2402 
AutoHide()2403 void SplitWindow::AutoHide()
2404 {
2405 	maAutoHideHdl.Call( this );
2406 }
2407 
2408 // -----------------------------------------------------------------------
2409 
FadeIn()2410 void SplitWindow::FadeIn()
2411 {
2412 	maFadeInHdl.Call( this );
2413 }
2414 
2415 // -----------------------------------------------------------------------
2416 
FadeOut()2417 void SplitWindow::FadeOut()
2418 {
2419 	maFadeOutHdl.Call( this );
2420 }
2421 
2422 // -----------------------------------------------------------------------
2423 
MouseButtonDown(const MouseEvent & rMEvt)2424 void SplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
2425 {
2426 	if ( !rMEvt.IsLeft() || rMEvt.IsMod2() )
2427 	{
2428 		DockingWindow::MouseButtonDown( rMEvt );
2429 		return;
2430 	}
2431 
2432 	Point			aMousePosPixel = rMEvt.GetPosPixel();
2433 	Rectangle		aTestRect;
2434 
2435 	mbFadeNoButtonMode = sal_False;
2436 	ImplGetAutoHideRect( aTestRect, sal_True );
2437 	if ( aTestRect.IsInside( aMousePosPixel ) )
2438 	{
2439 		mbAutoHideDown = sal_True;
2440 		mbAutoHidePressed = sal_True;
2441 		ImplDrawAutoHide( sal_False );
2442 	}
2443 	else
2444 	{
2445 		ImplGetFadeOutRect( aTestRect, sal_True );
2446 		if ( aTestRect.IsInside( aMousePosPixel ) )
2447 		{
2448 			mbFadeOutDown = sal_True;
2449 			mbFadeOutPressed = sal_True;
2450 			ImplDrawFadeOut( sal_False );
2451 		}
2452 		else
2453 		{
2454 			ImplGetFadeInRect( aTestRect, sal_True );
2455 			if ( aTestRect.IsInside( aMousePosPixel ) )
2456 			{
2457 				mbFadeInDown = sal_True;
2458 				mbFadeInPressed = sal_True;
2459 				ImplDrawFadeIn( sal_False );
2460 			}
2461 			else if ( !aTestRect.IsEmpty() && !(mnWinStyle & WB_SIZEABLE) )
2462 			{
2463 				mbFadeNoButtonMode = sal_True;
2464 				FadeIn();
2465 				return;
2466 			}
2467 		}
2468 	}
2469 
2470 	if ( mbAutoHideDown || mbFadeInDown || mbFadeOutDown )
2471 		StartTracking();
2472 	else
2473 		ImplStartSplit( rMEvt );
2474 }
2475 
2476 // -----------------------------------------------------------------------
2477 
MouseMove(const MouseEvent & rMEvt)2478 void SplitWindow::MouseMove( const MouseEvent& rMEvt )
2479 {
2480 	if ( !IsTracking() )
2481 	{
2482 		Point			aPos = rMEvt.GetPosPixel();
2483 		long			nTemp;
2484 		ImplSplitSet*	pTempSplitSet;
2485 		sal_uInt16			nTempSplitPos;
2486 		sal_uInt16			nSplitTest = ImplTestSplit( this, aPos, nTemp, &pTempSplitSet, nTempSplitPos );
2487 		PointerStyle	eStyle = POINTER_ARROW;
2488 		Rectangle		aAutoHideRect;
2489 		Rectangle		aFadeInRect;
2490 		Rectangle		aFadeOutRect;
2491 
2492 		ImplGetAutoHideRect( aAutoHideRect );
2493 		ImplGetFadeInRect( aFadeInRect );
2494 		ImplGetFadeOutRect( aFadeOutRect );
2495 		if ( !aAutoHideRect.IsInside( aPos ) &&
2496 			 !aFadeInRect.IsInside( aPos ) &&
2497 			 !aFadeOutRect.IsInside( aPos ) )
2498 		{
2499 			if ( nSplitTest && !(nSplitTest & SPLIT_NOSPLIT) )
2500 			{
2501 				if ( nSplitTest & SPLIT_HORZ )
2502 					eStyle = POINTER_HSPLIT;
2503 				else if ( nSplitTest & SPLIT_VERT )
2504 					eStyle = POINTER_VSPLIT;
2505 			}
2506 		}
2507 
2508 		Pointer aPtr( eStyle );
2509 		SetPointer( aPtr );
2510 	}
2511 }
2512 
2513 // -----------------------------------------------------------------------
2514 
Tracking(const TrackingEvent & rTEvt)2515 void SplitWindow::Tracking( const TrackingEvent& rTEvt )
2516 {
2517 	Point aMousePosPixel = rTEvt.GetMouseEvent().GetPosPixel();
2518 
2519 	if ( mbAutoHideDown )
2520 	{
2521 		if ( rTEvt.IsTrackingEnded() )
2522 		{
2523 			mbAutoHideDown = sal_False;
2524 			if ( mbAutoHidePressed )
2525 			{
2526 				mbAutoHidePressed = sal_False;
2527 
2528 				if ( !rTEvt.IsTrackingCanceled() )
2529 				{
2530 					mbAutoHideIn = !mbAutoHideIn;
2531 					ImplDrawAutoHide( sal_False );
2532 					AutoHide();
2533 				}
2534 				else
2535 					ImplDrawAutoHide( sal_False );
2536 			}
2537 		}
2538 		else
2539 		{
2540 			Rectangle aTestRect;
2541 			ImplGetAutoHideRect( aTestRect, sal_True );
2542 			sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2543 			if ( bNewPressed != mbAutoHidePressed )
2544 			{
2545 				mbAutoHidePressed = bNewPressed;
2546 				ImplDrawAutoHide( sal_False );
2547 			}
2548 		}
2549 	}
2550 	else if ( mbFadeInDown )
2551 	{
2552 		if ( rTEvt.IsTrackingEnded() )
2553 		{
2554 			mbFadeInDown = sal_False;
2555 			if ( mbFadeInPressed )
2556 			{
2557 				mbFadeInPressed = sal_False;
2558 				ImplDrawFadeIn( sal_False );
2559 
2560 				if ( !rTEvt.IsTrackingCanceled() )
2561 					FadeIn();
2562 			}
2563 		}
2564 		else
2565 		{
2566 			Rectangle aTestRect;
2567 			ImplGetFadeInRect( aTestRect, sal_True );
2568 			sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2569 			if ( bNewPressed != mbFadeInPressed )
2570 			{
2571 				mbFadeInPressed = bNewPressed;
2572 				ImplDrawFadeIn( sal_False );
2573 			}
2574 		}
2575 	}
2576 	else if ( mbFadeOutDown )
2577 	{
2578 		if ( rTEvt.IsTrackingEnded() )
2579 		{
2580 			mbFadeOutDown = sal_False;
2581 			if ( mbFadeOutPressed )
2582 			{
2583 				mbFadeOutPressed = sal_False;
2584 				ImplDrawFadeOut( sal_False );
2585 
2586 				if ( !rTEvt.IsTrackingCanceled() )
2587 					FadeOut();
2588 			}
2589 		}
2590 		else
2591 		{
2592 			Rectangle aTestRect;
2593 			ImplGetFadeOutRect( aTestRect, sal_True );
2594 			sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2595 			if ( bNewPressed == sal_False )
2596 			{
2597 				mbFadeOutPressed = bNewPressed;
2598 				ImplDrawFadeOut( sal_False );
2599 
2600                 // We need a mouseevent with a position inside the button for the
2601                 // ImplStartSplit function!
2602                 MouseEvent aOrgMEvt = rTEvt.GetMouseEvent();
2603                 MouseEvent aNewMEvt = MouseEvent( aTestRect.Center(), aOrgMEvt.GetClicks(),
2604                                                   aOrgMEvt.GetMode(), aOrgMEvt.GetButtons(),
2605                                                   aOrgMEvt.GetModifier() );
2606 
2607                 ImplStartSplit( aNewMEvt );
2608                 mbFadeOutDown = sal_False;
2609 			}
2610 		}
2611 	}
2612 	else
2613 	{
2614 		ImplSplitMousePos( aMousePosPixel );
2615 		sal_Bool bSplit = sal_True;
2616 		if ( mbDragFull )
2617 		{
2618 			if ( rTEvt.IsTrackingEnded() )
2619 			{
2620 				if ( rTEvt.IsTrackingCanceled() )
2621 				{
2622 					ImplSplitItem*	pItems = mpSplitSet->mpItems;
2623 					sal_uInt16			nItems = mpSplitSet->mnItems;
2624 					for ( sal_uInt16 i = 0; i < nItems; i++ )
2625 					{
2626 						pItems[i].mnSize	 = mpLastSizes[i*2];
2627 						pItems[i].mnPixSize  = mpLastSizes[i*2+1];
2628 					}
2629 					ImplUpdate();
2630 					Split();
2631 				}
2632 				bSplit = sal_False;
2633 			}
2634 		}
2635 		else
2636 		{
2637 			if ( rTEvt.IsTrackingEnded() )
2638 			{
2639 				HideTracking();
2640 				bSplit = !rTEvt.IsTrackingCanceled();
2641 			}
2642 			else
2643 			{
2644 				ImplDrawSplitTracking( this, aMousePosPixel );
2645 				bSplit = sal_False;
2646 			}
2647 		}
2648 
2649 		if ( bSplit )
2650 		{
2651 			sal_Bool	bPropSmaller = (mnMouseModifier & KEY_SHIFT) ? sal_True : sal_False;
2652 			sal_Bool	bPropGreater = (mnMouseModifier & KEY_MOD1) ? sal_True : sal_False;
2653 			long	nDelta = mnMSplitPos-mnMStartPos;
2654 
2655 			if ( (mnSplitTest & SPLIT_WINDOW) && !mpMainSet->mpItems )
2656 			{
2657 				if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2658 					nDelta *= -1;
2659 				ImplSetWindowSize( nDelta );
2660 			}
2661 			else
2662 			{
2663 				long nNewSize = mpSplitSet->mpItems[mnSplitPos].mnPixSize;
2664 				if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2665 					nNewSize -= nDelta;
2666 				else
2667 					nNewSize += nDelta;
2668 				SplitItem( mpSplitSet->mpItems[mnSplitPos].mnId, nNewSize,
2669 						   bPropSmaller, bPropGreater );
2670 			}
2671 
2672 			Split();
2673 
2674 			if ( mbDragFull )
2675 			{
2676 				Update();
2677 				mnMStartPos = mnMSplitPos;
2678 			}
2679 		}
2680 
2681 		if ( rTEvt.IsTrackingEnded() )
2682 		{
2683 			if ( mpLastSizes )
2684 				delete mpLastSizes;
2685 			mpLastSizes 	= NULL;
2686 			mpSplitSet		= NULL;
2687 			mnMouseOff		= 0;
2688 			mnMStartPos 	= 0;
2689 			mnMSplitPos 	= 0;
2690 			mnMouseModifier = 0;
2691 			mnSplitTest 	= 0;
2692 			mnSplitPos		= 0;
2693 		}
2694 	}
2695 }
2696 
2697 // -----------------------------------------------------------------------
2698 
PreNotify(NotifyEvent & rNEvt)2699 long SplitWindow::PreNotify( NotifyEvent& rNEvt )
2700 {
2701 	const MouseEvent* pMouseEvt = NULL;
2702 
2703     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2704     {
2705         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2706         {
2707             // trigger redraw if mouse over state has changed
2708             Rectangle aFadeInRect;
2709             Rectangle aFadeOutRect;
2710 		    ImplGetFadeInRect( aFadeInRect );
2711 		    ImplGetFadeOutRect( aFadeOutRect );
2712 
2713 		    if ( aFadeInRect.IsInside( GetPointerPosPixel() ) != aFadeInRect.IsInside( GetLastPointerPosPixel() ) )
2714                 Invalidate( aFadeInRect );
2715 		    if ( aFadeOutRect.IsInside( GetPointerPosPixel() ) != aFadeOutRect.IsInside( GetLastPointerPosPixel() ) )
2716                 Invalidate( aFadeOutRect );
2717 
2718             if( pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
2719             {
2720                 Invalidate( aFadeInRect );
2721                 Invalidate( aFadeOutRect );
2722             }
2723         }
2724     }
2725     return Window::PreNotify( rNEvt );
2726 }
2727 
2728 // -----------------------------------------------------------------------
2729 
Paint(const Rectangle &)2730 void SplitWindow::Paint( const Rectangle& )
2731 {
2732 	if ( mnWinStyle & WB_BORDER )
2733 		ImplDrawBorder( this );
2734 
2735 	ImplDrawBorderLine( this );
2736 	ImplDrawFadeOut( sal_True );
2737 	ImplDrawFadeIn( sal_True );
2738 	ImplDrawAutoHide( sal_True );
2739 
2740 	// FrameSet-Hintergruende zeichnen
2741 	ImplDrawBack( this, mpMainSet );
2742 
2743 	// Splitter zeichnen
2744 	if ( !(mnWinStyle & WB_NOSPLITDRAW) )
2745 		ImplDrawSplit( this, mpMainSet, mbHorz, !mbBottomRight );
2746 }
2747 
2748 // -----------------------------------------------------------------------
2749 
Move()2750 void SplitWindow::Move()
2751 {
2752 	DockingWindow::Move();
2753 }
2754 
2755 // -----------------------------------------------------------------------
2756 
Resize()2757 void SplitWindow::Resize()
2758 {
2759 	Size aSize = GetOutputSizePixel();
2760 	mnDX = aSize.Width();
2761 	mnDY = aSize.Height();
2762 
2763 	ImplUpdate();
2764 	Invalidate();
2765 }
2766 
2767 // -----------------------------------------------------------------------
2768 
RequestHelp(const HelpEvent & rHEvt)2769 void SplitWindow::RequestHelp( const HelpEvent& rHEvt )
2770 {
2771 	// no keyboard help for splitwin
2772 	if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) && !rHEvt.KeyboardActivated() )
2773 	{
2774 		Point		aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
2775 		Rectangle	aHelpRect;
2776 		sal_uInt16		nHelpResId = 0;
2777 
2778 		ImplGetAutoHideRect( aHelpRect, sal_True );
2779 		if ( aHelpRect.IsInside( aMousePosPixel ) )
2780 		{
2781 			if ( mbAutoHideIn )
2782 				nHelpResId = SV_HELPTEXT_SPLITFIXED;
2783 			else
2784 				nHelpResId = SV_HELPTEXT_SPLITFLOATING;
2785 		}
2786 		else
2787 		{
2788 			ImplGetFadeInRect( aHelpRect, sal_True );
2789 			if ( aHelpRect.IsInside( aMousePosPixel ) )
2790 				nHelpResId = SV_HELPTEXT_FADEIN;
2791 			else
2792 			{
2793 				ImplGetFadeOutRect( aHelpRect, sal_True );
2794 				if ( aHelpRect.IsInside( aMousePosPixel ) )
2795 					nHelpResId = SV_HELPTEXT_FADEOUT;
2796 			}
2797 		}
2798 
2799 		// Rechteck ermitteln
2800 		if ( nHelpResId )
2801 		{
2802 			Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
2803 			aHelpRect.Left()   = aPt.X();
2804 			aHelpRect.Top()    = aPt.Y();
2805 			aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
2806 			aHelpRect.Right()  = aPt.X();
2807 			aHelpRect.Bottom() = aPt.Y();
2808 
2809 			// Text ermitteln und anzeigen
2810 			XubString aStr;
2811 			ResMgr* pResMgr = ImplGetResMgr();
2812 			if( pResMgr )
2813 				aStr = XubString( ResId( nHelpResId, *pResMgr ) );
2814 			if ( rHEvt.GetMode() & HELPMODE_BALLOON )
2815 				Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aStr );
2816 			else
2817 				Help::ShowQuickHelp( this, aHelpRect, aStr );
2818 			return;
2819 		}
2820 	}
2821 
2822 	DockingWindow::RequestHelp( rHEvt );
2823 }
2824 
2825 // -----------------------------------------------------------------------
2826 
StateChanged(StateChangedType nType)2827 void SplitWindow::StateChanged( StateChangedType nType )
2828 {
2829 	if ( nType == STATE_CHANGE_INITSHOW )
2830 	{
2831 		if ( IsUpdateMode() )
2832 			ImplCalcLayout();
2833 	}
2834 	else if ( nType == STATE_CHANGE_UPDATEMODE )
2835 	{
2836 		if ( IsUpdateMode() && IsReallyShown() )
2837 			ImplCalcLayout();
2838 	}
2839 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2840 	{
2841 		ImplInitSettings();
2842 		Invalidate();
2843 	}
2844 
2845 	DockingWindow::StateChanged( nType );
2846 }
2847 
2848 // -----------------------------------------------------------------------
2849 
DataChanged(const DataChangedEvent & rDCEvt)2850 void SplitWindow::DataChanged( const DataChangedEvent& rDCEvt )
2851 {
2852 	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2853 		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2854 	{
2855 		ImplInitSettings();
2856 		Invalidate();
2857 	}
2858 	else
2859 		DockingWindow::DataChanged( rDCEvt );
2860 }
2861 
2862 // -----------------------------------------------------------------------
2863 
InsertItem(sal_uInt16 nId,Window * pWindow,long nSize,sal_uInt16 nPos,sal_uInt16 nSetId,SplitWindowItemBits nBits)2864 void SplitWindow::InsertItem( sal_uInt16 nId, Window* pWindow, long nSize,
2865 							  sal_uInt16 nPos, sal_uInt16 nSetId,
2866 							  SplitWindowItemBits nBits )
2867 {
2868 #ifdef DBG_UTIL
2869 	sal_uInt16 nDbgDummy;
2870 	DBG_ASSERT( ImplFindSet( mpMainSet, nSetId ), "SplitWindow::InsertItem() - Set not exists" );
2871 	DBG_ASSERT( !ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::InsertItem() - Id already exists" );
2872 #endif
2873 
2874 	// Size has to be at least 1.
2875 	if ( nSize < 1 )
2876 		nSize = 1;
2877 
2878 	ImplSplitSet* pSet		 = ImplFindSet( mpMainSet, nSetId );
2879 	ImplSplitSet* pNewSet;
2880 	ImplSplitItem* pItem;
2881 
2882 	// Make room for the new item.
2883 	if ( nPos > pSet->mnItems )
2884 		nPos = pSet->mnItems;
2885 	ImplSplitItem* pNewItems = new ImplSplitItem[pSet->mnItems+1];
2886 	if ( nPos )
2887 		memcpy( pNewItems, pSet->mpItems, sizeof( ImplSplitItem )*nPos );
2888 	if ( nPos < pSet->mnItems )
2889 		memcpy( pNewItems+nPos+1, pSet->mpItems+nPos, sizeof( ImplSplitItem )*(pSet->mnItems-nPos) );
2890 	delete[] pSet->mpItems;
2891 	pSet->mpItems = pNewItems;
2892 	pSet->mnItems++;
2893 	pSet->mbCalcPix = sal_True;
2894 
2895 	// Create and initialize item.
2896 	pItem			= &(pSet->mpItems[nPos]);
2897 	memset( pItem, 0, sizeof( ImplSplitItem ) );
2898 	pItem->mnSize	= nSize;
2899 	pItem->mnId 	= nId;
2900 	pItem->mnBits	= nBits;
2901 	pItem->mnMinSize=-1;
2902 	pItem->mnMaxSize=-1;
2903 
2904 	if ( pWindow )
2905 	{
2906 		pItem->mpWindow 		= pWindow;
2907 		pItem->mpOrgParent		= pWindow->GetParent();
2908 
2909 		// Attach window to SplitWindow.
2910 		pWindow->Hide();
2911 		pWindow->SetParent( this );
2912 	}
2913 	else
2914 	{
2915 		pNewSet 				= new ImplSplitSet;
2916 		pNewSet->mpItems		= NULL;
2917 		pNewSet->mpWallpaper	= NULL;
2918 		pNewSet->mpBitmap		= NULL;
2919 		pNewSet->mnLastSize 	= 0;
2920 		pNewSet->mnItems		= 0;
2921 		pNewSet->mnId			= nId;
2922 		pNewSet->mnSplitSize	= pSet->mnSplitSize;
2923 		pNewSet->mbCalcPix		= sal_True;
2924 
2925 		pItem->mpSet			= pNewSet;
2926 	}
2927 
2928 	ImplUpdate();
2929 }
2930 
2931 // -----------------------------------------------------------------------
2932 
InsertItem(sal_uInt16 nId,long nSize,sal_uInt16 nPos,sal_uInt16 nSetId,SplitWindowItemBits nBits)2933 void SplitWindow::InsertItem( sal_uInt16 nId, long nSize,
2934 							  sal_uInt16 nPos, sal_uInt16 nSetId,
2935 							  SplitWindowItemBits nBits )
2936 {
2937 	InsertItem( nId, NULL, nSize, nPos, nSetId, nBits );
2938 }
2939 
2940 // -----------------------------------------------------------------------
2941 
MoveItem(sal_uInt16 nId,sal_uInt16 nNewPos,sal_uInt16 nNewSetId)2942 void SplitWindow::MoveItem( sal_uInt16 nId, sal_uInt16 nNewPos, sal_uInt16 nNewSetId )
2943 {
2944 #ifdef DBG_UTIL
2945 	sal_uInt16 nDbgDummy;
2946 	DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::MoveItem() - Id not found" );
2947 	DBG_ASSERT( ImplFindSet( mpMainSet, nNewSetId ), "SplitWindow::MoveItem() - Set not exists" );
2948 #endif
2949 
2950 	sal_uInt16			nPos;
2951 	ImplSplitSet*	 pNewSet = ImplFindSet( mpMainSet, nNewSetId );
2952 	ImplSplitSet*	 pSet	 = ImplFindItem( mpMainSet, nId, nPos );
2953 	ImplSplitItem	 aTempItem;
2954 
2955 	if ( pNewSet == pSet )
2956 	{
2957 		if ( nNewPos >= pNewSet->mnItems )
2958 			nNewPos = pNewSet->mnItems-1;
2959 		if ( nPos != nNewPos )
2960 		{
2961 			memcpy( &aTempItem, &(pSet->mpItems[nPos]), sizeof( aTempItem ) );
2962 			if ( nPos < nNewPos )
2963 			{
2964 				memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
2965 						 (nNewPos-nPos)*sizeof( ImplSplitItem ) );
2966 			}
2967 			else
2968 			{
2969 				memmove( pSet->mpItems+nNewPos+1, pSet->mpItems+nNewPos,
2970 						 (nPos-nNewPos)*sizeof( ImplSplitItem ) );
2971 			}
2972 			memcpy( &(pSet->mpItems[nNewPos]), &aTempItem, sizeof( aTempItem ) );
2973 
2974 			ImplUpdate();
2975 		}
2976 	}
2977 	else
2978 	{
2979 		if ( nNewPos >= pNewSet->mnItems )
2980 			nNewPos = pNewSet->mnItems;
2981 		memcpy( &aTempItem, &(pSet->mpItems[nPos]), sizeof( aTempItem ) );
2982 		pSet->mnItems--;
2983 		pSet->mbCalcPix = sal_True;
2984 		if ( pSet->mnItems )
2985 		{
2986 			memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
2987 					 (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
2988 		}
2989 		else
2990 		{
2991 			delete[] pSet->mpItems;
2992 			pSet->mpItems = NULL;
2993 		}
2994 		ImplSplitItem* pNewItems = new ImplSplitItem[pNewSet->mnItems+1];
2995 		if ( nNewPos )
2996 			memcpy( pNewItems, pNewSet->mpItems, sizeof( ImplSplitItem )*nNewPos );
2997 		if ( nNewPos < pNewSet->mnItems )
2998 		{
2999 			memcpy( pNewItems+nNewPos+1, pNewSet->mpItems+nNewPos,
3000 					sizeof( ImplSplitItem )*(pNewSet->mnItems-nNewPos) );
3001 		}
3002 		delete[] pNewSet->mpItems;
3003 		pNewSet->mpItems = pNewItems;
3004 		pNewSet->mnItems++;
3005 		pNewSet->mbCalcPix = sal_True;
3006 		memcpy( &(pNewSet->mpItems[nNewPos]), &aTempItem, sizeof( aTempItem ) );
3007 		ImplUpdate();
3008 	}
3009 }
3010 
3011 // -----------------------------------------------------------------------
3012 
RemoveItem(sal_uInt16 nId,sal_Bool bHide)3013 void SplitWindow::RemoveItem( sal_uInt16 nId, sal_Bool bHide )
3014 {
3015 #ifdef DBG_UTIL
3016 	sal_uInt16 nDbgDummy;
3017 	DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::RemoveItem() - Id not found" );
3018 #endif
3019 
3020 	// Set suchen
3021 	sal_uInt16			nPos;
3022 	ImplSplitSet*	 pSet	 = ImplFindItem( mpMainSet, nId, nPos );
3023 	ImplSplitItem*	 pItem	 = &(pSet->mpItems[nPos]);
3024 	Window* 		pWindow = pItem->mpWindow;
3025 	Window* 		pOrgParent = pItem->mpOrgParent;
3026 
3027 	// Evtl. Set loeschen
3028 	if ( !pWindow )
3029 		ImplDeleteSet( pItem->mpSet );
3030 
3031 	// Item entfernen
3032 	pSet->mnItems--;
3033 	pSet->mbCalcPix = sal_True;
3034 	if ( pSet->mnItems )
3035 	{
3036 		memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
3037 				 (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
3038 	}
3039 	else
3040 	{
3041 		delete[] pSet->mpItems;
3042 		pSet->mpItems = NULL;
3043 	}
3044 
3045 	ImplUpdate();
3046 
3047 	// Window erst hier loeschen, um weniger Paints zu haben
3048 	if ( pWindow )
3049 	{
3050 		// Fenster wieder herstellen
3051 		if ( bHide || (pOrgParent != this) )
3052 		{
3053 			pWindow->Hide();
3054 			pWindow->SetParent( pOrgParent );
3055 		}
3056 	}
3057 }
3058 
3059 // -----------------------------------------------------------------------
3060 
Clear()3061 void SplitWindow::Clear()
3062 {
3063 	// Alle Sets loeschen
3064 	ImplDeleteSet( mpMainSet );
3065 
3066 	// Main-Set wieder anlegen
3067 	mpMainSet					= new ImplSplitSet;
3068 	mpMainSet->mpItems			= NULL;
3069 	mpMainSet->mpWallpaper		= NULL;
3070 	mpMainSet->mpBitmap 		= NULL;
3071 	mpMainSet->mnLastSize		= 0;
3072 	mpMainSet->mnItems			= 0;
3073 	mpMainSet->mnId 			= 0;
3074 	mpMainSet->mnSplitSize		= SPLITWIN_SPLITSIZE;
3075 	mpMainSet->mbCalcPix		= sal_True;
3076 	if ( mnWinStyle & WB_NOSPLITDRAW )
3077 		mpMainSet->mnSplitSize -= 2;
3078 	mpBaseSet					= mpMainSet;
3079 
3080 	// Und neu invalidieren
3081 	ImplUpdate();
3082 }
3083 
3084 // -----------------------------------------------------------------------
3085 
SetBaseSet(sal_uInt16 nSetId)3086 void SplitWindow::SetBaseSet( sal_uInt16 nSetId )
3087 {
3088 	mpBaseSet = ImplFindSet( mpMainSet, nSetId );
3089 }
3090 
3091 // -----------------------------------------------------------------------
3092 
GetBaseSet() const3093 sal_uInt16 SplitWindow::GetBaseSet() const
3094 {
3095 	return mpBaseSet->mnId;
3096 }
3097 
3098 // -----------------------------------------------------------------------
3099 
SetSplitSize(sal_uInt16 nSetId,long nSplitSize,sal_Bool bWithChilds)3100 void SplitWindow::SetSplitSize( sal_uInt16 nSetId, long nSplitSize,
3101 								sal_Bool bWithChilds )
3102 {
3103 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3104 	if ( pSet )
3105 	{
3106 		if ( bWithChilds )
3107 			ImplSetSplitSize( pSet, nSplitSize );
3108 		else
3109 			pSet->mnSplitSize = nSplitSize;
3110 	}
3111 	ImplUpdate();
3112 }
3113 
3114 // -----------------------------------------------------------------------
3115 
GetSplitSize(sal_uInt16 nSetId) const3116 long SplitWindow::GetSplitSize( sal_uInt16 nSetId ) const
3117 {
3118 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3119 	if ( pSet )
3120 		return pSet->mnSplitSize;
3121 	else
3122 		return 0;
3123 }
3124 
3125 // -----------------------------------------------------------------------
3126 
SetItemBackground(sal_uInt16 nSetId)3127 void SplitWindow::SetItemBackground( sal_uInt16 nSetId )
3128 {
3129 	Wallpaper aWall;
3130 	SetItemBackground( nSetId, aWall );
3131 }
3132 
3133 // -----------------------------------------------------------------------
3134 
SetItemBackground(sal_uInt16 nSetId,const Wallpaper & rWallpaper)3135 void SplitWindow::SetItemBackground( sal_uInt16 nSetId, const Wallpaper& rWallpaper )
3136 {
3137 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3138 
3139 	if ( pSet )
3140 	{
3141 		sal_Bool bUpdate = sal_True;
3142 
3143 		if ( rWallpaper.GetStyle() == WALLPAPER_NULL )
3144 		{
3145 			if ( pSet->mpWallpaper )
3146 			{
3147 				delete pSet->mpWallpaper;
3148 				pSet->mpWallpaper = NULL;
3149 			}
3150 			else
3151 				bUpdate = sal_False;
3152 		}
3153 		else
3154 		{
3155 			// Ab jetzt muss immer invalidiert werden
3156 			mbInvalidate = sal_True;
3157 
3158 			if ( !pSet->mpWallpaper )
3159 				pSet->mpWallpaper = new Wallpaper( rWallpaper );
3160 			else
3161 				*(pSet->mpWallpaper) = rWallpaper;
3162 		}
3163 
3164 		// Beim MainSet koennen wir den Background umsetzen
3165 		if ( pSet == mpMainSet )
3166 			ImplInitSettings();
3167 
3168 		if ( bUpdate )
3169 			ImplUpdateSet( pSet );
3170 	}
3171 }
3172 
3173 // -----------------------------------------------------------------------
3174 
GetItemBackground(sal_uInt16 nSetId) const3175 Wallpaper SplitWindow::GetItemBackground( sal_uInt16 nSetId ) const
3176 {
3177 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3178 
3179 	if ( pSet && pSet->mpWallpaper )
3180 		return *(pSet->mpWallpaper);
3181 	else
3182 	{
3183 		Wallpaper aWall;
3184 		return aWall;
3185 	}
3186 }
3187 
3188 // -----------------------------------------------------------------------
3189 
IsItemBackground(sal_uInt16 nSetId) const3190 sal_Bool SplitWindow::IsItemBackground( sal_uInt16 nSetId ) const
3191 {
3192 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3193 
3194 	if ( pSet && pSet->mpWallpaper )
3195 		return sal_True;
3196 	else
3197 		return sal_False;
3198 }
3199 
3200 // -----------------------------------------------------------------------
3201 
SetItemBitmap(sal_uInt16 nSetId,const Bitmap & rBitmap)3202 void SplitWindow::SetItemBitmap( sal_uInt16 nSetId, const Bitmap& rBitmap )
3203 {
3204 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3205 
3206 	if ( pSet )
3207 	{
3208 		sal_Bool bUpdate = sal_True;
3209 
3210 		if ( !rBitmap )
3211 		{
3212 			if ( pSet->mpBitmap )
3213 			{
3214 				delete pSet->mpBitmap;
3215 				pSet->mpBitmap = NULL;
3216 			}
3217 			else
3218 				bUpdate = sal_False;
3219 		}
3220 		else
3221 		{
3222 			// Ab jetzt muss immer invalidiert werden
3223 			mbInvalidate = sal_True;
3224 
3225 			if ( !pSet->mpBitmap )
3226 				pSet->mpBitmap = new Bitmap( rBitmap );
3227 			else
3228 				*(pSet->mpBitmap) = rBitmap;
3229 		}
3230 
3231 		// Beim MainSet koennen wir den Background umsetzen
3232 		if ( pSet == mpMainSet )
3233 			ImplInitSettings();
3234 
3235 		if ( bUpdate )
3236 			ImplUpdateSet( pSet );
3237 	}
3238 }
3239 
3240 // -----------------------------------------------------------------------
3241 
GetItemBitmap(sal_uInt16 nSetId) const3242 Bitmap SplitWindow::GetItemBitmap( sal_uInt16 nSetId ) const
3243 {
3244 	ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
3245 
3246 	if ( pSet && pSet->mpBitmap )
3247 		return *(pSet->mpBitmap);
3248 	else
3249 	{
3250 		Bitmap aBitmap;
3251 		return aBitmap;
3252 	}
3253 }
3254 
3255 // -----------------------------------------------------------------------
3256 
SplitItem(sal_uInt16 nId,long nNewSize,sal_Bool bPropSmall,sal_Bool bPropGreat)3257 void SplitWindow::SplitItem( sal_uInt16 nId, long nNewSize,
3258 							 sal_Bool bPropSmall, sal_Bool bPropGreat )
3259 {
3260 	sal_uInt16			nItems;
3261 	sal_uInt16			nPos;
3262 	sal_uInt16			nMin;
3263 	sal_uInt16			nMax;
3264 	sal_uInt16			i;
3265 	sal_uInt16			n;
3266 	long			nDelta;
3267 	long			nTempDelta;
3268 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3269 	ImplSplitItem*	pItems;
3270 
3271 	if ( !pSet )
3272 		return;
3273 
3274 	nItems = pSet->mnItems;
3275 	pItems = pSet->mpItems;
3276 
3277 	// When there is an explicit minimum or maximum size then move nNewSize
3278 	// into that range (when it is not yet already in it.)
3279 	nNewSize = ValidateSize(nNewSize, pItems[nPos]);
3280 
3281 	if ( mbCalc )
3282 	{
3283 		pItems[nPos].mnSize = nNewSize;
3284 		return;
3285 	}
3286 
3287 	nDelta = nNewSize-pItems[nPos].mnPixSize;
3288 	if ( !nDelta )
3289 		return;
3290 
3291 	// Bereich berechnen, der beim Splitten betroffen sein kann
3292 	nMin = 0;
3293 	nMax = nItems;
3294 	for ( i = 0; i < nItems; i++ )
3295 	{
3296 		if ( pItems[i].mbFixed )
3297 		{
3298 			if ( i < nPos )
3299 				nMin = i+1;
3300 			else
3301 				nMax = i;
3302 		}
3303 	}
3304 
3305 	// Wenn das Fenster sizeable ist, wird das TopSet anders behandelt
3306 	sal_Bool bSmall = sal_True;
3307 	sal_Bool bGreat = sal_True;
3308 	if ( (pSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) )
3309 	{
3310 		if ( nPos < pSet->mnItems-1 )
3311 		{
3312 			if ( !((bPropSmall && bPropGreat) ||
3313 				   ((nDelta > 0) && bPropSmall) ||
3314 				   ((nDelta < 0) && bPropGreat)) )
3315 			{
3316 				if ( nDelta < 0 )
3317 					bGreat = sal_False;
3318 				else
3319 					bSmall = sal_False;
3320 			}
3321 		}
3322 		else
3323 		{
3324 			if ( nDelta < 0 )
3325 				bGreat = sal_False;
3326 			else
3327 				bSmall = sal_False;
3328 		}
3329 	}
3330 	else if ( nPos >= nMax )
3331 	{
3332 		bSmall = sal_False;
3333 		bGreat = sal_False;
3334 	}
3335 	else if ( nPos && (nPos >= pSet->mnItems-1) )
3336 	{
3337 		nPos--;
3338 		nDelta *= -1;
3339 		sal_Bool bTemp = bPropSmall;
3340 		bPropSmall = bPropGreat;
3341 		bPropGreat = bTemp;
3342 	}
3343 
3344 	// Jetzt die Fenster splitten
3345 	if ( nDelta < 0 )
3346 	{
3347 		if ( bGreat )
3348 		{
3349 			if ( bPropGreat )
3350 			{
3351 				nTempDelta = nDelta;
3352 				do
3353 				{
3354 					n = nPos+1;
3355 					do
3356 					{
3357 						if ( nTempDelta )
3358 						{
3359 							pItems[n].mnPixSize++;
3360 							nTempDelta++;
3361 						}
3362 						n++;
3363 					}
3364 					while ( n < nMax );
3365 				}
3366 				while ( nTempDelta );
3367 			}
3368 			else
3369 				pItems[nPos+1].mnPixSize -= nDelta;
3370 		}
3371 
3372 		if ( bSmall )
3373 		{
3374 			if ( bPropSmall )
3375 			{
3376 				do
3377 				{
3378 					n = nPos+1;
3379 					do
3380 					{
3381 						if ( nDelta && pItems[n-1].mnPixSize )
3382 						{
3383 							pItems[n-1].mnPixSize--;
3384 							nDelta++;
3385 						}
3386 
3387 						n--;
3388 					}
3389 					while ( n > nMin );
3390 				}
3391 				while ( nDelta );
3392 			}
3393 			else
3394 			{
3395 				n = nPos+1;
3396 				do
3397 				{
3398 					if ( pItems[n-1].mnPixSize+nDelta < 0 )
3399 					{
3400 						nDelta += pItems[n-1].mnPixSize;
3401 						pItems[n-1].mnPixSize = 0;
3402 					}
3403 					else
3404 					{
3405 						pItems[n-1].mnPixSize += nDelta;
3406 						break;
3407 					}
3408 					n--;
3409 				}
3410 				while ( n > nMin );
3411 			}
3412 		}
3413 	}
3414 	else
3415 	{
3416 		if ( bGreat )
3417 		{
3418 			if ( bPropGreat )
3419 			{
3420 				nTempDelta = nDelta;
3421 				do
3422 				{
3423 					n = nPos+1;
3424 					do
3425 					{
3426 						if ( nTempDelta )
3427 						{
3428 							pItems[n-1].mnPixSize++;
3429 							nTempDelta--;
3430 						}
3431 						n--;
3432 					}
3433 					while ( n > nMin );
3434 				}
3435 				while ( nTempDelta );
3436 			}
3437 			else
3438 				pItems[nPos].mnPixSize += nDelta;
3439 		}
3440 
3441 		if ( bSmall )
3442 		{
3443 			if ( bPropSmall )
3444 			{
3445 				do
3446 				{
3447 					n = nPos+1;
3448 					do
3449 					{
3450 						if ( nDelta && pItems[n].mnPixSize )
3451 						{
3452 							pItems[n].mnPixSize--;
3453 							nDelta--;
3454 						}
3455 
3456 						n++;
3457 					}
3458 					while ( n < nMax );
3459 				}
3460 				while ( nDelta );
3461 			}
3462 			else
3463 			{
3464 				n = nPos+1;
3465 				do
3466 				{
3467 					if ( pItems[n].mnPixSize-nDelta < 0 )
3468 					{
3469 						nDelta -= pItems[n].mnPixSize;
3470 						pItems[n].mnPixSize = 0;
3471 					}
3472 					else
3473 					{
3474 						pItems[n].mnPixSize -= nDelta;
3475 						break;
3476 					}
3477 					n++;
3478 				}
3479 				while ( n < nMax );
3480 			}
3481 		}
3482 	}
3483 
3484 	// Original-Groessen updaten
3485 	ImplCalcLogSize( pItems, nItems );
3486 
3487 	ImplUpdate();
3488 }
3489 
3490 // -----------------------------------------------------------------------
3491 
SetItemSize(sal_uInt16 nId,long nNewSize)3492 void SplitWindow::SetItemSize( sal_uInt16 nId, long nNewSize )
3493 {
3494 	sal_uInt16			nPos;
3495 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3496 	ImplSplitItem*	pItem;
3497 
3498 	if ( !pSet )
3499 		return;
3500 
3501 	// Testen, ob sich Groesse aendert
3502 	pItem = &(pSet->mpItems[nPos]);
3503 	if ( pItem->mnSize != nNewSize )
3504 	{
3505 		// Neue Groesse setzen und neu durchrechnen
3506 		pItem->mnSize = nNewSize;
3507 		pSet->mbCalcPix = sal_True;
3508 		ImplUpdate();
3509 	}
3510 }
3511 
3512 // -----------------------------------------------------------------------
3513 
GetItemSize(sal_uInt16 nId) const3514 long SplitWindow::GetItemSize( sal_uInt16 nId ) const
3515 {
3516 	sal_uInt16			nPos;
3517 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3518 
3519 	if ( pSet )
3520 		return pSet->mpItems[nPos].mnSize;
3521 	else
3522 		return 0;
3523 }
3524 
3525 // -----------------------------------------------------------------------
3526 
GetItemSize(sal_uInt16 nId,SplitWindowItemBits nBits) const3527 long SplitWindow::GetItemSize( sal_uInt16 nId, SplitWindowItemBits nBits ) const
3528 {
3529 	sal_uInt16			nPos;
3530 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3531 
3532 	if ( pSet )
3533 	{
3534 		if ( nBits == pSet->mpItems[nPos].mnBits )
3535 			return pSet->mpItems[nPos].mnSize;
3536 		else
3537 		{
3538 			((SplitWindow*)this)->ImplCalcLayout();
3539 
3540 			long				nRelSize = 0;
3541 			long				nPerSize = 0;
3542 			ImplSplitItem*		pItems;
3543 			sal_uInt16				nItems;
3544 			SplitWindowItemBits nTempBits;
3545 			sal_uInt16				i;
3546 			nItems = pSet->mnItems;
3547 			pItems = pSet->mpItems;
3548 			for ( i = 0; i < nItems; i++ )
3549 			{
3550 				if ( i == nPos )
3551 					nTempBits = nBits;
3552 				else
3553 					nTempBits = pItems[i].mnBits;
3554 				if ( nTempBits & SWIB_RELATIVESIZE )
3555 					nRelSize += pItems[i].mnPixSize;
3556 				else if ( nTempBits & SWIB_PERCENTSIZE )
3557 					nPerSize += pItems[i].mnPixSize;
3558 			}
3559 			nPerSize += nRelSize;
3560 			if ( nBits & SWIB_RELATIVESIZE )
3561 			{
3562 				if ( nRelSize )
3563 					return (pItems[nPos].mnPixSize+(nRelSize/2))/nRelSize;
3564 				else
3565 					return 1;
3566 			}
3567 			else if ( nBits & SWIB_PERCENTSIZE )
3568 			{
3569 				if ( nPerSize )
3570 					return (pItems[nPos].mnPixSize*100)/nPerSize;
3571 				else
3572 					return 1;
3573 			}
3574 			else
3575 				return pItems[nPos].mnPixSize;
3576 		}
3577 	}
3578 	else
3579 		return 0;
3580 }
3581 
3582 
3583 
3584 
SetItemSizeRange(sal_uInt16 nId,const Range aRange)3585 void SplitWindow::SetItemSizeRange (sal_uInt16 nId, const Range aRange)
3586 {
3587 	sal_uInt16 nPos;
3588 	ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos);
3589 
3590 	if (pSet != NULL)
3591 	{
3592 		pSet->mpItems[nPos].mnMinSize = aRange.Min();
3593 		pSet->mpItems[nPos].mnMaxSize = aRange.Max();
3594 	}
3595 }
3596 
3597 
3598 
3599 
GetItemSizeRange(sal_uInt16 nId) const3600 Range SplitWindow::GetItemSizeRange (sal_uInt16 nId) const
3601 {
3602 	sal_uInt16 nPos;
3603 	ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos);
3604 
3605 	if (pSet != NULL)
3606 		return Range (pSet->mpItems[nPos].mnMinSize, pSet->mpItems[nPos].mnMaxSize);
3607 	else
3608 		return Range(-1,-1);
3609 }
3610 
3611 
3612 // -----------------------------------------------------------------------
3613 
SetItemBits(sal_uInt16 nId,SplitWindowItemBits nNewBits)3614 void SplitWindow::SetItemBits( sal_uInt16 nId, SplitWindowItemBits nNewBits )
3615 {
3616 	sal_uInt16			nPos;
3617 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3618 	ImplSplitItem*	pItem;
3619 
3620 	if ( !pSet )
3621 		return;
3622 
3623 	pItem = &(pSet->mpItems[nPos]);
3624 	if ( pItem->mpWindow )
3625 		nNewBits &= ~SWIB_COLSET;
3626 
3627 	if ( pItem->mnBits != nNewBits )
3628 	{
3629 		// Neue Bits setzen und neu durchrechnen
3630 		pItem->mnBits = nNewBits;
3631 		pSet->mbCalcPix = sal_True;
3632 		ImplUpdate();
3633 	}
3634 }
3635 
3636 // -----------------------------------------------------------------------
3637 
GetItemBits(sal_uInt16 nId) const3638 SplitWindowItemBits SplitWindow::GetItemBits( sal_uInt16 nId ) const
3639 {
3640 	sal_uInt16			nPos;
3641 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3642 
3643 	if ( pSet )
3644 		return pSet->mpItems[nPos].mnBits;
3645 	else
3646 		return 0;
3647 }
3648 
3649 // -----------------------------------------------------------------------
3650 
GetItemWindow(sal_uInt16 nId) const3651 Window* SplitWindow::GetItemWindow( sal_uInt16 nId ) const
3652 {
3653 	sal_uInt16			nPos;
3654 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3655 
3656 	if ( pSet )
3657 		return pSet->mpItems[nPos].mpWindow;
3658 	else
3659 		return NULL;
3660 }
3661 
3662 // -----------------------------------------------------------------------
3663 
GetSet(sal_uInt16 nId) const3664 sal_uInt16 SplitWindow::GetSet( sal_uInt16 nId ) const
3665 {
3666 	sal_uInt16			nPos;
3667 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3668 
3669 	if ( pSet )
3670 		return pSet->mnId;
3671 	else
3672 		return 0;
3673 }
3674 
3675 // -----------------------------------------------------------------------
3676 
GetSet(sal_uInt16 nId,sal_uInt16 & rSetId,sal_uInt16 & rPos) const3677 sal_Bool SplitWindow::GetSet( sal_uInt16 nId, sal_uInt16& rSetId, sal_uInt16& rPos ) const
3678 {
3679 	ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, rPos );
3680 	if ( pSet )
3681 	{
3682 		rSetId = pSet->mnId;
3683 		return sal_True;
3684 	}
3685 	else
3686 		return sal_False;
3687 }
3688 
3689 // -----------------------------------------------------------------------
3690 
IsItemValid(sal_uInt16 nId) const3691 sal_Bool SplitWindow::IsItemValid( sal_uInt16 nId ) const
3692 {
3693 	sal_uInt16			nPos;
3694 	ImplSplitSet*	pSet = ImplFindItem( mpBaseSet, nId, nPos );
3695 
3696 	if ( pSet )
3697 		return sal_True;
3698 	else
3699 		return sal_False;
3700 }
3701 
3702 // -----------------------------------------------------------------------
3703 
GetItemId(Window * pWindow) const3704 sal_uInt16 SplitWindow::GetItemId( Window* pWindow ) const
3705 {
3706 	return ImplFindItem( mpBaseSet, pWindow );
3707 }
3708 
3709 // -----------------------------------------------------------------------
3710 
GetItemId(const Point & rPos) const3711 sal_uInt16 SplitWindow::GetItemId( const Point& rPos ) const
3712 {
3713 	return ImplFindItem( mpBaseSet, rPos, mbHorz, !mbBottomRight );
3714 }
3715 
3716 // -----------------------------------------------------------------------
3717 
GetItemPos(sal_uInt16 nId,sal_uInt16 nSetId) const3718 sal_uInt16 SplitWindow::GetItemPos( sal_uInt16 nId, sal_uInt16 nSetId ) const
3719 {
3720 	ImplSplitSet*	pSet = ImplFindSet( mpBaseSet, nSetId );
3721 	sal_uInt16			nPos = SPLITWINDOW_ITEM_NOTFOUND;
3722 
3723 	if ( pSet )
3724 	{
3725 		for ( sal_uInt16 i = 0; i < pSet->mnItems; i++ )
3726 		{
3727 			if ( pSet->mpItems[i].mnId == nId )
3728 			{
3729 				nPos = i;
3730 				break;
3731 			}
3732 		}
3733 	}
3734 
3735 	return nPos;
3736 }
3737 
3738 // -----------------------------------------------------------------------
3739 
GetItemId(sal_uInt16 nPos,sal_uInt16 nSetId) const3740 sal_uInt16 SplitWindow::GetItemId( sal_uInt16 nPos, sal_uInt16 nSetId ) const
3741 {
3742 	ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3743 	if ( pSet && (nPos < pSet->mnItems) )
3744 		return pSet->mpItems[nPos].mnId;
3745 	else
3746 		return 0;
3747 }
3748 
3749 // -----------------------------------------------------------------------
3750 
GetItemCount(sal_uInt16 nSetId) const3751 sal_uInt16 SplitWindow::GetItemCount( sal_uInt16 nSetId ) const
3752 {
3753 	ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3754 	if ( pSet )
3755 		return pSet->mnItems;
3756 	else
3757 		return 0;
3758 }
3759 
3760 // -----------------------------------------------------------------------
3761 
ImplNewAlign()3762 void SplitWindow::ImplNewAlign()
3763 {
3764 	if ( mbNoAlign )
3765 	{
3766 		mbHorz		  = sal_False;
3767 		mbBottomRight = sal_False;
3768 	}
3769 	else if ( meAlign == WINDOWALIGN_TOP )
3770 	{
3771 		mbHorz		  = sal_True;
3772 		mbBottomRight = sal_False;
3773 	}
3774 	else if ( meAlign == WINDOWALIGN_BOTTOM )
3775 	{
3776 		mbHorz		  = sal_True;
3777 		mbBottomRight = sal_True;
3778 	}
3779 	else if ( meAlign == WINDOWALIGN_LEFT )
3780 	{
3781 		mbHorz		  = sal_False;
3782 		mbBottomRight = sal_False;
3783 	}
3784 	else if ( meAlign == WINDOWALIGN_RIGHT )
3785 	{
3786 		mbHorz		  = sal_False;
3787 		mbBottomRight = sal_True;
3788 	}
3789 
3790 	if ( mnWinStyle & WB_BORDER )
3791 	{
3792 		ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
3793 						mnRightBorder, mnBottomBorder );
3794 	}
3795 
3796 	if ( IsReallyVisible() && IsUpdateMode() )
3797 		Invalidate();
3798 	ImplUpdate();
3799 }
3800 
3801 // -----------------------------------------------------------------------
3802 
SetNoAlign(sal_Bool bNoAlign)3803 void SplitWindow::SetNoAlign( sal_Bool bNoAlign )
3804 {
3805 	bNoAlign = bNoAlign != 0;
3806 	if ( mbNoAlign != bNoAlign )
3807 	{
3808 		mbNoAlign = bNoAlign;
3809 		ImplNewAlign();
3810 	}
3811 }
3812 
3813 // -----------------------------------------------------------------------
3814 
SetAlign(WindowAlign eNewAlign)3815 void SplitWindow::SetAlign( WindowAlign eNewAlign )
3816 {
3817 	if ( meAlign != eNewAlign )
3818 	{
3819 		meAlign = eNewAlign;
3820 		ImplNewAlign();
3821 	}
3822 }
3823 
3824 // -----------------------------------------------------------------------
3825 
CalcWindowSizePixel(const Size & rSize,WindowAlign eAlign,WinBits nWinStyle,sal_Bool bExtra)3826 Size SplitWindow::CalcWindowSizePixel( const Size& rSize, WindowAlign eAlign,
3827 									   WinBits nWinStyle, sal_Bool bExtra )
3828 {
3829 	long	nLeft;
3830 	long	nTop;
3831 	long	nRight;
3832 	long	nBottom;
3833 	Size	aSize = rSize;
3834 
3835 	ImplCalcBorder( eAlign, sal_False, nLeft, nTop, nRight, nBottom );
3836 	aSize.Width()	+= nLeft+nRight;
3837 	aSize.Height()	+= nTop+nBottom;
3838 
3839 	if ( nWinStyle & WB_SIZEABLE )
3840 	{
3841 		if ( (eAlign == WINDOWALIGN_TOP) || (eAlign == WINDOWALIGN_BOTTOM) )
3842 		{
3843 			aSize.Height() += SPLITWIN_SPLITSIZE-2;
3844 			if ( bExtra )
3845 				aSize.Height() += SPLITWIN_SPLITSIZEEXLN;
3846 		}
3847 		else
3848 		{
3849 			aSize.Width() += SPLITWIN_SPLITSIZE-2;
3850 			if ( bExtra )
3851 				aSize.Width() += SPLITWIN_SPLITSIZEEXLN;
3852 		}
3853 	}
3854 
3855 	return aSize;
3856 }
3857 
3858 // -----------------------------------------------------------------------
3859 
ShowAutoHideButton(sal_Bool bShow)3860 void SplitWindow::ShowAutoHideButton( sal_Bool bShow )
3861 {
3862 	mbAutoHide = bShow;
3863 	ImplUpdate();
3864 }
3865 
3866 // -----------------------------------------------------------------------
3867 
ShowFadeInHideButton(sal_Bool bShow)3868 void SplitWindow::ShowFadeInHideButton( sal_Bool bShow )
3869 {
3870 	mbFadeIn = bShow;
3871 	ImplUpdate();
3872 }
3873 
3874 // -----------------------------------------------------------------------
3875 
ShowFadeOutButton(sal_Bool bShow)3876 void SplitWindow::ShowFadeOutButton( sal_Bool bShow )
3877 {
3878 	mbFadeOut = bShow;
3879 	ImplUpdate();
3880 }
3881 
3882 // -----------------------------------------------------------------------
3883 
SetAutoHideState(sal_Bool bAutoHide)3884 void SplitWindow::SetAutoHideState( sal_Bool bAutoHide )
3885 {
3886 	mbAutoHideIn = bAutoHide;
3887 	if ( IsReallyVisible() )
3888 	{
3889 		Rectangle aRect;
3890 		ImplGetAutoHideRect( aRect );
3891 		Invalidate( aRect );
3892 	}
3893 }
3894 
3895 // -----------------------------------------------------------------------
3896 
GetFadeInSize() const3897 long SplitWindow::GetFadeInSize() const
3898 {
3899 	long n = 0;
3900 
3901 	if ( mbHorz )
3902 		n = mnTopBorder+mnBottomBorder;
3903 	else
3904 		n = mnLeftBorder+mnRightBorder;
3905 
3906 	return n+SPLITWIN_SPLITSIZE+SPLITWIN_SPLITSIZEEX-2;
3907 }
3908 
3909 // -----------------------------------------------------------------------
3910 
GetAutoHideRect() const3911 Rectangle SplitWindow::GetAutoHideRect() const
3912 {
3913 	Rectangle aRect;
3914 	ImplGetAutoHideRect( aRect, sal_True );
3915 	return aRect;
3916 }
3917 
3918 // -----------------------------------------------------------------------
3919 
GetFadeInRect() const3920 Rectangle SplitWindow::GetFadeInRect() const
3921 {
3922 	Rectangle aRect;
3923 	ImplGetFadeInRect( aRect, sal_True );
3924 	return aRect;
3925 }
3926 
3927 // -----------------------------------------------------------------------
3928 
GetFadeOutRect() const3929 Rectangle SplitWindow::GetFadeOutRect() const
3930 {
3931 	Rectangle aRect;
3932 	ImplGetFadeOutRect( aRect, sal_True );
3933 	return aRect;
3934 }
3935