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