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