xref: /AOO41X/main/vcl/source/window/splitwin.cxx (revision f1dd813452325018481a9efcce7a9a86fa953fcb)
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