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