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