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