LibreOffice Module vcl (master)  1
splitwin.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <string.h>
21 
22 #include <sal/log.hxx>
23 
24 #include <vcl/event.hxx>
25 #include <vcl/wall.hxx>
26 #include <vcl/help.hxx>
27 #include <vcl/splitwin.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/ptrstyle.hxx>
30 
31 #include <svdata.hxx>
32 #include <strings.hrc>
33 
34 
35 #define SPLITWIN_SPLITSIZE 4
36 #define SPLITWIN_SPLITSIZEEX 4
37 #define SPLITWIN_SPLITSIZEEXLN 7
38 #define SPLITWIN_SPLITSIZEAUTOHIDE 72
39 #define SPLITWIN_SPLITSIZEFADE 72
40 
41 #define SPLIT_HORZ (sal_uInt16(0x0001))
42 #define SPLIT_VERT (sal_uInt16(0x0002))
43 #define SPLIT_WINDOW (sal_uInt16(0x0004))
44 #define SPLIT_NOSPLIT (sal_uInt16(0x8000))
45 
47 {
48 public:
49  ImplSplitItem();
50 
51  long mnSize;
52  long mnPixSize;
53  long mnLeft;
54  long mnTop;
55  long mnWidth;
56  long mnHeight;
57  long mnSplitPos;
61  long mnOldWidth;
63  std::unique_ptr<ImplSplitSet> mpSet;
66  sal_uInt16 mnId;
68  bool mbFixed;
69  bool mbSubSize;
71  long mnMinSize;
73  long mnMaxSize;
74 };
75 
76 
78 {
79 public:
80  ImplSplitSet();
81  ~ImplSplitSet();
82 
83  std::vector< ImplSplitItem > mvItems;
84  std::unique_ptr<Wallpaper> mpWallpaper;
85  long mnLastSize;
87  sal_uInt16 mnId;
88  bool mbCalcPix;
89 };
90 
92  : mnSize(0)
93  , mnPixSize(0)
94  , mnLeft(0)
95  , mnTop(0)
96  , mnWidth(0)
97  , mnHeight(0)
98  , mnSplitPos(0)
99  , mnSplitSize(0)
100  , mnOldSplitPos(0)
101  , mnOldSplitSize(0)
102  , mnOldWidth(0)
103  , mnOldHeight(0)
104  , mnId(0)
105  , mnBits(SplitWindowItemFlags::NONE)
106  , mbFixed(false)
107  , mbSubSize(false)
108  , mnMinSize(-1)
109  , mnMaxSize(-1)
110 {
111 }
112 
114  mnLastSize( 0 ),
115  mnSplitSize( SPLITWIN_SPLITSIZE ),
116  mnId( 0 ),
117  mbCalcPix( true )
118 {
119 }
120 
122 {
123  mpWallpaper.reset();
124 }
125 
133 namespace {
134  long ValidateSize (const long nSize, const ImplSplitItem & rItem)
135  {
136  if (rItem.mnMinSize>=0 && nSize<rItem.mnMinSize)
137  return rItem.mnMinSize;
138  else if (rItem.mnMaxSize>0 && nSize>rItem.mnMaxSize)
139  return rItem.mnMaxSize;
140  else
141  return nSize;
142  }
143 }
144 
145 static void ImplCalcBorder( WindowAlign eAlign,
146  long& rLeft, long& rTop,
147  long& rRight, long& rBottom )
148 {
149  switch ( eAlign )
150  {
151  case WindowAlign::Top:
152  rLeft = 2;
153  rTop = 2;
154  rRight = 2;
155  rBottom = 0;
156  break;
157  case WindowAlign::Left:
158  rLeft = 0;
159  rTop = 2;
160  rRight = 2;
161  rBottom = 2;
162  break;
163  case WindowAlign::Bottom:
164  rLeft = 2;
165  rTop = 0;
166  rRight = 2;
167  rBottom = 2;
168  break;
169  default:
170  rLeft = 0;
171  rTop = 2;
172  rRight = 2;
173  rBottom = 2;
174  break;
175  }
176 }
177 
179 {
180  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
181  long nDX = mnDX;
182  long nDY = mnDY;
183 
184  switch (meAlign)
185  {
186  case WindowAlign::Bottom:
187  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
188  rRenderContext.DrawLine(Point(0, 0), Point(nDX - 1, 0));
189  rRenderContext.DrawLine(Point(0, nDY - 2), Point(nDX - 1, nDY - 2));
190 
191  rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
192  rRenderContext.DrawLine(Point(0, 1), Point(nDX - 1, 1));
193  rRenderContext.DrawLine(Point(0, nDY - 1), Point(nDX - 1, nDY - 1));
194  break;
195  case WindowAlign::Top:
196  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
197  rRenderContext.DrawLine(Point(0, nDY - 2), Point(nDX - 1, nDY - 2));
198  rRenderContext.DrawLine(Point(0, 0), Point(nDX - 1, 0));
199 
200  rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
201  rRenderContext.DrawLine(Point(0, nDY - 1), Point(nDX - 1, nDY - 1));
202  rRenderContext.DrawLine(Point(0, 1), Point(nDX - 1, 1));
203  break;
204  case WindowAlign::Left:
205  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
206  rRenderContext.DrawLine(Point(nDX - 2, 0), Point(nDX - 2, nDY - 2));
207  rRenderContext.DrawLine(Point(0, 0), Point(nDX - 1, 0));
208  rRenderContext.DrawLine(Point(0, nDY - 2), Point(nDX - 2, nDY - 2));
209 
210  rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
211  rRenderContext.DrawLine(Point(nDX - 1, 0), Point(nDX - 1, nDY - 1));
212  rRenderContext.DrawLine(Point(0, 1), Point(nDX - 3, 1));
213  rRenderContext.DrawLine(Point(0, nDY - 1), Point(nDX - 2, nDY - 1));
214  break;
215  default:
216  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
217  rRenderContext.DrawLine(Point(0, 0), Point( 0, nDY - 2));
218  rRenderContext.DrawLine(Point(0, 0), Point( nDX - 1, 0));
219  rRenderContext.DrawLine(Point(0, nDY - 2), Point(nDX - 1, nDY - 2));
220 
221  rRenderContext.SetLineColor( rStyleSettings.GetLightColor());
222  rRenderContext.DrawLine(Point(1, 1), Point(1, nDY - 3));
223  rRenderContext.DrawLine(Point(1, 1), Point(nDX - 1, 1));
224  rRenderContext.DrawLine(Point(0, nDY - 1), Point(nDX - 1, nDY - 1));
225  }
226 }
227 
229 {
230  if (mbFadeOut)
231  {
232  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
233  long nDX = mnDX;
234  long nDY = mnDY;
235 
236  switch (meAlign)
237  {
238  case WindowAlign::Left:
239  rRenderContext.SetLineColor( rStyleSettings.GetShadowColor() );
240  rRenderContext.DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN-1, nDY-2 ) );
241 
242  rRenderContext.SetLineColor( rStyleSettings.GetLightColor() );
243  rRenderContext.DrawLine( Point( nDX-SPLITWIN_SPLITSIZEEXLN, 1 ), Point( nDX-SPLITWIN_SPLITSIZEEXLN, nDY-3 ) );
244  break;
245  case WindowAlign::Right:
246  rRenderContext.SetLineColor( rStyleSettings.GetShadowColor() );
247  rRenderContext.DrawLine( Point( SPLITWIN_SPLITSIZEEXLN-1, 0 ), Point( SPLITWIN_SPLITSIZEEXLN-1, nDY-2 ) );
248 
249  rRenderContext.SetLineColor( rStyleSettings.GetLightColor() );
250  rRenderContext.DrawLine( Point( SPLITWIN_SPLITSIZEEXLN, 1 ), Point( SPLITWIN_SPLITSIZEEXLN, nDY-3 ) );
251  break;
252  case WindowAlign::Top:
253  rRenderContext.SetLineColor( rStyleSettings.GetShadowColor() );
254  rRenderContext.DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN-1 ), Point( nDX-1, nDY-SPLITWIN_SPLITSIZEEXLN-1 ) );
255 
256  rRenderContext.SetLineColor( rStyleSettings.GetLightColor() );
257  rRenderContext.DrawLine( Point( 0, nDY-SPLITWIN_SPLITSIZEEXLN ), Point( nDX-1, nDY-SPLITWIN_SPLITSIZEEXLN ) );
258  break;
259  case WindowAlign::Bottom:
260  rRenderContext.SetLineColor( rStyleSettings.GetShadowColor() );
261  rRenderContext.DrawLine( Point( 0, 5 ), Point( nDX-1, 5 ) );
262 
263  rRenderContext.SetLineColor( rStyleSettings.GetLightColor() );
264  rRenderContext.DrawLine( Point( 0, SPLITWIN_SPLITSIZEEXLN ), Point( nDX-1, SPLITWIN_SPLITSIZEEXLN ) );
265  break;
266  }
267  }
268 }
269 
270 static ImplSplitSet* ImplFindSet( ImplSplitSet* pSet, sal_uInt16 nId )
271 {
272  if ( pSet->mnId == nId )
273  return pSet;
274 
275  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
276 
277  for ( const auto& rItem : rItems )
278  {
279  if ( rItem.mnId == nId )
280  return rItem.mpSet.get();
281  }
282 
283  for ( auto& rItem : rItems )
284  {
285  if ( rItem.mpSet )
286  {
287  ImplSplitSet* pFindSet = ImplFindSet( rItem.mpSet.get(), nId );
288  if ( pFindSet )
289  return pFindSet;
290  }
291  }
292 
293  return nullptr;
294 }
295 
296 static ImplSplitSet* ImplFindItem( ImplSplitSet* pSet, sal_uInt16 nId, sal_uInt16& rPos )
297 {
298  size_t nItems = pSet->mvItems.size();
299  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
300 
301  for ( size_t i = 0; i < nItems; i++ )
302  {
303  if ( rItems[i].mnId == nId )
304  {
305  rPos = i;
306  return pSet;
307  }
308  }
309 
310  for ( auto& rItem : rItems )
311  {
312  if ( rItem.mpSet )
313  {
314  ImplSplitSet* pFindSet = ImplFindItem( rItem.mpSet.get(), nId, rPos );
315  if ( pFindSet )
316  return pFindSet;
317  }
318  }
319 
320  return nullptr;
321 }
322 
323 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, vcl::Window* pWindow )
324 {
325  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
326 
327  for ( auto& rItem : rItems )
328  {
329  if ( rItem.mpWindow == pWindow )
330  return rItem.mnId;
331  else
332  {
333  if ( rItem.mpSet )
334  {
335  sal_uInt16 nId = ImplFindItem( rItem.mpSet.get(), pWindow );
336  if ( nId )
337  return nId;
338  }
339  }
340  }
341 
342  return 0;
343 }
344 
345 static sal_uInt16 ImplFindItem( ImplSplitSet* pSet, const Point& rPos,
346  bool bRows, bool bDown = true )
347 {
348  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
349 
350  for ( auto& rItem : rItems )
351  {
352  if ( rItem.mnWidth && rItem.mnHeight )
353  {
354  Point aPoint( rItem.mnLeft, rItem.mnTop );
355  Size aSize( rItem.mnWidth, rItem.mnHeight );
356  tools::Rectangle aRect( aPoint, aSize );
357  if ( bRows )
358  {
359  if ( bDown )
360  aRect.AdjustBottom(pSet->mnSplitSize );
361  else
362  aRect.AdjustTop( -(pSet->mnSplitSize) );
363  }
364  else
365  {
366  if ( bDown )
367  aRect.AdjustRight(pSet->mnSplitSize );
368  else
369  aRect.AdjustLeft( -(pSet->mnSplitSize) );
370  }
371 
372  if ( aRect.IsInside( rPos ) )
373  {
374  if ( rItem.mpSet && !rItem.mpSet->mvItems.empty() )
375  {
376  return ImplFindItem( rItem.mpSet.get(), rPos,
378  }
379  else
380  return rItem.mnId;
381  }
382  }
383  }
384 
385  return 0;
386 }
387 
388 static void ImplCalcSet( ImplSplitSet* pSet,
389  long nSetLeft, long nSetTop,
390  long nSetWidth, long nSetHeight,
391  bool bRows, bool bDown = true )
392 {
393  if ( pSet->mvItems.empty() )
394  return;
395 
396  sal_uInt16 nMins;
397  sal_uInt16 nCalcItems;
398  size_t nItems = pSet->mvItems.size();
399  sal_uInt16 nAbsItems;
400  long nCalcSize;
401  long nPos;
402  long nMaxPos;
403  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
404  bool bEmpty;
405 
406  // calculate sizes
407  if ( bRows )
408  nCalcSize = nSetHeight;
409  else
410  nCalcSize = nSetWidth;
411  nCalcSize -= (rItems.size()-1)*pSet->mnSplitSize;
412  if ( pSet->mbCalcPix || (pSet->mnLastSize != nCalcSize) )
413  {
414  long nPercentFactor = 10;
415  long nRelCount = 0;
416  long nPercent = 0;
417  long nRelPercent = 0;
418  long nAbsSize = 0;
419  long nCurSize = 0;
420  for ( const auto& rItem : rItems )
421  {
423  nRelCount += rItem.mnSize;
424  else if ( rItem.mnBits & SplitWindowItemFlags::PercentSize )
425  nPercent += rItem.mnSize;
426  else
427  nAbsSize += rItem.mnSize;
428  }
429  // map relative values to percentages (percentage here one tenth of a percent)
430  nPercent *= nPercentFactor;
431  if ( nRelCount )
432  {
433  long nRelPercentBase = 1000;
434  while ( (nRelCount > nRelPercentBase) && (nPercentFactor < 100000) )
435  {
436  nRelPercentBase *= 10;
437  nPercentFactor *= 10;
438  }
439  if ( nPercent < nRelPercentBase )
440  {
441  nRelPercent = (nRelPercentBase-nPercent)/nRelCount;
442  nPercent += nRelPercent*nRelCount;
443  }
444  else
445  nRelPercent = 0;
446  }
447  if ( !nPercent )
448  nPercent = 1;
449  long nSizeDelta = nCalcSize-nAbsSize;
450  for ( auto& rItem : rItems )
451  {
453  {
454  if ( nSizeDelta <= 0 )
455  rItem.mnPixSize = 0;
456  else
457  rItem.mnPixSize = (nSizeDelta*rItem.mnSize*nRelPercent)/nPercent;
458  }
459  else if ( rItem.mnBits & SplitWindowItemFlags::PercentSize )
460  {
461  if ( nSizeDelta <= 0 )
462  rItem.mnPixSize = 0;
463  else
464  rItem.mnPixSize = (nSizeDelta*rItem.mnSize*nPercentFactor)/nPercent;
465  }
466  else
467  rItem.mnPixSize = rItem.mnSize;
468  nCurSize += rItem.mnPixSize;
469  }
470 
471  pSet->mbCalcPix = false;
472  pSet->mnLastSize = nCalcSize;
473 
474  // adapt window
475  nSizeDelta = nCalcSize-nCurSize;
476  if ( nSizeDelta )
477  {
478  nAbsItems = 0;
479  long nSizeWinSize = 0;
480 
481  // first resize absolute items relative
482  for ( const auto& rItem : rItems )
483  {
485  {
486  nAbsItems++;
487  nSizeWinSize += rItem.mnPixSize;
488  }
489  }
490  // do not compensate rounding errors here
491  if ( (nAbsItems < static_cast<sal_uInt16>(std::abs( nSizeDelta ))) && nSizeWinSize )
492  {
493  long nNewSizeWinSize = 0;
494 
495  for ( auto& rItem : rItems )
496  {
498  {
499  rItem.mnPixSize += (nSizeDelta*rItem.mnPixSize)/nSizeWinSize;
500  nNewSizeWinSize += rItem.mnPixSize;
501  }
502  }
503 
504  nSizeDelta -= nNewSizeWinSize-nSizeWinSize;
505  }
506 
507  // compensate rounding errors now
508  sal_uInt16 j = 0;
509  nMins = 0;
510  while ( nSizeDelta && (nItems != nMins) )
511  {
512  // determine which items we can calculate
513  nCalcItems = 0;
514  while ( !nCalcItems )
515  {
516  for ( auto& rItem : rItems )
517  {
518  rItem.mbSubSize = false;
519 
520  if ( j >= 2 )
521  rItem.mbSubSize = true;
522  else
523  {
524  if ( (nSizeDelta > 0) || rItem.mnPixSize )
525  {
526  if ( j >= 1 )
527  rItem.mbSubSize = true;
528  else
529  {
531  rItem.mbSubSize = true;
532  }
533  }
534  }
535 
536  if ( rItem.mbSubSize )
537  nCalcItems++;
538  }
539 
540  j++;
541  }
542 
543  // subtract size of individual items
544  long nErrorSum = nSizeDelta % nCalcItems;
545  long nCurSizeDelta = nSizeDelta / nCalcItems;
546  nMins = 0;
547  for ( auto& rItem : rItems )
548  {
549  if ( rItem.mbSubSize )
550  {
551  long* pSize = &(rItem.mnPixSize);
552  long nTempErr;
553 
554  if ( nErrorSum )
555  {
556  if ( nErrorSum < 0 )
557  nTempErr = -1;
558  else
559  nTempErr = 1;
560  }
561  else
562  nTempErr = 0;
563 
564  if ( (*pSize+nCurSizeDelta+nTempErr) <= 0 )
565  {
566  long nTemp = *pSize;
567  if ( nTemp )
568  {
569  *pSize -= nTemp;
570  nSizeDelta += nTemp;
571  }
572  nMins++;
573  }
574  else
575  {
576  *pSize += nCurSizeDelta;
577  nSizeDelta -= nCurSizeDelta;
578  if ( nTempErr && (*pSize || (nTempErr > 0)) )
579  {
580  *pSize += nTempErr;
581  nSizeDelta -= nTempErr;
582  nErrorSum -= nTempErr;
583  }
584  }
585  }
586  }
587  }
588  }
589  }
590 
591  // calculate maximum size
592  if ( bRows )
593  {
594  nPos = nSetTop;
595  if ( !bDown )
596  nMaxPos = nSetTop-nSetHeight;
597  else
598  nMaxPos = nSetTop+nSetHeight;
599  }
600  else
601  {
602  nPos = nSetLeft;
603  if ( !bDown )
604  nMaxPos = nSetLeft-nSetWidth;
605  else
606  nMaxPos = nSetLeft+nSetWidth;
607  }
608 
609  // order windows and adept values
610  for ( size_t i = 0; i < nItems; i++ )
611  {
612  rItems[i].mnOldSplitPos = rItems[i].mnSplitPos;
613  rItems[i].mnOldSplitSize = rItems[i].mnSplitSize;
614  rItems[i].mnOldWidth = rItems[i].mnWidth;
615  rItems[i].mnOldHeight = rItems[i].mnHeight;
616 
617  bEmpty = false;
618  if ( bDown )
619  {
620  if ( nPos+rItems[i].mnPixSize > nMaxPos )
621  bEmpty = true;
622  }
623  else
624  {
625  nPos -= rItems[i].mnPixSize;
626  if ( nPos < nMaxPos )
627  bEmpty = true;
628  }
629 
630  if ( bEmpty )
631  {
632  rItems[i].mnWidth = 0;
633  rItems[i].mnHeight = 0;
634  rItems[i].mnSplitSize = 0;
635  }
636  else
637  {
638  if ( bRows )
639  {
640  rItems[i].mnLeft = nSetLeft;
641  rItems[i].mnTop = nPos;
642  rItems[i].mnWidth = nSetWidth;
643  rItems[i].mnHeight = rItems[i].mnPixSize;
644  }
645  else
646  {
647  rItems[i].mnLeft = nPos;
648  rItems[i].mnTop = nSetTop;
649  rItems[i].mnWidth = rItems[i].mnPixSize;
650  rItems[i].mnHeight = nSetHeight;
651  }
652 
653  if ( i > nItems-1 )
654  rItems[i].mnSplitSize = 0;
655  else
656  {
657  rItems[i].mnSplitSize = pSet->mnSplitSize;
658  if ( bDown )
659  {
660  rItems[i].mnSplitPos = nPos+rItems[i].mnPixSize;
661  if ( rItems[i].mnSplitPos+rItems[i].mnSplitSize > nMaxPos )
662  rItems[i].mnSplitSize = nMaxPos-rItems[i].mnSplitPos;
663  }
664  else
665  {
666  rItems[i].mnSplitPos = nPos-pSet->mnSplitSize;
667  if ( rItems[i].mnSplitPos < nMaxPos )
668  rItems[i].mnSplitSize = rItems[i].mnSplitPos+pSet->mnSplitSize-nMaxPos;
669  }
670  }
671  }
672 
673  if ( !bDown )
674  nPos -= pSet->mnSplitSize;
675  else
676  nPos += rItems[i].mnPixSize+pSet->mnSplitSize;
677  }
678 
679  // calculate Sub-Set's
680  for ( auto& rItem : rItems )
681  {
682  if ( rItem.mpSet && rItem.mnWidth && rItem.mnHeight )
683  {
684  ImplCalcSet( rItem.mpSet.get(),
685  rItem.mnLeft, rItem.mnTop,
686  rItem.mnWidth, rItem.mnHeight,
688  }
689  }
690 
691  // set fixed
692  for ( auto& rItem : rItems )
693  {
694  rItem.mbFixed = false;
695  if ( rItem.mnBits & SplitWindowItemFlags::Fixed )
696  rItem.mbFixed = true;
697  else
698  {
699  // this item is also fixed if Child-Set is available,
700  // if a child is fixed
701  if ( rItem.mpSet )
702  {
703  for ( auto const & j: rItem.mpSet->mvItems )
704  {
705  if ( j.mbFixed )
706  {
707  rItem.mbFixed = true;
708  break;
709  }
710  }
711  }
712  }
713  }
714 }
715 
716 void SplitWindow::ImplCalcSet2( SplitWindow* pWindow, ImplSplitSet* pSet, bool bHide,
717  bool bRows )
718 {
719  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
720 
721  if ( pWindow->IsReallyVisible() && pWindow->IsUpdateMode() && pWindow->mbInvalidate )
722  {
723  for ( const auto& rItem : rItems )
724  {
725  if ( rItem.mnSplitSize )
726  {
727  // invalidate all, if applicable or only a small part
728  if ( (rItem.mnOldSplitPos != rItem.mnSplitPos) ||
729  (rItem.mnOldSplitSize != rItem.mnSplitSize) ||
730  (rItem.mnOldWidth != rItem.mnWidth) ||
731  (rItem.mnOldHeight != rItem.mnHeight) )
732  {
733  tools::Rectangle aRect;
734 
735  // invalidate old rectangle
736  if ( bRows )
737  {
738  aRect.SetLeft( rItem.mnLeft );
739  aRect.SetRight( rItem.mnLeft+rItem.mnOldWidth-1 );
740  aRect.SetTop( rItem.mnOldSplitPos );
741  aRect.SetBottom( aRect.Top() + rItem.mnOldSplitSize );
742  }
743  else
744  {
745  aRect.SetTop( rItem.mnTop );
746  aRect.SetBottom( rItem.mnTop+rItem.mnOldHeight-1 );
747  aRect.SetLeft( rItem.mnOldSplitPos );
748  aRect.SetRight( aRect.Left() + rItem.mnOldSplitSize );
749  }
750  pWindow->Invalidate( aRect );
751  // invalidate new rectangle
752  if ( bRows )
753  {
754  aRect.SetLeft( rItem.mnLeft );
755  aRect.SetRight( rItem.mnLeft+rItem.mnWidth-1 );
756  aRect.SetTop( rItem.mnSplitPos );
757  aRect.SetBottom( aRect.Top() + rItem.mnSplitSize );
758  }
759  else
760  {
761  aRect.SetTop( rItem.mnTop );
762  aRect.SetBottom( rItem.mnTop+rItem.mnHeight-1 );
763  aRect.SetLeft( rItem.mnSplitPos );
764  aRect.SetRight( aRect.Left() + rItem.mnSplitSize );
765  }
766  pWindow->Invalidate( aRect );
767 
768  // invalidate complete set, as these areas
769  // are not cluttered by windows
770  if ( rItem.mpSet && rItem.mpSet->mvItems.empty() )
771  {
772  aRect.SetLeft( rItem.mnLeft );
773  aRect.SetTop( rItem.mnTop );
774  aRect.SetRight( rItem.mnLeft+rItem.mnWidth-1 );
775  aRect.SetBottom( rItem.mnTop+rItem.mnHeight-1 );
776  pWindow->Invalidate( aRect );
777  }
778  }
779  }
780  }
781  }
782 
783  // position windows
784  for ( auto& rItem : rItems )
785  {
786  if ( rItem.mpSet )
787  {
788  bool bTempHide = bHide;
789  if ( !rItem.mnWidth || !rItem.mnHeight )
790  bTempHide = true;
791  ImplCalcSet2( pWindow, rItem.mpSet.get(), bTempHide,
793  }
794  else
795  {
796  if ( rItem.mnWidth && rItem.mnHeight && !bHide )
797  {
798  Point aPos( rItem.mnLeft, rItem.mnTop );
799  Size aSize( rItem.mnWidth, rItem.mnHeight );
800  rItem.mpWindow->SetPosSizePixel( aPos, aSize );
801  }
802  else
803  rItem.mpWindow->Hide();
804  }
805  }
806 
807  // show windows and reset flag
808  for ( auto& rItem : rItems )
809  {
810  if ( rItem.mpWindow && rItem.mnWidth && rItem.mnHeight && !bHide )
811  rItem.mpWindow->Show();
812  }
813 }
814 
815 static void ImplCalcLogSize( std::vector< ImplSplitItem > & rItems, size_t nItems )
816 {
817  // update original sizes
818  size_t i;
819  long nRelSize = 0;
820  long nPerSize = 0;
821 
822  for ( i = 0; i < nItems; i++ )
823  {
824  if ( rItems[i].mnBits & SplitWindowItemFlags::RelativeSize )
825  nRelSize += rItems[i].mnPixSize;
826  else if ( rItems[i].mnBits & SplitWindowItemFlags::PercentSize )
827  nPerSize += rItems[i].mnPixSize;
828  }
829  nPerSize += nRelSize;
830  for ( i = 0; i < nItems; i++ )
831  {
832  if ( rItems[i].mnBits & SplitWindowItemFlags::RelativeSize )
833  {
834  if ( nRelSize )
835  rItems[i].mnSize = (rItems[i].mnPixSize+(nRelSize/2))/nRelSize;
836  else
837  rItems[i].mnSize = 1;
838  }
839  else if ( rItems[i].mnBits & SplitWindowItemFlags::PercentSize )
840  {
841  if ( nPerSize )
842  rItems[i].mnSize = (rItems[i].mnPixSize*100)/nPerSize;
843  else
844  rItems[i].mnSize = 1;
845  }
846  else
847  rItems[i].mnSize = rItems[i].mnPixSize;
848  }
849 }
850 
852 {
853  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
854 
855  for ( const auto& rItem : rItems )
856  {
857  pSet = rItem.mpSet.get();
858  if (pSet && pSet->mpWallpaper)
859  {
860  Point aPoint(rItem.mnLeft, rItem.mnTop);
861  Size aSize(rItem.mnWidth, rItem.mnHeight);
862  tools::Rectangle aRect(aPoint, aSize);
863  rRenderContext.DrawWallpaper(aRect, *pSet->mpWallpaper);
864  }
865  }
866 
867  for ( auto& rItem : rItems )
868  {
869  if (rItem.mpSet)
870  ImplDrawBack(rRenderContext, rItem.mpSet.get());
871  }
872 }
873 
874 static void ImplDrawSplit(vcl::RenderContext& rRenderContext, ImplSplitSet* pSet, bool bRows, bool bDown)
875 {
876  if (pSet->mvItems.empty())
877  return;
878 
879  size_t nItems = pSet->mvItems.size();
880  long nPos;
881  long nTop;
882  long nBottom;
883  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
884  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
885 
886  for (size_t i = 0; i < nItems-1; i++)
887  {
888  if (rItems[i].mnSplitSize)
889  {
890  nPos = rItems[i].mnSplitPos;
891 
892  long nItemSplitSize = rItems[i].mnSplitSize;
893  long nSplitSize = pSet->mnSplitSize;
894  if (bRows)
895  {
896  nTop = rItems[i].mnLeft;
897  nBottom = rItems[i].mnLeft+rItems[i].mnWidth-1;
898 
899  if (bDown || (nItemSplitSize >= nSplitSize))
900  {
901  rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
902  rRenderContext.DrawLine(Point(nTop, nPos + 1), Point(nBottom, nPos + 1));
903  }
904  nPos += nSplitSize-2;
905  if ((!bDown && (nItemSplitSize >= 2)) ||
906  (bDown && (nItemSplitSize >= nSplitSize - 1)))
907  {
908  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
909  rRenderContext.DrawLine(Point(nTop, nPos), Point(nBottom, nPos));
910  }
911  nPos++;
912  if (!bDown || (nItemSplitSize >= nSplitSize))
913  {
914  rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
915  rRenderContext.DrawLine(Point(nTop, nPos), Point(nBottom, nPos));
916  }
917  }
918  else
919  {
920  nTop = rItems[i].mnTop;
921  nBottom = rItems[i].mnTop+pSet->mvItems[i].mnHeight-1;
922 
923  if (bDown || (nItemSplitSize >= nSplitSize))
924  {
925  rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
926  rRenderContext.DrawLine(Point(nPos + 1, nTop), Point(nPos+1, nBottom));
927  }
928  nPos += pSet->mnSplitSize - 2;
929  if ((!bDown && (nItemSplitSize >= 2)) ||
930  (bDown && (nItemSplitSize >= nSplitSize - 1)))
931  {
932  rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
933  rRenderContext.DrawLine(Point(nPos, nTop), Point(nPos, nBottom));
934  }
935  nPos++;
936  if (!bDown || (nItemSplitSize >= nSplitSize))
937  {
938  rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
939  rRenderContext.DrawLine(Point(nPos, nTop), Point(nPos, nBottom));
940  }
941  }
942  }
943  }
944 
945  for ( auto& rItem : rItems )
946  {
947  if (rItem.mpSet && rItem.mnWidth && rItem.mnHeight)
948  {
949  ImplDrawSplit(rRenderContext, rItem.mpSet.get(), !(rItem.mnBits & SplitWindowItemFlags::ColSet), true/*bDown*/);
950  }
951  }
952 }
953 
954 sal_uInt16 SplitWindow::ImplTestSplit( ImplSplitSet* pSet, const Point& rPos,
955  long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos,
956  bool bRows )
957 {
958  if ( pSet->mvItems.empty() )
959  return 0;
960 
961  sal_uInt16 nSplitTest;
962  size_t nItems = pSet->mvItems.size();
963  long nMPos1;
964  long nMPos2;
965  long nPos;
966  long nTop;
967  long nBottom;
968  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
969 
970  if ( bRows )
971  {
972  nMPos1 = rPos.X();
973  nMPos2 = rPos.Y();
974  }
975  else
976  {
977  nMPos1 = rPos.Y();
978  nMPos2 = rPos.X();
979  }
980 
981  for ( size_t i = 0; i < nItems-1; i++ )
982  {
983  if ( rItems[i].mnSplitSize )
984  {
985  if ( bRows )
986  {
987  nTop = rItems[i].mnLeft;
988  nBottom = rItems[i].mnLeft+rItems[i].mnWidth-1;
989  }
990  else
991  {
992  nTop = rItems[i].mnTop;
993  nBottom = rItems[i].mnTop+rItems[i].mnHeight-1;
994  }
995  nPos = rItems[i].mnSplitPos;
996 
997  if ( (nMPos1 >= nTop) && (nMPos1 <= nBottom) &&
998  (nMPos2 >= nPos) && (nMPos2 <= nPos+rItems[i].mnSplitSize) )
999  {
1000  if ( !rItems[i].mbFixed && !rItems[i+1].mbFixed )
1001  {
1002  rMouseOff = nMPos2-nPos;
1003  *ppFoundSet = pSet;
1004  rFoundPos = i;
1005  if ( bRows )
1006  return SPLIT_VERT;
1007  else
1008  return SPLIT_HORZ;
1009  }
1010  else
1011  return SPLIT_NOSPLIT;
1012  }
1013  }
1014  }
1015 
1016  for ( auto& rItem : rItems )
1017  {
1018  if ( rItem.mpSet )
1019  {
1020  nSplitTest = ImplTestSplit( rItem.mpSet.get(), rPos,
1021  rMouseOff, ppFoundSet, rFoundPos,
1022  !(rItem.mnBits & SplitWindowItemFlags::ColSet) );
1023  if ( nSplitTest )
1024  return nSplitTest;
1025  }
1026  }
1027 
1028  return 0;
1029 }
1030 
1031 sal_uInt16 SplitWindow::ImplTestSplit( const SplitWindow* pWindow, const Point& rPos,
1032  long& rMouseOff, ImplSplitSet** ppFoundSet, sal_uInt16& rFoundPos )
1033 {
1034  // Resizable SplitWindow should be treated different
1035  if ( pWindow->mnWinStyle & WB_SIZEABLE )
1036  {
1037  long nTPos;
1038  long nPos;
1039  long nBorder;
1040 
1041  if ( pWindow->mbHorz )
1042  {
1043  if ( pWindow->mbBottomRight )
1044  {
1045  nBorder = pWindow->mnBottomBorder;
1046  nPos = 0;
1047  }
1048  else
1049  {
1050  nBorder = pWindow->mnTopBorder;
1051  nPos = pWindow->mnDY-nBorder;
1052  }
1053  nTPos = rPos.Y();
1054  }
1055  else
1056  {
1057  if ( pWindow->mbBottomRight )
1058  {
1059  nBorder = pWindow->mnRightBorder;
1060  nPos = 0;
1061  }
1062  else
1063  {
1064  nBorder = pWindow->mnLeftBorder;
1065  nPos = pWindow->mnDX-nBorder;
1066  }
1067  nTPos = rPos.X();
1068  }
1069  long nSplitSize = pWindow->mpMainSet->mnSplitSize-2;
1070  if (pWindow->mbFadeOut)
1071  nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1072  if ( !pWindow->mbBottomRight )
1073  nPos -= nSplitSize;
1074  if ( (nTPos >= nPos) && (nTPos <= nPos+nSplitSize+nBorder) )
1075  {
1076  rMouseOff = nTPos-nPos;
1077  *ppFoundSet = pWindow->mpMainSet.get();
1078  if ( !pWindow->mpMainSet->mvItems.empty() )
1079  rFoundPos = pWindow->mpMainSet->mvItems.size() - 1;
1080  else
1081  rFoundPos = 0;
1082  if ( pWindow->mbHorz )
1083  return SPLIT_VERT | SPLIT_WINDOW;
1084  else
1085  return SPLIT_HORZ | SPLIT_WINDOW;
1086  }
1087  }
1088 
1089  return ImplTestSplit( pWindow->mpMainSet.get(), rPos, rMouseOff, ppFoundSet, rFoundPos,
1090  pWindow->mbHorz );
1091 }
1092 
1094 {
1095  tools::Rectangle aRect;
1096 
1097  if (mnSplitTest & SPLIT_HORZ)
1098  {
1099  aRect.SetTop( maDragRect.Top() );
1100  aRect.SetBottom( maDragRect.Bottom() );
1101  aRect.SetLeft( rPos.X() );
1102  aRect.SetRight( aRect.Left() + mpSplitSet->mnSplitSize - 1 );
1103  if (!(mnWinStyle & WB_NOSPLITDRAW))
1104  aRect.AdjustRight( -1 );
1105  if ((mnSplitTest & SPLIT_WINDOW) && mbFadeOut)
1106  {
1109  }
1110  }
1111  else
1112  {
1113  aRect.SetLeft( maDragRect.Left() );
1114  aRect.SetRight( maDragRect.Right() );
1115  aRect.SetTop( rPos.Y() );
1116  aRect.SetBottom( aRect.Top() + mpSplitSet->mnSplitSize - 1 );
1117  if (!(mnWinStyle & WB_NOSPLITDRAW))
1118  aRect.AdjustBottom( -1 );
1119  if ((mnSplitTest & SPLIT_WINDOW) && mbFadeOut)
1120  {
1123  }
1124  }
1126 }
1127 
1129 {
1130  mpMainSet.reset(new ImplSplitSet());
1131  mpBaseSet = mpMainSet.get();
1132  mpSplitSet = nullptr;
1133  mpLastSizes = nullptr;
1134  mnDX = 0;
1135  mnDY = 0;
1136  mnLeftBorder = 0;
1137  mnTopBorder = 0;
1138  mnRightBorder = 0;
1139  mnBottomBorder = 0;
1140  mnMaxSize = 0;
1141  mnMouseOff = 0;
1142  meAlign = WindowAlign::Top;
1143  mnWinStyle = nStyle;
1144  mnSplitTest = 0;
1145  mnSplitPos = 0;
1146  mnMouseModifier = 0;
1147  mnMStartPos = 0;
1148  mnMSplitPos = 0;
1149  mbDragFull = false;
1150  mbHorz = true;
1151  mbBottomRight = false;
1152  mbCalc = false;
1153  mbRecalc = true;
1154  mbInvalidate = true;
1155  mbFadeIn = false;
1156  mbFadeOut = false;
1157  mbFadeInDown = false;
1158  mbFadeOutDown = false;
1159  mbFadeInPressed = false;
1160  mbFadeOutPressed = false;
1161  mbFadeNoButtonMode = false;
1162 
1163  if ( nStyle & WB_NOSPLITDRAW )
1164  {
1165  mpMainSet->mnSplitSize -= 2;
1166  mbInvalidate = false;
1167  }
1168 
1169  if ( nStyle & WB_BORDER )
1170  {
1173  }
1174  else
1175  {
1176  mnLeftBorder = 0;
1177  mnTopBorder = 0;
1178  mnRightBorder = 0;
1179  mnBottomBorder = 0;
1180  }
1181 
1182  DockingWindow::ImplInit( pParent, (nStyle | WB_CLIPCHILDREN) & ~(WB_BORDER | WB_SIZEABLE) );
1183 
1184  ImplInitSettings();
1185 }
1186 
1188 {
1189  // If MainSet has a Wallpaper, this is the background,
1190  // otherwise it is the standard colour
1191  if ( mpMainSet->mpWallpaper )
1192  SetBackground( *mpMainSet->mpWallpaper );
1193  else
1194  {
1195  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1196 
1197  Color aColor;
1198  if ( IsControlBackground() )
1199  aColor = GetControlBackground();
1200  else if ( Window::GetStyle() & WB_3DLOOK )
1201  aColor = rStyleSettings.GetFaceColor();
1202  else
1203  aColor = rStyleSettings.GetWindowColor();
1204  SetBackground( aColor );
1205  }
1206 }
1207 
1210 {
1211  ImplInit( pParent, nStyle );
1212  DockingWindow::SetIdleDebugName( "vcl::SplitWindow maLayoutIdle" );
1213 }
1214 
1216 {
1217  disposeOnce();
1218 }
1219 
1221 {
1222  // delete Sets
1223  mpMainSet.reset();
1225 }
1226 
1228 {
1229  if ( !nDelta )
1230  return;
1231 
1232  Size aSize = GetSizePixel();
1233  switch ( meAlign )
1234  {
1235  case WindowAlign::Top:
1236  aSize.AdjustHeight(nDelta );
1237  SetSizePixel( aSize );
1238  break;
1239  case WindowAlign::Bottom:
1240  {
1241  maDragRect.AdjustTop(nDelta );
1242  Point aPos = GetPosPixel();
1243  aPos.AdjustY( -nDelta );
1244  aSize.AdjustHeight(nDelta );
1245  SetPosSizePixel( aPos, aSize );
1246  break;
1247  }
1248  case WindowAlign::Left:
1249  aSize.AdjustWidth(nDelta );
1250  SetSizePixel( aSize );
1251  break;
1252  case WindowAlign::Right:
1253  default:
1254  {
1255  maDragRect.AdjustLeft(nDelta );
1256  Point aPos = GetPosPixel();
1257  aPos.AdjustX( -nDelta );
1258  aSize.AdjustWidth(nDelta );
1259  SetPosSizePixel( aPos, aSize );
1260  break;
1261  }
1262  }
1263 
1264  SplitResize();
1265 }
1266 
1268 {
1269  Size aSize( aNewSize );
1270  long nSplitSize = mpMainSet->mnSplitSize-2;
1271 
1272  if (mbFadeOut)
1273  nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1274 
1275  // if the window is sizeable and if it does not contain a relative window,
1276  // the size is determined according to MainSet
1277  if ( mnWinStyle & WB_SIZEABLE )
1278  {
1279  long nCalcSize = 0;
1280  std::vector< ImplSplitItem* >::size_type i;
1281 
1282  for ( i = 0; i < mpMainSet->mvItems.size(); i++ )
1283  {
1285  break;
1286  else
1287  nCalcSize += mpMainSet->mvItems[i].mnSize;
1288  }
1289 
1290  if ( i == mpMainSet->mvItems.size() )
1291  {
1292  long nDelta = 0;
1293  long nCurSize;
1294 
1295  if ( mbHorz )
1296  nCurSize = aNewSize.Height()-mnTopBorder-mnBottomBorder;
1297  else
1298  nCurSize = aNewSize.Width()-mnLeftBorder-mnRightBorder;
1299  nCurSize -= nSplitSize;
1300  nCurSize -= (mpMainSet->mvItems.size()-1)*mpMainSet->mnSplitSize;
1301 
1302  nDelta = nCalcSize-nCurSize;
1303  if ( !nDelta )
1304  return aSize;
1305 
1306  switch ( meAlign )
1307  {
1308  case WindowAlign::Top:
1309  aSize.AdjustHeight(nDelta );
1310  break;
1311  case WindowAlign::Bottom:
1312  aSize.AdjustHeight(nDelta );
1313  break;
1314  case WindowAlign::Left:
1315  aSize.AdjustWidth(nDelta );
1316  break;
1317  case WindowAlign::Right:
1318  default:
1319  aSize.AdjustWidth(nDelta );
1320  break;
1321  }
1322  }
1323  }
1324 
1325  return aSize;
1326 }
1327 
1329 {
1330  if ( !mbCalc || !mbRecalc || mpMainSet->mvItems.empty() )
1331  return;
1332 
1333  long nSplitSize = mpMainSet->mnSplitSize-2;
1334  if (mbFadeOut)
1335  nSplitSize += SPLITWIN_SPLITSIZEEXLN;
1336 
1337  // if the window is sizeable and if it does not contain a relative window,
1338  // the size is determined according to MainSet
1339  if ( mnWinStyle & WB_SIZEABLE )
1340  {
1341  long nCalcSize = 0;
1342  std::vector<ImplSplitItem *>::size_type i;
1343 
1344  for ( i = 0; i < mpMainSet->mvItems.size(); i++ )
1345  {
1347  break;
1348  else
1349  nCalcSize += mpMainSet->mvItems[i].mnSize;
1350  }
1351 
1352  if ( i == mpMainSet->mvItems.size() )
1353  {
1354  long nCurSize;
1355  if ( mbHorz )
1356  nCurSize = mnDY-mnTopBorder-mnBottomBorder;
1357  else
1358  nCurSize = mnDX-mnLeftBorder-mnRightBorder;
1359  nCurSize -= nSplitSize;
1360  nCurSize -= (mpMainSet->mvItems.size()-1)*mpMainSet->mnSplitSize;
1361 
1362  mbRecalc = false;
1363  ImplSetWindowSize( nCalcSize-nCurSize );
1364  mbRecalc = true;
1365  }
1366  }
1367 
1368  if ( (mnDX <= 0) || (mnDY <= 0) )
1369  return;
1370 
1371  // pre-calculate sizes/position
1372  long nL;
1373  long nT;
1374  long nW;
1375  long nH;
1376 
1377  if ( mbHorz )
1378  {
1379  if ( mbBottomRight )
1380  nT = mnDY-mnBottomBorder;
1381  else
1382  nT = mnTopBorder;
1383  nL = mnLeftBorder;
1384  }
1385  else
1386  {
1387  if ( mbBottomRight )
1388  nL = mnDX-mnRightBorder;
1389  else
1390  nL = mnLeftBorder;
1391  nT = mnTopBorder;
1392  }
1395  if ( mnWinStyle & WB_SIZEABLE )
1396  {
1397  if ( mbHorz )
1398  nH -= nSplitSize;
1399  else
1400  nW -= nSplitSize;
1401  }
1402 
1403  // calculate sets recursive
1404  ImplCalcSet( mpMainSet.get(), nL, nT, nW, nH, mbHorz, !mbBottomRight );
1405  ImplCalcSet2( this, mpMainSet.get(), false, mbHorz );
1406  mbCalc = false;
1407 }
1408 
1410 {
1411  mbCalc = true;
1412 
1413  if ( IsReallyShown() && IsUpdateMode() && mbRecalc )
1414  {
1415  if ( !mpMainSet->mvItems.empty() )
1416  ImplCalcLayout();
1417  else
1418  Invalidate();
1419  }
1420 }
1421 
1423 {
1424  if ( mnSplitTest & SPLIT_HORZ )
1425  {
1426  rMousePos.AdjustX( -mnMouseOff );
1427  if ( rMousePos.X() < maDragRect.Left() )
1428  rMousePos.setX( maDragRect.Left() );
1429  else if ( rMousePos.X()+mpSplitSet->mnSplitSize+1 > maDragRect.Right() )
1430  rMousePos.setX( maDragRect.Right()-mpSplitSet->mnSplitSize+1 );
1431  // store in screen coordinates due to FullDrag
1432  mnMSplitPos = OutputToScreenPixel( rMousePos ).X();
1433  }
1434  else
1435  {
1436  rMousePos.AdjustY( -mnMouseOff );
1437  if ( rMousePos.Y() < maDragRect.Top() )
1438  rMousePos.setY( maDragRect.Top() );
1439  else if ( rMousePos.Y()+mpSplitSet->mnSplitSize+1 > maDragRect.Bottom() )
1440  rMousePos.setY( maDragRect.Bottom()-mpSplitSet->mnSplitSize+1 );
1441  mnMSplitPos = OutputToScreenPixel( rMousePos ).Y();
1442  }
1443 }
1444 
1445 void SplitWindow::ImplGetButtonRect( tools::Rectangle& rRect, bool bTest ) const
1446 {
1447  long nSplitSize = mpMainSet->mnSplitSize-1;
1448  if (mbFadeOut || mbFadeIn)
1449  nSplitSize += SPLITWIN_SPLITSIZEEX;
1450 
1451  long nButtonSize = 0;
1452  if ( mbFadeIn )
1453  nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1454  if ( mbFadeOut )
1455  nButtonSize += SPLITWIN_SPLITSIZEFADE+1;
1456  long nCenterEx = 0;
1457  if ( mbHorz )
1458  nCenterEx += ((mnDX-mnLeftBorder-mnRightBorder)-nButtonSize)/2;
1459  else
1460  nCenterEx += ((mnDY-mnTopBorder-mnBottomBorder)-nButtonSize)/2;
1461  long nEx = 0;
1462  if ( nCenterEx > 0 )
1463  nEx += nCenterEx;
1464 
1465  switch ( meAlign )
1466  {
1467  case WindowAlign::Top:
1468  rRect.SetLeft( mnLeftBorder+nEx );
1469  rRect.SetTop( mnDY-mnBottomBorder-nSplitSize );
1470  rRect.SetRight( rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE );
1471  rRect.SetBottom( mnDY-mnBottomBorder-1 );
1472  if ( bTest )
1473  {
1474  rRect.AdjustTop( -mnTopBorder );
1475  rRect.AdjustBottom(mnBottomBorder );
1476  }
1477  break;
1478  case WindowAlign::Bottom:
1479  rRect.SetLeft( mnLeftBorder+nEx );
1480  rRect.SetTop( mnTopBorder );
1481  rRect.SetRight( rRect.Left()+SPLITWIN_SPLITSIZEAUTOHIDE );
1482  rRect.SetBottom( mnTopBorder+nSplitSize-1 );
1483  if ( bTest )
1484  {
1485  rRect.AdjustTop( -mnTopBorder );
1486  rRect.AdjustBottom(mnBottomBorder );
1487  }
1488  break;
1489  case WindowAlign::Left:
1490  rRect.SetLeft( mnDX-mnRightBorder-nSplitSize );
1491  rRect.SetTop( mnTopBorder+nEx );
1492  rRect.SetRight( mnDX-mnRightBorder-1 );
1493  rRect.SetBottom( rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE );
1494  if ( bTest )
1495  {
1496  rRect.AdjustLeft( -mnLeftBorder );
1497  rRect.AdjustRight(mnRightBorder );
1498  }
1499  break;
1500  case WindowAlign::Right:
1501  rRect.SetLeft( mnLeftBorder );
1502  rRect.SetTop( mnTopBorder+nEx );
1503  rRect.SetRight( mnLeftBorder+nSplitSize-1 );
1504  rRect.SetBottom( rRect.Top()+SPLITWIN_SPLITSIZEAUTOHIDE );
1505  if ( bTest )
1506  {
1507  rRect.AdjustLeft( -mnLeftBorder );
1508  rRect.AdjustRight(mnRightBorder );
1509  }
1510  break;
1511  }
1512 }
1513 
1514 void SplitWindow::ImplGetFadeInRect( tools::Rectangle& rRect, bool bTest ) const
1515 {
1516  tools::Rectangle aRect;
1517 
1518  if ( mbFadeIn )
1519  ImplGetButtonRect( aRect, bTest );
1520 
1521  rRect = aRect;
1522 }
1523 
1525 {
1526  tools::Rectangle aRect;
1527 
1528  if ( mbFadeOut )
1529  ImplGetButtonRect( aRect, false );
1530 
1531  rRect = aRect;
1532 }
1533 
1534 void SplitWindow::ImplDrawGrip(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, bool bHorizontal, bool bLeft)
1535 {
1536  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1537 
1538  Color aColor;
1539 
1540  if (rRect.IsInside(GetPointerPosPixel()))
1541  {
1542  vcl::RenderTools::DrawSelectionBackground(rRenderContext, *this, rRect, 2, false, false, false);
1543 
1544  aColor = rStyleSettings.GetDarkShadowColor();
1545  }
1546  else
1547  {
1548  rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
1549  rRenderContext.SetFillColor(rStyleSettings.GetDarkShadowColor());
1550 
1551  rRenderContext.DrawRect(rRect);
1552 
1553  aColor = rStyleSettings.GetFaceColor();
1554  }
1555 
1556  AntialiasingFlags nAA = rRenderContext.GetAntialiasing();
1558 
1559  long nWidth = rRect.getWidth();
1560  long nWidthHalf = nWidth / 2;
1561  long nHeight = rRect.getHeight();
1562  long nHeightHalf = nHeight / 2;
1563 
1564  long nLeft = rRect.Left();
1565  long nRight = rRect.Right();
1566  long nTop = rRect.Top();
1567  long nBottom = rRect.Bottom();
1568  long nMargin = 1;
1569 
1570  rRenderContext.SetLineColor(aColor);
1571  rRenderContext.SetFillColor(aColor);
1572 
1573  tools::Polygon aPoly(3);
1574 
1575  if (bHorizontal)
1576  {
1577  long nCenter = nLeft + nWidthHalf;
1578 
1579  if (bLeft)
1580  {
1581  aPoly.SetPoint(Point(nCenter, nTop + nMargin), 0);
1582  aPoly.SetPoint(Point(nCenter - nHeightHalf, nBottom - nMargin), 1);
1583  aPoly.SetPoint(Point(nCenter - nHeightHalf, nBottom - nMargin), 2);
1584  }
1585  else
1586  {
1587  aPoly.SetPoint(Point(nCenter, nBottom - nMargin), 0);
1588  aPoly.SetPoint(Point(nCenter - nHeightHalf, nTop + nMargin), 1);
1589  aPoly.SetPoint(Point(nCenter + nHeightHalf, nTop + nMargin), 2);
1590  }
1591  rRenderContext.DrawPolygon(aPoly);
1592  }
1593  else
1594  {
1595  long nCenter = nTop + nHeightHalf;
1596 
1597  if (bLeft)
1598  {
1599  aPoly.SetPoint(Point(nLeft + nMargin, nCenter), 0);
1600  aPoly.SetPoint(Point(nRight - nMargin, nCenter - nWidthHalf), 1);
1601  aPoly.SetPoint(Point(nRight - nMargin, nCenter + nWidthHalf), 2);
1602  }
1603  else
1604  {
1605  aPoly.SetPoint(Point(nRight - nMargin, nCenter), 0);
1606  aPoly.SetPoint(Point(nLeft + nMargin, nCenter - nWidthHalf), 1);
1607  aPoly.SetPoint(Point(nLeft + nMargin, nCenter + nWidthHalf), 2);
1608  }
1609  rRenderContext.DrawPolygon(aPoly);
1610  }
1611 
1612  rRenderContext.SetAntialiasing(nAA);
1613 }
1614 
1616 {
1617  if (mbFadeIn)
1618  {
1619  tools::Rectangle aTempRect;
1620  ImplGetFadeInRect(aTempRect);
1621 
1622  bool bLeft = true;
1623  switch (meAlign)
1624  {
1625  case WindowAlign::Top:
1626  case WindowAlign::Left:
1627  bLeft = false;
1628  break;
1629  case WindowAlign::Bottom:
1630  case WindowAlign::Right:
1631  default:
1632  bLeft = true;
1633  break;
1634  }
1635 
1636  ImplDrawGrip(rRenderContext, aTempRect, (meAlign == WindowAlign::Top) || (meAlign == WindowAlign::Bottom), bLeft);
1637  }
1638 }
1639 
1641 {
1642  if (mbFadeOut)
1643  {
1644  tools::Rectangle aTempRect;
1645  ImplGetFadeOutRect(aTempRect);
1646 
1647  bool bLeft = true;
1648  switch (meAlign)
1649  {
1650  case WindowAlign::Bottom:
1651  case WindowAlign::Right:
1652  bLeft = false;
1653  break;
1654  case WindowAlign::Top:
1655  case WindowAlign::Left:
1656  default:
1657  bLeft = true;
1658  break;
1659  }
1660 
1661  ImplDrawGrip(rRenderContext, aTempRect, (meAlign == WindowAlign::Top) || (meAlign == WindowAlign::Bottom), bLeft);
1662  }
1663 }
1664 
1666 {
1667  Point aMousePosPixel = rMEvt.GetPosPixel();
1668  mnSplitTest = ImplTestSplit( this, aMousePosPixel, mnMouseOff, &mpSplitSet, mnSplitPos );
1669 
1670  if ( !mnSplitTest || (mnSplitTest & SPLIT_NOSPLIT) )
1671  return;
1672 
1673  ImplSplitItem* pSplitItem;
1674  long nCurMaxSize;
1675  bool bPropSmaller;
1676 
1677  mnMouseModifier = rMEvt.GetModifier();
1678  bPropSmaller = (mnMouseModifier & KEY_SHIFT) && (static_cast<sal_uInt16>(mnSplitPos+1) < mpSplitSet->mvItems.size());
1679 
1680  // here we can set the maximum size
1681  StartSplit();
1682 
1683  if ( mnMaxSize )
1684  nCurMaxSize = mnMaxSize;
1685  else
1686  {
1687  Size aSize = GetParent()->GetOutputSizePixel();
1688  if ( mbHorz )
1689  nCurMaxSize = aSize.Height();
1690  else
1691  nCurMaxSize = aSize.Width();
1692  }
1693 
1694  if ( !mpSplitSet->mvItems.empty() )
1695  {
1696  bool bDown = true;
1697  if ( (mpSplitSet == mpMainSet.get()) && mbBottomRight )
1698  bDown = false;
1699 
1700  pSplitItem = &mpSplitSet->mvItems[mnSplitPos];
1701  maDragRect.SetLeft( pSplitItem->mnLeft );
1702  maDragRect.SetTop( pSplitItem->mnTop );
1703  maDragRect.SetRight( pSplitItem->mnLeft+pSplitItem->mnWidth-1 );
1704  maDragRect.SetBottom( pSplitItem->mnTop+pSplitItem->mnHeight-1 );
1705 
1706  if ( mnSplitTest & SPLIT_HORZ )
1707  {
1708  if ( bDown )
1710  else
1712  }
1713  else
1714  {
1715  if ( bDown )
1717  else
1719  }
1720 
1721  if ( mnSplitPos )
1722  {
1723  long nTemp = mnSplitPos;
1724  while ( nTemp )
1725  {
1726  pSplitItem = &mpSplitSet->mvItems[nTemp-1];
1727  if ( pSplitItem->mbFixed )
1728  break;
1729  else
1730  {
1731  if ( mnSplitTest & SPLIT_HORZ )
1732  {
1733  if ( bDown )
1734  maDragRect.AdjustLeft( -(pSplitItem->mnPixSize) );
1735  else
1736  maDragRect.AdjustRight(pSplitItem->mnPixSize );
1737  }
1738  else
1739  {
1740  if ( bDown )
1741  maDragRect.AdjustTop( -(pSplitItem->mnPixSize) );
1742  else
1743  maDragRect.AdjustBottom(pSplitItem->mnPixSize );
1744  }
1745  }
1746  nTemp--;
1747  }
1748  }
1749 
1750  if ( (mpSplitSet == mpMainSet.get()) && (mnWinStyle & WB_SIZEABLE) && !bPropSmaller )
1751  {
1752  if ( bDown )
1753  {
1754  if ( mbHorz )
1755  maDragRect.AdjustBottom(nCurMaxSize-mnDY-mnTopBorder );
1756  else
1757  maDragRect.AdjustRight(nCurMaxSize-mnDX-mnLeftBorder );
1758  }
1759  else
1760  {
1761  if ( mbHorz )
1762  maDragRect.AdjustTop( -(nCurMaxSize-mnDY-mnBottomBorder) );
1763  else
1764  maDragRect.AdjustLeft( -(nCurMaxSize-mnDX-mnRightBorder) );
1765  }
1766  }
1767  else
1768  {
1769  std::vector<ImplSplitItem *>::size_type nTemp = mnSplitPos+1;
1770  while ( nTemp < mpSplitSet->mvItems.size() )
1771  {
1772  pSplitItem = &mpSplitSet->mvItems[nTemp];
1773  if ( pSplitItem->mbFixed )
1774  break;
1775  else
1776  {
1777  if ( mnSplitTest & SPLIT_HORZ )
1778  {
1779  if ( bDown )
1780  maDragRect.AdjustRight(pSplitItem->mnPixSize );
1781  else
1782  maDragRect.AdjustLeft( -(pSplitItem->mnPixSize) );
1783  }
1784  else
1785  {
1786  if ( bDown )
1787  maDragRect.AdjustBottom(pSplitItem->mnPixSize );
1788  else
1789  maDragRect.AdjustTop( -(pSplitItem->mnPixSize) );
1790  }
1791  }
1792  nTemp++;
1793  }
1794  }
1795  }
1796  else
1797  {
1802  if ( mbHorz )
1803  {
1804  if ( mbBottomRight )
1805  maDragRect.AdjustTop( -(nCurMaxSize-mnDY-mnBottomBorder) );
1806  else
1807  maDragRect.AdjustBottom(nCurMaxSize-mnDY-mnTopBorder );
1808  }
1809  else
1810  {
1811  if ( mbBottomRight )
1812  maDragRect.AdjustLeft( -(nCurMaxSize-mnDX-mnRightBorder) );
1813  else
1814  maDragRect.AdjustRight(nCurMaxSize-mnDX-mnLeftBorder );
1815  }
1816  }
1817 
1818  StartTracking();
1819 
1820  mbDragFull = bool(GetSettings().GetStyleSettings().GetDragFullOptions() & DragFullOptions::Split);
1821 
1822  ImplSplitMousePos( aMousePosPixel );
1823 
1824  if (!mbDragFull)
1825  {
1826  ImplDrawSplitTracking(aMousePosPixel);
1827  }
1828  else
1829  {
1830  std::vector< ImplSplitItem >& rItems = mpSplitSet->mvItems;
1831  sal_uInt16 nItems = mpSplitSet->mvItems.size();
1832  mpLastSizes = new long[nItems*2];
1833  for ( sal_uInt16 i = 0; i < nItems; i++ )
1834  {
1835  mpLastSizes[i*2] = rItems[i].mnSize;
1836  mpLastSizes[i*2+1] = rItems[i].mnPixSize;
1837  }
1838  }
1840 
1842  if ( mnSplitTest & SPLIT_HORZ )
1843  eStyle = PointerStyle::HSplit;
1844  else if ( mnSplitTest & SPLIT_VERT )
1845  eStyle = PointerStyle::VSplit;
1846 
1847  SetPointer( eStyle );
1848 }
1849 
1851 {
1852 }
1853 
1855 {
1856  maSplitHdl.Call( this );
1857 }
1858 
1860 {
1861 }
1862 
1864 {
1865 }
1866 
1868 {
1869 }
1870 
1872 {
1873  if ( !rMEvt.IsLeft() || rMEvt.IsMod2() )
1874  {
1876  return;
1877  }
1878 
1879  Point aMousePosPixel = rMEvt.GetPosPixel();
1880  tools::Rectangle aTestRect;
1881 
1882  mbFadeNoButtonMode = false;
1883 
1884  ImplGetFadeOutRect( aTestRect );
1885  if ( aTestRect.IsInside( aMousePosPixel ) )
1886  {
1887  mbFadeOutDown = true;
1888  mbFadeOutPressed = true;
1889  Invalidate();
1890  }
1891  else
1892  {
1893  ImplGetFadeInRect( aTestRect, true );
1894  if ( aTestRect.IsInside( aMousePosPixel ) )
1895  {
1896  mbFadeInDown = true;
1897  mbFadeInPressed = true;
1898  Invalidate();
1899  }
1900  else if ( !aTestRect.IsEmpty() && !(mnWinStyle & WB_SIZEABLE) )
1901  {
1902  mbFadeNoButtonMode = true;
1903  FadeIn();
1904  return;
1905  }
1906  }
1907 
1908  if ( mbFadeInDown || mbFadeOutDown )
1909  StartTracking();
1910  else
1911  ImplStartSplit( rMEvt );
1912 }
1913 
1915 {
1916  if ( IsTracking() )
1917  return;
1918 
1919  Point aPos = rMEvt.GetPosPixel();
1920  long nTemp;
1921  ImplSplitSet* pTempSplitSet;
1922  sal_uInt16 nTempSplitPos;
1923  sal_uInt16 nSplitTest = ImplTestSplit( this, aPos, nTemp, &pTempSplitSet, nTempSplitPos );
1925  tools::Rectangle aFadeInRect;
1926  tools::Rectangle aFadeOutRect;
1927 
1928  ImplGetFadeInRect( aFadeInRect );
1929  ImplGetFadeOutRect( aFadeOutRect );
1930  if ( !aFadeInRect.IsInside( aPos ) &&
1931  !aFadeOutRect.IsInside( aPos ) )
1932  {
1933  if ( nSplitTest && !(nSplitTest & SPLIT_NOSPLIT) )
1934  {
1935  if ( nSplitTest & SPLIT_HORZ )
1936  eStyle = PointerStyle::HSplit;
1937  else if ( nSplitTest & SPLIT_VERT )
1938  eStyle = PointerStyle::VSplit;
1939  }
1940  }
1941 
1942  SetPointer( eStyle );
1943 }
1944 
1946 {
1947  Point aMousePosPixel = rTEvt.GetMouseEvent().GetPosPixel();
1948 
1949  if ( mbFadeInDown )
1950  {
1951  if ( rTEvt.IsTrackingEnded() )
1952  {
1953  mbFadeInDown = false;
1954  if ( mbFadeInPressed )
1955  {
1956  mbFadeInPressed = false;
1957  Invalidate();
1958 
1959  if ( !rTEvt.IsTrackingCanceled() )
1960  FadeIn();
1961  }
1962  }
1963  else
1964  {
1965  tools::Rectangle aTestRect;
1966  ImplGetFadeInRect( aTestRect, true );
1967  bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
1968  if ( bNewPressed != mbFadeInPressed )
1969  {
1970  mbFadeInPressed = bNewPressed;
1971  Invalidate();
1972  }
1973  }
1974  }
1975  else if ( mbFadeOutDown )
1976  {
1977  if ( rTEvt.IsTrackingEnded() )
1978  {
1979  mbFadeOutDown = false;
1980  if ( mbFadeOutPressed )
1981  {
1982  mbFadeOutPressed = false;
1983  Invalidate();
1984 
1985  if ( !rTEvt.IsTrackingCanceled() )
1986  FadeOut();
1987  }
1988  }
1989  else
1990  {
1991  tools::Rectangle aTestRect;
1992  ImplGetFadeOutRect( aTestRect );
1993  bool bNewPressed = aTestRect.IsInside( aMousePosPixel );
1994  if ( !bNewPressed )
1995  {
1996  mbFadeOutPressed = bNewPressed;
1997  Invalidate();
1998 
1999  // We need a mouseevent with a position inside the button for the
2000  // ImplStartSplit function!
2001  MouseEvent aOrgMEvt = rTEvt.GetMouseEvent();
2002  MouseEvent aNewMEvt( aTestRect.Center(), aOrgMEvt.GetClicks(),
2003  aOrgMEvt.GetMode(), aOrgMEvt.GetButtons(),
2004  aOrgMEvt.GetModifier() );
2005 
2006  ImplStartSplit( aNewMEvt );
2007  mbFadeOutDown = false;
2008  }
2009  }
2010  }
2011  else
2012  {
2013  ImplSplitMousePos( aMousePosPixel );
2014  bool bSplit = true;
2015  if ( mbDragFull )
2016  {
2017  if ( rTEvt.IsTrackingEnded() )
2018  {
2019  if ( rTEvt.IsTrackingCanceled() )
2020  {
2021  std::vector< ImplSplitItem >& rItems = mpSplitSet->mvItems;
2022  size_t nItems = rItems.size();
2023  for ( size_t i = 0; i < nItems; i++ )
2024  {
2025  rItems[i].mnSize = mpLastSizes[i*2];
2026  rItems[i].mnPixSize = mpLastSizes[i*2+1];
2027  }
2028  ImplUpdate();
2029  Split();
2030  }
2031  bSplit = false;
2032  }
2033  }
2034  else
2035  {
2036  if ( rTEvt.IsTrackingEnded() )
2037  {
2038  HideTracking();
2039  bSplit = !rTEvt.IsTrackingCanceled();
2040  }
2041  else
2042  {
2043  ImplDrawSplitTracking(aMousePosPixel);
2044  bSplit = false;
2045  }
2046  }
2047 
2048  if ( bSplit )
2049  {
2050  bool bPropSmaller = (mnMouseModifier & KEY_SHIFT) != 0;
2051  bool bPropGreater = (mnMouseModifier & KEY_MOD1) != 0;
2052  long nDelta = mnMSplitPos-mnMStartPos;
2053 
2054  if ( (mnSplitTest & SPLIT_WINDOW) && mpMainSet->mvItems.empty() )
2055  {
2056  if ( (mpSplitSet == mpMainSet.get()) && mbBottomRight )
2057  nDelta *= -1;
2058  ImplSetWindowSize( nDelta );
2059  }
2060  else
2061  {
2062  long nNewSize = mpSplitSet->mvItems[mnSplitPos].mnPixSize;
2063  if ( (mpSplitSet == mpMainSet.get()) && mbBottomRight )
2064  nNewSize -= nDelta;
2065  else
2066  nNewSize += nDelta;
2067  SplitItem( mpSplitSet->mvItems[mnSplitPos].mnId, nNewSize,
2068  bPropSmaller, bPropGreater );
2069  }
2070 
2071  Split();
2072 
2073  if ( mbDragFull )
2074  {
2075  Update();
2076  mnMStartPos = mnMSplitPos;
2077  }
2078  }
2079 
2080  if ( rTEvt.IsTrackingEnded() )
2081  {
2082  delete [] mpLastSizes;
2083  mpLastSizes = nullptr;
2084  mpSplitSet = nullptr;
2085  mnMouseOff = 0;
2086  mnMStartPos = 0;
2087  mnMSplitPos = 0;
2088  mnMouseModifier = 0;
2089  mnSplitTest = 0;
2090  mnSplitPos = 0;
2091  }
2092  }
2093 }
2094 
2096 {
2097  const MouseEvent* pMouseEvt = nullptr;
2098 
2099  if( (rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != nullptr )
2100  {
2101  if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2102  {
2103  // trigger redraw if mouse over state has changed
2104  tools::Rectangle aFadeInRect;
2105  tools::Rectangle aFadeOutRect;
2106  ImplGetFadeInRect( aFadeInRect );
2107  ImplGetFadeOutRect( aFadeOutRect );
2108 
2109  if ( aFadeInRect.IsInside( GetPointerPosPixel() ) != aFadeInRect.IsInside( GetLastPointerPosPixel() ) )
2110  Invalidate( aFadeInRect );
2111  if ( aFadeOutRect.IsInside( GetPointerPosPixel() ) != aFadeOutRect.IsInside( GetLastPointerPosPixel() ) )
2112  Invalidate( aFadeOutRect );
2113 
2114  if( pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
2115  {
2116  Invalidate( aFadeInRect );
2117  Invalidate( aFadeOutRect );
2118  }
2119  }
2120  }
2121  return Window::PreNotify( rNEvt );
2122 }
2123 
2125 {
2126  if (mnWinStyle & WB_BORDER)
2127  ImplDrawBorder(rRenderContext);
2128 
2129  ImplDrawBorderLine(rRenderContext);
2130  ImplDrawFadeOut(rRenderContext);
2131  ImplDrawFadeIn(rRenderContext);
2132 
2133  // draw FrameSet-backgrounds
2134  ImplDrawBack(rRenderContext, mpMainSet.get());
2135 
2136  // draw splitter
2137  if (!(mnWinStyle & WB_NOSPLITDRAW))
2138  {
2139  ImplDrawSplit(rRenderContext, mpMainSet.get(), mbHorz, !mbBottomRight);
2140  }
2141 }
2142 
2144 {
2145  Size aSize = GetOutputSizePixel();
2146  mnDX = aSize.Width();
2147  mnDY = aSize.Height();
2148 
2149  ImplUpdate();
2150  Invalidate();
2151 }
2152 
2154 {
2155  // no keyboard help for splitwin
2156  if ( rHEvt.GetMode() & (HelpEventMode::BALLOON | HelpEventMode::QUICK) && !rHEvt.KeyboardActivated() )
2157  {
2158  Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
2159  tools::Rectangle aHelpRect;
2160  const char* pHelpResId = nullptr;
2161 
2162  ImplGetFadeInRect( aHelpRect, true );
2163  if ( aHelpRect.IsInside( aMousePosPixel ) )
2164  pHelpResId = SV_HELPTEXT_FADEIN;
2165  else
2166  {
2167  ImplGetFadeOutRect( aHelpRect );
2168  if ( aHelpRect.IsInside( aMousePosPixel ) )
2169  pHelpResId = SV_HELPTEXT_FADEOUT;
2170  }
2171 
2172  // get rectangle
2173  if (pHelpResId)
2174  {
2175  Point aPt = OutputToScreenPixel( aHelpRect.TopLeft() );
2176  aHelpRect.SetLeft( aPt.X() );
2177  aHelpRect.SetTop( aPt.Y() );
2178  aPt = OutputToScreenPixel( aHelpRect.BottomRight() );
2179  aHelpRect.SetRight( aPt.X() );
2180  aHelpRect.SetBottom( aPt.Y() );
2181 
2182  // get and draw text
2183  OUString aStr = VclResId(pHelpResId);
2184  if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
2185  Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aStr );
2186  else
2187  Help::ShowQuickHelp( this, aHelpRect, aStr );
2188  return;
2189  }
2190  }
2191 
2192  DockingWindow::RequestHelp( rHEvt );
2193 }
2194 
2196 {
2197  switch ( nType )
2198  {
2200  if ( IsUpdateMode() )
2201  ImplCalcLayout();
2202  break;
2204  if ( IsUpdateMode() && IsReallyShown() )
2205  ImplCalcLayout();
2206  break;
2208  ImplInitSettings();
2209  Invalidate();
2210  break;
2211  default:;
2212  }
2213 
2214  DockingWindow::StateChanged( nType );
2215 }
2216 
2218 {
2219  if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2220  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
2221  {
2222  ImplInitSettings();
2223  Invalidate();
2224  }
2225  else
2226  DockingWindow::DataChanged( rDCEvt );
2227 }
2228 
2229 void SplitWindow::InsertItem( sal_uInt16 nId, vcl::Window* pWindow, long nSize,
2230  sal_uInt16 nPos, sal_uInt16 nIntoSetId,
2231  SplitWindowItemFlags nBits )
2232 {
2233 #ifdef DBG_UTIL
2234  sal_uInt16 nDbgDummy;
2235  SAL_WARN_IF( ImplFindItem( mpMainSet.get(), nId, nDbgDummy ), "vcl", "SplitWindow::InsertItem() - Id already exists" );
2236 #endif
2237 
2238  // Size has to be at least 1.
2239  if ( nSize < 1 )
2240  nSize = 1;
2241 
2242  ImplSplitSet* pSet = ImplFindSet( mpMainSet.get(), nIntoSetId );
2243 #ifdef DBG_UTIL
2244  SAL_WARN_IF( !pSet, "vcl", "SplitWindow::InsertItem() - Set not exists" );
2245 #endif
2246  if(!pSet)
2247  {
2248  return;
2249  }
2250 
2251  // Don't insert further than the end
2252  if ( nPos > pSet->mvItems.size() )
2253  nPos = pSet->mvItems.size();
2254 
2255  // Insert in set
2256  pSet->mvItems.emplace( pSet->mvItems.begin() + nPos );
2257 
2258  // init new item
2259  ImplSplitItem & aItem = pSet->mvItems[nPos];
2260  aItem.mnSize = nSize;
2261  aItem.mnPixSize = 0;
2262  aItem.mnId = nId;
2263  aItem.mnBits = nBits;
2264  aItem.mnMinSize=-1;
2265  aItem.mnMaxSize=-1;
2266 
2267  if ( pWindow )
2268  {
2269  // New VclPtr reference
2270  aItem.mpWindow = pWindow;
2271  aItem.mpOrgParent = pWindow->GetParent();
2272 
2273  // Attach window to SplitWindow.
2274  pWindow->Hide();
2275  pWindow->SetParent( this );
2276  }
2277  else
2278  {
2279  ImplSplitSet * pNewSet = new ImplSplitSet();
2280  pNewSet->mnId = nId;
2281  pNewSet->mnSplitSize = pSet->mnSplitSize;
2282 
2283  aItem.mpSet.reset(pNewSet);
2284  }
2285 
2286  pSet->mbCalcPix = true;
2287 
2288  ImplUpdate();
2289 }
2290 
2291 void SplitWindow::InsertItem( sal_uInt16 nId, long nSize,
2292  sal_uInt16 nPos, sal_uInt16 nIntoSetId,
2293  SplitWindowItemFlags nBits )
2294 {
2295  InsertItem( nId, nullptr, nSize, nPos, nIntoSetId, nBits );
2296 }
2297 
2298 void SplitWindow::RemoveItem( sal_uInt16 nId )
2299 {
2300 #ifdef DBG_UTIL
2301  sal_uInt16 nDbgDummy;
2302  SAL_WARN_IF( !ImplFindItem( mpMainSet.get(), nId, nDbgDummy ), "vcl", "SplitWindow::RemoveItem() - Id not found" );
2303 #endif
2304 
2305  // search set
2306  sal_uInt16 nPos;
2307  ImplSplitSet* pSet = ImplFindItem( mpMainSet.get(), nId, nPos );
2308 
2309  if (!pSet)
2310  return;
2311 
2312  ImplSplitItem* pItem = &pSet->mvItems[nPos];
2313  VclPtr<vcl::Window> pWindow = pItem->mpWindow;
2314  VclPtr<vcl::Window> pOrgParent = pItem->mpOrgParent;
2315 
2316  // delete set if required
2317  if ( !pWindow )
2318  pItem->mpSet.reset();
2319 
2320  // remove item
2321  pSet->mbCalcPix = true;
2322  pSet->mvItems.erase( pSet->mvItems.begin() + nPos );
2323 
2324  ImplUpdate();
2325 
2326  // to have the least amounts of paints delete window only here
2327  if ( pWindow )
2328  {
2329  // restore window
2330  pWindow->Hide();
2331  pWindow->SetParent( pOrgParent );
2332  }
2333 
2334  // Clear and delete
2335  pWindow.clear();
2336  pOrgParent.clear();
2337 }
2338 
2340 {
2341  // create Main-Set again
2342  mpMainSet.reset(new ImplSplitSet());
2343  if ( mnWinStyle & WB_NOSPLITDRAW )
2344  mpMainSet->mnSplitSize -= 2;
2345  mpBaseSet = mpMainSet.get();
2346 
2347  // and invalidate again
2348  ImplUpdate();
2349 }
2350 
2351 void SplitWindow::SplitItem( sal_uInt16 nId, long nNewSize,
2352  bool bPropSmall, bool bPropGreat )
2353 {
2354  sal_uInt16 nPos;
2355  ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
2356 
2357  if (!pSet)
2358  return;
2359 
2360  size_t nItems = pSet->mvItems.size();
2361  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
2362 
2363  // When there is an explicit minimum or maximum size then move nNewSize
2364  // into that range (when it is not yet already in it.)
2365  nNewSize = ValidateSize(nNewSize, rItems[nPos]);
2366 
2367  if ( mbCalc )
2368  {
2369  rItems[nPos].mnSize = nNewSize;
2370  return;
2371  }
2372 
2373  long nDelta = nNewSize-rItems[nPos].mnPixSize;
2374  if ( !nDelta )
2375  return;
2376 
2377  // calculate area, which could be affected by splitting
2378  sal_uInt16 nMin = 0;
2379  sal_uInt16 nMax = nItems;
2380  for (size_t i = 0; i < nItems; ++i)
2381  {
2382  if ( rItems[i].mbFixed )
2383  {
2384  if ( i < nPos )
2385  nMin = i+1;
2386  else
2387  nMax = i;
2388  }
2389  }
2390 
2391  // treat TopSet different if the window is sizeable
2392  bool bSmall = true;
2393  bool bGreat = true;
2394  if ( (pSet == mpMainSet.get()) && (mnWinStyle & WB_SIZEABLE) )
2395  {
2396  if ( nPos < pSet->mvItems.size()-1 )
2397  {
2398  if ( !((bPropSmall && bPropGreat) ||
2399  ((nDelta > 0) && bPropSmall) ||
2400  ((nDelta < 0) && bPropGreat)) )
2401  {
2402  if ( nDelta < 0 )
2403  bGreat = false;
2404  else
2405  bSmall = false;
2406  }
2407  }
2408  else
2409  {
2410  if ( nDelta < 0 )
2411  bGreat = false;
2412  else
2413  bSmall = false;
2414  }
2415  }
2416  else if ( nPos >= nMax )
2417  {
2418  bSmall = false;
2419  bGreat = false;
2420  }
2421  else if ( nPos && (nPos >= pSet->mvItems.size()-1) )
2422  {
2423  nPos--;
2424  nDelta *= -1;
2425  bool bTemp = bPropSmall;
2426  bPropSmall = bPropGreat;
2427  bPropGreat = bTemp;
2428  }
2429 
2430  sal_uInt16 n;
2431  // now splitt the windows
2432  if ( nDelta < 0 )
2433  {
2434  if ( bGreat )
2435  {
2436  if ( bPropGreat )
2437  {
2438  long nTempDelta = nDelta;
2439  do
2440  {
2441  n = nPos+1;
2442  do
2443  {
2444  if ( nTempDelta )
2445  {
2446  rItems[n].mnPixSize++;
2447  nTempDelta++;
2448  }
2449  n++;
2450  }
2451  while ( n < nMax );
2452  }
2453  while ( nTempDelta );
2454  }
2455  else
2456  rItems[nPos+1].mnPixSize -= nDelta;
2457  }
2458 
2459  if ( bSmall )
2460  {
2461  if ( bPropSmall )
2462  {
2463  do
2464  {
2465  n = nPos+1;
2466  do
2467  {
2468  if ( nDelta && rItems[n-1].mnPixSize )
2469  {
2470  rItems[n-1].mnPixSize--;
2471  nDelta++;
2472  }
2473 
2474  n--;
2475  }
2476  while ( n > nMin );
2477  }
2478  while ( nDelta );
2479  }
2480  else
2481  {
2482  n = nPos+1;
2483  do
2484  {
2485  if ( rItems[n-1].mnPixSize+nDelta < 0 )
2486  {
2487  nDelta += rItems[n-1].mnPixSize;
2488  rItems[n-1].mnPixSize = 0;
2489  }
2490  else
2491  {
2492  rItems[n-1].mnPixSize += nDelta;
2493  break;
2494  }
2495  n--;
2496  }
2497  while ( n > nMin );
2498  }
2499  }
2500  }
2501  else
2502  {
2503  if ( bGreat )
2504  {
2505  if ( bPropGreat )
2506  {
2507  long nTempDelta = nDelta;
2508  do
2509  {
2510  n = nPos+1;
2511  do
2512  {
2513  if ( nTempDelta )
2514  {
2515  rItems[n-1].mnPixSize++;
2516  nTempDelta--;
2517  }
2518  n--;
2519  }
2520  while ( n > nMin );
2521  }
2522  while ( nTempDelta );
2523  }
2524  else
2525  rItems[nPos].mnPixSize += nDelta;
2526  }
2527 
2528  if ( bSmall )
2529  {
2530  if ( bPropSmall )
2531  {
2532  do
2533  {
2534  n = nPos+1;
2535  do
2536  {
2537  if ( nDelta && rItems[n].mnPixSize )
2538  {
2539  rItems[n].mnPixSize--;
2540  nDelta--;
2541  }
2542 
2543  n++;
2544  }
2545  while ( n < nMax );
2546  }
2547  while ( nDelta );
2548  }
2549  else
2550  {
2551  n = nPos+1;
2552  do
2553  {
2554  if ( rItems[n].mnPixSize-nDelta < 0 )
2555  {
2556  nDelta -= rItems[n].mnPixSize;
2557  rItems[n].mnPixSize = 0;
2558  }
2559  else
2560  {
2561  rItems[n].mnPixSize -= nDelta;
2562  break;
2563  }
2564  n++;
2565  }
2566  while ( n < nMax );
2567  }
2568  }
2569  }
2570 
2571  // update original sizes
2572  ImplCalcLogSize( rItems, nItems );
2573 
2574  ImplUpdate();
2575 }
2576 
2577 void SplitWindow::SetItemSize( sal_uInt16 nId, long nNewSize )
2578 {
2579  sal_uInt16 nPos;
2580  ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
2581  ImplSplitItem* pItem;
2582 
2583  if ( !pSet )
2584  return;
2585 
2586  // check if size is changed
2587  pItem = &pSet->mvItems[nPos];
2588  if ( pItem->mnSize != nNewSize )
2589  {
2590  // set new size and re-calculate
2591  pItem->mnSize = nNewSize;
2592  pSet->mbCalcPix = true;
2593  ImplUpdate();
2594  }
2595 }
2596 
2597 long SplitWindow::GetItemSize( sal_uInt16 nId ) const
2598 {
2599  sal_uInt16 nPos;
2600  ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
2601 
2602  if ( pSet )
2603  return pSet->mvItems[nPos].mnSize;
2604  else
2605  return 0;
2606 }
2607 
2608 long SplitWindow::GetItemSize( sal_uInt16 nId, SplitWindowItemFlags nBits ) const
2609 {
2610  sal_uInt16 nPos;
2611  ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
2612 
2613  if ( pSet )
2614  {
2615  if ( nBits == pSet->mvItems[nPos].mnBits )
2616  return pSet->mvItems[nPos].mnSize;
2617  else
2618  {
2619  const_cast<SplitWindow*>(this)->ImplCalcLayout();
2620 
2621  long nRelSize = 0;
2622  long nPerSize = 0;
2623  size_t nItems;
2624  SplitWindowItemFlags nTempBits;
2625  nItems = pSet->mvItems.size();
2626  std::vector< ImplSplitItem >& rItems = pSet->mvItems;
2627  for ( size_t i = 0; i < nItems; i++ )
2628  {
2629  if ( i == nPos )
2630  nTempBits = nBits;
2631  else
2632  nTempBits = rItems[i].mnBits;
2633  if ( nTempBits & SplitWindowItemFlags::RelativeSize )
2634  nRelSize += rItems[i].mnPixSize;
2635  else if ( nTempBits & SplitWindowItemFlags::PercentSize )
2636  nPerSize += rItems[i].mnPixSize;
2637  }
2638  nPerSize += nRelSize;
2639  if ( nBits & SplitWindowItemFlags::RelativeSize )
2640  {
2641  if ( nRelSize )
2642  return (rItems[nPos].mnPixSize+(nRelSize/2))/nRelSize;
2643  else
2644  return 1;
2645  }
2646  else if ( nBits & SplitWindowItemFlags::PercentSize )
2647  {
2648  if ( nPerSize )
2649  return (rItems[nPos].mnPixSize*100)/nPerSize;
2650  else
2651  return 1;
2652  }
2653  else
2654  return rItems[nPos].mnPixSize;
2655  }
2656  }
2657  else
2658  return 0;
2659 }
2660 
2661 void SplitWindow::SetItemSizeRange (sal_uInt16 nId, const Range& rRange)
2662 {
2663  sal_uInt16 nPos;
2664  ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos);
2665 
2666  if (pSet != nullptr)
2667  {
2668  pSet->mvItems[nPos].mnMinSize = rRange.Min();
2669  pSet->mvItems[nPos].mnMaxSize = rRange.Max();
2670  }
2671 }
2672 
2673 sal_uInt16 SplitWindow::GetSet( sal_uInt16 nId ) const
2674 {
2675  sal_uInt16 nPos;
2676  ImplSplitSet* pSet = ImplFindItem( mpBaseSet, nId, nPos );
2677 
2678  if ( pSet )
2679  return pSet->mnId;
2680  else
2681  return 0;
2682 }
2683 
2684 bool SplitWindow::IsItemValid( sal_uInt16 nId ) const
2685 {
2686  sal_uInt16 nPos;
2687  ImplSplitSet* pSet = mpBaseSet ? ImplFindItem(mpBaseSet, nId, nPos) : nullptr;
2688 
2689  return pSet != nullptr;
2690 }
2691 
2692 sal_uInt16 SplitWindow::GetItemId( vcl::Window* pWindow ) const
2693 {
2694  return ImplFindItem( mpBaseSet, pWindow );
2695 }
2696 
2697 sal_uInt16 SplitWindow::GetItemId( const Point& rPos ) const
2698 {
2699  return ImplFindItem( mpBaseSet, rPos, mbHorz, !mbBottomRight );
2700 }
2701 
2702 sal_uInt16 SplitWindow::GetItemPos( sal_uInt16 nId, sal_uInt16 nSetId ) const
2703 {
2704  ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
2705  sal_uInt16 nPos = SPLITWINDOW_ITEM_NOTFOUND;
2706 
2707  if ( pSet )
2708  {
2709  for ( size_t i = 0; i < pSet->mvItems.size(); i++ )
2710  {
2711  if ( pSet->mvItems[i].mnId == nId )
2712  {
2713  nPos = i;
2714  break;
2715  }
2716  }
2717  }
2718 
2719  return nPos;
2720 }
2721 
2722 sal_uInt16 SplitWindow::GetItemId( sal_uInt16 nPos ) const
2723 {
2724  ImplSplitSet* pSet = ImplFindSet( mpBaseSet, 0/*nSetId*/ );
2725  if ( pSet && (nPos < pSet->mvItems.size()) )
2726  return pSet->mvItems[nPos].mnId;
2727  else
2728  return 0;
2729 }
2730 
2731 sal_uInt16 SplitWindow::GetItemCount( sal_uInt16 nSetId ) const
2732 {
2733  ImplSplitSet* pSet = ImplFindSet( mpBaseSet, nSetId );
2734  if ( pSet )
2735  return pSet->mvItems.size();
2736  else
2737  return 0;
2738 }
2739 
2741 {
2742  switch ( meAlign )
2743  {
2744  case WindowAlign::Top:
2745  mbHorz = true;
2746  mbBottomRight = false;
2747  break;
2748  case WindowAlign::Bottom:
2749  mbHorz = true;
2750  mbBottomRight = true;
2751  break;
2752  case WindowAlign::Left:
2753  mbHorz = false;
2754  mbBottomRight = false;
2755  break;
2756  case WindowAlign::Right:
2757  mbHorz = false;
2758  mbBottomRight = true;
2759  break;
2760  }
2761 
2762  if ( mnWinStyle & WB_BORDER )
2763  {
2766  }
2767 
2768  if ( IsReallyVisible() && IsUpdateMode() )
2769  Invalidate();
2770  ImplUpdate();
2771 }
2772 
2774 {
2775  if ( meAlign != eNewAlign )
2776  {
2777  meAlign = eNewAlign;
2778  ImplNewAlign();
2779  }
2780 }
2781 
2783 {
2784  mbFadeIn = true;
2785  ImplUpdate();
2786 }
2787 
2789 {
2790  mbFadeOut = true;
2791  ImplUpdate();
2792 }
2793 
2795 {
2796  long n = 0;
2797 
2798  if ( mbHorz )
2800  else
2802 
2804 }
2805 
2806 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long getHeight() const
long Width() const
WindowAlign
double mnHeight
const Color & GetShadowColor() const
bool IsControlBackground() const
Definition: window2.cxx:1081
sal_uInt16 mnMouseModifier
Definition: splitwin.hxx:67
Point GetPointerPosPixel()
Definition: mouse.cxx:548
bool mbInvalidate
Definition: splitwin.hxx:68
sal_Int32 mnLeft
#define SPLITWIN_SPLITSIZEAUTOHIDE
Definition: splitwin.cxx:38
SplitWindow(const SplitWindow &)=delete
void SetAntialiasing(AntialiasingFlags nMode)
sal_uInt16 mnId
Definition: splitwin.cxx:66
static SAL_DLLPRIVATE void ImplCalcSet2(SplitWindow *pWindow, ImplSplitSet *pSet, bool bHide, bool bRows)
Definition: splitwin.cxx:716
#define SPLIT_HORZ
Definition: splitwin.cxx:41
ImplSplitSet * mpBaseSet
Definition: splitwin.hxx:49
bool mbCalc
Definition: splitwin.hxx:68
long AdjustWidth(long n)
long AdjustX(long nHorzMove)
virtual void MouseButtonDown(const MouseEvent &rMEvt)
Definition: mouse.cxx:412
static void DrawSelectionBackground(vcl::RenderContext &rRenderContext, vcl::Window const &rWindow, const tools::Rectangle &rRect, sal_uInt16 nHighlight, bool bChecked, bool bDrawBorder, bool bDrawExtBorderOnly, Color *pSelectionTextColor=nullptr, long nCornerRadius=0, Color const *pPaintColor=nullptr)
Definition: paint.cxx:317
virtual void StartSplit()
Definition: splitwin.cxx:1850
long Height() const
#define SPLIT_NOSPLIT
Definition: splitwin.cxx:44
void Clear()
Definition: splitwin.cxx:2339
#define SPLIT_VERT
Definition: splitwin.cxx:42
long getWidth() const
long AdjustLeft(long nHorzMoveDelta)
MouseEventModifiers GetMode() const
Definition: event.hxx:118
sal_uInt16 mnSplitTest
Definition: splitwin.hxx:65
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: splitwin.cxx:1945
const StyleSettings & GetStyleSettings() const
const Color & GetFaceColor() const
SAL_DLLPRIVATE void ImplGetFadeOutRect(tools::Rectangle &rRect) const
Definition: splitwin.cxx:1524
#define KEY_SHIFT
Definition: keycodes.hxx:30
long mnPixSize
Definition: splitwin.cxx:52
bool mbDragFull
Definition: splitwin.hxx:68
void DrawPolygon(const tools::Polygon &rPoly)
Render the given polygon.
Definition: polygon.cxx:156
void HideTracking()
Definition: window2.cxx:147
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1256
#define KEY_MOD1
Definition: keycodes.hxx:31
virtual void FadeOut()
Definition: splitwin.cxx:1867
void SetItemSizeRange(sal_uInt16 nId, const Range &rRange)
Set a range that limits the (variable part of the) size with an upper and a lower bound (both are val...
Definition: splitwin.cxx:2661
sal_Int16 nId
SAL_DLLPRIVATE void ImplGetFadeInRect(tools::Rectangle &rRect, bool bTest=false) const
Definition: splitwin.cxx:1514
long mnSplitSize
Definition: splitwin.cxx:58
SAL_DLLPRIVATE void ImplGetButtonRect(tools::Rectangle &rRect, bool bTest) const
Definition: splitwin.cxx:1445
DataChangedEventType GetType() const
Definition: event.hxx:348
long mnTopBorder
Definition: splitwin.hxx:56
void InsertItem(sal_uInt16 nId, vcl::Window *pWindow, long nSize, sal_uInt16 nPos, sal_uInt16 nIntoSetId, SplitWindowItemFlags nBits)
Definition: splitwin.cxx:2229
bool mbRecalc
Definition: splitwin.hxx:68
bool mbFadeInPressed
Definition: splitwin.hxx:68
const Color & GetControlBackground() const
Definition: window2.cxx:1076
VclPtr< vcl::Window > mpOrgParent
Definition: splitwin.cxx:65
static void ImplCalcBorder(WindowAlign eAlign, long &rLeft, long &rTop, long &rRight, long &rBottom)
Definition: splitwin.cxx:145
void SetPoint(const Point &rPt, sal_uInt16 nPos)
long AdjustHeight(long n)
Point GetPosPixel() const override
Definition: dockwin.cxx:845
void StartTracking(StartTrackingFlags nFlags=StartTrackingFlags::NONE)
Definition: window2.cxx:244
AntialiasingFlags GetAntialiasing() const
Definition: outdev.hxx:592
HelpEventMode GetMode() const
Definition: event.hxx:192
bool IsTracking() const
Definition: window2.cxx:312
sal_uInt16 mnSplitPos
Definition: splitwin.hxx:66
SAL_DLLPRIVATE void ImplNewAlign()
Definition: splitwin.cxx:2740
long AdjustBottom(long nVertMoveDelta)
void DrawWallpaper(const tools::Rectangle &rRect, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:42
bool IsEmpty() const
WinBits mnWinStyle
Definition: splitwin.hxx:63
StateChangedType
Definition: window.hxx:309
sal_uInt16 GetClicks() const
Definition: event.hxx:120
sal_Int64 WinBits
void SetBackground()
bool mbFadeIn
Definition: splitwin.hxx:68
long Right() const
sal_uInt16 mnId
Definition: splitwin.cxx:87
ImplSplitSet * mpSplitSet
Definition: splitwin.hxx:50
SAL_DLLPRIVATE void ImplDrawSplitTracking(const Point &rPos)
Definition: splitwin.cxx:1093
sal_uInt16 GetButtons() const
Definition: event.hxx:131
static void ImplCalcLogSize(std::vector< ImplSplitItem > &rItems, size_t nItems)
Definition: splitwin.cxx:815
void setX(long nX)
#define SPLITWIN_SPLITSIZEFADE
Definition: splitwin.cxx:39
bool IsEnterWindow() const
Definition: event.hxx:122
void ShowTracking(const tools::Rectangle &rRect, ShowTrackFlags nFlags=ShowTrackFlags::Small)
Definition: window2.cxx:124
void ShowFadeOutButton()
Definition: splitwin.cxx:2788
SAL_DLLPRIVATE void ImplSplitMousePos(Point &rMousePos)
Definition: splitwin.cxx:1422
void Hide()
Definition: window.hxx:930
SAL_DLLPRIVATE void ImplDrawBorder(vcl::RenderContext &rRenderContext)
Definition: splitwin.cxx:178
AllSettingsFlags GetFlags() const
Definition: event.hxx:349
SAL_DLLPRIVATE void ImplDrawFadeIn(vcl::RenderContext &rRenderContext)
Definition: splitwin.cxx:1615
long mnMaxSize
Maximal width or height of the item. -1 means no restriction.
Definition: splitwin.cxx:73
const Color & GetLightColor() const
long mnMouseOff
Definition: splitwin.hxx:60
bool mbFadeOutDown
Definition: splitwin.hxx:68
bool mbSubSize
Definition: splitwin.cxx:69
long mnRightBorder
Definition: splitwin.hxx:57
long Top() const
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: splitwin.cxx:2124
WinBits const WB_NOSPLITDRAW
#define SPLIT_WINDOW
Definition: splitwin.cxx:43
void RemoveItem(sal_uInt16 nId)
Definition: splitwin.cxx:2298
void setY(long nY)
std::unique_ptr< ImplSplitSet > mpMainSet
Definition: splitwin.hxx:48
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: splitwin.cxx:1128
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:88
SplitWindowItemFlags
Definition: splitwin.hxx:29
if(nullptr==pCandidateA||nullptr==pCandidateB)
Size GetOutputSizePixel() const
Definition: dockwin.cxx:897
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:32
virtual void MouseMove(const MouseEvent &rMEvt) override
Definition: splitwin.cxx:1914
void ShowFadeInHideButton()
Definition: splitwin.cxx:2782
SplitWindowItemFlags mnBits
Definition: splitwin.cxx:67
void Update()
Definition: paint.cxx:1273
const Point & GetMousePosPixel() const
Definition: event.hxx:191
#define SPLITWINDOW_ITEM_NOTFOUND
Definition: splitwin.hxx:43
long mnSplitPos
Definition: splitwin.cxx:57
bool IsItemValid(sal_uInt16 nId) const
Definition: splitwin.cxx:2684
const Color & GetDarkShadowColor() const
long mnLeftBorder
Definition: splitwin.hxx:55
NONE
void SetLineColor()
void clear()
Definition: vclptr.hxx:190
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: dockwin.cxx:386
void SetTop(long v)
bool IsLeaveWindow() const
Definition: event.hxx:124
static ImplSplitSet * ImplFindSet(ImplSplitSet *pSet, sal_uInt16 nId)
Definition: splitwin.cxx:270
long AdjustY(long nVertMove)
long mnLastSize
Definition: splitwin.cxx:85
bool IsMod2() const
Definition: event.hxx:146
long mnOldSplitPos
Definition: splitwin.cxx:59
void SetParent(vcl::Window *pNewParent)
Definition: stacking.cxx:831
int i
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1153
void SetRight(long v)
long mnMaxSize
Definition: splitwin.hxx:59
SAL_DLLPRIVATE void ImplCalcLayout()
Definition: splitwin.cxx:1328
bool IsUpdateMode() const
Definition: window2.cxx:1167
void SetFillColor()
AntialiasingFlags
Definition: outdev.hxx:231
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
SAL_DLLPRIVATE void ImplSetWindowSize(long nDelta)
Definition: splitwin.cxx:1227
long Bottom() const
Link< SplitWindow *, void > maSplitHdl
Definition: splitwin.hxx:81
static SAL_DLLPRIVATE sal_uInt16 ImplTestSplit(ImplSplitSet *pSet, const Point &rPos, long &rMouseOff, ImplSplitSet **ppFoundSet, sal_uInt16 &rFoundPos, bool bRows)
Definition: splitwin.cxx:954
long const nBorder
static ImplSplitSet * ImplFindItem(ImplSplitSet *pSet, sal_uInt16 nId, sal_uInt16 &rPos)
Definition: splitwin.cxx:296
Size CalcLayoutSizePixel(const Size &aNewSize)
Definition: splitwin.cxx:1267
bool mbHorz
Definition: splitwin.hxx:68
MouseNotifyEvent GetType() const
Definition: event.hxx:294
bool IsInside(const Point &rPOINT) const
bool mbFadeOut
Definition: splitwin.hxx:68
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: splitwin.cxx:1220
long mnMinSize
Minimal width or height of the item. -1 means no restriction.
Definition: splitwin.cxx:71
const AllSettings & GetSettings() const
Definition: outdev.hxx:420
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
long mnMSplitPos
Definition: splitwin.hxx:62
void SetAlign(WindowAlign eNewAlign)
Definition: splitwin.cxx:2773
virtual void RequestHelp(const HelpEvent &rHEvt) override
Definition: splitwin.cxx:2153
WindowAlign meAlign
Definition: splitwin.hxx:64
std::unique_ptr< ImplSplitSet > mpSet
Definition: splitwin.cxx:63
sal_uInt16 GetModifier() const
Definition: event.hxx:140
bool mbFadeNoButtonMode
Definition: splitwin.hxx:68
long mnOldHeight
Definition: splitwin.cxx:62
sal_uInt32 const mnSize
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2824
bool KeyboardActivated() const
Definition: event.hxx:193
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
Definition: help.cxx:178
vcl::Window * GetParent() const
Definition: window2.cxx:1091
virtual void Split()
Definition: splitwin.cxx:1854
bool mbBottomRight
Definition: splitwin.hxx:68
long X() const
bool mbCalcPix
Definition: splitwin.cxx:88
bool IsReallyShown() const
Definition: window2.cxx:1106
bool IsTrackingEnded() const
Definition: event.hxx:254
virtual void StateChanged(StateChangedType nType) override
Definition: dockwin.cxx:653
virtual void Resize() override
Definition: splitwin.cxx:2143
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1262
virtual ~SplitWindow() override
Definition: splitwin.cxx:1215
sal_uInt16 GetSet(sal_uInt16 nId) const
Definition: splitwin.cxx:2673
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: splitwin.cxx:1871
sal_Int32 mnTop
WinBits const WB_3DLOOK
long mnSplitSize
Definition: splitwin.cxx:86
WinBits const WB_SIZEABLE
bool IsModifierChanged() const
Definition: event.hxx:128
long Max() const
std::unique_ptr< Wallpaper > mpWallpaper
Definition: splitwin.cxx:84
void SetPointer(PointerStyle)
Definition: mouse.cxx:473
Size GetSizePixel() const override
Definition: dockwin.cxx:862
long mnBottomBorder
Definition: splitwin.hxx:58
long AdjustRight(long nHorzMoveDelta)
SAL_DLLPRIVATE void ImplInitSettings()
Definition: splitwin.cxx:1187
WindowType
long mnOldSplitSize
Definition: splitwin.cxx:60
long * mpLastSizes
Definition: splitwin.hxx:51
bool IsSynthetic() const
Definition: event.hxx:126
bool mbFadeOutPressed
Definition: splitwin.hxx:68
#define SAL_WARN_IF(condition, area, stream)
SAL_DLLPRIVATE void ImplDrawBack(vcl::RenderContext &rRenderContext, ImplSplitSet *pSet)
Definition: splitwin.cxx:851
SAL_DLLPRIVATE void ImplDrawBorderLine(vcl::RenderContext &rRenderContext)
Definition: splitwin.cxx:228
std::vector< ImplSplitItem > mvItems
Definition: splitwin.cxx:83
WinBits const WB_BORDER
sal_uInt16 GetItemId(vcl::Window *pWindow) const
Definition: splitwin.cxx:2692
sal_uInt16 const mnId
const MouseEvent * GetMouseEvent() const
Definition: event.hxx:310
#define SPLITWIN_SPLITSIZEEXLN
Definition: splitwin.cxx:37
bool IsLeft() const
Definition: event.hxx:133
double mnWidth
long mnMStartPos
Definition: splitwin.hxx:61
VclPtr< vcl::Window > mpWindow
Definition: splitwin.cxx:64
void SetBottom(long v)
virtual void StateChanged(StateChangedType nType) override
Definition: splitwin.cxx:2195
long AdjustTop(long nVertMoveDelta)
const Color & GetWindowColor() const
const Point & GetPosPixel() const
Definition: event.hxx:117
long Left() const
PointerStyle
Definition: ptrstyle.hxx:25
SAL_DLLPRIVATE void ImplUpdate()
Definition: splitwin.cxx:1409
long GetItemSize(sal_uInt16 nId) const
Definition: splitwin.cxx:2597
SAL_DLLPRIVATE void ImplDrawFadeOut(vcl::RenderContext &rRenderContext)
Definition: splitwin.cxx:1640
sal_uInt16 GetItemPos(sal_uInt16 nId, sal_uInt16 nSetId=0) const
Definition: splitwin.cxx:2702
void SetLeft(long v)
bool IsTrackingCanceled() const
Definition: event.hxx:256
OUString VclResId(const char *pId)
Definition: svdata.cxx:258
long GetFadeInSize() const
Definition: splitwin.cxx:2794
void SetItemSize(sal_uInt16 nId, long nNewSize)
Definition: splitwin.cxx:2577
SAL_DLLPRIVATE void ImplDrawGrip(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect, bool bHorz, bool bLeft)
Definition: splitwin.cxx:1534
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2818
#define SPLITWIN_SPLITSIZE
Definition: splitwin.cxx:35
SAL_DLLPRIVATE void SetIdleDebugName(const sal_Char *pDebugName)
Definition: dockwin.hxx:372
Point GetLastPointerPosPixel()
Definition: mouse.cxx:560
bool mbFadeInDown
Definition: splitwin.hxx:68
long Min() const
virtual void FadeIn()
Definition: splitwin.cxx:1863
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: dockwin.cxx:677
const MouseEvent & GetMouseEvent() const
Definition: event.hxx:250
bool IsReallyVisible() const
Definition: window2.cxx:1101
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: splitwin.cxx:2095
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: dockwin.cxx:308
sal_uInt16 GetItemCount(sal_uInt16 nSetId=0) const
Definition: splitwin.cxx:2731
sal_Int32 nPos
virtual void RequestHelp(const HelpEvent &rHEvt)
Definition: window.cxx:1832
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: splitwin.cxx:2217
WinBits const WB_CLIPCHILDREN
aStr
long mnOldWidth
Definition: splitwin.cxx:61
tools::Rectangle maDragRect
Definition: splitwin.hxx:52
Point Center() const
long Y() const
#define SPLITWIN_SPLITSIZEEX
Definition: splitwin.cxx:36
static void ImplCalcSet(ImplSplitSet *pSet, long nSetLeft, long nSetTop, long nSetWidth, long nSetHeight, bool bRows, bool bDown=true)
Definition: splitwin.cxx:388
static void ImplDrawSplit(vcl::RenderContext &rRenderContext, ImplSplitSet *pSet, bool bRows, bool bDown)
Definition: splitwin.cxx:874
static void ShowBalloon(vcl::Window *pParent, const Point &rScreenPos, const tools::Rectangle &, const OUString &rHelpText)
Definition: help.cxx:155
virtual void SplitResize()
Definition: splitwin.cxx:1859
SAL_DLLPRIVATE void ImplStartSplit(const MouseEvent &rMEvt)
Definition: splitwin.cxx:1665
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2150
void SplitItem(sal_uInt16 nId, long nNewSize, bool bPropSmall, bool bPropGreat)
Definition: splitwin.cxx:2351