1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <tools/debug.hxx>
23 #include <tools/rcid.h>
25 #include <vcl/event.hxx>
26 #include <vcl/wall.hxx>
27 #include <vcl/bitmap.hxx>
28 #include <vcl/decoview.hxx>
29 #include <vcl/image.hxx>
30 #include <vcl/help.hxx>
31 #include <vcl/splitwin.hxx>
32 #include <vcl/settings.hxx>
34 #include <rsc/rsc-vcl-shared-types.hxx>
40 #define SPLITWIN_SPLITSIZE 4
41 #define SPLITWIN_SPLITSIZEEX 4
42 #define SPLITWIN_SPLITSIZEEXLN 7
43 #define SPLITWIN_SPLITSIZEAUTOHIDE 72
44 #define SPLITWIN_SPLITSIZEFADE 72
46 #define SPLIT_HORZ ((sal_uInt16)0x0001)
47 #define SPLIT_VERT ((sal_uInt16)0x0002)
48 #define SPLIT_WINDOW ((sal_uInt16)0x0004)
49 #define SPLIT_NOSPLIT ((sal_uInt16)0x8000)
71 VclPtr
<vcl::Window
> mpWindow
;
72 VclPtr
<vcl::Window
> mpOrgParent
;
74 SplitWindowItemFlags mnBits
;
77 /// Minimal width or height of the item. -1 means no restriction.
79 /// Maximal width or height of the item. -1 means no restriction.
91 std::vector
< ImplSplitItem
* > mpItems
;
92 Wallpaper
* mpWallpaper
;
100 ImplSplitItem::ImplSplitItem()
115 , mnBits(SplitWindowItemFlags::NONE
)
123 ImplSplitItem::~ImplSplitItem()
128 void ImplSplitItem::dispose()
138 ImplSplitSet::ImplSplitSet() :
139 mpWallpaper( nullptr ),
142 mnSplitSize( SPLITWIN_SPLITSIZE
),
148 ImplSplitSet::~ImplSplitSet()
153 void ImplSplitSet::dispose()
155 size_t nItems
= mpItems
.size();
157 for ( size_t i
= 0; i
< nItems
; i
++ )
163 mpWallpaper
= nullptr;
172 /** Check whether the given size is inside the valid range defined by
173 [rItem.mnMinSize,rItem.mnMaxSize]. When it is not inside it then return
174 the upper or lower bound, respectively. Otherwise return the given size
176 Note that either mnMinSize and/or mnMaxSize can be -1 in which case the
177 size has not lower or upper bound.
180 long ValidateSize (const long nSize
, const ImplSplitItem
* pItem
)
182 if (pItem
->mnMinSize
>=0 && nSize
<pItem
->mnMinSize
)
183 return pItem
->mnMinSize
;
184 else if (pItem
->mnMaxSize
>0 && nSize
>pItem
->mnMaxSize
)
185 return pItem
->mnMaxSize
;
191 static void ImplCalcBorder( WindowAlign eAlign
, bool bNoAlign
,
192 long& rLeft
, long& rTop
,
193 long& rRight
, long& rBottom
)
206 case WindowAlign::Top
:
212 case WindowAlign::Left
:
218 case WindowAlign::Bottom
:
234 void SplitWindow::ImplDrawBorder(vcl::RenderContext
& rRenderContext
)
236 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
242 case WindowAlign::Bottom
:
243 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
244 rRenderContext
.DrawLine(Point(0, 0), Point(nDX
- 1, 0));
245 rRenderContext
.DrawLine(Point(0, nDY
- 2), Point(nDX
- 1, nDY
- 2));
247 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
248 rRenderContext
.DrawLine(Point(0, 1), Point(nDX
- 1, 1));
249 rRenderContext
.DrawLine(Point(0, nDY
- 1), Point(nDX
- 1, nDY
- 1));
251 case WindowAlign::Top
:
252 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
253 rRenderContext
.DrawLine(Point(0, nDY
- 2), Point(nDX
- 1, nDY
- 2));
254 rRenderContext
.DrawLine(Point(0, 0), Point(nDX
- 1, 0));
256 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
257 rRenderContext
.DrawLine(Point(0, nDY
- 1), Point(nDX
- 1, nDY
- 1));
258 rRenderContext
.DrawLine(Point(0, 1), Point(nDX
- 1, 1));
260 case WindowAlign::Left
:
261 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
262 rRenderContext
.DrawLine(Point(nDX
- 2, 0), Point(nDX
- 2, nDY
- 2));
263 rRenderContext
.DrawLine(Point(0, 0), Point(nDX
- 1, 0));
264 rRenderContext
.DrawLine(Point(0, nDY
- 2), Point(nDX
- 2, nDY
- 2));
266 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
267 rRenderContext
.DrawLine(Point(nDX
- 1, 0), Point(nDX
- 1, nDY
- 1));
268 rRenderContext
.DrawLine(Point(0, 1), Point(nDX
- 3, 1));
269 rRenderContext
.DrawLine(Point(0, nDY
- 1), Point(nDX
- 2, nDY
- 1));
272 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
273 rRenderContext
.DrawLine(Point(0, 0), Point( 0, nDY
- 2));
274 rRenderContext
.DrawLine(Point(0, 0), Point( nDX
- 1, 0));
275 rRenderContext
.DrawLine(Point(0, nDY
- 2), Point(nDX
- 1, nDY
- 2));
277 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor());
278 rRenderContext
.DrawLine(Point(1, 1), Point(1, nDY
- 3));
279 rRenderContext
.DrawLine(Point(1, 1), Point(nDX
- 1, 1));
280 rRenderContext
.DrawLine(Point(0, nDY
- 1), Point(nDX
- 1, nDY
- 1));
284 void SplitWindow::ImplDrawBorderLine(vcl::RenderContext
& rRenderContext
)
286 if (mbFadeOut
|| mbAutoHide
)
288 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
294 case WindowAlign::Left
:
295 rRenderContext
.SetLineColor( rStyleSettings
.GetShadowColor() );
296 rRenderContext
.DrawLine( Point( nDX
-SPLITWIN_SPLITSIZEEXLN
-1, 1 ), Point( nDX
-SPLITWIN_SPLITSIZEEXLN
-1, nDY
-2 ) );
298 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor() );
299 rRenderContext
.DrawLine( Point( nDX
-SPLITWIN_SPLITSIZEEXLN
, 1 ), Point( nDX
-SPLITWIN_SPLITSIZEEXLN
, nDY
-3 ) );
301 case WindowAlign::Right
:
302 rRenderContext
.SetLineColor( rStyleSettings
.GetShadowColor() );
303 rRenderContext
.DrawLine( Point( SPLITWIN_SPLITSIZEEXLN
-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN
-1, nDY
-2 ) );
305 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor() );
306 rRenderContext
.DrawLine( Point( SPLITWIN_SPLITSIZEEXLN
, 1 ), Point( SPLITWIN_SPLITSIZEEXLN
, nDY
-3 ) );
308 case WindowAlign::Top
:
309 rRenderContext
.SetLineColor( rStyleSettings
.GetShadowColor() );
310 rRenderContext
.DrawLine( Point( 0, nDY
-SPLITWIN_SPLITSIZEEXLN
-1 ), Point( nDX
-1, nDY
-SPLITWIN_SPLITSIZEEXLN
-1 ) );
312 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor() );
313 rRenderContext
.DrawLine( Point( 0, nDY
-SPLITWIN_SPLITSIZEEXLN
), Point( nDX
-1, nDY
-SPLITWIN_SPLITSIZEEXLN
) );
315 case WindowAlign::Bottom
:
316 rRenderContext
.SetLineColor( rStyleSettings
.GetShadowColor() );
317 rRenderContext
.DrawLine( Point( 0, 5 ), Point( nDX
-1, 5 ) );
319 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor() );
320 rRenderContext
.DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN
), Point( nDX
-1, SPLITWIN_SPLITSIZEEXLN
) );
326 static ImplSplitSet
* ImplFindSet( ImplSplitSet
* pSet
, sal_uInt16 nId
)
328 if ( pSet
->mnId
== nId
)
332 size_t nItems
= pSet
->mpItems
.size();
333 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
335 for ( i
= 0; i
< nItems
; i
++ )
337 if ( rItems
[i
]->mnId
== nId
)
338 return rItems
[i
]->mpSet
;
341 for ( i
= 0; i
< nItems
; i
++ )
343 if ( rItems
[i
]->mpSet
)
345 ImplSplitSet
* pFindSet
= ImplFindSet( rItems
[i
]->mpSet
, nId
);
354 static ImplSplitSet
* ImplFindItem( ImplSplitSet
* pSet
, sal_uInt16 nId
, sal_uInt16
& rPos
)
357 size_t nItems
= pSet
->mpItems
.size();
358 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
360 for ( i
= 0; i
< nItems
; i
++ )
362 if ( rItems
[i
]->mnId
== nId
)
369 for ( i
= 0; i
< nItems
; i
++ )
371 if ( rItems
[i
]->mpSet
)
373 ImplSplitSet
* pFindSet
= ImplFindItem( rItems
[i
]->mpSet
, nId
, rPos
);
382 static sal_uInt16
ImplFindItem( ImplSplitSet
* pSet
, vcl::Window
* pWindow
)
385 size_t nItems
= pSet
->mpItems
.size();
386 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
388 for ( i
= 0; i
< nItems
; i
++ )
390 if ( rItems
[i
]->mpWindow
== pWindow
)
391 return rItems
[i
]->mnId
;
394 if ( rItems
[i
]->mpSet
)
396 sal_uInt16 nId
= ImplFindItem( rItems
[i
]->mpSet
, pWindow
);
406 static sal_uInt16
ImplFindItem( ImplSplitSet
* pSet
, const Point
& rPos
,
407 bool bRows
, bool bDown
= true )
410 size_t nItems
= pSet
->mpItems
.size();
411 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
413 for ( i
= 0; i
< nItems
; i
++ )
415 if ( rItems
[i
]->mnWidth
&& rItems
[i
]->mnHeight
)
417 Point
aPoint( rItems
[i
]->mnLeft
, rItems
[i
]->mnTop
);
418 Size
aSize( rItems
[i
]->mnWidth
, rItems
[i
]->mnHeight
);
419 Rectangle
aRect( aPoint
, aSize
);
423 aRect
.Bottom() += pSet
->mnSplitSize
;
425 aRect
.Top() -= pSet
->mnSplitSize
;
430 aRect
.Right() += pSet
->mnSplitSize
;
432 aRect
.Left() -= pSet
->mnSplitSize
;
435 if ( aRect
.IsInside( rPos
) )
437 if ( rItems
[i
]->mpSet
&& !rItems
[i
]->mpSet
->mpItems
.empty() )
439 return ImplFindItem( rItems
[i
]->mpSet
, rPos
,
440 !(rItems
[i
]->mnBits
& SplitWindowItemFlags::ColSet
) );
443 return rItems
[i
]->mnId
;
451 static void ImplCalcSet( ImplSplitSet
* pSet
,
452 long nSetLeft
, long nSetTop
,
453 long nSetWidth
, long nSetHeight
,
454 bool bRows
, bool bDown
= true )
456 if ( pSet
->mpItems
.empty() )
462 sal_uInt16 nCalcItems
;
463 size_t nItems
= pSet
->mpItems
.size();
464 sal_uInt16 nVisItems
;
465 sal_uInt16 nAbsItems
;
469 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
472 // get number of visible items
474 for ( i
= 0; i
< nItems
; i
++ )
476 if ( !(rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
) )
482 nCalcSize
= nSetHeight
;
484 nCalcSize
= nSetWidth
;
485 nCalcSize
-= (nVisItems
-1)*pSet
->mnSplitSize
;
486 if ( pSet
->mbCalcPix
|| (pSet
->mnLastSize
!= nCalcSize
) )
488 long nPercentFactor
= 10;
491 long nRelPercent
= 0;
494 for ( i
= 0; i
< nItems
; i
++ )
496 if ( !(rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
) )
498 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::RelativeSize
)
499 nRelCount
+= rItems
[i
]->mnSize
;
500 else if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::PercentSize
)
501 nPercent
+= rItems
[i
]->mnSize
;
503 nAbsSize
+= rItems
[i
]->mnSize
;
506 // map relative values to percentages (percentage here one tenth of a procent)
507 nPercent
*= nPercentFactor
;
510 long nRelPercentBase
= 1000;
511 while ( (nRelCount
> nRelPercentBase
) && (nPercentFactor
< 100000) )
513 nRelPercentBase
*= 10;
514 nPercentFactor
*= 10;
516 if ( nPercent
< nRelPercentBase
)
518 nRelPercent
= (nRelPercentBase
-nPercent
)/nRelCount
;
519 nPercent
+= nRelPercent
*nRelCount
;
526 long nSizeDelta
= nCalcSize
-nAbsSize
;
527 for ( i
= 0; i
< nItems
; i
++ )
529 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
)
530 rItems
[i
]->mnPixSize
= 0;
531 else if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::RelativeSize
)
533 if ( nSizeDelta
<= 0 )
534 rItems
[i
]->mnPixSize
= 0;
536 rItems
[i
]->mnPixSize
= (nSizeDelta
*rItems
[i
]->mnSize
*nRelPercent
)/nPercent
;
538 else if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::PercentSize
)
540 if ( nSizeDelta
<= 0 )
541 rItems
[i
]->mnPixSize
= 0;
543 rItems
[i
]->mnPixSize
= (nSizeDelta
*rItems
[i
]->mnSize
*nPercentFactor
)/nPercent
;
546 rItems
[i
]->mnPixSize
= rItems
[i
]->mnSize
;
547 nCurSize
+= rItems
[i
]->mnPixSize
;
550 pSet
->mbCalcPix
= false;
551 pSet
->mnLastSize
= nCalcSize
;
554 nSizeDelta
= nCalcSize
-nCurSize
;
558 long nSizeWinSize
= 0;
560 // first resize absolute items relative
561 for ( i
= 0; i
< nItems
; i
++ )
563 if ( !(rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
) )
565 if ( !(rItems
[i
]->mnBits
& (SplitWindowItemFlags::RelativeSize
| SplitWindowItemFlags::PercentSize
)) )
568 nSizeWinSize
+= rItems
[i
]->mnPixSize
;
572 // do not compensate rounding errors here
573 if ( (nAbsItems
< (sal_uInt16
)(std::abs( nSizeDelta
))) && nSizeWinSize
)
575 long nNewSizeWinSize
= 0;
577 for ( i
= 0; i
< nItems
; i
++ )
579 if ( !(rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
) )
581 if ( !(rItems
[i
]->mnBits
& (SplitWindowItemFlags::RelativeSize
| SplitWindowItemFlags::PercentSize
)) )
583 rItems
[i
]->mnPixSize
+= (nSizeDelta
*rItems
[i
]->mnPixSize
)/nSizeWinSize
;
584 nNewSizeWinSize
+= rItems
[i
]->mnPixSize
;
589 nSizeDelta
-= nNewSizeWinSize
-nSizeWinSize
;
592 // compensate rounding errors now
595 while ( nSizeDelta
&& (nItems
!= nMins
) )
597 // determine which items we can calculate
599 while ( !nCalcItems
)
601 for ( i
= 0; i
< nItems
; i
++ )
603 rItems
[i
]->mbSubSize
= false;
606 rItems
[i
]->mbSubSize
= true;
609 if ( !(rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
) )
611 if ( (nSizeDelta
> 0) || rItems
[i
]->mnPixSize
)
614 rItems
[i
]->mbSubSize
= true;
617 if ( (j
== 0) && (rItems
[i
]->mnBits
& (SplitWindowItemFlags::RelativeSize
| SplitWindowItemFlags::PercentSize
)) )
618 rItems
[i
]->mbSubSize
= true;
624 if ( rItems
[i
]->mbSubSize
)
631 // subtract size of individual items
632 long nErrorSum
= nSizeDelta
% nCalcItems
;
633 long nCurSizeDelta
= nSizeDelta
/ nCalcItems
;
635 for ( i
= 0; i
< nItems
; i
++ )
637 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
)
639 else if ( rItems
[i
]->mbSubSize
)
641 long* pSize
= &(rItems
[i
]->mnPixSize
);
654 if ( (*pSize
+nCurSizeDelta
+nTempErr
) <= 0 )
666 *pSize
+= nCurSizeDelta
;
667 nSizeDelta
-= nCurSizeDelta
;
668 if ( nTempErr
&& (*pSize
|| (nTempErr
> 0)) )
671 nSizeDelta
-= nTempErr
;
672 nErrorSum
-= nTempErr
;
681 // calculate maximum size
686 nMaxPos
= nSetTop
-nSetHeight
;
688 nMaxPos
= nSetTop
+nSetHeight
;
694 nMaxPos
= nSetLeft
-nSetWidth
;
696 nMaxPos
= nSetLeft
+nSetWidth
;
699 // order windows and adept values
700 for ( i
= 0; i
< nItems
; i
++ )
702 rItems
[i
]->mnOldSplitPos
= rItems
[i
]->mnSplitPos
;
703 rItems
[i
]->mnOldSplitSize
= rItems
[i
]->mnSplitSize
;
704 rItems
[i
]->mnOldWidth
= rItems
[i
]->mnWidth
;
705 rItems
[i
]->mnOldHeight
= rItems
[i
]->mnHeight
;
707 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
)
714 if ( nPos
+rItems
[i
]->mnPixSize
> nMaxPos
)
719 nPos
-= rItems
[i
]->mnPixSize
;
720 if ( nPos
< nMaxPos
)
727 rItems
[i
]->mnWidth
= 0;
728 rItems
[i
]->mnHeight
= 0;
729 rItems
[i
]->mnSplitSize
= 0;
735 rItems
[i
]->mnLeft
= nSetLeft
;
736 rItems
[i
]->mnTop
= nPos
;
737 rItems
[i
]->mnWidth
= nSetWidth
;
738 rItems
[i
]->mnHeight
= rItems
[i
]->mnPixSize
;
742 rItems
[i
]->mnLeft
= nPos
;
743 rItems
[i
]->mnTop
= nSetTop
;
744 rItems
[i
]->mnWidth
= rItems
[i
]->mnPixSize
;
745 rItems
[i
]->mnHeight
= nSetHeight
;
749 rItems
[i
]->mnSplitSize
= 0;
752 rItems
[i
]->mnSplitSize
= pSet
->mnSplitSize
;
755 rItems
[i
]->mnSplitPos
= nPos
+rItems
[i
]->mnPixSize
;
756 if ( rItems
[i
]->mnSplitPos
+rItems
[i
]->mnSplitSize
> nMaxPos
)
757 rItems
[i
]->mnSplitSize
= nMaxPos
-rItems
[i
]->mnSplitPos
;
761 rItems
[i
]->mnSplitPos
= nPos
-pSet
->mnSplitSize
;
762 if ( rItems
[i
]->mnSplitPos
< nMaxPos
)
763 rItems
[i
]->mnSplitSize
= rItems
[i
]->mnSplitPos
+pSet
->mnSplitSize
-nMaxPos
;
768 if ( !(rItems
[i
]->mnBits
& SplitWindowItemFlags::Invisible
) )
771 nPos
-= pSet
->mnSplitSize
;
773 nPos
+= rItems
[i
]->mnPixSize
+pSet
->mnSplitSize
;
777 // calculate Sub-Set's
778 for ( i
= 0; i
< nItems
; i
++ )
780 if ( rItems
[i
]->mpSet
&& rItems
[i
]->mnWidth
&& rItems
[i
]->mnHeight
)
782 ImplCalcSet( rItems
[i
]->mpSet
,
783 rItems
[i
]->mnLeft
, rItems
[i
]->mnTop
,
784 rItems
[i
]->mnWidth
, rItems
[i
]->mnHeight
,
785 !(rItems
[i
]->mnBits
& SplitWindowItemFlags::ColSet
) );
790 for ( i
= 0; i
< nItems
; i
++ )
792 rItems
[i
]->mbFixed
= false;
793 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::Fixed
)
794 rItems
[i
]->mbFixed
= true;
797 // this item is also fixed if Child-Set is available,
798 // if a child is fixed
799 if ( rItems
[i
]->mpSet
)
801 for ( j
= 0; j
< rItems
[i
]->mpSet
->mpItems
.size(); j
++ )
803 if ( rItems
[i
]->mpSet
->mpItems
[j
]->mbFixed
)
805 rItems
[i
]->mbFixed
= true;
814 void SplitWindow::ImplCalcSet2( SplitWindow
* pWindow
, ImplSplitSet
* pSet
, bool bHide
,
815 bool bRows
, bool /*bDown*/ )
818 size_t nItems
= pSet
->mpItems
.size();
819 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
821 if ( pWindow
->IsReallyVisible() && pWindow
->IsUpdateMode() && pWindow
->mbInvalidate
)
823 for ( i
= 0; i
< nItems
; i
++ )
825 if ( rItems
[i
]->mnSplitSize
)
827 // invalidate all, if applicable or only a small part
828 if ( (rItems
[i
]->mnOldSplitPos
!= rItems
[i
]->mnSplitPos
) ||
829 (rItems
[i
]->mnOldSplitSize
!= rItems
[i
]->mnSplitSize
) ||
830 (rItems
[i
]->mnOldWidth
!= rItems
[i
]->mnWidth
) ||
831 (rItems
[i
]->mnOldHeight
!= rItems
[i
]->mnHeight
) )
835 // invalidate old rectangle
838 aRect
.Left() = rItems
[i
]->mnLeft
;
839 aRect
.Right() = rItems
[i
]->mnLeft
+rItems
[i
]->mnOldWidth
-1;
840 aRect
.Top() = rItems
[i
]->mnOldSplitPos
;
841 aRect
.Bottom() = aRect
.Top() + rItems
[i
]->mnOldSplitSize
;
845 aRect
.Top() = rItems
[i
]->mnTop
;
846 aRect
.Bottom() = rItems
[i
]->mnTop
+rItems
[i
]->mnOldHeight
-1;
847 aRect
.Left() = rItems
[i
]->mnOldSplitPos
;
848 aRect
.Right() = aRect
.Left() + rItems
[i
]->mnOldSplitSize
;
850 pWindow
->Invalidate( aRect
);
851 // invalidate new rectangle
854 aRect
.Left() = rItems
[i
]->mnLeft
;
855 aRect
.Right() = rItems
[i
]->mnLeft
+rItems
[i
]->mnWidth
-1;
856 aRect
.Top() = rItems
[i
]->mnSplitPos
;
857 aRect
.Bottom() = aRect
.Top() + rItems
[i
]->mnSplitSize
;
861 aRect
.Top() = rItems
[i
]->mnTop
;
862 aRect
.Bottom() = rItems
[i
]->mnTop
+rItems
[i
]->mnHeight
-1;
863 aRect
.Left() = rItems
[i
]->mnSplitPos
;
864 aRect
.Right() = aRect
.Left() + rItems
[i
]->mnSplitSize
;
866 pWindow
->Invalidate( aRect
);
868 // invalidate complete set, as these areas
869 // are not cluttered by windows
870 if ( rItems
[i
]->mpSet
&& rItems
[i
]->mpSet
->mpItems
.empty() )
872 aRect
.Left() = rItems
[i
]->mnLeft
;
873 aRect
.Top() = rItems
[i
]->mnTop
;
874 aRect
.Right() = rItems
[i
]->mnLeft
+rItems
[i
]->mnWidth
-1;
875 aRect
.Bottom() = rItems
[i
]->mnTop
+rItems
[i
]->mnHeight
-1;
876 pWindow
->Invalidate( aRect
);
884 for ( i
= 0; i
< nItems
; i
++ )
886 if ( rItems
[i
]->mpSet
)
888 bool bTempHide
= bHide
;
889 if ( !rItems
[i
]->mnWidth
|| !rItems
[i
]->mnHeight
)
891 ImplCalcSet2( pWindow
, rItems
[i
]->mpSet
, bTempHide
,
892 !(rItems
[i
]->mnBits
& SplitWindowItemFlags::ColSet
) );
896 if ( rItems
[i
]->mnWidth
&& rItems
[i
]->mnHeight
&& !bHide
)
898 Point
aPos( rItems
[i
]->mnLeft
, rItems
[i
]->mnTop
);
899 Size
aSize( rItems
[i
]->mnWidth
, rItems
[i
]->mnHeight
);
900 rItems
[i
]->mpWindow
->SetPosSizePixel( aPos
, aSize
);
903 rItems
[i
]->mpWindow
->Hide();
907 // show windows and reset flag
908 for ( i
= 0; i
< nItems
; i
++ )
910 if ( rItems
[i
]->mpWindow
&& rItems
[i
]->mnWidth
&& rItems
[i
]->mnHeight
&& !bHide
)
911 rItems
[i
]->mpWindow
->Show();
915 static void ImplCalcLogSize( std::vector
< ImplSplitItem
* > rItems
, size_t nItems
)
917 // update original sizes
922 for ( i
= 0; i
< nItems
; i
++ )
924 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::RelativeSize
)
925 nRelSize
+= rItems
[i
]->mnPixSize
;
926 else if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::PercentSize
)
927 nPerSize
+= rItems
[i
]->mnPixSize
;
929 nPerSize
+= nRelSize
;
930 for ( i
= 0; i
< nItems
; i
++ )
932 if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::RelativeSize
)
935 rItems
[i
]->mnSize
= (rItems
[i
]->mnPixSize
+(nRelSize
/2))/nRelSize
;
937 rItems
[i
]->mnSize
= 1;
939 else if ( rItems
[i
]->mnBits
& SplitWindowItemFlags::PercentSize
)
942 rItems
[i
]->mnSize
= (rItems
[i
]->mnPixSize
*100)/nPerSize
;
944 rItems
[i
]->mnSize
= 1;
947 rItems
[i
]->mnSize
= rItems
[i
]->mnPixSize
;
951 void SplitWindow::ImplDrawBack(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
,
952 const Wallpaper
* pWall
, const Bitmap
* pBitmap
)
956 Point aPos
= rRect
.TopLeft();
957 Size aBmpSize
= pBitmap
->GetSizePixel();
958 rRenderContext
.Push(PushFlags::CLIPREGION
);
959 rRenderContext
.IntersectClipRegion(rRect
);
962 aPos
.X() = rRect
.Left();
965 rRenderContext
.DrawBitmap(aPos
, *pBitmap
);
966 aPos
.X() += aBmpSize
.Width();
968 while (aPos
.X() < rRect
.Right());
969 aPos
.Y() += aBmpSize
.Height();
971 while (aPos
.Y() < rRect
.Bottom());
972 rRenderContext
.Pop();
976 rRenderContext
.DrawWallpaper(rRect
, *pWall
);
980 void SplitWindow::ImplDrawBack(vcl::RenderContext
& rRenderContext
, ImplSplitSet
* pSet
)
983 size_t nItems
= pSet
->mpItems
.size();
984 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
986 // also draw background for mainset
991 Rectangle
aRect(mnLeftBorder
, mnTopBorder
,
992 mnDX
- mnRightBorder
- 1,
993 mnDY
- mnBottomBorder
- 1);
995 ImplDrawBack(rRenderContext
, aRect
, pSet
->mpWallpaper
, pSet
->mpBitmap
);
999 for (i
= 0; i
< nItems
; i
++)
1001 pSet
= rItems
[i
]->mpSet
;
1004 if (pSet
->mpBitmap
|| pSet
->mpWallpaper
)
1006 Point
aPoint(rItems
[i
]->mnLeft
, rItems
[i
]->mnTop
);
1007 Size
aSize(rItems
[i
]->mnWidth
, rItems
[i
]->mnHeight
);
1008 Rectangle
aRect(aPoint
, aSize
);
1009 ImplDrawBack(rRenderContext
, aRect
, pSet
->mpWallpaper
, pSet
->mpBitmap
);
1014 for (i
= 0; i
< nItems
; i
++)
1016 if (rItems
[i
]->mpSet
)
1017 ImplDrawBack(rRenderContext
, rItems
[i
]->mpSet
);
1021 static void ImplDrawSplit(vcl::RenderContext
& rRenderContext
, ImplSplitSet
* pSet
, bool bRows
, bool bFlat
, bool bDown
= true)
1023 if (pSet
->mpItems
.empty())
1027 size_t nItems
= pSet
->mpItems
.size();
1031 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
1032 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1034 for (i
= 0; i
< nItems
-1; i
++)
1036 if (rItems
[i
]->mnSplitSize
)
1038 nPos
= rItems
[i
]->mnSplitPos
;
1040 long nItemSplitSize
= rItems
[i
]->mnSplitSize
;
1041 long nSplitSize
= pSet
->mnSplitSize
;
1044 nTop
= rItems
[i
]->mnLeft
;
1045 nBottom
= rItems
[i
]->mnLeft
+rItems
[i
]->mnWidth
-1;
1050 if (bDown
|| (nItemSplitSize
>= nSplitSize
))
1052 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
1053 rRenderContext
.DrawLine(Point(nTop
, nPos
+ 1), Point(nBottom
, nPos
+ 1));
1055 nPos
+= nSplitSize
-2;
1058 if ((!bDown
&& (nItemSplitSize
>= 2)) ||
1059 (bDown
&& (nItemSplitSize
>= nSplitSize
- 1)))
1061 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
1062 rRenderContext
.DrawLine(Point(nTop
, nPos
), Point(nBottom
, nPos
));
1067 if (!bDown
|| (nItemSplitSize
>= nSplitSize
))
1069 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
1070 rRenderContext
.DrawLine(Point(nTop
, nPos
), Point(nBottom
, nPos
));
1076 nTop
= rItems
[i
]->mnTop
;
1077 nBottom
= rItems
[i
]->mnTop
+pSet
->mpItems
[i
]->mnHeight
-1;
1081 if (bDown
|| (nItemSplitSize
>= nSplitSize
))
1083 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
1084 rRenderContext
.DrawLine(Point(nPos
+ 1, nTop
), Point(nPos
+1, nBottom
));
1086 nPos
+= pSet
->mnSplitSize
- 2;
1089 if ((!bDown
&& (nItemSplitSize
>= 2)) ||
1090 (bDown
&& (nItemSplitSize
>= nSplitSize
- 1)))
1092 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
1093 rRenderContext
.DrawLine(Point(nPos
, nTop
), Point(nPos
, nBottom
));
1098 if (!bDown
|| (nItemSplitSize
>= nSplitSize
))
1100 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
1101 rRenderContext
.DrawLine(Point(nPos
, nTop
), Point(nPos
, nBottom
));
1108 for (i
= 0; i
< nItems
; i
++)
1110 if (rItems
[i
]->mpSet
&& rItems
[i
]->mnWidth
&& rItems
[i
]->mnHeight
)
1112 ImplDrawSplit(rRenderContext
, rItems
[i
]->mpSet
, !(rItems
[i
]->mnBits
& SplitWindowItemFlags::ColSet
), bFlat
);
1117 sal_uInt16
SplitWindow::ImplTestSplit( ImplSplitSet
* pSet
, const Point
& rPos
,
1118 long& rMouseOff
, ImplSplitSet
** ppFoundSet
, sal_uInt16
& rFoundPos
,
1119 bool bRows
, bool /*bDown*/ )
1121 if ( pSet
->mpItems
.empty() )
1125 sal_uInt16 nSplitTest
;
1126 size_t nItems
= pSet
->mpItems
.size();
1132 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
1145 for ( i
= 0; i
< nItems
-1; i
++ )
1147 if ( rItems
[i
]->mnSplitSize
)
1151 nTop
= rItems
[i
]->mnLeft
;
1152 nBottom
= rItems
[i
]->mnLeft
+rItems
[i
]->mnWidth
-1;
1156 nTop
= rItems
[i
]->mnTop
;
1157 nBottom
= rItems
[i
]->mnTop
+rItems
[i
]->mnHeight
-1;
1159 nPos
= rItems
[i
]->mnSplitPos
;
1161 if ( (nMPos1
>= nTop
) && (nMPos1
<= nBottom
) &&
1162 (nMPos2
>= nPos
) && (nMPos2
<= nPos
+rItems
[i
]->mnSplitSize
) )
1164 if ( !rItems
[i
]->mbFixed
&& !rItems
[i
+1]->mbFixed
)
1166 rMouseOff
= nMPos2
-nPos
;
1175 return SPLIT_NOSPLIT
;
1180 for ( i
= 0; i
< nItems
; i
++ )
1182 if ( rItems
[i
]->mpSet
)
1184 nSplitTest
= ImplTestSplit( rItems
[i
]->mpSet
, rPos
,
1185 rMouseOff
, ppFoundSet
, rFoundPos
,
1186 !(rItems
[i
]->mnBits
& SplitWindowItemFlags::ColSet
) );
1195 sal_uInt16
SplitWindow::ImplTestSplit( SplitWindow
* pWindow
, const Point
& rPos
,
1196 long& rMouseOff
, ImplSplitSet
** ppFoundSet
, sal_uInt16
& rFoundPos
)
1198 // Resizable SplitWindow should be treated different
1199 if ( pWindow
->mnWinStyle
& WB_SIZEABLE
)
1205 if ( pWindow
->mbHorz
)
1207 if ( pWindow
->mbBottomRight
)
1209 nBorder
= pWindow
->mnBottomBorder
;
1214 nBorder
= pWindow
->mnTopBorder
;
1215 nPos
= pWindow
->mnDY
-nBorder
;
1221 if ( pWindow
->mbBottomRight
)
1223 nBorder
= pWindow
->mnRightBorder
;
1228 nBorder
= pWindow
->mnLeftBorder
;
1229 nPos
= pWindow
->mnDX
-nBorder
;
1233 long nSplitSize
= pWindow
->mpMainSet
->mnSplitSize
-2;
1234 if ( pWindow
->mbAutoHide
|| pWindow
->mbFadeOut
)
1235 nSplitSize
+= SPLITWIN_SPLITSIZEEXLN
;
1236 if ( !pWindow
->mbBottomRight
)
1238 if ( (nTPos
>= nPos
) && (nTPos
<= nPos
+nSplitSize
+nBorder
) )
1240 rMouseOff
= nTPos
-nPos
;
1241 *ppFoundSet
= pWindow
->mpMainSet
;
1242 if ( !pWindow
->mpMainSet
->mpItems
.empty() )
1243 rFoundPos
= pWindow
->mpMainSet
->mpItems
.size() - 1;
1246 if ( pWindow
->mbHorz
)
1247 return SPLIT_VERT
| SPLIT_WINDOW
;
1249 return SPLIT_HORZ
| SPLIT_WINDOW
;
1253 return ImplTestSplit( pWindow
->mpMainSet
, rPos
, rMouseOff
, ppFoundSet
, rFoundPos
,
1254 pWindow
->mbHorz
, !pWindow
->mbBottomRight
);
1257 void SplitWindow::ImplDrawSplitTracking(const Point
& rPos
)
1261 if (mnSplitTest
& SPLIT_HORZ
)
1263 aRect
.Top() = maDragRect
.Top();
1264 aRect
.Bottom() = maDragRect
.Bottom();
1265 aRect
.Left() = rPos
.X();
1266 aRect
.Right() = aRect
.Left() + mpSplitSet
->mnSplitSize
- 1;
1267 if (!(mnWinStyle
& WB_NOSPLITDRAW
))
1269 if ((mnSplitTest
& SPLIT_WINDOW
) && (mbAutoHide
|| mbFadeOut
))
1271 aRect
.Left() += SPLITWIN_SPLITSIZEEXLN
;
1272 aRect
.Right() += SPLITWIN_SPLITSIZEEXLN
;
1277 aRect
.Left() = maDragRect
.Left();
1278 aRect
.Right() = maDragRect
.Right();
1279 aRect
.Top() = rPos
.Y();
1280 aRect
.Bottom() = aRect
.Top() + mpSplitSet
->mnSplitSize
- 1;
1281 if (!(mnWinStyle
& WB_NOSPLITDRAW
))
1283 if ((mnSplitTest
& SPLIT_WINDOW
) && (mbAutoHide
|| mbFadeOut
))
1285 aRect
.Top() += SPLITWIN_SPLITSIZEEXLN
;
1286 aRect
.Bottom() += SPLITWIN_SPLITSIZEEXLN
;
1289 ShowTracking(aRect
, ShowTrackFlags::Split
);
1292 void SplitWindow::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
1294 ImplSplitSet
* pNewSet
= new ImplSplitSet();
1296 mpMainSet
= pNewSet
;
1297 mpBaseSet
= pNewSet
;
1298 mpSplitSet
= nullptr;
1299 mpLastSizes
= nullptr;
1308 meAlign
= WindowAlign::Top
;
1309 mnWinStyle
= nStyle
;
1312 mnMouseModifier
= 0;
1317 mbBottomRight
= false;
1320 mbInvalidate
= true;
1324 mbAutoHideIn
= false;
1325 mbAutoHideDown
= false;
1326 mbFadeInDown
= false;
1327 mbFadeOutDown
= false;
1328 mbAutoHidePressed
= false;
1329 mbFadeInPressed
= false;
1330 mbFadeOutPressed
= false;
1331 mbFadeNoButtonMode
= false;
1333 if ( nStyle
& WB_NOSPLITDRAW
)
1335 pNewSet
->mnSplitSize
-= 2;
1336 mbInvalidate
= false;
1339 if ( nStyle
& WB_BORDER
)
1341 ImplCalcBorder( meAlign
, false/*bNoAlign*/, mnLeftBorder
, mnTopBorder
,
1342 mnRightBorder
, mnBottomBorder
);
1352 DockingWindow::ImplInit( pParent
, (nStyle
| WB_CLIPCHILDREN
) & ~(WB_BORDER
| WB_SIZEABLE
) );
1357 void SplitWindow::ImplInitSettings()
1359 // If a bitmap was set for MainSet, we should not delete the background.
1360 // If MainSet has a Wallpaper, this is the background,
1361 // otherwise it is the standard colour
1362 if ( mpMainSet
->mpBitmap
)
1364 else if ( mpMainSet
->mpWallpaper
)
1365 SetBackground( *mpMainSet
->mpWallpaper
);
1368 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1371 if ( IsControlBackground() )
1372 aColor
= GetControlBackground();
1373 else if ( Window::GetStyle() & WB_3DLOOK
)
1374 aColor
= rStyleSettings
.GetFaceColor();
1376 aColor
= rStyleSettings
.GetWindowColor();
1377 SetBackground( aColor
);
1381 SplitWindow::SplitWindow( vcl::Window
* pParent
, WinBits nStyle
) :
1382 DockingWindow( WINDOW_SPLITWINDOW
)
1384 ImplInit( pParent
, nStyle
);
1385 DockingWindow::SetIdleDebugName( "vcl::SplitWindow maLayoutIdle" );
1388 SplitWindow::~SplitWindow()
1393 void SplitWindow::dispose()
1398 mpMainSet
= nullptr; //NULL for base-class callbacks during destruction
1400 DockingWindow::dispose();
1403 void SplitWindow::ImplSetWindowSize( long nDelta
)
1408 Size aSize
= GetSizePixel();
1411 case WindowAlign::Top
:
1412 aSize
.Height() += nDelta
;
1413 SetSizePixel( aSize
);
1415 case WindowAlign::Bottom
:
1417 maDragRect
.Top() += nDelta
;
1418 Point aPos
= GetPosPixel();
1420 aSize
.Height() += nDelta
;
1421 SetPosSizePixel( aPos
, aSize
);
1424 case WindowAlign::Left
:
1425 aSize
.Width() += nDelta
;
1426 SetSizePixel( aSize
);
1428 case WindowAlign::Right
:
1431 maDragRect
.Left() += nDelta
;
1432 Point aPos
= GetPosPixel();
1434 aSize
.Width() += nDelta
;
1435 SetPosSizePixel( aPos
, aSize
);
1443 Size
SplitWindow::CalcLayoutSizePixel( const Size
& aNewSize
)
1445 Size
aSize( aNewSize
);
1446 long nSplitSize
= mpMainSet
->mnSplitSize
-2;
1448 if ( mbAutoHide
|| mbFadeOut
)
1449 nSplitSize
+= SPLITWIN_SPLITSIZEEXLN
;
1451 // if the window is sizeable and if it does not contain a relative window,
1452 // the size is determined according to MainSet
1453 if ( mnWinStyle
& WB_SIZEABLE
)
1458 for ( i
= 0; i
< mpMainSet
->mpItems
.size(); i
++ )
1460 if ( mpMainSet
->mpItems
[i
]->mnBits
& (SplitWindowItemFlags::RelativeSize
| SplitWindowItemFlags::PercentSize
) )
1463 nCalcSize
+= mpMainSet
->mpItems
[i
]->mnSize
;
1466 if ( i
== mpMainSet
->mpItems
.size() )
1469 Point aPos
= GetPosPixel();
1473 nCurSize
= aNewSize
.Height()-mnTopBorder
-mnBottomBorder
;
1475 nCurSize
= aNewSize
.Width()-mnLeftBorder
-mnRightBorder
;
1476 nCurSize
-= nSplitSize
;
1477 nCurSize
-= (mpMainSet
->mpItems
.size()-1)*mpMainSet
->mnSplitSize
;
1479 nDelta
= nCalcSize
-nCurSize
;
1485 case WindowAlign::Top
:
1486 aSize
.Height() += nDelta
;
1488 case WindowAlign::Bottom
:
1490 aSize
.Height() += nDelta
;
1492 case WindowAlign::Left
:
1493 aSize
.Width() += nDelta
;
1495 case WindowAlign::Right
:
1498 aSize
.Width() += nDelta
;
1507 void SplitWindow::ImplCalcLayout()
1509 if ( !mbCalc
|| !mbRecalc
|| mpMainSet
->mpItems
.empty() )
1512 long nSplitSize
= mpMainSet
->mnSplitSize
-2;
1513 if ( mbAutoHide
|| mbFadeOut
)
1514 nSplitSize
+= SPLITWIN_SPLITSIZEEXLN
;
1516 // if the window is sizeable and if it does not contain a relative window,
1517 // the size is determined according to MainSet
1518 if ( mnWinStyle
& WB_SIZEABLE
)
1523 for ( i
= 0; i
< mpMainSet
->mpItems
.size(); i
++ )
1525 if ( mpMainSet
->mpItems
[i
]->mnBits
& (SplitWindowItemFlags::RelativeSize
| SplitWindowItemFlags::PercentSize
) )
1528 nCalcSize
+= mpMainSet
->mpItems
[i
]->mnSize
;
1531 if ( i
== mpMainSet
->mpItems
.size() )
1535 nCurSize
= mnDY
-mnTopBorder
-mnBottomBorder
;
1537 nCurSize
= mnDX
-mnLeftBorder
-mnRightBorder
;
1538 nCurSize
-= nSplitSize
;
1539 nCurSize
-= (mpMainSet
->mpItems
.size()-1)*mpMainSet
->mnSplitSize
;
1542 ImplSetWindowSize( nCalcSize
-nCurSize
);
1547 if ( (mnDX
<= 0) || (mnDY
<= 0) )
1550 // pre-calculate sizes/position
1558 if ( mbBottomRight
)
1559 nT
= mnDY
-mnBottomBorder
;
1566 if ( mbBottomRight
)
1567 nL
= mnDX
-mnRightBorder
;
1572 nW
= mnDX
-mnLeftBorder
-mnRightBorder
;
1573 nH
= mnDY
-mnTopBorder
-mnBottomBorder
;
1574 if ( mnWinStyle
& WB_SIZEABLE
)
1582 // calculate sets recursive
1583 ImplCalcSet( mpMainSet
, nL
, nT
, nW
, nH
, mbHorz
, !mbBottomRight
);
1584 ImplCalcSet2( this, mpMainSet
, false, mbHorz
, !mbBottomRight
);
1588 void SplitWindow::ImplUpdate()
1592 if ( IsReallyShown() && IsUpdateMode() && mbRecalc
)
1594 if ( !mpMainSet
->mpItems
.empty() )
1601 void SplitWindow::ImplSplitMousePos( Point
& rMousePos
)
1603 if ( mnSplitTest
& SPLIT_HORZ
)
1605 rMousePos
.X() -= mnMouseOff
;
1606 if ( rMousePos
.X() < maDragRect
.Left() )
1607 rMousePos
.X() = maDragRect
.Left();
1608 else if ( rMousePos
.X()+mpSplitSet
->mnSplitSize
+1 > maDragRect
.Right() )
1609 rMousePos
.X() = maDragRect
.Right()-mpSplitSet
->mnSplitSize
+1;
1610 // store in screen coordinates due to FullDrag
1611 mnMSplitPos
= OutputToScreenPixel( rMousePos
).X();
1615 rMousePos
.Y() -= mnMouseOff
;
1616 if ( rMousePos
.Y() < maDragRect
.Top() )
1617 rMousePos
.Y() = maDragRect
.Top();
1618 else if ( rMousePos
.Y()+mpSplitSet
->mnSplitSize
+1 > maDragRect
.Bottom() )
1619 rMousePos
.Y() = maDragRect
.Bottom()-mpSplitSet
->mnSplitSize
+1;
1620 mnMSplitPos
= OutputToScreenPixel( rMousePos
).Y();
1624 void SplitWindow::ImplGetButtonRect( Rectangle
& rRect
, long nEx
, bool bTest
) const
1626 long nSplitSize
= mpMainSet
->mnSplitSize
-1;
1627 if ( mbAutoHide
|| mbFadeOut
|| mbFadeIn
)
1628 nSplitSize
+= SPLITWIN_SPLITSIZEEX
;
1630 long nButtonSize
= 0;
1632 nButtonSize
+= SPLITWIN_SPLITSIZEFADE
+1;
1634 nButtonSize
+= SPLITWIN_SPLITSIZEFADE
+1;
1636 nButtonSize
+= SPLITWIN_SPLITSIZEAUTOHIDE
+1;
1639 nCenterEx
+= ((mnDX
-mnLeftBorder
-mnRightBorder
)-nButtonSize
)/2;
1641 nCenterEx
+= ((mnDY
-mnTopBorder
-mnBottomBorder
)-nButtonSize
)/2;
1642 if ( nCenterEx
> 0 )
1647 case WindowAlign::Top
:
1648 rRect
.Left() = mnLeftBorder
+nEx
;
1649 rRect
.Top() = mnDY
-mnBottomBorder
-nSplitSize
;
1650 rRect
.Right() = rRect
.Left()+SPLITWIN_SPLITSIZEAUTOHIDE
;
1651 rRect
.Bottom() = mnDY
-mnBottomBorder
-1;
1654 rRect
.Top() -= mnTopBorder
;
1655 rRect
.Bottom() += mnBottomBorder
;
1658 case WindowAlign::Bottom
:
1659 rRect
.Left() = mnLeftBorder
+nEx
;
1660 rRect
.Top() = mnTopBorder
;
1661 rRect
.Right() = rRect
.Left()+SPLITWIN_SPLITSIZEAUTOHIDE
;
1662 rRect
.Bottom() = mnTopBorder
+nSplitSize
-1;
1665 rRect
.Top() -= mnTopBorder
;
1666 rRect
.Bottom() += mnBottomBorder
;
1669 case WindowAlign::Left
:
1670 rRect
.Left() = mnDX
-mnRightBorder
-nSplitSize
;
1671 rRect
.Top() = mnTopBorder
+nEx
;
1672 rRect
.Right() = mnDX
-mnRightBorder
-1;
1673 rRect
.Bottom() = rRect
.Top()+SPLITWIN_SPLITSIZEAUTOHIDE
;
1676 rRect
.Left() -= mnLeftBorder
;
1677 rRect
.Right() += mnRightBorder
;
1680 case WindowAlign::Right
:
1681 rRect
.Left() = mnLeftBorder
;
1682 rRect
.Top() = mnTopBorder
+nEx
;
1683 rRect
.Right() = mnLeftBorder
+nSplitSize
-1;
1684 rRect
.Bottom() = rRect
.Top()+SPLITWIN_SPLITSIZEAUTOHIDE
;
1687 rRect
.Left() -= mnLeftBorder
;
1688 rRect
.Right() += mnRightBorder
;
1694 void SplitWindow::ImplGetAutoHideRect( Rectangle
& rRect
, bool bTest
) const
1701 if ( mbFadeIn
|| mbFadeOut
)
1702 nEx
= SPLITWIN_SPLITSIZEFADE
+1;
1703 ImplGetButtonRect( aRect
, nEx
, bTest
&& mbFadeIn
);
1709 void SplitWindow::ImplGetFadeInRect( Rectangle
& rRect
, bool bTest
) const
1714 ImplGetButtonRect( aRect
, 0, bTest
);
1719 void SplitWindow::ImplGetFadeOutRect( Rectangle
& rRect
, bool ) const
1724 ImplGetButtonRect( aRect
, 0, false );
1729 void SplitWindow::ImplDrawButtonRect(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
, long nSize
)
1731 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1735 long nLeft
= rRect
.Left();
1736 long nRight
= rRect
.Right();
1737 long nCenter
= rRect
.Center().Y();
1738 long nEx1
= nLeft
+((rRect
.GetWidth()-nSize
)/2)-2;
1739 long nEx2
= nEx1
+nSize
+3;
1740 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor() );
1741 rRenderContext
.DrawLine( Point( rRect
.Left(), rRect
.Top() ), Point( rRect
.Left(), rRect
.Bottom() ) );
1742 rRenderContext
.DrawLine( Point( rRect
.Left(), rRect
.Top() ), Point( rRect
.Right(), rRect
.Top() ) );
1743 rRenderContext
.SetLineColor( rStyleSettings
.GetShadowColor() );
1744 rRenderContext
.DrawLine( Point( rRect
.Right(), rRect
.Top() ), Point( rRect
.Right(), rRect
.Bottom() ) );
1745 rRenderContext
.DrawLine( Point( rRect
.Left(), rRect
.Bottom() ), Point( rRect
.Right(), rRect
.Bottom() ) );
1747 while ( i
< nRight
-3 )
1749 if ( (i
< nEx1
) || (i
> nEx2
) )
1751 rRenderContext
.DrawPixel( Point( i
, nCenter
-2 ), rStyleSettings
.GetLightColor() );
1752 rRenderContext
.DrawPixel( Point( i
+1, nCenter
-2+1 ), rStyleSettings
.GetShadowColor() );
1755 if ( (i
< nEx1
) || ((i
> nEx2
) && (i
< nRight
-3)) )
1757 rRenderContext
.DrawPixel( Point( i
, nCenter
+2 ), rStyleSettings
.GetLightColor() );
1758 rRenderContext
.DrawPixel( Point( i
+1, nCenter
+2+1 ), rStyleSettings
.GetShadowColor() );
1765 long nTop
= rRect
.Top();
1766 long nBottom
= rRect
.Bottom();
1767 long nCenter
= rRect
.Center().X();
1768 long nEx1
= nTop
+((rRect
.GetHeight()-nSize
)/2)-2;
1769 long nEx2
= nEx1
+nSize
+3;
1770 rRenderContext
.SetLineColor( rStyleSettings
.GetLightColor() );
1771 rRenderContext
.DrawLine( Point( rRect
.Left(), rRect
.Top() ), Point( rRect
.Right(), rRect
.Top() ) );
1772 rRenderContext
.DrawLine( Point( rRect
.Left(), rRect
.Top() ), Point( rRect
.Left(), rRect
.Bottom() ) );
1773 rRenderContext
.SetLineColor( rStyleSettings
.GetShadowColor() );
1774 rRenderContext
.DrawLine( Point( rRect
.Right(), rRect
.Top() ), Point( rRect
.Right(), rRect
.Bottom() ) );
1775 rRenderContext
.DrawLine( Point( rRect
.Left(), rRect
.Bottom() ), Point( rRect
.Right(), rRect
.Bottom() ) );
1777 while ( i
< nBottom
-3 )
1779 if ( (i
< nEx1
) || (i
> nEx2
) )
1781 rRenderContext
.DrawPixel( Point( nCenter
-2, i
), rStyleSettings
.GetLightColor() );
1782 rRenderContext
.DrawPixel( Point( nCenter
-2+1, i
+1 ), rStyleSettings
.GetShadowColor() );
1785 if ( (i
< nEx1
) || ((i
> nEx2
) && (i
< nBottom
-3)) )
1787 rRenderContext
.DrawPixel( Point( nCenter
+2, i
), rStyleSettings
.GetLightColor() );
1788 rRenderContext
.DrawPixel( Point( nCenter
+2+1, i
+1 ), rStyleSettings
.GetShadowColor() );
1795 void SplitWindow::ImplDrawAutoHide(vcl::RenderContext
& rRenderContext
)
1799 Rectangle aTempRect
;
1800 ImplGetAutoHideRect( aTempRect
);
1802 // load ImageListe, if not available
1803 ImplSVData
* pSVData
= ImplGetSVData();
1804 ImageList
* pImageList
;
1807 if (!pSVData
->maCtrlData
.mpSplitHPinImgList
)
1809 ResMgr
* pResMgr
= ImplGetResMgr();
1812 Color
aNonAlphaMask( 0x00, 0x00, 0xFF );
1813 pSVData
->maCtrlData
.mpSplitHPinImgList
= new ImageList
;
1814 pSVData
->maCtrlData
.mpSplitHPinImgList
->InsertFromHorizontalBitmap
1815 ( ResId( SV_RESID_BITMAP_SPLITHPIN
, *pResMgr
), 4, &aNonAlphaMask
);
1818 pImageList
= pSVData
->maCtrlData
.mpSplitHPinImgList
;
1822 if (!pSVData
->maCtrlData
.mpSplitVPinImgList
)
1824 ResMgr
* pResMgr
= ImplGetResMgr();
1825 pSVData
->maCtrlData
.mpSplitVPinImgList
= new ImageList
;
1828 Color
aNonAlphaMask( 0x00, 0x00, 0xFF );
1829 pSVData
->maCtrlData
.mpSplitVPinImgList
->InsertFromHorizontalBitmap(
1830 ResId( SV_RESID_BITMAP_SPLITVPIN
, *pResMgr
), 4, &aNonAlphaMask
);
1833 pImageList
= pSVData
->maCtrlData
.mpSplitVPinImgList
;
1839 // retrieve and return image
1841 if (mbAutoHidePressed
)
1856 Image aImage
= pImageList
->GetImage( nId
);
1857 Size aImageSize
= aImage
.GetSizePixel();
1858 Point
aPos(aTempRect
.Left() + ((aTempRect
.GetWidth() - aImageSize
.Width()) / 2),
1859 aTempRect
.Top() + ((aTempRect
.GetHeight() - aImageSize
.Height()) / 2));
1862 nSize
= aImageSize
.Width();
1864 nSize
= aImageSize
.Height();
1865 ImplDrawButtonRect(rRenderContext
, aTempRect
, nSize
);
1866 rRenderContext
.DrawImage(aPos
, aImage
);
1870 void SplitWindow::ImplDrawGrip(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
, bool bHorizontal
, bool bLeft
)
1872 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1876 if (rRect
.IsInside(GetPointerPosPixel()))
1878 vcl::RenderTools::DrawSelectionBackground(rRenderContext
, *this, rRect
, 2, false, false, false);
1880 aColor
= rStyleSettings
.GetDarkShadowColor();
1884 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
1885 rRenderContext
.SetFillColor(rStyleSettings
.GetDarkShadowColor());
1887 rRenderContext
.DrawRect(rRect
);
1889 aColor
= rStyleSettings
.GetFaceColor();
1892 AntialiasingFlags nAA
= rRenderContext
.GetAntialiasing();
1893 rRenderContext
.SetAntialiasing(nAA
| AntialiasingFlags::PixelSnapHairline
| AntialiasingFlags::EnableB2dDraw
);
1895 long nWidth
= rRect
.getWidth();
1896 long nWidthHalf
= nWidth
/ 2;
1897 long nHeight
= rRect
.getHeight();
1898 long nHeightHalf
= nHeight
/ 2;
1900 long nLeft
= rRect
.Left();
1901 long nRight
= rRect
.Right();
1902 long nTop
= rRect
.Top();
1903 long nBottom
= rRect
.Bottom();
1906 rRenderContext
.SetLineColor(aColor
);
1907 rRenderContext
.SetFillColor(aColor
);
1909 tools::Polygon
aPoly(3);
1913 long nCenter
= nLeft
+ nWidthHalf
;
1917 aPoly
.SetPoint(Point(nCenter
, nTop
+ nMargin
), 0);
1918 aPoly
.SetPoint(Point(nCenter
- nHeightHalf
, nBottom
- nMargin
), 1);
1919 aPoly
.SetPoint(Point(nCenter
- nHeightHalf
, nBottom
- nMargin
), 2);
1923 aPoly
.SetPoint(Point(nCenter
, nBottom
- nMargin
), 0);
1924 aPoly
.SetPoint(Point(nCenter
- nHeightHalf
, nTop
+ nMargin
), 1);
1925 aPoly
.SetPoint(Point(nCenter
+ nHeightHalf
, nTop
+ nMargin
), 2);
1927 rRenderContext
.DrawPolygon(aPoly
);
1931 long nCenter
= nTop
+ nHeightHalf
;
1935 aPoly
.SetPoint(Point(nLeft
+ nMargin
, nCenter
), 0);
1936 aPoly
.SetPoint(Point(nRight
- nMargin
, nCenter
- nWidthHalf
), 1);
1937 aPoly
.SetPoint(Point(nRight
- nMargin
, nCenter
+ nWidthHalf
), 2);
1941 aPoly
.SetPoint(Point(nRight
- nMargin
, nCenter
), 0);
1942 aPoly
.SetPoint(Point(nLeft
+ nMargin
, nCenter
- nWidthHalf
), 1);
1943 aPoly
.SetPoint(Point(nLeft
+ nMargin
, nCenter
+ nWidthHalf
), 2);
1945 rRenderContext
.DrawPolygon(aPoly
);
1948 rRenderContext
.SetAntialiasing(nAA
);
1951 void SplitWindow::ImplDrawFadeIn(vcl::RenderContext
& rRenderContext
)
1955 Rectangle aTempRect
;
1956 ImplGetFadeInRect(aTempRect
);
1961 case WindowAlign::Top
:
1962 case WindowAlign::Left
:
1965 case WindowAlign::Bottom
:
1966 case WindowAlign::Right
:
1972 ImplDrawGrip(rRenderContext
, aTempRect
, (meAlign
== WindowAlign::Top
) || (meAlign
== WindowAlign::Bottom
), bLeft
);
1976 void SplitWindow::ImplDrawFadeOut(vcl::RenderContext
& rRenderContext
)
1980 Rectangle aTempRect
;
1981 ImplGetFadeOutRect(aTempRect
);
1986 case WindowAlign::Bottom
:
1987 case WindowAlign::Right
:
1990 case WindowAlign::Top
:
1991 case WindowAlign::Left
:
1997 ImplDrawGrip(rRenderContext
, aTempRect
, (meAlign
== WindowAlign::Top
) || (meAlign
== WindowAlign::Bottom
), bLeft
);
2001 void SplitWindow::ImplStartSplit( const MouseEvent
& rMEvt
)
2003 Point aMousePosPixel
= rMEvt
.GetPosPixel();
2004 mnSplitTest
= ImplTestSplit( this, aMousePosPixel
, mnMouseOff
, &mpSplitSet
, mnSplitPos
);
2006 if ( mnSplitTest
&& !(mnSplitTest
& SPLIT_NOSPLIT
) )
2008 ImplSplitItem
* pSplitItem
;
2013 mnMouseModifier
= rMEvt
.GetModifier();
2014 if ( !(mnMouseModifier
& KEY_SHIFT
) || (static_cast<sal_uInt16
>(mnSplitPos
+1) >= mpSplitSet
->mpItems
.size()) )
2015 bPropSmaller
= false;
2017 bPropSmaller
= true;
2019 // here we can set the maximum size
2023 nCurMaxSize
= mnMaxSize
;
2026 Size aSize
= GetParent()->GetOutputSizePixel();
2028 nCurMaxSize
= aSize
.Height();
2030 nCurMaxSize
= aSize
.Width();
2033 if ( !mpSplitSet
->mpItems
.empty() )
2036 if ( (mpSplitSet
== mpMainSet
) && mbBottomRight
)
2039 pSplitItem
= mpSplitSet
->mpItems
[mnSplitPos
];
2040 maDragRect
.Left() = pSplitItem
->mnLeft
;
2041 maDragRect
.Top() = pSplitItem
->mnTop
;
2042 maDragRect
.Right() = pSplitItem
->mnLeft
+pSplitItem
->mnWidth
-1;
2043 maDragRect
.Bottom() = pSplitItem
->mnTop
+pSplitItem
->mnHeight
-1;
2045 if ( mnSplitTest
& SPLIT_HORZ
)
2048 maDragRect
.Right() += mpSplitSet
->mnSplitSize
;
2050 maDragRect
.Left() -= mpSplitSet
->mnSplitSize
;
2055 maDragRect
.Bottom() += mpSplitSet
->mnSplitSize
;
2057 maDragRect
.Top() -= mpSplitSet
->mnSplitSize
;
2065 pSplitItem
= mpSplitSet
->mpItems
[nTemp
-1];
2066 if ( pSplitItem
->mbFixed
)
2070 if ( mnSplitTest
& SPLIT_HORZ
)
2073 maDragRect
.Left() -= pSplitItem
->mnPixSize
;
2075 maDragRect
.Right() += pSplitItem
->mnPixSize
;
2080 maDragRect
.Top() -= pSplitItem
->mnPixSize
;
2082 maDragRect
.Bottom() += pSplitItem
->mnPixSize
;
2089 if ( (mpSplitSet
== mpMainSet
) && (mnWinStyle
& WB_SIZEABLE
) && !bPropSmaller
)
2094 maDragRect
.Bottom() += nCurMaxSize
-mnDY
-mnTopBorder
;
2096 maDragRect
.Right() += nCurMaxSize
-mnDX
-mnLeftBorder
;
2101 maDragRect
.Top() -= nCurMaxSize
-mnDY
-mnBottomBorder
;
2103 maDragRect
.Left() -= nCurMaxSize
-mnDX
-mnRightBorder
;
2108 nTemp
= mnSplitPos
+1;
2109 while ( nTemp
< mpSplitSet
->mpItems
.size() )
2111 pSplitItem
= mpSplitSet
->mpItems
[nTemp
];
2112 if ( pSplitItem
->mbFixed
)
2116 if ( mnSplitTest
& SPLIT_HORZ
)
2119 maDragRect
.Right() += pSplitItem
->mnPixSize
;
2121 maDragRect
.Left() -= pSplitItem
->mnPixSize
;
2126 maDragRect
.Bottom() += pSplitItem
->mnPixSize
;
2128 maDragRect
.Top() -= pSplitItem
->mnPixSize
;
2137 maDragRect
.Left() = mnLeftBorder
;
2138 maDragRect
.Top() = mnTopBorder
;
2139 maDragRect
.Right() = mnDX
-mnRightBorder
-1;
2140 maDragRect
.Bottom() = mnDY
-mnBottomBorder
-1;
2143 if ( mbBottomRight
)
2144 maDragRect
.Top() -= nCurMaxSize
-mnDY
-mnBottomBorder
;
2146 maDragRect
.Bottom() += nCurMaxSize
-mnDY
-mnTopBorder
;
2150 if ( mbBottomRight
)
2151 maDragRect
.Left() -= nCurMaxSize
-mnDX
-mnRightBorder
;
2153 maDragRect
.Right() += nCurMaxSize
-mnDX
-mnLeftBorder
;
2159 mbDragFull
= bool(GetSettings().GetStyleSettings().GetDragFullOptions() & DragFullOptions::Split
);
2161 ImplSplitMousePos( aMousePosPixel
);
2165 ImplDrawSplitTracking(aMousePosPixel
);
2169 std::vector
< ImplSplitItem
* >& rItems
= mpSplitSet
->mpItems
;
2170 sal_uInt16 nItems
= mpSplitSet
->mpItems
.size();
2171 mpLastSizes
= new long[nItems
*2];
2172 for ( sal_uInt16 i
= 0; i
< nItems
; i
++ )
2174 mpLastSizes
[i
*2] = rItems
[i
]->mnSize
;
2175 mpLastSizes
[i
*2+1] = rItems
[i
]->mnPixSize
;
2178 mnMStartPos
= mnMSplitPos
;
2180 PointerStyle eStyle
= PointerStyle::Arrow
;
2181 if ( mnSplitTest
& SPLIT_HORZ
)
2182 eStyle
= PointerStyle::HSplit
;
2183 else if ( mnSplitTest
& SPLIT_VERT
)
2184 eStyle
= PointerStyle::VSplit
;
2186 Pointer
aPtr( eStyle
);
2191 void SplitWindow::StartSplit()
2195 void SplitWindow::Split()
2197 maSplitHdl
.Call( this );
2200 void SplitWindow::SplitResize()
2204 void SplitWindow::AutoHide()
2208 void SplitWindow::FadeIn()
2212 void SplitWindow::FadeOut()
2216 void SplitWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
2218 if ( !rMEvt
.IsLeft() || rMEvt
.IsMod2() )
2220 DockingWindow::MouseButtonDown( rMEvt
);
2224 Point aMousePosPixel
= rMEvt
.GetPosPixel();
2225 Rectangle aTestRect
;
2227 mbFadeNoButtonMode
= false;
2228 ImplGetAutoHideRect( aTestRect
, true );
2229 if ( aTestRect
.IsInside( aMousePosPixel
) )
2231 mbAutoHideDown
= true;
2232 mbAutoHidePressed
= true;
2237 ImplGetFadeOutRect( aTestRect
, true );
2238 if ( aTestRect
.IsInside( aMousePosPixel
) )
2240 mbFadeOutDown
= true;
2241 mbFadeOutPressed
= true;
2246 ImplGetFadeInRect( aTestRect
, true );
2247 if ( aTestRect
.IsInside( aMousePosPixel
) )
2249 mbFadeInDown
= true;
2250 mbFadeInPressed
= true;
2253 else if ( !aTestRect
.IsEmpty() && !(mnWinStyle
& WB_SIZEABLE
) )
2255 mbFadeNoButtonMode
= true;
2262 if ( mbAutoHideDown
|| mbFadeInDown
|| mbFadeOutDown
)
2265 ImplStartSplit( rMEvt
);
2268 void SplitWindow::MouseMove( const MouseEvent
& rMEvt
)
2270 if ( !IsTracking() )
2272 Point aPos
= rMEvt
.GetPosPixel();
2274 ImplSplitSet
* pTempSplitSet
;
2275 sal_uInt16 nTempSplitPos
;
2276 sal_uInt16 nSplitTest
= ImplTestSplit( this, aPos
, nTemp
, &pTempSplitSet
, nTempSplitPos
);
2277 PointerStyle eStyle
= PointerStyle::Arrow
;
2278 Rectangle aAutoHideRect
;
2279 Rectangle aFadeInRect
;
2280 Rectangle aFadeOutRect
;
2282 ImplGetAutoHideRect( aAutoHideRect
);
2283 ImplGetFadeInRect( aFadeInRect
);
2284 ImplGetFadeOutRect( aFadeOutRect
);
2285 if ( !aAutoHideRect
.IsInside( aPos
) &&
2286 !aFadeInRect
.IsInside( aPos
) &&
2287 !aFadeOutRect
.IsInside( aPos
) )
2289 if ( nSplitTest
&& !(nSplitTest
& SPLIT_NOSPLIT
) )
2291 if ( nSplitTest
& SPLIT_HORZ
)
2292 eStyle
= PointerStyle::HSplit
;
2293 else if ( nSplitTest
& SPLIT_VERT
)
2294 eStyle
= PointerStyle::VSplit
;
2298 Pointer
aPtr( eStyle
);
2303 void SplitWindow::Tracking( const TrackingEvent
& rTEvt
)
2305 Point aMousePosPixel
= rTEvt
.GetMouseEvent().GetPosPixel();
2307 if ( mbAutoHideDown
)
2309 if ( rTEvt
.IsTrackingEnded() )
2311 mbAutoHideDown
= false;
2312 if ( mbAutoHidePressed
)
2314 mbAutoHidePressed
= false;
2316 if ( !rTEvt
.IsTrackingCanceled() )
2318 mbAutoHideIn
= !mbAutoHideIn
;
2328 Rectangle aTestRect
;
2329 ImplGetAutoHideRect( aTestRect
, true );
2330 bool bNewPressed
= aTestRect
.IsInside( aMousePosPixel
);
2331 if ( bNewPressed
!= mbAutoHidePressed
)
2333 mbAutoHidePressed
= bNewPressed
;
2338 else if ( mbFadeInDown
)
2340 if ( rTEvt
.IsTrackingEnded() )
2342 mbFadeInDown
= false;
2343 if ( mbFadeInPressed
)
2345 mbFadeInPressed
= false;
2348 if ( !rTEvt
.IsTrackingCanceled() )
2354 Rectangle aTestRect
;
2355 ImplGetFadeInRect( aTestRect
, true );
2356 bool bNewPressed
= aTestRect
.IsInside( aMousePosPixel
);
2357 if ( bNewPressed
!= mbFadeInPressed
)
2359 mbFadeInPressed
= bNewPressed
;
2364 else if ( mbFadeOutDown
)
2366 if ( rTEvt
.IsTrackingEnded() )
2368 mbFadeOutDown
= false;
2369 if ( mbFadeOutPressed
)
2371 mbFadeOutPressed
= false;
2374 if ( !rTEvt
.IsTrackingCanceled() )
2380 Rectangle aTestRect
;
2381 ImplGetFadeOutRect( aTestRect
, true );
2382 bool bNewPressed
= aTestRect
.IsInside( aMousePosPixel
);
2385 mbFadeOutPressed
= bNewPressed
;
2388 // We need a mouseevent with a position inside the button for the
2389 // ImplStartSplit function!
2390 MouseEvent aOrgMEvt
= rTEvt
.GetMouseEvent();
2391 MouseEvent aNewMEvt
= MouseEvent( aTestRect
.Center(), aOrgMEvt
.GetClicks(),
2392 aOrgMEvt
.GetMode(), aOrgMEvt
.GetButtons(),
2393 aOrgMEvt
.GetModifier() );
2395 ImplStartSplit( aNewMEvt
);
2396 mbFadeOutDown
= false;
2402 ImplSplitMousePos( aMousePosPixel
);
2406 if ( rTEvt
.IsTrackingEnded() )
2408 if ( rTEvt
.IsTrackingCanceled() )
2410 std::vector
< ImplSplitItem
* >& rItems
= mpSplitSet
->mpItems
;
2411 size_t nItems
= rItems
.size();
2412 for ( size_t i
= 0; i
< nItems
; i
++ )
2414 rItems
[i
]->mnSize
= mpLastSizes
[i
*2];
2415 rItems
[i
]->mnPixSize
= mpLastSizes
[i
*2+1];
2425 if ( rTEvt
.IsTrackingEnded() )
2428 bSplit
= !rTEvt
.IsTrackingCanceled();
2432 ImplDrawSplitTracking(aMousePosPixel
);
2439 bool bPropSmaller
= (mnMouseModifier
& KEY_SHIFT
) != 0;
2440 bool bPropGreater
= (mnMouseModifier
& KEY_MOD1
) != 0;
2441 long nDelta
= mnMSplitPos
-mnMStartPos
;
2443 if ( (mnSplitTest
& SPLIT_WINDOW
) && mpMainSet
->mpItems
.empty() )
2445 if ( (mpSplitSet
== mpMainSet
) && mbBottomRight
)
2447 ImplSetWindowSize( nDelta
);
2451 long nNewSize
= mpSplitSet
->mpItems
[mnSplitPos
]->mnPixSize
;
2452 if ( (mpSplitSet
== mpMainSet
) && mbBottomRight
)
2456 SplitItem( mpSplitSet
->mpItems
[mnSplitPos
]->mnId
, nNewSize
,
2457 bPropSmaller
, bPropGreater
);
2465 mnMStartPos
= mnMSplitPos
;
2469 if ( rTEvt
.IsTrackingEnded() )
2471 delete [] mpLastSizes
;
2472 mpLastSizes
= nullptr;
2473 mpSplitSet
= nullptr;
2477 mnMouseModifier
= 0;
2484 bool SplitWindow::PreNotify( NotifyEvent
& rNEvt
)
2486 const MouseEvent
* pMouseEvt
= nullptr;
2488 if( (rNEvt
.GetType() == MouseNotifyEvent::MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != nullptr )
2490 if( !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
2492 // trigger redraw if mouse over state has changed
2493 Rectangle aFadeInRect
;
2494 Rectangle aFadeOutRect
;
2495 ImplGetFadeInRect( aFadeInRect
);
2496 ImplGetFadeOutRect( aFadeOutRect
);
2498 if ( aFadeInRect
.IsInside( GetPointerPosPixel() ) != aFadeInRect
.IsInside( GetLastPointerPosPixel() ) )
2499 Invalidate( aFadeInRect
);
2500 if ( aFadeOutRect
.IsInside( GetPointerPosPixel() ) != aFadeOutRect
.IsInside( GetLastPointerPosPixel() ) )
2501 Invalidate( aFadeOutRect
);
2503 if( pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
2505 Invalidate( aFadeInRect
);
2506 Invalidate( aFadeOutRect
);
2510 return Window::PreNotify( rNEvt
);
2513 void SplitWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
&)
2515 if (mnWinStyle
& WB_BORDER
)
2516 ImplDrawBorder(rRenderContext
);
2518 ImplDrawBorderLine(rRenderContext
);
2519 ImplDrawFadeOut(rRenderContext
);
2520 ImplDrawFadeIn(rRenderContext
);
2521 ImplDrawAutoHide(rRenderContext
);
2523 // draw FrameSet-backgrounds
2524 ImplDrawBack(rRenderContext
, mpMainSet
);
2527 if (!(mnWinStyle
& WB_NOSPLITDRAW
))
2529 bool bFlat
= (GetStyle() & WB_FLATSPLITDRAW
) == WB_FLATSPLITDRAW
;
2530 ImplDrawSplit(rRenderContext
, mpMainSet
, mbHorz
, bFlat
, !mbBottomRight
);
2534 void SplitWindow::Resize()
2536 Size aSize
= GetOutputSizePixel();
2537 mnDX
= aSize
.Width();
2538 mnDY
= aSize
.Height();
2544 void SplitWindow::RequestHelp( const HelpEvent
& rHEvt
)
2546 // no keyboard help for splitwin
2547 if ( rHEvt
.GetMode() & (HelpEventMode::BALLOON
| HelpEventMode::QUICK
) && !rHEvt
.KeyboardActivated() )
2549 Point aMousePosPixel
= ScreenToOutputPixel( rHEvt
.GetMousePosPixel() );
2550 Rectangle aHelpRect
;
2551 sal_uInt16 nHelpResId
= 0;
2553 ImplGetAutoHideRect( aHelpRect
, true );
2554 if ( aHelpRect
.IsInside( aMousePosPixel
) )
2557 nHelpResId
= SV_HELPTEXT_SPLITFIXED
;
2559 nHelpResId
= SV_HELPTEXT_SPLITFLOATING
;
2563 ImplGetFadeInRect( aHelpRect
, true );
2564 if ( aHelpRect
.IsInside( aMousePosPixel
) )
2565 nHelpResId
= SV_HELPTEXT_FADEIN
;
2568 ImplGetFadeOutRect( aHelpRect
, true );
2569 if ( aHelpRect
.IsInside( aMousePosPixel
) )
2570 nHelpResId
= SV_HELPTEXT_FADEOUT
;
2577 Point aPt
= OutputToScreenPixel( aHelpRect
.TopLeft() );
2578 aHelpRect
.Left() = aPt
.X();
2579 aHelpRect
.Top() = aPt
.Y();
2580 aPt
= OutputToScreenPixel( aHelpRect
.BottomRight() );
2581 aHelpRect
.Right() = aPt
.X();
2582 aHelpRect
.Bottom() = aPt
.Y();
2584 // get and draw text
2586 ResMgr
* pResMgr
= ImplGetResMgr();
2588 aStr
= ResId( nHelpResId
, *pResMgr
).toString();
2589 if ( rHEvt
.GetMode() & HelpEventMode::BALLOON
)
2590 Help::ShowBalloon( this, aHelpRect
.Center(), aHelpRect
, aStr
);
2592 Help::ShowQuickHelp( this, aHelpRect
, aStr
);
2597 DockingWindow::RequestHelp( rHEvt
);
2600 void SplitWindow::StateChanged( StateChangedType nType
)
2604 case StateChangedType::InitShow
:
2605 if ( IsUpdateMode() )
2608 case StateChangedType::UpdateMode
:
2609 if ( IsUpdateMode() && IsReallyShown() )
2612 case StateChangedType::ControlBackground
:
2619 DockingWindow::StateChanged( nType
);
2622 void SplitWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
2624 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
2625 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
2631 DockingWindow::DataChanged( rDCEvt
);
2634 void SplitWindow::InsertItem( sal_uInt16 nId
, vcl::Window
* pWindow
, long nSize
,
2635 sal_uInt16 nPos
, sal_uInt16 nIntoSetId
,
2636 SplitWindowItemFlags nBits
)
2639 sal_uInt16 nDbgDummy
;
2640 SAL_WARN_IF( ImplFindItem( mpMainSet
, nId
, nDbgDummy
), "vcl", "SplitWindow::InsertItem() - Id already exists" );
2643 // Size has to be at least 1.
2647 ImplSplitSet
* pSet
= ImplFindSet( mpMainSet
, nIntoSetId
);
2649 SAL_WARN_IF( !pSet
, "vcl", "SplitWindow::InsertItem() - Set not exists" );
2656 // Don't insert further than the end
2657 if ( nPos
> pSet
->mpItems
.size() )
2658 nPos
= pSet
->mpItems
.size();
2661 ImplSplitItem
* pItem
= new ImplSplitItem();
2662 pItem
->mnSize
= nSize
;
2663 pItem
->mnPixSize
= 0;
2665 pItem
->mnBits
= nBits
;
2666 pItem
->mnMinSize
=-1;
2667 pItem
->mnMaxSize
=-1;
2671 // New VclPtr reference
2672 pItem
->mpWindow
= pWindow
;
2673 pItem
->mpOrgParent
= pWindow
->GetParent();
2675 // Attach window to SplitWindow.
2677 pWindow
->SetParent( this );
2681 ImplSplitSet
* pNewSet
= new ImplSplitSet();
2682 pNewSet
->mnId
= nId
;
2683 pNewSet
->mnSplitSize
= pSet
->mnSplitSize
;
2685 pItem
->mpSet
= pNewSet
;
2689 pSet
->mpItems
.insert( pSet
->mpItems
.begin() + nPos
, pItem
);
2690 pSet
->mbCalcPix
= true;
2695 void SplitWindow::InsertItem( sal_uInt16 nId
, long nSize
,
2696 sal_uInt16 nPos
, sal_uInt16 nIntoSetId
,
2697 SplitWindowItemFlags nBits
)
2699 InsertItem( nId
, nullptr, nSize
, nPos
, nIntoSetId
, nBits
);
2702 void SplitWindow::RemoveItem( sal_uInt16 nId
)
2705 sal_uInt16 nDbgDummy
;
2706 SAL_WARN_IF( !ImplFindItem( mpMainSet
, nId
, nDbgDummy
), "vcl", "SplitWindow::RemoveItem() - Id not found" );
2711 ImplSplitSet
* pSet
= ImplFindItem( mpMainSet
, nId
, nPos
);
2716 ImplSplitItem
* pItem
= pSet
->mpItems
[nPos
];
2717 VclPtr
<vcl::Window
> pWindow
= pItem
->mpWindow
;
2718 VclPtr
<vcl::Window
> pOrgParent
= pItem
->mpOrgParent
;
2720 // delete set if required
2722 delete pItem
->mpSet
;
2723 pItem
->mpSet
= nullptr;
2727 pSet
->mbCalcPix
= true;
2728 pSet
->mpItems
.erase( pSet
->mpItems
.begin() + nPos
);
2732 // to have the least amounts of paints delete window only here
2737 pWindow
->SetParent( pOrgParent
);
2746 void SplitWindow::Clear()
2751 // create Main-Set again
2752 mpMainSet
= new ImplSplitSet();
2753 if ( mnWinStyle
& WB_NOSPLITDRAW
)
2754 mpMainSet
->mnSplitSize
-= 2;
2755 mpBaseSet
= mpMainSet
;
2757 // and invalidate again
2761 void SplitWindow::SplitItem( sal_uInt16 nId
, long nNewSize
,
2762 bool bPropSmall
, bool bPropGreat
)
2765 ImplSplitSet
* pSet
= ImplFindItem( mpBaseSet
, nId
, nPos
);
2770 size_t nItems
= pSet
->mpItems
.size();
2771 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
2773 // When there is an explicit minimum or maximum size then move nNewSize
2774 // into that range (when it is not yet already in it.)
2775 nNewSize
= ValidateSize(nNewSize
, rItems
[nPos
]);
2779 rItems
[nPos
]->mnSize
= nNewSize
;
2783 long nDelta
= nNewSize
-rItems
[nPos
]->mnPixSize
;
2787 // calculate area, which could be affected by splitting
2788 sal_uInt16 nMin
= 0;
2789 sal_uInt16 nMax
= nItems
;
2790 for (size_t i
= 0; i
< nItems
; ++i
)
2792 if ( rItems
[i
]->mbFixed
)
2801 // treat TopSet different if the window is sizeable
2804 if ( (pSet
== mpMainSet
) && (mnWinStyle
& WB_SIZEABLE
) )
2806 if ( nPos
< pSet
->mpItems
.size()-1 )
2808 if ( !((bPropSmall
&& bPropGreat
) ||
2809 ((nDelta
> 0) && bPropSmall
) ||
2810 ((nDelta
< 0) && bPropGreat
)) )
2826 else if ( nPos
>= nMax
)
2831 else if ( nPos
&& (nPos
>= pSet
->mpItems
.size()-1) )
2835 bool bTemp
= bPropSmall
;
2836 bPropSmall
= bPropGreat
;
2841 // now splitt the windows
2848 long nTempDelta
= nDelta
;
2856 rItems
[n
]->mnPixSize
++;
2863 while ( nTempDelta
);
2866 rItems
[nPos
+1]->mnPixSize
-= nDelta
;
2878 if ( nDelta
&& rItems
[n
-1]->mnPixSize
)
2880 rItems
[n
-1]->mnPixSize
--;
2895 if ( rItems
[n
-1]->mnPixSize
+nDelta
< 0 )
2897 nDelta
+= rItems
[n
-1]->mnPixSize
;
2898 rItems
[n
-1]->mnPixSize
= 0;
2902 rItems
[n
-1]->mnPixSize
+= nDelta
;
2917 long nTempDelta
= nDelta
;
2925 rItems
[n
-1]->mnPixSize
++;
2932 while ( nTempDelta
);
2935 rItems
[nPos
]->mnPixSize
+= nDelta
;
2947 if ( nDelta
&& rItems
[n
]->mnPixSize
)
2949 rItems
[n
]->mnPixSize
--;
2964 if ( rItems
[n
]->mnPixSize
-nDelta
< 0 )
2966 nDelta
-= rItems
[n
]->mnPixSize
;
2967 rItems
[n
]->mnPixSize
= 0;
2971 rItems
[n
]->mnPixSize
-= nDelta
;
2981 // update original sizes
2982 ImplCalcLogSize( rItems
, nItems
);
2987 void SplitWindow::SetItemSize( sal_uInt16 nId
, long nNewSize
)
2990 ImplSplitSet
* pSet
= ImplFindItem( mpBaseSet
, nId
, nPos
);
2991 ImplSplitItem
* pItem
;
2996 // check if size is changed
2997 pItem
= pSet
->mpItems
[nPos
];
2998 if ( pItem
->mnSize
!= nNewSize
)
3000 // set new size and re-calculate
3001 pItem
->mnSize
= nNewSize
;
3002 pSet
->mbCalcPix
= true;
3007 long SplitWindow::GetItemSize( sal_uInt16 nId
) const
3010 ImplSplitSet
* pSet
= ImplFindItem( mpBaseSet
, nId
, nPos
);
3013 return pSet
->mpItems
[nPos
]->mnSize
;
3018 long SplitWindow::GetItemSize( sal_uInt16 nId
, SplitWindowItemFlags nBits
) const
3021 ImplSplitSet
* pSet
= ImplFindItem( mpBaseSet
, nId
, nPos
);
3025 if ( nBits
== pSet
->mpItems
[nPos
]->mnBits
)
3026 return pSet
->mpItems
[nPos
]->mnSize
;
3029 const_cast<SplitWindow
*>(this)->ImplCalcLayout();
3034 SplitWindowItemFlags nTempBits
;
3036 nItems
= pSet
->mpItems
.size();
3037 std::vector
< ImplSplitItem
* >& rItems
= pSet
->mpItems
;
3038 for ( i
= 0; i
< nItems
; i
++ )
3043 nTempBits
= rItems
[i
]->mnBits
;
3044 if ( nTempBits
& SplitWindowItemFlags::RelativeSize
)
3045 nRelSize
+= rItems
[i
]->mnPixSize
;
3046 else if ( nTempBits
& SplitWindowItemFlags::PercentSize
)
3047 nPerSize
+= rItems
[i
]->mnPixSize
;
3049 nPerSize
+= nRelSize
;
3050 if ( nBits
& SplitWindowItemFlags::RelativeSize
)
3053 return (rItems
[nPos
]->mnPixSize
+(nRelSize
/2))/nRelSize
;
3057 else if ( nBits
& SplitWindowItemFlags::PercentSize
)
3060 return (rItems
[nPos
]->mnPixSize
*100)/nPerSize
;
3065 return rItems
[nPos
]->mnPixSize
;
3072 void SplitWindow::SetItemSizeRange (sal_uInt16 nId
, const Range
& rRange
)
3075 ImplSplitSet
* pSet
= ImplFindItem(mpBaseSet
, nId
, nPos
);
3077 if (pSet
!= nullptr)
3079 pSet
->mpItems
[nPos
]->mnMinSize
= rRange
.Min();
3080 pSet
->mpItems
[nPos
]->mnMaxSize
= rRange
.Max();
3084 sal_uInt16
SplitWindow::GetSet( sal_uInt16 nId
) const
3087 ImplSplitSet
* pSet
= ImplFindItem( mpBaseSet
, nId
, nPos
);
3095 bool SplitWindow::IsItemValid( sal_uInt16 nId
) const
3098 ImplSplitSet
* pSet
= mpBaseSet
? ImplFindItem(mpBaseSet
, nId
, nPos
) : nullptr;
3106 sal_uInt16
SplitWindow::GetItemId( vcl::Window
* pWindow
) const
3108 return ImplFindItem( mpBaseSet
, pWindow
);
3111 sal_uInt16
SplitWindow::GetItemId( const Point
& rPos
) const
3113 return ImplFindItem( mpBaseSet
, rPos
, mbHorz
, !mbBottomRight
);
3116 sal_uInt16
SplitWindow::GetItemPos( sal_uInt16 nId
, sal_uInt16 nSetId
) const
3118 ImplSplitSet
* pSet
= ImplFindSet( mpBaseSet
, nSetId
);
3119 sal_uInt16 nPos
= SPLITWINDOW_ITEM_NOTFOUND
;
3123 for ( size_t i
= 0; i
< pSet
->mpItems
.size(); i
++ )
3125 if ( pSet
->mpItems
[i
]->mnId
== nId
)
3136 sal_uInt16
SplitWindow::GetItemId( sal_uInt16 nPos
) const
3138 ImplSplitSet
* pSet
= ImplFindSet( mpBaseSet
, 0/*nSetId*/ );
3139 if ( pSet
&& (nPos
< pSet
->mpItems
.size()) )
3140 return pSet
->mpItems
[nPos
]->mnId
;
3145 sal_uInt16
SplitWindow::GetItemCount( sal_uInt16 nSetId
) const
3147 ImplSplitSet
* pSet
= ImplFindSet( mpBaseSet
, nSetId
);
3149 return pSet
->mpItems
.size();
3154 void SplitWindow::ImplNewAlign()
3158 case WindowAlign::Top
:
3160 mbBottomRight
= false;
3162 case WindowAlign::Bottom
:
3164 mbBottomRight
= true;
3166 case WindowAlign::Left
:
3168 mbBottomRight
= false;
3170 case WindowAlign::Right
:
3172 mbBottomRight
= true;
3176 if ( mnWinStyle
& WB_BORDER
)
3178 ImplCalcBorder( meAlign
, false/*bNoAlign*/, mnLeftBorder
, mnTopBorder
,
3179 mnRightBorder
, mnBottomBorder
);
3182 if ( IsReallyVisible() && IsUpdateMode() )
3187 void SplitWindow::SetAlign( WindowAlign eNewAlign
)
3189 if ( meAlign
!= eNewAlign
)
3191 meAlign
= eNewAlign
;
3196 void SplitWindow::ShowAutoHideButton( bool bShow
)
3202 void SplitWindow::ShowFadeInHideButton()
3208 void SplitWindow::ShowFadeOutButton()
3214 void SplitWindow::SetAutoHideState( bool bAutoHide
)
3216 mbAutoHideIn
= bAutoHide
;
3217 if ( IsReallyVisible() )
3220 ImplGetAutoHideRect( aRect
);
3221 Invalidate( aRect
);
3225 long SplitWindow::GetFadeInSize() const
3230 n
= mnTopBorder
+mnBottomBorder
;
3232 n
= mnLeftBorder
+mnRightBorder
;
3234 return n
+SPLITWIN_SPLITSIZE
+SPLITWIN_SPLITSIZEEX
-2;
3237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */