bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / window / splitwin.cxx
blob617efa05eceaf41cbd75aca288c2461995aa0618
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <string.h>
23 #include <tools/debug.hxx>
24 #include <tools/rcid.h>
25 #include <tools/solar.h>
27 #include <vcl/event.hxx>
28 #include <vcl/wall.hxx>
29 #include <vcl/bitmap.hxx>
30 #include <vcl/decoview.hxx>
31 #include <vcl/image.hxx>
32 #include <vcl/help.hxx>
33 #include <vcl/splitwin.hxx>
35 #include <rsc/rsc-vcl-shared-types.hxx>
37 #include <svdata.hxx>
38 #include <svids.hrc>
40 // =======================================================================
42 // Attention: Must not contain non-PODs because array is enlarged/copied
43 // with the use of memmove/memcpy.
44 struct ImplSplitItem
46 long mnSize;
47 long mnPixSize;
48 long mnLeft;
49 long mnTop;
50 long mnWidth;
51 long mnHeight;
52 long mnSplitPos;
53 long mnSplitSize;
54 long mnOldSplitPos;
55 long mnOldSplitSize;
56 long mnOldWidth;
57 long mnOldHeight;
58 ImplSplitSet* mpSet;
59 Window* mpWindow;
60 Window* mpOrgParent;
61 sal_uInt16 mnId;
62 SplitWindowItemBits mnBits;
63 sal_Bool mbFixed;
64 sal_Bool mbSubSize;
65 /// Minimal width or height of the item. -1 means no restriction.
66 long mnMinSize;
67 /// Maximal width or height of the item. -1 means no restriction.
68 long mnMaxSize;
71 struct ImplSplitSet
73 ImplSplitItem* mpItems;
74 Wallpaper* mpWallpaper;
75 Bitmap* mpBitmap;
76 long mnLastSize;
77 long mnSplitSize;
78 sal_uInt16 mnItems;
79 sal_uInt16 mnId;
80 sal_Bool mbCalcPix;
85 /** Check whether the given size is inside the valid range defined by
86 [rItem.mnMinSize,rItem.mnMaxSize]. When it is not inside it then return
87 the upper or lower bound, respectively. Otherwise return the given size
88 unmodified.
89 Note that either mnMinSize and/or mnMaxSize can be -1 in which case the
90 size has not lower or upper bound.
92 namespace {
93 long ValidateSize (const long nSize, const ImplSplitItem &rItem)
95 if (rItem.mnMinSize>=0 && nSize<rItem.mnMinSize)
96 return rItem.mnMinSize;
97 else if (rItem.mnMaxSize>0 && nSize>rItem.mnMaxSize)
98 return rItem.mnMaxSize;
99 else
100 return nSize;
105 #define SPLITWIN_SPLITSIZE 3
106 #define SPLITWIN_SPLITSIZEEX 4
107 #define SPLITWIN_SPLITSIZEEXLN 6
108 #define SPLITWIN_SPLITSIZEAUTOHIDE 36
109 #define SPLITWIN_SPLITSIZEFADE 36
111 #define SPLIT_HORZ ((sal_uInt16)0x0001)
112 #define SPLIT_VERT ((sal_uInt16)0x0002)
113 #define SPLIT_WINDOW ((sal_uInt16)0x0004)
114 #define SPLIT_NOSPLIT ((sal_uInt16)0x8000)
116 // =======================================================================
118 static void ImplCalcBorder( WindowAlign eAlign, sal_Bool bNoAlign,
119 long& rLeft, long& rTop,
120 long& rRight, long& rBottom )
122 if ( bNoAlign )
124 rLeft = 2;
125 rTop = 2;
126 rRight = 2;
127 rBottom = 2;
129 else
131 switch ( eAlign )
133 case WINDOWALIGN_TOP:
134 rLeft = 2;
135 rTop = 2;
136 rRight = 2;
137 rBottom = 0;
138 break;
139 case WINDOWALIGN_LEFT:
140 rLeft = 0;
141 rTop = 2;
142 rRight = 2;
143 rBottom = 2;
144 break;
145 case WINDOWALIGN_BOTTOM:
146 rLeft = 2;
147 rTop = 0;
148 rRight = 2;
149 rBottom = 2;
150 break;
151 default:
152 rLeft = 0;
153 rTop = 2;
154 rRight = 2;
155 rBottom = 2;
156 break;
161 // -----------------------------------------------------------------------
163 void SplitWindow::ImplDrawBorder( SplitWindow* pWin )
165 const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
166 long nDX = pWin->mnDX;
167 long nDY = pWin->mnDY;
169 if ( pWin->mbNoAlign )
171 DecorationView aDecoView( pWin );
172 Point aTmpPoint;
173 Rectangle aRect( aTmpPoint, Size( nDX, nDY ) );
174 aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
176 else
178 switch ( pWin->meAlign )
180 case WINDOWALIGN_BOTTOM:
181 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
182 pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
183 pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
185 pWin->SetLineColor( rStyleSettings.GetLightColor() );
186 pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
187 pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
188 break;
189 case WINDOWALIGN_TOP:
190 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
191 pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
192 pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
194 pWin->SetLineColor( rStyleSettings.GetLightColor() );
195 pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
196 pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
197 break;
198 case WINDOWALIGN_LEFT:
199 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
200 pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-2 ) );
201 pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
202 pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
204 pWin->SetLineColor( rStyleSettings.GetLightColor() );
205 pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
206 pWin->DrawLine( Point( 0, 1 ), Point( nDX-3, 1 ) );
207 pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-2, nDY-1 ) );
208 break;
209 default:
210 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
211 pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-2 ) );
212 pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
213 pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
215 pWin->SetLineColor( rStyleSettings.GetLightColor() );
216 pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
217 pWin->DrawLine( Point( 1, 1 ), Point( nDX-1, 1 ) );
218 pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
223 // -----------------------------------------------------------------------
225 void SplitWindow::ImplDrawBorderLine( SplitWindow* pWin )
227 if ( pWin->mbFadeOut || pWin->mbAutoHide )
229 const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
230 long nDX = pWin->mnDX;
231 long nDY = pWin->mnDY;
233 switch ( pWin->meAlign )
235 case WINDOWALIGN_LEFT:
236 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
237 pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, nDY-2 ) );
239 pWin->SetLineColor( rStyleSettings.GetLightColor() );
240 pWin->DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN, nDY-3 ) );
241 break;
242 case WINDOWALIGN_RIGHT:
243 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
244 pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN-1, nDY-2 ) );
246 pWin->SetLineColor( rStyleSettings.GetLightColor() );
247 pWin->DrawLine( Point( SPLITWIN_SPLITSIZEEXLN, 1 ), Point( SPLITWIN_SPLITSIZEEXLN, nDY-3 ) );
248 break;
249 case WINDOWALIGN_TOP:
250 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
251 pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-1, nDY-SPLITWIN_SPLITSIZEEXLN-1 ) );
253 pWin->SetLineColor( rStyleSettings.GetLightColor() );
254 pWin->DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN ), Point( nDX-1, nDY-SPLITWIN_SPLITSIZEEXLN ) );
255 break;
256 case WINDOWALIGN_BOTTOM:
257 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
258 pWin->DrawLine( Point( 0, 5 ), Point( nDX-1, 5 ) );
260 pWin->SetLineColor( rStyleSettings.GetLightColor() );
261 pWin->DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN ), Point( nDX-1, SPLITWIN_SPLITSIZEEXLN ) );
262 break;
267 // -----------------------------------------------------------------------
269 static ImplSplitSet* ImplFindSet( ImplSplitSet* pSet, sal_uInt16 nId )
271 if ( pSet->mnId == nId )
272 return pSet;
274 sal_uInt16 i;
275 sal_uInt16 nItems = pSet->mnItems;
276 ImplSplitItem* pItems = pSet->mpItems;
278 for ( i = 0; i < nItems; i++ )
280 if ( pItems[i].mnId == nId )
281 return pItems[i].mpSet;
284 for ( i = 0; i < nItems; i++ )
286 if ( pItems[i].mpSet )
288 ImplSplitSet* pFindSet = ImplFindSet( pItems[i].mpSet, nId );
289 if ( pFindSet )
290 return pFindSet;
294 return NULL;
297 // -----------------------------------------------------------------------
299 static ImplSplitSet* ImplFindItem( ImplSplitSet* pSet, sal_uInt16 nId, sal_uInt16& rPos )
301 sal_uInt16 i;
302 sal_uInt16 nItems = pSet->mnItems;
303 ImplSplitItem* pItems = pSet->mpItems;
305 for ( i = 0; i < nItems; i++ )
307 if ( pItems[i].mnId == nId )
309 rPos = i;
310 return pSet;
314 for ( i = 0; i < nItems; i++ )
316 if ( pItems[i].mpSet )
318 ImplSplitSet* pFindSet = ImplFindItem( pItems[i].mpSet, nId, rPos );
319 if ( pFindSet )
320 return pFindSet;
324 return NULL;
327 // -----------------------------------------------------------------------
329 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, Window* pWindow )
331 sal_uInt16 i;
332 sal_uInt16 nItems = pSet->mnItems;
333 ImplSplitItem* pItems = pSet->mpItems;
335 for ( i = 0; i < nItems; i++ )
337 if ( pItems[i].mpWindow == pWindow )
338 return pItems[i].mnId;
339 else
341 if ( pItems[i].mpSet )
343 sal_uInt16 nId = ImplFindItem( pItems[i].mpSet, pWindow );
344 if ( nId )
345 return nId;
350 return 0;
353 // -----------------------------------------------------------------------
355 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, const Point& rPos,
356 sal_Bool bRows, sal_Bool bDown = sal_True )
358 sal_uInt16 i;
359 sal_uInt16 nItems = pSet->mnItems;
360 ImplSplitItem* pItems = pSet->mpItems;
362 for ( i = 0; i < nItems; i++ )
364 if ( pItems[i].mnWidth && pItems[i].mnHeight )
366 // Wegen ICC auftrennen
367 Point aPoint( pItems[i].mnLeft, pItems[i].mnTop );
368 Size aSize( pItems[i].mnWidth, pItems[i].mnHeight );
369 Rectangle aRect( aPoint, aSize );
370 if ( bRows )
372 if ( bDown )
373 aRect.Bottom() += pSet->mnSplitSize;
374 else
375 aRect.Top() -= pSet->mnSplitSize;
377 else
379 if ( bDown )
380 aRect.Right() += pSet->mnSplitSize;
381 else
382 aRect.Left() -= pSet->mnSplitSize;
385 if ( aRect.IsInside( rPos ) )
387 if ( pItems[i].mpSet && pItems[i].mpSet->mpItems )
389 return ImplFindItem( pItems[i].mpSet, rPos,
390 ((pItems[i].mnBits & SWIB_COLSET) == 0) );
392 else
393 return pItems[i].mnId;
398 return 0;
401 // -----------------------------------------------------------------------
403 static void ImplDeleteSet( ImplSplitSet* pSet )
405 sal_uInt16 i;
406 sal_uInt16 nItems = pSet->mnItems;
407 ImplSplitItem* pItems = pSet->mpItems;
409 for ( i = 0; i < nItems; i++ )
411 if ( pItems[i].mpSet )
412 ImplDeleteSet( pItems[i].mpSet );
415 if ( pSet->mpWallpaper )
416 delete pSet->mpWallpaper;
418 if ( pSet->mpBitmap )
419 delete pSet->mpBitmap;
421 delete [] pItems;
422 delete pSet;
425 // -----------------------------------------------------------------------
427 static void ImplCalcSet( ImplSplitSet* pSet,
428 long nSetLeft, long nSetTop,
429 long nSetWidth, long nSetHeight,
430 sal_Bool bRows, sal_Bool bDown = sal_True )
432 if ( !pSet->mpItems )
433 return;
435 sal_uInt16 i;
436 sal_uInt16 j;
437 sal_uInt16 nMins;
438 sal_uInt16 nCalcItems;
439 sal_uInt16 nItems = pSet->mnItems;
440 sal_uInt16 nVisItems;
441 sal_uInt16 nAbsItems;
442 long nCalcSize;
443 long nSizeDelta;
444 long nCurSize;
445 long nSizeWinSize;
446 long nNewSizeWinSize;
447 long nTemp;
448 long nTempErr;
449 long nErrorSum;
450 long nCurSizeDelta;
451 long nPos;
452 long nMaxPos;
453 long* pSize;
454 ImplSplitItem* pItems = pSet->mpItems;
455 sal_Bool bEmpty;
457 // Anzahl sichtbarer Items ermitteln
458 nVisItems = 0;
459 for ( i = 0; i < nItems; i++ )
461 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
462 nVisItems++;
465 // Groessen berechnen
466 if ( bRows )
467 nCalcSize = nSetHeight;
468 else
469 nCalcSize = nSetWidth;
470 nCalcSize -= (nVisItems-1)*pSet->mnSplitSize;
471 nCurSize = 0;
472 if ( pSet->mbCalcPix || (pSet->mnLastSize != nCalcSize) )
474 long nPercentFactor = 10;
475 long nRelCount = 0;
476 long nPercent = 0;
477 long nRelPercent = 0;
478 long nAbsSize = 0;
479 for ( i = 0; i < nItems; i++ )
481 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
483 if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
484 nRelCount += pItems[i].mnSize;
485 else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
486 nPercent += pItems[i].mnSize;
487 else
488 nAbsSize += pItems[i].mnSize;
491 // Relative-Werte auf prozentual mappen (Percent bei uns 10tel Prozent)
492 nPercent *= nPercentFactor;
493 if ( nRelCount )
495 long nRelPercentBase = 1000;
496 while ( (nRelCount > nRelPercentBase) && (nPercentFactor < 100000) )
498 nRelPercentBase *= 10;
499 nPercentFactor *= 10;
501 if ( nPercent < nRelPercentBase )
503 nRelPercent = (nRelPercentBase-nPercent)/nRelCount;
504 nPercent += nRelPercent*nRelCount;
506 else
507 nRelPercent = 0;
509 if ( !nPercent )
510 nPercent = 1;
511 nSizeDelta = nCalcSize-nAbsSize;
512 for ( i = 0; i < nItems; i++ )
514 if ( pItems[i].mnBits & SWIB_INVISIBLE )
515 pItems[i].mnPixSize = 0;
516 else if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
518 if ( nSizeDelta <= 0 )
519 pItems[i].mnPixSize = 0;
520 else
521 pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nRelPercent)/nPercent;
523 else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
525 if ( nSizeDelta <= 0 )
526 pItems[i].mnPixSize = 0;
527 else
528 pItems[i].mnPixSize = (nSizeDelta*pItems[i].mnSize*nPercentFactor)/nPercent;
530 else
531 pItems[i].mnPixSize = pItems[i].mnSize;
532 nCurSize += pItems[i].mnPixSize;
535 pSet->mbCalcPix = sal_False;
536 pSet->mnLastSize = nCalcSize;
538 // Fenster einpassen
539 nSizeDelta = nCalcSize-nCurSize;
540 if ( nSizeDelta )
542 nAbsItems = 0;
543 nSizeWinSize = 0;
544 nNewSizeWinSize = 0;
546 // Zuerst die absoluten Items relativ resizen
547 for ( i = 0; i < nItems; i++ )
549 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
551 if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
553 nAbsItems++;
554 nSizeWinSize += pItems[i].mnPixSize;
558 // Rundungsfehler werden hier nicht ausgelichen
559 if ( (nAbsItems < (sal_uInt16)(std::abs( nSizeDelta ))) && nSizeWinSize )
561 for ( i = 0; i < nItems; i++ )
563 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
565 if ( !(pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
567 pItems[i].mnPixSize += (nSizeDelta*pItems[i].mnPixSize)/nSizeWinSize;
568 nNewSizeWinSize += pItems[i].mnPixSize;
572 nSizeDelta -= nNewSizeWinSize-nSizeWinSize;
575 // Jetzt die Rundunsfehler ausgleichen
576 j = 0;
577 nMins = 0;
578 while ( nSizeDelta && (nItems != nMins) )
580 // Feststellen, welche Items berechnet werden duerfen
581 nCalcItems = 0;
582 while ( !nCalcItems )
584 for ( i = 0; i < nItems; i++ )
586 pItems[i].mbSubSize = sal_False;
588 if ( j >= 2 )
589 pItems[i].mbSubSize = sal_True;
590 else
592 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
594 if ( (nSizeDelta > 0) || pItems[i].mnPixSize )
596 if ( j >= 1 )
597 pItems[i].mbSubSize = sal_True;
598 else
600 if ( (j == 0) && (pItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE)) )
601 pItems[i].mbSubSize = sal_True;
607 if ( pItems[i].mbSubSize )
608 nCalcItems++;
611 j++;
614 // Groessen von den einzelnen Items abziehen
615 nErrorSum = nSizeDelta % nCalcItems;
616 nCurSizeDelta = nSizeDelta / nCalcItems;
617 nMins = 0;
618 for ( i = 0; i < nItems; i++ )
620 if ( pItems[i].mnBits & SWIB_INVISIBLE )
621 nMins++;
622 else if ( pItems[i].mbSubSize )
624 pSize = &(pItems[i].mnPixSize);
626 if ( nErrorSum )
628 if ( nErrorSum < 0 )
629 nTempErr = -1;
630 else
631 nTempErr = 1;
633 else
634 nTempErr = 0;
636 if ( (*pSize+nCurSizeDelta+nTempErr) <= 0 )
638 nTemp = *pSize;
639 if ( nTemp )
641 *pSize -= nTemp;
642 nSizeDelta += nTemp;
644 nMins++;
646 else
648 *pSize += nCurSizeDelta;
649 nSizeDelta -= nCurSizeDelta;
650 if ( nTempErr && (*pSize || (nTempErr > 0)) )
652 *pSize += nTempErr;
653 nSizeDelta -= nTempErr;
654 nErrorSum -= nTempErr;
662 else
664 for ( i = 0; i < nItems; i++ )
666 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
667 nCurSize += pItems[i].mnPixSize;
671 // Maximale Groesse berechnen
672 if ( bRows )
674 nPos = nSetTop;
675 if ( !bDown )
676 nMaxPos = nSetTop-nSetHeight;
677 else
678 nMaxPos = nSetTop+nSetHeight;
680 else
682 nPos = nSetLeft;
683 if ( !bDown )
684 nMaxPos = nSetLeft-nSetWidth;
685 else
686 nMaxPos = nSetLeft+nSetWidth;
689 // Fenster anordnen und Werte anpassen
690 for ( i = 0; i < nItems; i++ )
692 pItems[i].mnOldSplitPos = pItems[i].mnSplitPos;
693 pItems[i].mnOldSplitSize = pItems[i].mnSplitSize;
694 pItems[i].mnOldWidth = pItems[i].mnWidth;
695 pItems[i].mnOldHeight = pItems[i].mnHeight;
697 if ( pItems[i].mnBits & SWIB_INVISIBLE )
698 bEmpty = sal_True;
699 else
701 bEmpty = sal_False;
702 if ( bDown )
704 if ( nPos+pItems[i].mnPixSize > nMaxPos )
705 bEmpty = sal_True;
707 else
709 nPos -= pItems[i].mnPixSize;
710 if ( nPos < nMaxPos )
711 bEmpty = sal_True;
715 if ( bEmpty )
717 pItems[i].mnWidth = 0;
718 pItems[i].mnHeight = 0;
719 pItems[i].mnSplitSize = 0;
721 else
723 if ( bRows )
725 pItems[i].mnLeft = nSetLeft;
726 pItems[i].mnTop = nPos;
727 pItems[i].mnWidth = nSetWidth;
728 pItems[i].mnHeight = pItems[i].mnPixSize;
730 else
732 pItems[i].mnLeft = nPos;
733 pItems[i].mnTop = nSetTop;
734 pItems[i].mnWidth = pItems[i].mnPixSize;
735 pItems[i].mnHeight = nSetHeight;
738 if ( i > nItems-1 )
739 pItems[i].mnSplitSize = 0;
740 else
742 pItems[i].mnSplitSize = pSet->mnSplitSize;
743 if ( bDown )
745 pItems[i].mnSplitPos = nPos+pItems[i].mnPixSize;
746 if ( pItems[i].mnSplitPos+pItems[i].mnSplitSize > nMaxPos )
747 pItems[i].mnSplitSize = nMaxPos-pItems[i].mnSplitPos;
749 else
751 pItems[i].mnSplitPos = nPos-pSet->mnSplitSize;
752 if ( pItems[i].mnSplitPos < nMaxPos )
753 pItems[i].mnSplitSize = pItems[i].mnSplitPos+pSet->mnSplitSize-nMaxPos;
758 if ( !(pItems[i].mnBits & SWIB_INVISIBLE) )
760 if ( !bDown )
761 nPos -= pSet->mnSplitSize;
762 else
763 nPos += pItems[i].mnPixSize+pSet->mnSplitSize;
767 // Sub-Set's berechnen
768 for ( i = 0; i < nItems; i++ )
770 if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
772 ImplCalcSet( pItems[i].mpSet,
773 pItems[i].mnLeft, pItems[i].mnTop,
774 pItems[i].mnWidth, pItems[i].mnHeight,
775 ((pItems[i].mnBits & SWIB_COLSET) == 0) );
779 // Fixed setzen
780 for ( i = 0; i < nItems; i++ )
782 pItems[i].mbFixed = sal_False;
783 if ( pItems[i].mnBits & SWIB_FIXED )
784 pItems[i].mbFixed = sal_True;
785 else
787 // Wenn Child-Set vorhanden, ist dieses Item auch Fixed, wenn
788 // ein Child fixed ist
789 if ( pItems[i].mpSet )
791 for ( j = 0; j < pItems[i].mpSet->mnItems; j++ )
793 if ( pItems[i].mpSet->mpItems[j].mbFixed )
795 pItems[i].mbFixed = sal_True;
796 break;
804 // -----------------------------------------------------------------------
806 void SplitWindow::ImplCalcSet2( SplitWindow* pWindow, ImplSplitSet* pSet, sal_Bool bHide,
807 sal_Bool bRows, sal_Bool /*bDown*/ )
809 sal_uInt16 i;
810 sal_uInt16 nItems = pSet->mnItems;
811 ImplSplitItem* pItems = pSet->mpItems;
813 if ( pWindow->IsReallyVisible() && pWindow->IsUpdateMode() && pWindow->mbInvalidate )
815 for ( i = 0; i < nItems; i++ )
817 if ( pItems[i].mnSplitSize )
819 // Evt. alles invalidieren oder nur einen kleinen Teil
820 if ( (pItems[i].mnOldSplitPos != pItems[i].mnSplitPos) ||
821 (pItems[i].mnOldSplitSize != pItems[i].mnSplitSize) ||
822 (pItems[i].mnOldWidth != pItems[i].mnWidth) ||
823 (pItems[i].mnOldHeight != pItems[i].mnHeight) )
825 Rectangle aRect;
827 // Old Rect invalidieren
828 if ( bRows )
830 aRect.Left() = pItems[i].mnLeft;
831 aRect.Right() = pItems[i].mnLeft+pItems[i].mnOldWidth-1;
832 aRect.Top() = pItems[i].mnOldSplitPos;
833 aRect.Bottom() = aRect.Top() + pItems[i].mnOldSplitSize;
835 else
837 aRect.Top() = pItems[i].mnTop;
838 aRect.Bottom() = pItems[i].mnTop+pItems[i].mnOldHeight-1;
839 aRect.Left() = pItems[i].mnOldSplitPos;
840 aRect.Right() = aRect.Left() + pItems[i].mnOldSplitSize;
842 pWindow->Invalidate( aRect );
843 // New Rect invalidieren
844 if ( bRows )
846 aRect.Left() = pItems[i].mnLeft;
847 aRect.Right() = pItems[i].mnLeft+pItems[i].mnWidth-1;
848 aRect.Top() = pItems[i].mnSplitPos;
849 aRect.Bottom() = aRect.Top() + pItems[i].mnSplitSize;
851 else
853 aRect.Top() = pItems[i].mnTop;
854 aRect.Bottom() = pItems[i].mnTop+pItems[i].mnHeight-1;
855 aRect.Left() = pItems[i].mnSplitPos;
856 aRect.Right() = aRect.Left() + pItems[i].mnSplitSize;
858 pWindow->Invalidate( aRect );
860 // Leere Sets komplett invalidieren, da diese Flaechen
861 // nicht von Fenstern ueberladen werden
862 if ( pItems[i].mpSet && !pItems[i].mpSet->mpItems )
864 aRect.Left() = pItems[i].mnLeft;
865 aRect.Top() = pItems[i].mnTop;
866 aRect.Right() = pItems[i].mnLeft+pItems[i].mnWidth-1;
867 aRect.Bottom() = pItems[i].mnTop+pItems[i].mnHeight-1;
868 pWindow->Invalidate( aRect );
875 // Fenster positionieren
876 for ( i = 0; i < nItems; i++ )
878 if ( pItems[i].mpSet )
880 sal_Bool bTempHide = bHide;
881 if ( !pItems[i].mnWidth || !pItems[i].mnHeight )
882 bTempHide = sal_True;
883 ImplCalcSet2( pWindow, pItems[i].mpSet, bTempHide,
884 ((pItems[i].mnBits & SWIB_COLSET) == 0) );
886 else
888 if ( pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
890 Point aPos( pItems[i].mnLeft, pItems[i].mnTop );
891 Size aSize( pItems[i].mnWidth, pItems[i].mnHeight );
892 pItems[i].mpWindow->SetPosSizePixel( aPos, aSize );
894 else
895 pItems[i].mpWindow->Hide();
899 // Fenster anzeigen und Flag zuruecksetzen
900 for ( i = 0; i < nItems; i++ )
902 if ( pItems[i].mpWindow && pItems[i].mnWidth && pItems[i].mnHeight && !bHide )
903 pItems[i].mpWindow->Show();
907 // -----------------------------------------------------------------------
909 static void ImplCalcLogSize( ImplSplitItem* pItems, sal_uInt16 nItems )
911 // Original-Groessen updaten
912 sal_uInt16 i;
913 long nRelSize = 0;
914 long nPerSize = 0;
915 for ( i = 0; i < nItems; i++ )
917 if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
918 nRelSize += pItems[i].mnPixSize;
919 else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
920 nPerSize += pItems[i].mnPixSize;
922 nPerSize += nRelSize;
923 for ( i = 0; i < nItems; i++ )
925 if ( pItems[i].mnBits & SWIB_RELATIVESIZE )
927 if ( nRelSize )
928 pItems[i].mnSize = (pItems[i].mnPixSize+(nRelSize/2))/nRelSize;
929 else
930 pItems[i].mnSize = 1;
932 else if ( pItems[i].mnBits & SWIB_PERCENTSIZE )
934 if ( nPerSize )
935 pItems[i].mnSize = (pItems[i].mnPixSize*100)/nPerSize;
936 else
937 pItems[i].mnSize = 1;
939 else
940 pItems[i].mnSize = pItems[i].mnPixSize;
944 // -----------------------------------------------------------------------
946 void SplitWindow::ImplDrawBack( SplitWindow* pWindow, const Rectangle& rRect,
947 const Wallpaper* pWall, const Bitmap* pBitmap )
949 if ( pBitmap )
951 Point aPos = rRect.TopLeft();
952 Size aBmpSize = pBitmap->GetSizePixel();
953 pWindow->Push( PUSH_CLIPREGION );
954 pWindow->IntersectClipRegion( rRect );
957 aPos.X() = rRect.Left();
960 pWindow->DrawBitmap( aPos, *pBitmap );
961 aPos.X() += aBmpSize.Width();
963 while ( aPos.X() < rRect.Right() );
964 aPos.Y() += aBmpSize.Height();
966 while ( aPos.Y() < rRect.Bottom() );
967 pWindow->Pop();
969 else
970 pWindow->DrawWallpaper( rRect, *pWall );
973 // -----------------------------------------------------------------------
975 void SplitWindow::ImplDrawBack( SplitWindow* pWindow, ImplSplitSet* pSet )
977 sal_uInt16 i;
978 sal_uInt16 nItems = pSet->mnItems;
979 ImplSplitItem* pItems = pSet->mpItems;
981 // Beim Mainset auch den Hintergrund zeichnen
982 if ( pSet->mnId == 0 )
984 if ( pSet->mpBitmap )
986 Rectangle aRect( pWindow->mnLeftBorder,
987 pWindow->mnTopBorder,
988 pWindow->mnDX-pWindow->mnRightBorder-1,
989 pWindow->mnDY-pWindow->mnBottomBorder-1 );
990 ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
994 for ( i = 0; i < nItems; i++ )
996 pSet = pItems[i].mpSet;
997 if ( pSet )
999 if ( pSet->mpBitmap || pSet->mpWallpaper )
1001 // Wegen ICC auftrennen
1002 Point aPoint( pItems[i].mnLeft, pItems[i].mnTop );
1003 Size aSize( pItems[i].mnWidth, pItems[i].mnHeight );
1004 Rectangle aRect( aPoint, aSize );
1005 ImplDrawBack( pWindow, aRect, pSet->mpWallpaper, pSet->mpBitmap );
1010 for ( i = 0; i < nItems; i++ )
1012 if ( pItems[i].mpSet )
1013 ImplDrawBack( pWindow, pItems[i].mpSet );
1017 // -----------------------------------------------------------------------
1019 static void ImplDrawSplit( SplitWindow* pWindow, ImplSplitSet* pSet,
1020 sal_Bool bRows, sal_Bool bDown = sal_True )
1022 if ( !pSet->mpItems )
1023 return;
1025 sal_uInt16 i;
1026 sal_uInt16 nItems = pSet->mnItems;
1027 long nPos;
1028 long nTop;
1029 long nBottom;
1030 ImplSplitItem* pItems = pSet->mpItems;
1031 const StyleSettings& rStyleSettings = pWindow->GetSettings().GetStyleSettings();
1033 sal_Bool bFlat = (pWindow->GetStyle() & WB_FLATSPLITDRAW) == WB_FLATSPLITDRAW;
1035 for ( i = 0; i < nItems-1; i++ )
1037 if ( pItems[i].mnSplitSize )
1039 nPos = pItems[i].mnSplitPos;
1041 long nItemSplitSize = pItems[i].mnSplitSize;
1042 long nSplitSize = pSet->mnSplitSize;
1043 if ( bRows )
1045 nTop = pItems[i].mnLeft;
1046 nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
1048 if ( bFlat ) nPos--;
1050 if ( bDown || (nItemSplitSize >= nSplitSize) )
1052 pWindow->SetLineColor( rStyleSettings.GetLightColor() );
1053 pWindow->DrawLine( Point( nTop, nPos+1 ), Point( nBottom, nPos+1 ) );
1055 nPos += nSplitSize-2;
1056 if ( bFlat ) nPos+=2;
1057 if ( (!bDown && (nItemSplitSize >= 2)) ||
1058 (bDown && (nItemSplitSize >= nSplitSize-1)) )
1060 pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
1061 pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
1063 if ( !bFlat )
1065 nPos++;
1066 if ( !bDown || (nItemSplitSize >= nSplitSize) )
1068 pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
1069 pWindow->DrawLine( Point( nTop, nPos ), Point( nBottom, nPos ) );
1073 else
1075 nTop = pItems[i].mnTop;
1076 nBottom = pItems[i].mnTop+pSet->mpItems[i].mnHeight-1;
1078 if ( bFlat ) nPos--;
1079 if ( bDown || (nItemSplitSize >= nSplitSize) )
1081 pWindow->SetLineColor( rStyleSettings.GetLightColor() );
1082 pWindow->DrawLine( Point( nPos+1, nTop ), Point( nPos+1, nBottom ) );
1084 nPos += pSet->mnSplitSize-2;
1085 if ( bFlat ) nPos+=2;
1086 if ( (!bDown && (nItemSplitSize >= 2)) ||
1087 (bDown && (nItemSplitSize >= nSplitSize-1)) )
1089 pWindow->SetLineColor( rStyleSettings.GetShadowColor() );
1090 pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
1092 if( !bFlat )
1094 nPos++;
1095 if ( !bDown || (nItemSplitSize >= nSplitSize) )
1097 pWindow->SetLineColor( rStyleSettings.GetDarkShadowColor() );
1098 pWindow->DrawLine( Point( nPos, nTop ), Point( nPos, nBottom ) );
1105 for ( i = 0; i < nItems; i++ )
1107 if ( pItems[i].mpSet && pItems[i].mnWidth && pItems[i].mnHeight )
1108 ImplDrawSplit( pWindow, pItems[i].mpSet, ((pItems[i].mnBits & SWIB_COLSET) == 0) );
1112 // -----------------------------------------------------------------------
1114 sal_uInt16 SplitWindow::ImplTestSplit( ImplSplitSet* pSet, const Point& rPos,
1115 long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos,
1116 sal_Bool bRows, sal_Bool /*bDown*/ )
1118 if ( !pSet->mpItems )
1119 return 0;
1121 sal_uInt16 i;
1122 sal_uInt16 nSplitTest;
1123 sal_uInt16 nItems = pSet->mnItems;
1124 long nMPos1;
1125 long nMPos2;
1126 long nPos;
1127 long nTop;
1128 long nBottom;
1129 ImplSplitItem* pItems = pSet->mpItems;
1131 if ( bRows )
1133 nMPos1 = rPos.X();
1134 nMPos2 = rPos.Y();
1136 else
1138 nMPos1 = rPos.Y();
1139 nMPos2 = rPos.X();
1142 for ( i = 0; i < nItems-1; i++ )
1144 if ( pItems[i].mnSplitSize )
1146 if ( bRows )
1148 nTop = pItems[i].mnLeft;
1149 nBottom = pItems[i].mnLeft+pItems[i].mnWidth-1;
1151 else
1153 nTop = pItems[i].mnTop;
1154 nBottom = pItems[i].mnTop+pItems[i].mnHeight-1;
1156 nPos = pItems[i].mnSplitPos;
1158 if ( (nMPos1 >= nTop) && (nMPos1 <= nBottom) &&
1159 (nMPos2 >= nPos) && (nMPos2 <= nPos+pItems[i].mnSplitSize) )
1161 if ( !pItems[i].mbFixed && !pItems[i+1].mbFixed )
1163 rMouseOff = nMPos2-nPos;
1164 *ppFoundSet = pSet;
1165 rFoundPos = i;
1166 if ( bRows )
1167 return SPLIT_VERT;
1168 else
1169 return SPLIT_HORZ;
1171 else
1172 return SPLIT_NOSPLIT;
1177 for ( i = 0; i < nItems; i++ )
1179 if ( pItems[i].mpSet )
1181 nSplitTest = ImplTestSplit( pItems[i].mpSet, rPos,
1182 rMouseOff, ppFoundSet, rFoundPos,
1183 ((pItems[i].mnBits & SWIB_COLSET) == 0) );
1184 if ( nSplitTest )
1185 return nSplitTest;
1189 return 0;
1192 // -----------------------------------------------------------------------
1194 sal_uInt16 SplitWindow::ImplTestSplit( SplitWindow* pWindow, const Point& rPos,
1195 long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos )
1197 // Resizable SplitWindow muss anders behandelt werden
1198 if ( pWindow->mnWinStyle & WB_SIZEABLE )
1200 long nTPos;
1201 long nPos;
1202 long nBorder;
1204 if ( pWindow->mbHorz )
1206 if ( pWindow->mbBottomRight )
1208 nBorder = pWindow->mnBottomBorder;
1209 nPos = 0;
1211 else
1213 nBorder = pWindow->mnTopBorder;
1214 nPos = pWindow->mnDY-nBorder;
1216 nTPos = rPos.Y();
1218 else
1220 if ( pWindow->mbBottomRight )
1222 nBorder = pWindow->mnRightBorder;
1223 nPos = 0;
1225 else
1227 nBorder = pWindow->mnLeftBorder;
1228 nPos = pWindow->mnDX-nBorder;
1230 nTPos = rPos.X();
1232 long nSplitSize = pWindow->mpMainSet->mnSplitSize-2;
1233 if ( pWindow->mbAutoHide || pWindow->mbFadeOut )
1234 nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1235 if ( !pWindow->mbBottomRight )
1236 nPos -= nSplitSize;
1237 if ( (nTPos >= nPos) && (nTPos <= nPos+nSplitSize+nBorder) )
1239 rMouseOff = nTPos-nPos;
1240 *ppFoundSet = pWindow->mpMainSet;
1241 if ( pWindow->mpMainSet->mpItems )
1242 rFoundPos = pWindow->mpMainSet->mnItems-1;
1243 else
1244 rFoundPos = 0;
1245 if ( pWindow->mbHorz )
1246 return SPLIT_VERT | SPLIT_WINDOW;
1247 else
1248 return SPLIT_HORZ | SPLIT_WINDOW;
1252 return ImplTestSplit( pWindow->mpMainSet, rPos, rMouseOff, ppFoundSet, rFoundPos,
1253 pWindow->mbHorz, !pWindow->mbBottomRight );
1256 // -----------------------------------------------------------------------
1258 void SplitWindow::ImplDrawSplitTracking( SplitWindow* pThis, const Point& rPos )
1260 Rectangle aRect;
1262 if ( pThis->mnSplitTest & SPLIT_HORZ )
1264 aRect.Top() = pThis->maDragRect.Top();
1265 aRect.Bottom() = pThis->maDragRect.Bottom();
1266 aRect.Left() = rPos.X();
1267 aRect.Right() = aRect.Left()+pThis->mpSplitSet->mnSplitSize-1;
1268 if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
1269 aRect.Right()--;
1270 if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
1271 (pThis->mbAutoHide || pThis->mbFadeOut) )
1273 aRect.Left() += SPLITWIN_SPLITSIZEEXLN;
1274 aRect.Right() += SPLITWIN_SPLITSIZEEXLN;
1277 else
1279 aRect.Left() = pThis->maDragRect.Left();
1280 aRect.Right() = pThis->maDragRect.Right();
1281 aRect.Top() = rPos.Y();
1282 aRect.Bottom() = aRect.Top()+pThis->mpSplitSet->mnSplitSize-1;
1283 if ( !(pThis->mnWinStyle & WB_NOSPLITDRAW) )
1284 aRect.Bottom()--;
1285 if ( (pThis->mnSplitTest & SPLIT_WINDOW) &&
1286 (pThis->mbAutoHide || pThis->mbFadeOut) )
1288 aRect.Top() += SPLITWIN_SPLITSIZEEXLN;
1289 aRect.Bottom() += SPLITWIN_SPLITSIZEEXLN;
1292 pThis->ShowTracking( aRect, SHOWTRACK_SPLIT );
1295 // -----------------------------------------------------------------------
1297 void SplitWindow::ImplInit( Window* pParent, WinBits nStyle )
1299 ImplSplitSet* pNewSet = new ImplSplitSet;
1300 pNewSet->mpItems = NULL;
1301 pNewSet->mpWallpaper = NULL;
1302 pNewSet->mpBitmap = NULL;
1303 pNewSet->mnLastSize = 0;
1304 pNewSet->mnItems = 0;
1305 pNewSet->mnId = 0;
1306 pNewSet->mnSplitSize = SPLITWIN_SPLITSIZE;
1307 pNewSet->mbCalcPix = sal_True;
1309 mpMainSet = pNewSet;
1310 mpBaseSet = pNewSet;
1311 mpSplitSet = NULL;
1312 mpLastSizes = NULL;
1313 mnDX = 0;
1314 mnDY = 0;
1315 mnLeftBorder = 0;
1316 mnTopBorder = 0;
1317 mnRightBorder = 0;
1318 mnBottomBorder = 0;
1319 mnMaxSize = 0;
1320 mnMouseOff = 0;
1321 meAlign = WINDOWALIGN_TOP;
1322 mnWinStyle = nStyle;
1323 mnSplitTest = 0;
1324 mnSplitPos = 0;
1325 mnMouseModifier = 0;
1326 mnMStartPos = 0;
1327 mnMSplitPos = 0;
1328 mbDragFull = sal_False;
1329 mbHorz = sal_True;
1330 mbBottomRight = sal_False;
1331 mbCalc = sal_False;
1332 mbRecalc = sal_True;
1333 mbInvalidate = sal_True;
1334 mbAutoHide = sal_False;
1335 mbFadeIn = sal_False;
1336 mbFadeOut = sal_False;
1337 mbAutoHideIn = sal_False;
1338 mbAutoHideDown = sal_False;
1339 mbFadeInDown = sal_False;
1340 mbFadeOutDown = sal_False;
1341 mbAutoHidePressed = sal_False;
1342 mbFadeInPressed = sal_False;
1343 mbFadeOutPressed = sal_False;
1344 mbFadeNoButtonMode = sal_False;
1345 mbNoAlign = sal_False;
1347 if ( nStyle & WB_NOSPLITDRAW )
1349 pNewSet->mnSplitSize -= 2;
1350 mbInvalidate = sal_False;
1353 if ( nStyle & WB_BORDER )
1355 ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
1356 mnRightBorder, mnBottomBorder );
1358 else
1360 mnLeftBorder = 0;
1361 mnTopBorder = 0;
1362 mnRightBorder = 0;
1363 mnBottomBorder = 0;
1366 DockingWindow::ImplInit( pParent, (nStyle | WB_CLIPCHILDREN) & ~(WB_BORDER | WB_SIZEABLE) );
1368 ImplInitSettings();
1371 // -----------------------------------------------------------------------
1373 void SplitWindow::ImplInitSettings()
1375 // Wenn fuer das MainSet eine Bitmap gesetzt wird, dann
1376 // brauchen wir nicht mehr den Hintergrund loeschen
1377 // Wenn MainSet Wallpaper hat, dann ist das der Hintergrund, ansonsten
1378 // sind es die Standard-Farben
1379 if ( mpMainSet->mpBitmap )
1380 SetBackground();
1381 else if ( mpMainSet->mpWallpaper )
1382 SetBackground( *mpMainSet->mpWallpaper );
1383 else
1385 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1387 Color aColor;
1388 if ( IsControlBackground() )
1389 aColor = GetControlBackground();
1390 else if ( Window::GetStyle() & WB_3DLOOK )
1391 aColor = rStyleSettings.GetFaceColor();
1392 else
1393 aColor = rStyleSettings.GetWindowColor();
1394 SetBackground( aColor );
1398 // =======================================================================
1400 SplitWindow::SplitWindow( Window* pParent, WinBits nStyle ) :
1401 DockingWindow( WINDOW_SPLITWINDOW )
1403 ImplInit( pParent, nStyle );
1406 // -----------------------------------------------------------------------
1408 SplitWindow::~SplitWindow()
1410 // Sets loeschen
1411 ImplDeleteSet( mpMainSet );
1412 mpMainSet = NULL; //NULL for base-class callbacks during dtoring
1415 // -----------------------------------------------------------------------
1417 void SplitWindow::ImplSetWindowSize( long nDelta )
1419 if ( !nDelta )
1420 return;
1422 Size aSize = GetSizePixel();
1423 switch ( meAlign )
1425 case WINDOWALIGN_TOP:
1426 aSize.Height() += nDelta;
1427 SetSizePixel( aSize );
1428 break;
1429 case WINDOWALIGN_BOTTOM:
1431 maDragRect.Top() += nDelta;
1432 Point aPos = GetPosPixel();
1433 aPos.Y() -= nDelta;
1434 aSize.Height() += nDelta;
1435 SetPosSizePixel( aPos, aSize );
1436 break;
1438 case WINDOWALIGN_LEFT:
1439 aSize.Width() += nDelta;
1440 SetSizePixel( aSize );
1441 break;
1442 case WINDOWALIGN_RIGHT:
1443 default:
1445 maDragRect.Left() += nDelta;
1446 Point aPos = GetPosPixel();
1447 aPos.X() -= nDelta;
1448 aSize.Width() += nDelta;
1449 SetPosSizePixel( aPos, aSize );
1450 break;
1454 SplitResize();
1457 // -----------------------------------------------------------------------
1459 Size SplitWindow::CalcLayoutSizePixel( const Size& aNewSize )
1461 Size aSize( aNewSize );
1462 long nSplitSize = mpMainSet->mnSplitSize-2;
1464 if ( mbAutoHide || mbFadeOut )
1465 nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1467 // Wenn Fenster sizeable ist, wird die groesse automatisch nach
1468 // dem MainSet festgelegt, wenn kein relatives Fenster enthalten
1469 // ist
1470 if ( mnWinStyle & WB_SIZEABLE )
1472 long nCurSize;
1473 long nCalcSize = 0;
1474 sal_uInt16 i;
1476 for ( i = 0; i < mpMainSet->mnItems; i++ )
1478 if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
1479 break;
1480 else
1481 nCalcSize += mpMainSet->mpItems[i].mnSize;
1484 if ( i == mpMainSet->mnItems )
1486 long nDelta = 0;
1487 Point aPos = GetPosPixel();
1489 if ( mbHorz )
1490 nCurSize = aNewSize.Height()-mnTopBorder-mnBottomBorder;
1491 else
1492 nCurSize = aNewSize.Width()-mnLeftBorder-mnRightBorder;
1493 nCurSize -= nSplitSize;
1494 nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
1496 nDelta = nCalcSize-nCurSize;
1497 if ( !nDelta )
1498 return aSize;
1500 switch ( meAlign )
1502 case WINDOWALIGN_TOP:
1503 aSize.Height() += nDelta;
1504 break;
1505 case WINDOWALIGN_BOTTOM:
1506 aPos.Y() -= nDelta;
1507 aSize.Height() += nDelta;
1508 break;
1509 case WINDOWALIGN_LEFT:
1510 aSize.Width() += nDelta;
1511 break;
1512 case WINDOWALIGN_RIGHT:
1513 default:
1514 aPos.X() -= nDelta;
1515 aSize.Width() += nDelta;
1516 break;
1521 return aSize;
1524 // -----------------------------------------------------------------------
1526 void SplitWindow::ImplCalcLayout()
1528 if ( !mbCalc || !mbRecalc || !mpMainSet->mpItems )
1529 return;
1531 long nSplitSize = mpMainSet->mnSplitSize-2;
1532 if ( mbAutoHide || mbFadeOut )
1533 nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1535 // Wenn Fenster sizeable ist, wird die groesse automatisch nach
1536 // dem MainSet festgelegt, wenn kein relatives Fenster enthalten
1537 // ist
1538 if ( mnWinStyle & WB_SIZEABLE )
1540 long nCurSize;
1541 long nCalcSize = 0;
1542 sal_uInt16 i;
1544 for ( i = 0; i < mpMainSet->mnItems; i++ )
1546 if ( mpMainSet->mpItems[i].mnBits & (SWIB_RELATIVESIZE | SWIB_PERCENTSIZE) )
1547 break;
1548 else
1549 nCalcSize += mpMainSet->mpItems[i].mnSize;
1552 if ( i == mpMainSet->mnItems )
1554 if ( mbHorz )
1555 nCurSize = mnDY-mnTopBorder-mnBottomBorder;
1556 else
1557 nCurSize = mnDX-mnLeftBorder-mnRightBorder;
1558 nCurSize -= nSplitSize;
1559 nCurSize -= (mpMainSet->mnItems-1)*mpMainSet->mnSplitSize;
1561 mbRecalc = sal_False;
1562 ImplSetWindowSize( nCalcSize-nCurSize );
1563 mbRecalc = sal_True;
1567 if ( (mnDX <= 0) || (mnDY <= 0) )
1568 return;
1570 // Groessen/Position vorberechnen
1571 long nL;
1572 long nT;
1573 long nW;
1574 long nH;
1576 if ( mbHorz )
1578 if ( mbBottomRight )
1579 nT = mnDY-mnBottomBorder;
1580 else
1581 nT = mnTopBorder;
1582 nL = mnLeftBorder;
1584 else
1586 if ( mbBottomRight )
1587 nL = mnDX-mnRightBorder;
1588 else
1589 nL = mnLeftBorder;
1590 nT = mnTopBorder;
1592 nW = mnDX-mnLeftBorder-mnRightBorder;
1593 nH = mnDY-mnTopBorder-mnBottomBorder;
1594 if ( mnWinStyle & WB_SIZEABLE )
1596 if ( mbHorz )
1597 nH -= nSplitSize;
1598 else
1599 nW -= nSplitSize;
1602 // Sets rekursiv berechnen
1603 ImplCalcSet( mpMainSet, nL, nT, nW, nH, mbHorz, !mbBottomRight );
1604 ImplCalcSet2( this, mpMainSet, sal_False, mbHorz, !mbBottomRight );
1605 mbCalc = sal_False;
1608 // -----------------------------------------------------------------------
1610 void SplitWindow::ImplUpdate()
1612 mbCalc = sal_True;
1614 if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
1616 if ( mpMainSet->mpItems )
1617 ImplCalcLayout();
1618 else
1619 Invalidate();
1623 // -----------------------------------------------------------------------
1625 void SplitWindow::ImplSplitMousePos( Point& rMousePos )
1627 if ( mnSplitTest & SPLIT_HORZ )
1629 rMousePos.X() -= mnMouseOff;
1630 if ( rMousePos.X() < maDragRect.Left() )
1631 rMousePos.X() = maDragRect.Left();
1632 else if ( rMousePos.X()+mpSplitSet->mnSplitSize+1 > maDragRect.Right() )
1633 rMousePos.X() = maDragRect.Right()-mpSplitSet->mnSplitSize+1;
1634 // Wegen FullDrag in Screen-Koordinaaten merken
1635 mnMSplitPos = OutputToScreenPixel( rMousePos ).X();
1637 else
1639 rMousePos.Y() -= mnMouseOff;
1640 if ( rMousePos.Y() < maDragRect.Top() )
1641 rMousePos.Y() = maDragRect.Top();
1642 else if ( rMousePos.Y()+mpSplitSet->mnSplitSize+1 > maDragRect.Bottom() )
1643 rMousePos.Y() = maDragRect.Bottom()-mpSplitSet->mnSplitSize+1;
1644 mnMSplitPos = OutputToScreenPixel( rMousePos ).Y();
1648 // -----------------------------------------------------------------------
1650 void SplitWindow::ImplGetButtonRect( Rectangle& rRect, long nEx, sal_Bool bTest ) const
1652 long nSplitSize = mpMainSet->mnSplitSize-1;
1653 if ( mbAutoHide || mbFadeOut || mbFadeIn )
1654 nSplitSize += SPLITWIN_SPLITSIZEEX;
1656 long nButtonSize = 0;
1657 if ( mbFadeIn )
1658 nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1659 if ( mbFadeOut )
1660 nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1661 if ( mbAutoHide )
1662 nButtonSize += SPLITWIN_SPLITSIZEAUTOHIDE+1;
1663 long nCenterEx = 0;
1664 if ( mbHorz )
1665 nCenterEx += ((mnDX-mnLeftBorder-mnRightBorder)-nButtonSize)/2;
1666 else
1667 nCenterEx += ((mnDY-mnTopBorder-mnBottomBorder)-nButtonSize)/2;
1668 if ( nCenterEx > 0 )
1669 nEx += nCenterEx;
1671 switch ( meAlign )
1673 case WINDOWALIGN_TOP:
1674 rRect.Left() = mnLeftBorder+nEx;
1675 rRect.Top() = mnDY-mnBottomBorder-nSplitSize;
1676 rRect.Right() = rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
1677 rRect.Bottom() = mnDY-mnBottomBorder-1;
1678 if ( bTest )
1680 rRect.Top() -= mnTopBorder;
1681 rRect.Bottom() += mnBottomBorder;
1683 break;
1684 case WINDOWALIGN_BOTTOM:
1685 rRect.Left() = mnLeftBorder+nEx;
1686 rRect.Top() = mnTopBorder;
1687 rRect.Right() = rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE;
1688 rRect.Bottom() = mnTopBorder+nSplitSize-1;
1689 if ( bTest )
1691 rRect.Top() -= mnTopBorder;
1692 rRect.Bottom() += mnBottomBorder;
1694 break;
1695 case WINDOWALIGN_LEFT:
1696 rRect.Left() = mnDX-mnRightBorder-nSplitSize;
1697 rRect.Top() = mnTopBorder+nEx;
1698 rRect.Right() = mnDX-mnRightBorder-1;
1699 rRect.Bottom() = rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
1700 if ( bTest )
1702 rRect.Left() -= mnLeftBorder;
1703 rRect.Right() += mnRightBorder;
1705 break;
1706 case WINDOWALIGN_RIGHT:
1707 rRect.Left() = mnLeftBorder;
1708 rRect.Top() = mnTopBorder+nEx;
1709 rRect.Right() = mnLeftBorder+nSplitSize-1;
1710 rRect.Bottom() = rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE;
1711 if ( bTest )
1713 rRect.Left() -= mnLeftBorder;
1714 rRect.Right() += mnRightBorder;
1716 break;
1720 // -----------------------------------------------------------------------
1722 void SplitWindow::ImplGetAutoHideRect( Rectangle& rRect, sal_Bool bTest ) const
1724 Rectangle aRect;
1726 if ( mbAutoHide )
1728 long nEx = 0;
1729 if ( mbFadeIn || mbFadeOut )
1730 nEx = SPLITWIN_SPLITSIZEFADE+1;
1731 ImplGetButtonRect( aRect, nEx, bTest && mbFadeIn );
1734 rRect = aRect;
1737 // -----------------------------------------------------------------------
1739 void SplitWindow::ImplGetFadeInRect( Rectangle& rRect, sal_Bool bTest ) const
1741 Rectangle aRect;
1743 if ( mbFadeIn )
1744 ImplGetButtonRect( aRect, 0, bTest );
1746 rRect = aRect;
1749 // -----------------------------------------------------------------------
1751 void SplitWindow::ImplGetFadeOutRect( Rectangle& rRect, sal_Bool ) const
1753 Rectangle aRect;
1755 if ( mbFadeOut )
1756 ImplGetButtonRect( aRect, 0, sal_False );
1758 rRect = aRect;
1761 // -----------------------------------------------------------------------
1763 void SplitWindow::ImplDrawButtonRect( const Rectangle& rRect, long nSize )
1765 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1767 if ( mbHorz )
1769 long nLeft = rRect.Left();
1770 long nRight = rRect.Right();
1771 long nCenter = rRect.Center().Y();
1772 long nEx1 = nLeft+((rRect.GetWidth()-nSize)/2)-2;
1773 long nEx2 = nEx1+nSize+3;
1774 SetLineColor( rStyleSettings.GetLightColor() );
1775 DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
1776 DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
1777 SetLineColor( rStyleSettings.GetShadowColor() );
1778 DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
1779 DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
1780 long i = nLeft+2;
1781 while ( i < nRight-3 )
1783 if ( (i < nEx1) || (i > nEx2 ) )
1785 DrawPixel( Point( i, nCenter-2 ), rStyleSettings.GetLightColor() );
1786 DrawPixel( Point( i+1, nCenter-2+1 ), rStyleSettings.GetShadowColor() );
1788 i++;
1789 if ( (i < nEx1) || ((i > nEx2 ) && (i < nRight-3)) )
1791 DrawPixel( Point( i, nCenter+2 ), rStyleSettings.GetLightColor() );
1792 DrawPixel( Point( i+1, nCenter+2+1 ), rStyleSettings.GetShadowColor() );
1794 i += 2;
1797 else
1799 long nTop = rRect.Top();
1800 long nBottom = rRect.Bottom();
1801 long nCenter = rRect.Center().X();
1802 long nEx1 = nTop+((rRect.GetHeight()-nSize)/2)-2;
1803 long nEx2 = nEx1+nSize+3;
1804 SetLineColor( rStyleSettings.GetLightColor() );
1805 DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Right(), rRect.Top() ) );
1806 DrawLine( Point( rRect.Left(), rRect.Top() ), Point( rRect.Left(), rRect.Bottom() ) );
1807 SetLineColor( rStyleSettings.GetShadowColor() );
1808 DrawLine( Point( rRect.Right(), rRect.Top() ), Point( rRect.Right(), rRect.Bottom() ) );
1809 DrawLine( Point( rRect.Left(), rRect.Bottom() ), Point( rRect.Right(), rRect.Bottom() ) );
1810 long i = nTop+2;
1811 while ( i < nBottom-3 )
1813 if ( (i < nEx1) || (i > nEx2 ) )
1815 DrawPixel( Point( nCenter-2, i ), rStyleSettings.GetLightColor() );
1816 DrawPixel( Point( nCenter-2+1, i+1 ), rStyleSettings.GetShadowColor() );
1818 i++;
1819 if ( (i < nEx1) || ((i > nEx2 ) && (i < nBottom-3)) )
1821 DrawPixel( Point( nCenter+2, i ), rStyleSettings.GetLightColor() );
1822 DrawPixel( Point( nCenter+2+1, i+1 ), rStyleSettings.GetShadowColor() );
1824 i += 2;
1829 // -----------------------------------------------------------------------
1831 void SplitWindow::ImplDrawAutoHide( sal_Bool bInPaint )
1833 if ( mbAutoHide )
1835 Rectangle aTempRect;
1836 ImplGetAutoHideRect( aTempRect );
1838 if ( !bInPaint )
1839 Erase( aTempRect );
1841 // ImageListe laden, wenn noch nicht vorhanden
1842 ImplSVData* pSVData = ImplGetSVData();
1843 ImageList* pImageList;
1844 if ( mbHorz )
1846 if ( !pSVData->maCtrlData.mpSplitHPinImgList )
1848 ResMgr* pResMgr = ImplGetResMgr();
1849 if( pResMgr )
1851 Color aNonAlphaMask( 0x00, 0x00, 0xFF );
1852 pSVData->maCtrlData.mpSplitHPinImgList = new ImageList(4);
1853 pSVData->maCtrlData.mpSplitHPinImgList->InsertFromHorizontalBitmap
1854 ( ResId( SV_RESID_BITMAP_SPLITHPIN, *pResMgr ), 4, &aNonAlphaMask );
1857 pImageList = pSVData->maCtrlData.mpSplitHPinImgList;
1859 else
1861 if ( !pSVData->maCtrlData.mpSplitVPinImgList )
1863 ResMgr* pResMgr = ImplGetResMgr();
1864 pSVData->maCtrlData.mpSplitVPinImgList = new ImageList(4);
1865 if( pResMgr )
1867 Color aNonAlphaMask( 0x00, 0x00, 0xFF );
1868 pSVData->maCtrlData.mpSplitVPinImgList->InsertFromHorizontalBitmap
1869 ( ResId( SV_RESID_BITMAP_SPLITVPIN, *pResMgr ), 4, &aNonAlphaMask );
1872 pImageList = pSVData->maCtrlData.mpSplitVPinImgList;
1875 // Image ermitteln und zurueckgeben
1876 sal_uInt16 nId;
1877 if ( mbAutoHidePressed )
1879 if ( mbAutoHideIn )
1880 nId = 3;
1881 else
1882 nId = 4;
1884 else
1886 if ( mbAutoHideIn )
1887 nId = 1;
1888 else
1889 nId = 2;
1892 Image aImage = pImageList->GetImage( nId );
1893 Size aImageSize = aImage.GetSizePixel();
1894 Point aPos( aTempRect.Left()+((aTempRect.GetWidth()-aImageSize.Width())/2),
1895 aTempRect.Top()+((aTempRect.GetHeight()-aImageSize.Height())/2) );
1896 long nSize;
1897 if ( mbHorz )
1898 nSize = aImageSize.Width();
1899 else
1900 nSize = aImageSize.Height();
1901 ImplDrawButtonRect( aTempRect, nSize );
1902 DrawImage( aPos, aImage );
1906 // -----------------------------------------------------------------------
1908 void SplitWindow::ImplDrawFadeArrow( const Point& rPt, sal_Bool bHorz, sal_Bool bLeft )
1910 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1912 int x( rPt.X() );
1913 int y( rPt.Y() );
1915 Color aCol;
1916 if( !bHorz )
1918 int dx = 1;
1919 if( bLeft )
1921 x ++;
1922 dx = -1;
1925 x++; y++;
1926 aCol = Color( COL_WHITE );
1927 DrawPixel( Point(x, y), aCol );
1928 DrawPixel( Point(x, y+1), aCol );
1929 DrawPixel( Point(x, y+2), aCol );
1930 DrawPixel( Point(x+dx, y+1), aCol );
1932 x--; y--;
1933 aCol = rStyleSettings.GetDarkShadowColor();
1934 DrawPixel( Point(x, y), rStyleSettings.GetDarkShadowColor() );
1935 DrawPixel( Point(x, y+1), rStyleSettings.GetDarkShadowColor() );
1936 DrawPixel( Point(x, y+2), rStyleSettings.GetDarkShadowColor() );
1937 DrawPixel( Point(x+dx, y+1), rStyleSettings.GetDarkShadowColor() );
1939 else
1941 int dy = 1;
1942 if( bLeft )
1944 y ++;
1945 dy = -1;
1948 x++; y++;
1949 aCol = Color( COL_WHITE );
1950 DrawPixel( Point(x, y), aCol );
1951 DrawPixel( Point(x+1, y), aCol );
1952 DrawPixel( Point(x+2, y), aCol );
1953 DrawPixel( Point(x+1, y+dy), aCol );
1955 x--; y--;
1956 aCol = rStyleSettings.GetDarkShadowColor();
1957 DrawPixel( Point(x, y), aCol );
1958 DrawPixel( Point(x+1, y), aCol );
1959 DrawPixel( Point(x+2, y), aCol );
1960 DrawPixel( Point(x+1, y+dy), aCol );
1964 void SplitWindow::ImplDrawGrip( const Rectangle& rRect, sal_Bool bHorz, sal_Bool bLeft )
1966 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1968 if( rRect.IsInside( GetPointerPosPixel() ) )
1970 DrawWallpaper( rRect, Wallpaper( Color( COL_WHITE ) ) );
1971 DrawSelectionBackground( rRect, 2, sal_False, sal_False, sal_False );
1974 if( bHorz )
1976 int width = (int) (0.5 * rRect.getWidth() + 0.5);
1977 int i = rRect.Left() + (rRect.getWidth() - width) / 2;
1978 width += i;
1979 const int y = rRect.Top() + 1;
1980 ImplDrawFadeArrow( Point( i-8, y), bHorz, bLeft );
1981 while( i <= width )
1984 DrawPixel( Point(i, y), rStyleSettings.GetDarkShadowColor() );
1985 DrawPixel( Point(i+1, y), rStyleSettings.GetShadowColor() );
1987 DrawPixel( Point(i, y+1), rStyleSettings.GetShadowColor() );
1988 DrawPixel( Point(i+1, y+1), rStyleSettings.GetFaceColor() );
1989 DrawPixel( Point(i+2, y+1), Color(COL_WHITE) );
1991 DrawPixel( Point(i+1, y+2), Color(COL_WHITE) );
1992 DrawPixel( Point(i+2, y+2), Color(COL_WHITE) );
1993 i+=4;
1995 ImplDrawFadeArrow( Point( i+3, y), bHorz, bLeft );
1997 else
1999 int height = (int) (0.5 * rRect.getHeight() + 0.5);
2000 int i = rRect.Top() + (rRect.getHeight() - height) / 2;
2001 height += i;
2002 const int x = rRect.Left() + 2;
2003 ImplDrawFadeArrow( Point( x, i-8), bHorz, bLeft );
2004 while( i <= height )
2007 DrawPixel( Point(x, i), rStyleSettings.GetDarkShadowColor() );
2008 DrawPixel( Point(x+1, i), rStyleSettings.GetShadowColor() );
2010 DrawPixel( Point(x, i+1), rStyleSettings.GetShadowColor() );
2011 DrawPixel( Point(x+1, i+1), rStyleSettings.GetFaceColor() );
2012 DrawPixel( Point(x+2, i+1), Color(COL_WHITE) );
2014 DrawPixel( Point(x+1, i+2), Color(COL_WHITE) );
2015 DrawPixel( Point(x+2, i+2), Color(COL_WHITE) );
2016 i+=4;
2018 ImplDrawFadeArrow( Point( x, i+3), bHorz, bLeft );
2022 void SplitWindow::ImplDrawFadeIn( sal_Bool bInPaint )
2024 if ( mbFadeIn )
2026 Rectangle aTempRect;
2027 ImplGetFadeInRect( aTempRect );
2029 sal_Bool bLeft = sal_True;
2030 switch ( meAlign )
2032 case WINDOWALIGN_TOP:
2033 case WINDOWALIGN_LEFT:
2034 bLeft = sal_False;
2035 break;
2036 case WINDOWALIGN_BOTTOM:
2037 case WINDOWALIGN_RIGHT:
2038 default:
2039 bLeft = sal_True;
2040 break;
2043 if ( !bInPaint )
2044 Erase( aTempRect );
2046 ImplDrawGrip( aTempRect, (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM), bLeft );
2050 // -----------------------------------------------------------------------
2052 void SplitWindow::ImplDrawFadeOut( sal_Bool bInPaint )
2054 if ( mbFadeOut )
2056 Rectangle aTempRect;
2057 ImplGetFadeOutRect( aTempRect );
2059 sal_Bool bLeft = sal_True;
2060 switch ( meAlign )
2062 case WINDOWALIGN_BOTTOM:
2063 case WINDOWALIGN_RIGHT:
2064 bLeft = sal_False;
2065 break;
2066 case WINDOWALIGN_TOP:
2067 case WINDOWALIGN_LEFT:
2068 default:
2069 bLeft = sal_True;
2070 break;
2073 if ( !bInPaint )
2074 Erase( aTempRect );
2076 ImplDrawGrip( aTempRect, (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM), bLeft );
2080 // -----------------------------------------------------------------------
2081 void SplitWindow::ImplStartSplit( const MouseEvent& rMEvt )
2083 Point aMousePosPixel = rMEvt.GetPosPixel();
2084 mnSplitTest = ImplTestSplit( this, aMousePosPixel, mnMouseOff, &mpSplitSet, mnSplitPos );
2086 if ( mnSplitTest && !(mnSplitTest & SPLIT_NOSPLIT) )
2088 ImplSplitItem* pSplitItem;
2089 long nCurMaxSize;
2090 sal_uInt16 nTemp;
2091 sal_Bool bDown;
2092 sal_Bool bPropSmaller;
2094 mnMouseModifier = rMEvt.GetModifier();
2095 if ( !(mnMouseModifier & KEY_SHIFT) || (mnSplitPos+1 >= mpSplitSet->mnItems) )
2096 bPropSmaller = sal_False;
2097 else
2098 bPropSmaller = sal_True;
2100 // Hier kann noch die maximale Groesse gesetzt werden
2101 StartSplit();
2103 if ( mnMaxSize )
2104 nCurMaxSize = mnMaxSize;
2105 else
2107 Size aSize = GetParent()->GetOutputSizePixel();
2108 if ( mbHorz )
2109 nCurMaxSize = aSize.Height();
2110 else
2111 nCurMaxSize = aSize.Width();
2114 if ( mpSplitSet->mpItems )
2116 bDown = sal_True;
2117 if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2118 bDown = sal_False;
2120 pSplitItem = &(mpSplitSet->mpItems[mnSplitPos]);
2121 maDragRect.Left() = pSplitItem->mnLeft;
2122 maDragRect.Top() = pSplitItem->mnTop;
2123 maDragRect.Right() = pSplitItem->mnLeft+pSplitItem->mnWidth-1;
2124 maDragRect.Bottom() = pSplitItem->mnTop+pSplitItem->mnHeight-1;
2126 if ( mnSplitTest & SPLIT_HORZ )
2128 if ( bDown )
2129 maDragRect.Right() += mpSplitSet->mnSplitSize;
2130 else
2131 maDragRect.Left() -= mpSplitSet->mnSplitSize;
2133 else
2135 if ( bDown )
2136 maDragRect.Bottom() += mpSplitSet->mnSplitSize;
2137 else
2138 maDragRect.Top() -= mpSplitSet->mnSplitSize;
2141 if ( mnSplitPos )
2143 nTemp = mnSplitPos;
2144 while ( nTemp )
2146 pSplitItem = &(mpSplitSet->mpItems[nTemp-1]);
2147 if ( pSplitItem->mbFixed )
2148 break;
2149 else
2151 if ( mnSplitTest & SPLIT_HORZ )
2153 if ( bDown )
2154 maDragRect.Left() -= pSplitItem->mnPixSize;
2155 else
2156 maDragRect.Right() += pSplitItem->mnPixSize;
2158 else
2160 if ( bDown )
2161 maDragRect.Top() -= pSplitItem->mnPixSize;
2162 else
2163 maDragRect.Bottom() += pSplitItem->mnPixSize;
2166 nTemp--;
2170 if ( (mpSplitSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) && !bPropSmaller )
2172 if ( bDown )
2174 if ( mbHorz )
2175 maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
2176 else
2177 maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
2179 else
2181 if ( mbHorz )
2182 maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
2183 else
2184 maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
2187 else
2189 nTemp = mnSplitPos+1;
2190 while ( nTemp < mpSplitSet->mnItems )
2192 pSplitItem = &(mpSplitSet->mpItems[nTemp]);
2193 if ( pSplitItem->mbFixed )
2194 break;
2195 else
2197 if ( mnSplitTest & SPLIT_HORZ )
2199 if ( bDown )
2200 maDragRect.Right() += pSplitItem->mnPixSize;
2201 else
2202 maDragRect.Left() -= pSplitItem->mnPixSize;
2204 else
2206 if ( bDown )
2207 maDragRect.Bottom() += pSplitItem->mnPixSize;
2208 else
2209 maDragRect.Top() -= pSplitItem->mnPixSize;
2212 nTemp++;
2216 else
2218 maDragRect.Left() = mnLeftBorder;
2219 maDragRect.Top() = mnTopBorder;
2220 maDragRect.Right() = mnDX-mnRightBorder-1;
2221 maDragRect.Bottom() = mnDY-mnBottomBorder-1;
2222 if ( mbHorz )
2224 if ( mbBottomRight )
2225 maDragRect.Top() -= nCurMaxSize-mnDY-mnBottomBorder;
2226 else
2227 maDragRect.Bottom() += nCurMaxSize-mnDY-mnTopBorder;
2229 else
2231 if ( mbBottomRight )
2232 maDragRect.Left() -= nCurMaxSize-mnDX-mnRightBorder;
2233 else
2234 maDragRect.Right() += nCurMaxSize-mnDX-mnLeftBorder;
2238 StartTracking();
2240 mbDragFull = (GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0;
2242 ImplSplitMousePos( aMousePosPixel );
2244 if ( !mbDragFull )
2245 ImplDrawSplitTracking( this, aMousePosPixel );
2246 else
2248 ImplSplitItem* pItems = mpSplitSet->mpItems;
2249 sal_uInt16 nItems = mpSplitSet->mnItems;
2250 mpLastSizes = new long[nItems*2];
2251 for ( sal_uInt16 i = 0; i < nItems; i++ )
2253 mpLastSizes[i*2] = pItems[i].mnSize;
2254 mpLastSizes[i*2+1] = pItems[i].mnPixSize;
2257 mnMStartPos = mnMSplitPos;
2259 PointerStyle eStyle = POINTER_ARROW;
2260 if ( mnSplitTest & SPLIT_HORZ )
2261 eStyle = POINTER_HSPLIT;
2262 else if ( mnSplitTest & SPLIT_VERT )
2263 eStyle = POINTER_VSPLIT;
2265 Pointer aPtr( eStyle );
2266 SetPointer( aPtr );
2271 // -----------------------------------------------------------------------
2273 void SplitWindow::StartSplit()
2275 maStartSplitHdl.Call( this );
2278 // -----------------------------------------------------------------------
2280 void SplitWindow::Split()
2282 maSplitHdl.Call( this );
2285 // -----------------------------------------------------------------------
2287 void SplitWindow::SplitResize()
2289 maSplitResizeHdl.Call( this );
2292 // -----------------------------------------------------------------------
2294 void SplitWindow::AutoHide()
2296 maAutoHideHdl.Call( this );
2299 // -----------------------------------------------------------------------
2301 void SplitWindow::FadeIn()
2303 maFadeInHdl.Call( this );
2306 // -----------------------------------------------------------------------
2308 void SplitWindow::FadeOut()
2310 maFadeOutHdl.Call( this );
2313 // -----------------------------------------------------------------------
2315 void SplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
2317 if ( !rMEvt.IsLeft() || rMEvt.IsMod2() )
2319 DockingWindow::MouseButtonDown( rMEvt );
2320 return;
2323 Point aMousePosPixel = rMEvt.GetPosPixel();
2324 Rectangle aTestRect;
2326 mbFadeNoButtonMode = sal_False;
2327 ImplGetAutoHideRect( aTestRect, sal_True );
2328 if ( aTestRect.IsInside( aMousePosPixel ) )
2330 mbAutoHideDown = sal_True;
2331 mbAutoHidePressed = sal_True;
2332 ImplDrawAutoHide( sal_False );
2334 else
2336 ImplGetFadeOutRect( aTestRect, sal_True );
2337 if ( aTestRect.IsInside( aMousePosPixel ) )
2339 mbFadeOutDown = sal_True;
2340 mbFadeOutPressed = sal_True;
2341 ImplDrawFadeOut( sal_False );
2343 else
2345 ImplGetFadeInRect( aTestRect, sal_True );
2346 if ( aTestRect.IsInside( aMousePosPixel ) )
2348 mbFadeInDown = sal_True;
2349 mbFadeInPressed = sal_True;
2350 ImplDrawFadeIn( sal_False );
2352 else if ( !aTestRect.IsEmpty() && !(mnWinStyle & WB_SIZEABLE) )
2354 mbFadeNoButtonMode = sal_True;
2355 FadeIn();
2356 return;
2361 if ( mbAutoHideDown || mbFadeInDown || mbFadeOutDown )
2362 StartTracking();
2363 else
2364 ImplStartSplit( rMEvt );
2367 // -----------------------------------------------------------------------
2369 void SplitWindow::MouseMove( const MouseEvent& rMEvt )
2371 if ( !IsTracking() )
2373 Point aPos = rMEvt.GetPosPixel();
2374 long nTemp;
2375 ImplSplitSet* pTempSplitSet;
2376 sal_uInt16 nTempSplitPos;
2377 sal_uInt16 nSplitTest = ImplTestSplit( this, aPos, nTemp, &pTempSplitSet, nTempSplitPos );
2378 PointerStyle eStyle = POINTER_ARROW;
2379 Rectangle aAutoHideRect;
2380 Rectangle aFadeInRect;
2381 Rectangle aFadeOutRect;
2383 ImplGetAutoHideRect( aAutoHideRect );
2384 ImplGetFadeInRect( aFadeInRect );
2385 ImplGetFadeOutRect( aFadeOutRect );
2386 if ( !aAutoHideRect.IsInside( aPos ) &&
2387 !aFadeInRect.IsInside( aPos ) &&
2388 !aFadeOutRect.IsInside( aPos ) )
2390 if ( nSplitTest && !(nSplitTest & SPLIT_NOSPLIT) )
2392 if ( nSplitTest & SPLIT_HORZ )
2393 eStyle = POINTER_HSPLIT;
2394 else if ( nSplitTest & SPLIT_VERT )
2395 eStyle = POINTER_VSPLIT;
2399 Pointer aPtr( eStyle );
2400 SetPointer( aPtr );
2404 // -----------------------------------------------------------------------
2406 void SplitWindow::Tracking( const TrackingEvent& rTEvt )
2408 Point aMousePosPixel = rTEvt.GetMouseEvent().GetPosPixel();
2410 if ( mbAutoHideDown )
2412 if ( rTEvt.IsTrackingEnded() )
2414 mbAutoHideDown = sal_False;
2415 if ( mbAutoHidePressed )
2417 mbAutoHidePressed = sal_False;
2419 if ( !rTEvt.IsTrackingCanceled() )
2421 mbAutoHideIn = !mbAutoHideIn;
2422 ImplDrawAutoHide( sal_False );
2423 AutoHide();
2425 else
2426 ImplDrawAutoHide( sal_False );
2429 else
2431 Rectangle aTestRect;
2432 ImplGetAutoHideRect( aTestRect, sal_True );
2433 sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2434 if ( bNewPressed != mbAutoHidePressed )
2436 mbAutoHidePressed = bNewPressed;
2437 ImplDrawAutoHide( sal_False );
2441 else if ( mbFadeInDown )
2443 if ( rTEvt.IsTrackingEnded() )
2445 mbFadeInDown = sal_False;
2446 if ( mbFadeInPressed )
2448 mbFadeInPressed = sal_False;
2449 ImplDrawFadeIn( sal_False );
2451 if ( !rTEvt.IsTrackingCanceled() )
2452 FadeIn();
2455 else
2457 Rectangle aTestRect;
2458 ImplGetFadeInRect( aTestRect, sal_True );
2459 sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2460 if ( bNewPressed != mbFadeInPressed )
2462 mbFadeInPressed = bNewPressed;
2463 ImplDrawFadeIn( sal_False );
2467 else if ( mbFadeOutDown )
2469 if ( rTEvt.IsTrackingEnded() )
2471 mbFadeOutDown = sal_False;
2472 if ( mbFadeOutPressed )
2474 mbFadeOutPressed = sal_False;
2475 ImplDrawFadeOut( sal_False );
2477 if ( !rTEvt.IsTrackingCanceled() )
2478 FadeOut();
2481 else
2483 Rectangle aTestRect;
2484 ImplGetFadeOutRect( aTestRect, sal_True );
2485 sal_Bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
2486 if ( bNewPressed == sal_False )
2488 mbFadeOutPressed = bNewPressed;
2489 ImplDrawFadeOut( sal_False );
2491 // We need a mouseevent with a position inside the button for the
2492 // ImplStartSplit function!
2493 MouseEvent aOrgMEvt = rTEvt.GetMouseEvent();
2494 MouseEvent aNewMEvt = MouseEvent( aTestRect.Center(), aOrgMEvt.GetClicks(),
2495 aOrgMEvt.GetMode(), aOrgMEvt.GetButtons(),
2496 aOrgMEvt.GetModifier() );
2498 ImplStartSplit( aNewMEvt );
2499 mbFadeOutDown = sal_False;
2503 else
2505 ImplSplitMousePos( aMousePosPixel );
2506 sal_Bool bSplit = sal_True;
2507 if ( mbDragFull )
2509 if ( rTEvt.IsTrackingEnded() )
2511 if ( rTEvt.IsTrackingCanceled() )
2513 ImplSplitItem* pItems = mpSplitSet->mpItems;
2514 sal_uInt16 nItems = mpSplitSet->mnItems;
2515 for ( sal_uInt16 i = 0; i < nItems; i++ )
2517 pItems[i].mnSize = mpLastSizes[i*2];
2518 pItems[i].mnPixSize = mpLastSizes[i*2+1];
2520 ImplUpdate();
2521 Split();
2523 bSplit = sal_False;
2526 else
2528 if ( rTEvt.IsTrackingEnded() )
2530 HideTracking();
2531 bSplit = !rTEvt.IsTrackingCanceled();
2533 else
2535 ImplDrawSplitTracking( this, aMousePosPixel );
2536 bSplit = sal_False;
2540 if ( bSplit )
2542 sal_Bool bPropSmaller = (mnMouseModifier & KEY_SHIFT) ? sal_True : sal_False;
2543 sal_Bool bPropGreater = (mnMouseModifier & KEY_MOD1) ? sal_True : sal_False;
2544 long nDelta = mnMSplitPos-mnMStartPos;
2546 if ( (mnSplitTest & SPLIT_WINDOW) && !mpMainSet->mpItems )
2548 if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2549 nDelta *= -1;
2550 ImplSetWindowSize( nDelta );
2552 else
2554 long nNewSize = mpSplitSet->mpItems[mnSplitPos].mnPixSize;
2555 if ( (mpSplitSet == mpMainSet) && mbBottomRight )
2556 nNewSize -= nDelta;
2557 else
2558 nNewSize += nDelta;
2559 SplitItem( mpSplitSet->mpItems[mnSplitPos].mnId, nNewSize,
2560 bPropSmaller, bPropGreater );
2563 Split();
2565 if ( mbDragFull )
2567 Update();
2568 mnMStartPos = mnMSplitPos;
2572 if ( rTEvt.IsTrackingEnded() )
2574 delete mpLastSizes;
2575 mpLastSizes = NULL;
2576 mpSplitSet = NULL;
2577 mnMouseOff = 0;
2578 mnMStartPos = 0;
2579 mnMSplitPos = 0;
2580 mnMouseModifier = 0;
2581 mnSplitTest = 0;
2582 mnSplitPos = 0;
2587 // -----------------------------------------------------------------------
2589 long SplitWindow::PreNotify( NotifyEvent& rNEvt )
2591 const MouseEvent* pMouseEvt = NULL;
2593 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2595 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2597 // trigger redraw if mouse over state has changed
2598 Rectangle aFadeInRect;
2599 Rectangle aFadeOutRect;
2600 ImplGetFadeInRect( aFadeInRect );
2601 ImplGetFadeOutRect( aFadeOutRect );
2603 if ( aFadeInRect.IsInside( GetPointerPosPixel() ) != aFadeInRect.IsInside( GetLastPointerPosPixel() ) )
2604 Invalidate( aFadeInRect );
2605 if ( aFadeOutRect.IsInside( GetPointerPosPixel() ) != aFadeOutRect.IsInside( GetLastPointerPosPixel() ) )
2606 Invalidate( aFadeOutRect );
2608 if( pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
2610 Invalidate( aFadeInRect );
2611 Invalidate( aFadeOutRect );
2615 return Window::PreNotify( rNEvt );
2618 // -----------------------------------------------------------------------
2620 void SplitWindow::Paint( const Rectangle& )
2622 if ( mnWinStyle & WB_BORDER )
2623 ImplDrawBorder( this );
2625 ImplDrawBorderLine( this );
2626 ImplDrawFadeOut( sal_True );
2627 ImplDrawFadeIn( sal_True );
2628 ImplDrawAutoHide( sal_True );
2630 // FrameSet-Hintergruende zeichnen
2631 ImplDrawBack( this, mpMainSet );
2633 // Splitter zeichnen
2634 if ( !(mnWinStyle & WB_NOSPLITDRAW) )
2635 ImplDrawSplit( this, mpMainSet, mbHorz, !mbBottomRight );
2638 // -----------------------------------------------------------------------
2640 void SplitWindow::Move()
2642 DockingWindow::Move();
2645 // -----------------------------------------------------------------------
2647 void SplitWindow::Resize()
2649 Size aSize = GetOutputSizePixel();
2650 mnDX = aSize.Width();
2651 mnDY = aSize.Height();
2653 ImplUpdate();
2654 Invalidate();
2657 // -----------------------------------------------------------------------
2659 void SplitWindow::RequestHelp( const HelpEvent& rHEvt )
2661 // no keyboard help for splitwin
2662 if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) && !rHEvt.KeyboardActivated() )
2664 Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
2665 Rectangle aHelpRect;
2666 sal_uInt16 nHelpResId = 0;
2668 ImplGetAutoHideRect( aHelpRect, sal_True );
2669 if ( aHelpRect.IsInside( aMousePosPixel ) )
2671 if ( mbAutoHideIn )
2672 nHelpResId = SV_HELPTEXT_SPLITFIXED;
2673 else
2674 nHelpResId = SV_HELPTEXT_SPLITFLOATING;
2676 else
2678 ImplGetFadeInRect( aHelpRect, sal_True );
2679 if ( aHelpRect.IsInside( aMousePosPixel ) )
2680 nHelpResId = SV_HELPTEXT_FADEIN;
2681 else
2683 ImplGetFadeOutRect( aHelpRect, sal_True );
2684 if ( aHelpRect.IsInside( aMousePosPixel ) )
2685 nHelpResId = SV_HELPTEXT_FADEOUT;
2689 // Rechteck ermitteln
2690 if ( nHelpResId )
2692 Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
2693 aHelpRect.Left() = aPt.X();
2694 aHelpRect.Top() = aPt.Y();
2695 aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
2696 aHelpRect.Right() = aPt.X();
2697 aHelpRect.Bottom() = aPt.Y();
2699 // Text ermitteln und anzeigen
2700 XubString aStr;
2701 ResMgr* pResMgr = ImplGetResMgr();
2702 if( pResMgr )
2703 aStr = ResId( nHelpResId, *pResMgr ).toString();
2704 if ( rHEvt.GetMode() & HELPMODE_BALLOON )
2705 Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aStr );
2706 else
2707 Help::ShowQuickHelp( this, aHelpRect, aStr );
2708 return;
2712 DockingWindow::RequestHelp( rHEvt );
2715 // -----------------------------------------------------------------------
2717 void SplitWindow::StateChanged( StateChangedType nType )
2719 switch ( nType )
2721 case STATE_CHANGE_INITSHOW:
2722 if ( IsUpdateMode() )
2723 ImplCalcLayout();
2724 break;
2725 case STATE_CHANGE_UPDATEMODE:
2726 if ( IsUpdateMode() && IsReallyShown() )
2727 ImplCalcLayout();
2728 break;
2729 case STATE_CHANGE_CONTROLBACKGROUND:
2730 ImplInitSettings();
2731 Invalidate();
2732 break;
2735 DockingWindow::StateChanged( nType );
2738 // -----------------------------------------------------------------------
2740 void SplitWindow::DataChanged( const DataChangedEvent& rDCEvt )
2742 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2743 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2745 ImplInitSettings();
2746 Invalidate();
2748 else
2749 DockingWindow::DataChanged( rDCEvt );
2752 // -----------------------------------------------------------------------
2754 void SplitWindow::InsertItem( sal_uInt16 nId, Window* pWindow, long nSize,
2755 sal_uInt16 nPos, sal_uInt16 nSetId,
2756 SplitWindowItemBits nBits )
2758 #ifdef DBG_UTIL
2759 sal_uInt16 nDbgDummy;
2760 DBG_ASSERT( ImplFindSet( mpMainSet, nSetId ), "SplitWindow::InsertItem() - Set not exists" );
2761 DBG_ASSERT( !ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::InsertItem() - Id already exists" );
2762 #endif
2764 // Size has to be at least 1.
2765 if ( nSize < 1 )
2766 nSize = 1;
2768 ImplSplitSet* pSet = ImplFindSet( mpMainSet, nSetId );
2769 ImplSplitSet* pNewSet;
2770 ImplSplitItem* pItem;
2772 // Make room for the new item.
2773 if ( nPos > pSet->mnItems )
2774 nPos = pSet->mnItems;
2775 ImplSplitItem* pNewItems = new ImplSplitItem[pSet->mnItems+1];
2776 if ( nPos )
2777 memcpy( pNewItems, pSet->mpItems, sizeof( ImplSplitItem )*nPos );
2778 if ( nPos < pSet->mnItems )
2779 memcpy( pNewItems+nPos+1, pSet->mpItems+nPos, sizeof( ImplSplitItem )*(pSet->mnItems-nPos) );
2780 delete[] pSet->mpItems;
2781 pSet->mpItems = pNewItems;
2782 pSet->mnItems++;
2783 pSet->mbCalcPix = sal_True;
2785 // Create and initialize item.
2786 pItem = &(pSet->mpItems[nPos]);
2787 memset( pItem, 0, sizeof( ImplSplitItem ) );
2788 pItem->mnSize = nSize;
2789 pItem->mnId = nId;
2790 pItem->mnBits = nBits;
2791 pItem->mnMinSize=-1;
2792 pItem->mnMaxSize=-1;
2794 if ( pWindow )
2796 pItem->mpWindow = pWindow;
2797 pItem->mpOrgParent = pWindow->GetParent();
2799 // Attach window to SplitWindow.
2800 pWindow->Hide();
2801 pWindow->SetParent( this );
2803 else
2805 pNewSet = new ImplSplitSet;
2806 pNewSet->mpItems = NULL;
2807 pNewSet->mpWallpaper = NULL;
2808 pNewSet->mpBitmap = NULL;
2809 pNewSet->mnLastSize = 0;
2810 pNewSet->mnItems = 0;
2811 pNewSet->mnId = nId;
2812 pNewSet->mnSplitSize = pSet->mnSplitSize;
2813 pNewSet->mbCalcPix = sal_True;
2815 pItem->mpSet = pNewSet;
2818 ImplUpdate();
2821 // -----------------------------------------------------------------------
2823 void SplitWindow::InsertItem( sal_uInt16 nId, long nSize,
2824 sal_uInt16 nPos, sal_uInt16 nSetId,
2825 SplitWindowItemBits nBits )
2827 InsertItem( nId, NULL, nSize, nPos, nSetId, nBits );
2830 // -----------------------------------------------------------------------
2832 void SplitWindow::RemoveItem( sal_uInt16 nId, sal_Bool bHide )
2834 #ifdef DBG_UTIL
2835 sal_uInt16 nDbgDummy;
2836 DBG_ASSERT( ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::RemoveItem() - Id not found" );
2837 #endif
2839 // Set suchen
2840 sal_uInt16 nPos;
2841 ImplSplitSet* pSet = ImplFindItem( mpMainSet, nId, nPos );
2842 ImplSplitItem* pItem = &(pSet->mpItems[nPos]);
2843 Window* pWindow = pItem->mpWindow;
2844 Window* pOrgParent = pItem->mpOrgParent;
2846 // Evt. Set loeschen
2847 if ( !pWindow )
2848 ImplDeleteSet( pItem->mpSet );
2850 // Item entfernen
2851 pSet->mnItems--;
2852 pSet->mbCalcPix = sal_True;
2853 if ( pSet->mnItems )
2855 memmove( pSet->mpItems+nPos, pSet->mpItems+nPos+1,
2856 (pSet->mnItems-nPos)*sizeof( ImplSplitItem ) );
2858 else
2860 delete[] pSet->mpItems;
2861 pSet->mpItems = NULL;
2864 ImplUpdate();
2866 // Window erst hier loeschen, um weniger Paints zu haben
2867 if ( pWindow )
2869 // Fenster wieder herstellen
2870 if ( bHide || (pOrgParent != this) )
2872 pWindow->Hide();
2873 pWindow->SetParent( pOrgParent );
2878 // -----------------------------------------------------------------------
2880 void SplitWindow::Clear()
2882 // Alle Sets loeschen
2883 ImplDeleteSet( mpMainSet );
2885 // Main-Set wieder anlegen
2886 mpMainSet = new ImplSplitSet;
2887 mpMainSet->mpItems = NULL;
2888 mpMainSet->mpWallpaper = NULL;
2889 mpMainSet->mpBitmap = NULL;
2890 mpMainSet->mnLastSize = 0;
2891 mpMainSet->mnItems = 0;
2892 mpMainSet->mnId = 0;
2893 mpMainSet->mnSplitSize = SPLITWIN_SPLITSIZE;
2894 mpMainSet->mbCalcPix = sal_True;
2895 if ( mnWinStyle & WB_NOSPLITDRAW )
2896 mpMainSet->mnSplitSize -= 2;
2897 mpBaseSet = mpMainSet;
2899 // Und neu invalidieren
2900 ImplUpdate();
2903 // -----------------------------------------------------------------------
2905 void SplitWindow::SplitItem( sal_uInt16 nId, long nNewSize,
2906 sal_Bool bPropSmall, sal_Bool bPropGreat )
2908 sal_uInt16 nItems;
2909 sal_uInt16 nPos;
2910 sal_uInt16 nMin;
2911 sal_uInt16 nMax;
2912 sal_uInt16 i;
2913 sal_uInt16 n;
2914 long nDelta;
2915 long nTempDelta;
2916 ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
2917 ImplSplitItem* pItems;
2919 if ( !pSet )
2920 return;
2922 nItems = pSet->mnItems;
2923 pItems = pSet->mpItems;
2925 // When there is an explicit minimum or maximum size then move nNewSize
2926 // into that range (when it is not yet already in it.)
2927 nNewSize = ValidateSize(nNewSize, pItems[nPos]);
2929 if ( mbCalc )
2931 pItems[nPos].mnSize = nNewSize;
2932 return;
2935 nDelta = nNewSize-pItems[nPos].mnPixSize;
2936 if ( !nDelta )
2937 return;
2939 // Bereich berechnen, der beim Splitten betroffen sein kann
2940 nMin = 0;
2941 nMax = nItems;
2942 for ( i = 0; i < nItems; i++ )
2944 if ( pItems[i].mbFixed )
2946 if ( i < nPos )
2947 nMin = i+1;
2948 else
2949 nMax = i;
2953 // Wenn das Fenster sizeable ist, wird das TopSet anders behandelt
2954 sal_Bool bSmall = sal_True;
2955 sal_Bool bGreat = sal_True;
2956 if ( (pSet == mpMainSet) && (mnWinStyle & WB_SIZEABLE) )
2958 if ( nPos < pSet->mnItems-1 )
2960 if ( !((bPropSmall && bPropGreat) ||
2961 ((nDelta > 0) && bPropSmall) ||
2962 ((nDelta < 0) && bPropGreat)) )
2964 if ( nDelta < 0 )
2965 bGreat = sal_False;
2966 else
2967 bSmall = sal_False;
2970 else
2972 if ( nDelta < 0 )
2973 bGreat = sal_False;
2974 else
2975 bSmall = sal_False;
2978 else if ( nPos >= nMax )
2980 bSmall = sal_False;
2981 bGreat = sal_False;
2983 else if ( nPos && (nPos >= pSet->mnItems-1) )
2985 nPos--;
2986 nDelta *= -1;
2987 sal_Bool bTemp = bPropSmall;
2988 bPropSmall = bPropGreat;
2989 bPropGreat = bTemp;
2992 // Jetzt die Fenster splitten
2993 if ( nDelta < 0 )
2995 if ( bGreat )
2997 if ( bPropGreat )
2999 nTempDelta = nDelta;
3002 n = nPos+1;
3005 if ( nTempDelta )
3007 pItems[n].mnPixSize++;
3008 nTempDelta++;
3010 n++;
3012 while ( n < nMax );
3014 while ( nTempDelta );
3016 else
3017 pItems[nPos+1].mnPixSize -= nDelta;
3020 if ( bSmall )
3022 if ( bPropSmall )
3026 n = nPos+1;
3029 if ( nDelta && pItems[n-1].mnPixSize )
3031 pItems[n-1].mnPixSize--;
3032 nDelta++;
3035 n--;
3037 while ( n > nMin );
3039 while ( nDelta );
3041 else
3043 n = nPos+1;
3046 if ( pItems[n-1].mnPixSize+nDelta < 0 )
3048 nDelta += pItems[n-1].mnPixSize;
3049 pItems[n-1].mnPixSize = 0;
3051 else
3053 pItems[n-1].mnPixSize += nDelta;
3054 break;
3056 n--;
3058 while ( n > nMin );
3062 else
3064 if ( bGreat )
3066 if ( bPropGreat )
3068 nTempDelta = nDelta;
3071 n = nPos+1;
3074 if ( nTempDelta )
3076 pItems[n-1].mnPixSize++;
3077 nTempDelta--;
3079 n--;
3081 while ( n > nMin );
3083 while ( nTempDelta );
3085 else
3086 pItems[nPos].mnPixSize += nDelta;
3089 if ( bSmall )
3091 if ( bPropSmall )
3095 n = nPos+1;
3098 if ( nDelta && pItems[n].mnPixSize )
3100 pItems[n].mnPixSize--;
3101 nDelta--;
3104 n++;
3106 while ( n < nMax );
3108 while ( nDelta );
3110 else
3112 n = nPos+1;
3115 if ( pItems[n].mnPixSize-nDelta < 0 )
3117 nDelta -= pItems[n].mnPixSize;
3118 pItems[n].mnPixSize = 0;
3120 else
3122 pItems[n].mnPixSize -= nDelta;
3123 break;
3125 n++;
3127 while ( n < nMax );
3132 // Original-Groessen updaten
3133 ImplCalcLogSize( pItems, nItems );
3135 ImplUpdate();
3138 // -----------------------------------------------------------------------
3140 void SplitWindow::SetItemSize( sal_uInt16 nId, long nNewSize )
3142 sal_uInt16 nPos;
3143 ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
3144 ImplSplitItem* pItem;
3146 if ( !pSet )
3147 return;
3149 // Testen, ob sich Groesse aendert
3150 pItem = &(pSet->mpItems[nPos]);
3151 if ( pItem->mnSize != nNewSize )
3153 // Neue Groesse setzen und neu durchrechnen
3154 pItem->mnSize = nNewSize;
3155 pSet->mbCalcPix = sal_True;
3156 ImplUpdate();
3160 // -----------------------------------------------------------------------
3162 long SplitWindow::GetItemSize( sal_uInt16 nId ) const
3164 sal_uInt16 nPos;
3165 ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
3167 if ( pSet )
3168 return pSet->mpItems[nPos].mnSize;
3169 else
3170 return 0;
3173 // -----------------------------------------------------------------------
3175 long SplitWindow::GetItemSize( sal_uInt16 nId, SplitWindowItemBits nBits ) const
3177 sal_uInt16 nPos;
3178 ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
3180 if ( pSet )
3182 if ( nBits == pSet->mpItems[nPos].mnBits )
3183 return pSet->mpItems[nPos].mnSize;
3184 else
3186 ((SplitWindow*)this)->ImplCalcLayout();
3188 long nRelSize = 0;
3189 long nPerSize = 0;
3190 ImplSplitItem* pItems;
3191 sal_uInt16 nItems;
3192 SplitWindowItemBits nTempBits;
3193 sal_uInt16 i;
3194 nItems = pSet->mnItems;
3195 pItems = pSet->mpItems;
3196 for ( i = 0; i < nItems; i++ )
3198 if ( i == nPos )
3199 nTempBits = nBits;
3200 else
3201 nTempBits = pItems[i].mnBits;
3202 if ( nTempBits & SWIB_RELATIVESIZE )
3203 nRelSize += pItems[i].mnPixSize;
3204 else if ( nTempBits & SWIB_PERCENTSIZE )
3205 nPerSize += pItems[i].mnPixSize;
3207 nPerSize += nRelSize;
3208 if ( nBits & SWIB_RELATIVESIZE )
3210 if ( nRelSize )
3211 return (pItems[nPos].mnPixSize+(nRelSize/2))/nRelSize;
3212 else
3213 return 1;
3215 else if ( nBits & SWIB_PERCENTSIZE )
3217 if ( nPerSize )
3218 return (pItems[nPos].mnPixSize*100)/nPerSize;
3219 else
3220 return 1;
3222 else
3223 return pItems[nPos].mnPixSize;
3226 else
3227 return 0;
3233 void SplitWindow::SetItemSizeRange (sal_uInt16 nId, const Range aRange)
3235 sal_uInt16 nPos;
3236 ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos);
3238 if (pSet != NULL)
3240 pSet->mpItems[nPos].mnMinSize = aRange.Min();
3241 pSet->mpItems[nPos].mnMaxSize = aRange.Max();
3245 // -----------------------------------------------------------------------
3247 sal_uInt16 SplitWindow::GetSet( sal_uInt16 nId ) const
3249 sal_uInt16 nPos;
3250 ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
3252 if ( pSet )
3253 return pSet->mnId;
3254 else
3255 return 0;
3258 // -----------------------------------------------------------------------
3260 sal_Bool SplitWindow::IsItemValid( sal_uInt16 nId ) const
3262 sal_uInt16 nPos;
3263 ImplSplitSet* pSet = mpBaseSet ? ImplFindItem(mpBaseSet, nId, nPos) : NULL;
3265 if ( pSet )
3266 return sal_True;
3267 else
3268 return sal_False;
3271 // -----------------------------------------------------------------------
3273 sal_uInt16 SplitWindow::GetItemId( Window* pWindow ) const
3275 return ImplFindItem( mpBaseSet, pWindow );
3278 // -----------------------------------------------------------------------
3280 sal_uInt16 SplitWindow::GetItemId( const Point& rPos ) const
3282 return ImplFindItem( mpBaseSet, rPos, mbHorz, !mbBottomRight );
3285 // -----------------------------------------------------------------------
3287 sal_uInt16 SplitWindow::GetItemPos( sal_uInt16 nId, sal_uInt16 nSetId ) const
3289 ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3290 sal_uInt16 nPos = SPLITWINDOW_ITEM_NOTFOUND;
3292 if ( pSet )
3294 for ( sal_uInt16 i = 0; i < pSet->mnItems; i++ )
3296 if ( pSet->mpItems[i].mnId == nId )
3298 nPos = i;
3299 break;
3304 return nPos;
3307 // -----------------------------------------------------------------------
3309 sal_uInt16 SplitWindow::GetItemId( sal_uInt16 nPos, sal_uInt16 nSetId ) const
3311 ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3312 if ( pSet && (nPos < pSet->mnItems) )
3313 return pSet->mpItems[nPos].mnId;
3314 else
3315 return 0;
3318 // -----------------------------------------------------------------------
3320 sal_uInt16 SplitWindow::GetItemCount( sal_uInt16 nSetId ) const
3322 ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
3323 if ( pSet )
3324 return pSet->mnItems;
3325 else
3326 return 0;
3329 // -----------------------------------------------------------------------
3331 void SplitWindow::ImplNewAlign()
3333 if ( mbNoAlign )
3335 mbHorz = sal_False;
3336 mbBottomRight = sal_False;
3338 else
3340 switch ( meAlign )
3342 case WINDOWALIGN_TOP:
3343 mbHorz = sal_True;
3344 mbBottomRight = sal_False;
3345 break;
3346 case WINDOWALIGN_BOTTOM:
3347 mbHorz = sal_True;
3348 mbBottomRight = sal_True;
3349 break;
3350 case WINDOWALIGN_LEFT:
3351 mbHorz = sal_False;
3352 mbBottomRight = sal_False;
3353 break;
3354 case WINDOWALIGN_RIGHT:
3355 mbHorz = sal_False;
3356 mbBottomRight = sal_True;
3357 break;
3361 if ( mnWinStyle & WB_BORDER )
3363 ImplCalcBorder( meAlign, mbNoAlign, mnLeftBorder, mnTopBorder,
3364 mnRightBorder, mnBottomBorder );
3367 if ( IsReallyVisible() && IsUpdateMode() )
3368 Invalidate();
3369 ImplUpdate();
3372 // -----------------------------------------------------------------------
3374 void SplitWindow::SetAlign( WindowAlign eNewAlign )
3376 if ( meAlign != eNewAlign )
3378 meAlign = eNewAlign;
3379 ImplNewAlign();
3383 // -----------------------------------------------------------------------
3385 void SplitWindow::ShowAutoHideButton( sal_Bool bShow )
3387 mbAutoHide = bShow;
3388 ImplUpdate();
3391 // -----------------------------------------------------------------------
3393 void SplitWindow::ShowFadeInHideButton( sal_Bool bShow )
3395 mbFadeIn = bShow;
3396 ImplUpdate();
3399 // -----------------------------------------------------------------------
3401 void SplitWindow::ShowFadeOutButton( sal_Bool bShow )
3403 mbFadeOut = bShow;
3404 ImplUpdate();
3407 // -----------------------------------------------------------------------
3409 void SplitWindow::SetAutoHideState( sal_Bool bAutoHide )
3411 mbAutoHideIn = bAutoHide;
3412 if ( IsReallyVisible() )
3414 Rectangle aRect;
3415 ImplGetAutoHideRect( aRect );
3416 Invalidate( aRect );
3420 // -----------------------------------------------------------------------
3422 long SplitWindow::GetFadeInSize() const
3424 long n = 0;
3426 if ( mbHorz )
3427 n = mnTopBorder+mnBottomBorder;
3428 else
3429 n = mnLeftBorder+mnRightBorder;
3431 return n+SPLITWIN_SPLITSIZE+SPLITWIN_SPLITSIZEEX-2;
3434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */