LibreOffice Module vcl (master)  1
layout.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 
10 #include <config_features.h>
11 #include <com/sun/star/accessibility/AccessibleRole.hpp>
12 #include <comphelper/base64.hxx>
13 #include <o3tl/enumarray.hxx>
14 #include <o3tl/enumrange.hxx>
15 #include <tools/stream.hxx>
16 #include <vcl/builder.hxx>
17 #include <vcl/toolkit/button.hxx>
18 #include <vcl/cvtgrf.hxx>
19 #include <vcl/decoview.hxx>
20 #include <vcl/toolkit/dialog.hxx>
21 #include <vcl/layout.hxx>
22 #include <vcl/scrbar.hxx>
23 #include <vcl/stdtext.hxx>
24 #include <vcl/split.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/virdev.hxx>
28 #include <bitmaps.hlst>
29 #include <messagedialog.hxx>
30 #include <svdata.hxx>
31 #include <window.h>
32 #include <boost/multi_array.hpp>
33 #include <vcl/toolkit/vclmedit.hxx>
34 #include <vcl/uitest/uiobject.hxx>
35 #include <sal/log.hxx>
36 #include <tools/json_writer.hxx>
37 
40  , m_bLayoutDirty(true)
41 {
42  ImplInit(pParent, nStyle, nullptr);
44  SetPaintTransparent(true);
45  SetBackground();
46 }
47 
49 {
50  return css::accessibility::AccessibleRole::PANEL;
51 }
52 
54 {
55  return calculateRequisition();
56 }
57 
58 void VclContainer::setLayoutPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
59 {
60  sal_Int32 nBorderWidth = rWindow.get_border_width();
61  sal_Int32 nLeft = rWindow.get_margin_start() + nBorderWidth;
62  sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
63  sal_Int32 nRight = rWindow.get_margin_end() + nBorderWidth;
64  sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
65  Point aPos(rPos.X() + nLeft, rPos.Y() + nTop);
66  Size aSize(rSize.Width() - nLeft - nRight, rSize.Height() - nTop - nBottom);
67  rWindow.SetPosSizePixel(aPos, aSize);
68 }
69 
70 void VclContainer::setLayoutAllocation(vcl::Window &rChild, const Point &rAllocPos, const Size &rChildAlloc)
71 {
72  VclAlign eHalign = rChild.get_halign();
73  VclAlign eValign = rChild.get_valign();
74 
75  //typical case
76  if (eHalign == VclAlign::Fill && eValign == VclAlign::Fill)
77  {
78  setLayoutPosSize(rChild, rAllocPos, rChildAlloc);
79  return;
80  }
81 
82  Point aChildPos(rAllocPos);
83  Size aChildSize(rChildAlloc);
84  Size aChildPreferredSize(getLayoutRequisition(rChild));
85 
86  switch (eHalign)
87  {
88  case VclAlign::Fill:
89  break;
90  case VclAlign::Start:
91  if (aChildPreferredSize.Width() < rChildAlloc.Width())
92  aChildSize.setWidth( aChildPreferredSize.Width() );
93  break;
94  case VclAlign::End:
95  if (aChildPreferredSize.Width() < rChildAlloc.Width())
96  aChildSize.setWidth( aChildPreferredSize.Width() );
97  aChildPos.AdjustX(rChildAlloc.Width() );
98  aChildPos.AdjustX( -(aChildSize.Width()) );
99  break;
100  case VclAlign::Center:
101  if (aChildPreferredSize.Width() < aChildSize.Width())
102  aChildSize.setWidth( aChildPreferredSize.Width() );
103  aChildPos.AdjustX((rChildAlloc.Width() - aChildSize.Width()) / 2 );
104  break;
105  }
106 
107  switch (eValign)
108  {
109  case VclAlign::Fill:
110  break;
111  case VclAlign::Start:
112  if (aChildPreferredSize.Height() < rChildAlloc.Height())
113  aChildSize.setHeight( aChildPreferredSize.Height() );
114  break;
115  case VclAlign::End:
116  if (aChildPreferredSize.Height() < rChildAlloc.Height())
117  aChildSize.setHeight( aChildPreferredSize.Height() );
118  aChildPos.AdjustY(rChildAlloc.Height() );
119  aChildPos.AdjustY( -(aChildSize.Height()) );
120  break;
121  case VclAlign::Center:
122  if (aChildPreferredSize.Height() < aChildSize.Height())
123  aChildSize.setHeight( aChildPreferredSize.Height() );
124  aChildPos.AdjustY((rChildAlloc.Height() - aChildSize.Height()) / 2 );
125  break;
126  }
127 
128  setLayoutPosSize(rChild, aChildPos, aChildSize);
129 }
130 
131 namespace
132 {
133  Size subtractBorder(const vcl::Window &rWindow, const Size& rSize)
134  {
135  sal_Int32 nBorderWidth = rWindow.get_border_width();
136  sal_Int32 nLeft = rWindow.get_margin_start() + nBorderWidth;
137  sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
138  sal_Int32 nRight = rWindow.get_margin_end() + nBorderWidth;
139  sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
140  Size aSize(rSize);
141  return Size(aSize.Width() + nLeft + nRight, aSize.Height() + nTop + nBottom);
142  }
143 }
144 
146 {
147  return subtractBorder(rWindow, rWindow.get_preferred_size());
148 }
149 
150 void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
151 {
152  bool bSizeChanged = rAllocation != GetOutputSizePixel();
153  Window::SetPosSizePixel(rAllocPos, rAllocation);
154  if (m_bLayoutDirty || bSizeChanged)
155  {
156  m_bLayoutDirty = false;
157  setAllocation(rAllocation);
158  }
159 }
160 
161 void VclContainer::SetPosPixel(const Point& rAllocPos)
162 {
163  Point aAllocPos = rAllocPos;
164  sal_Int32 nBorderWidth = get_border_width();
165  aAllocPos.AdjustX(nBorderWidth + get_margin_start() );
166  aAllocPos.AdjustY(nBorderWidth + get_margin_top() );
167 
168  if (aAllocPos != GetPosPixel())
169  Window::SetPosPixel(aAllocPos);
170 }
171 
172 void VclContainer::SetSizePixel(const Size& rAllocation)
173 {
174  Size aAllocation = rAllocation;
175  sal_Int32 nBorderWidth = get_border_width();
176  aAllocation.AdjustWidth( -(nBorderWidth*2 + get_margin_start() + get_margin_end()) );
177  aAllocation.AdjustHeight( -(nBorderWidth*2 + get_margin_top() + get_margin_bottom()) );
178  bool bSizeChanged = aAllocation != GetSizePixel();
179  if (bSizeChanged)
180  Window::SetSizePixel(aAllocation);
181  if (m_bLayoutDirty || bSizeChanged)
182  {
183  m_bLayoutDirty = false;
184  setAllocation(aAllocation);
185  }
186 }
187 
189 {
190  m_bLayoutDirty = true;
191  Window::queue_resize(eReason);
192 }
193 
194 // support for screenshot context menu
196 {
198  {
199  auto pParent = GetParent();
200  if (pParent)
201  {
202  CommandEvent aCEvt(rCEvt.GetMousePosPixel() + GetPosPixel(), rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetEventData());
203  pParent->Command(aCEvt);
204  return;
205  }
206  }
207 
208  // call parent (do not consume)
209  Window::Command(rCEvt);
210 }
211 
212 void VclBox::accumulateMaxes(const Size &rChildSize, Size &rSize) const
213 {
214  tools::Long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
215  tools::Long nSecondaryBoxDimension = getSecondaryDimension(rSize);
216  setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
217 
218  tools::Long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
219  tools::Long nPrimaryBoxDimension = getPrimaryDimension(rSize);
220  if (m_bHomogeneous)
221  setPrimaryDimension(rSize, std::max(nPrimaryBoxDimension, nPrimaryChildDimension));
222  else
223  setPrimaryDimension(rSize, nPrimaryBoxDimension + nPrimaryChildDimension);
224 }
225 
227 {
228  sal_uInt16 nVisibleChildren = 0;
229 
230  Size aSize;
231  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
232  {
233  if (!pChild->IsVisible())
234  continue;
235  ++nVisibleChildren;
236  Size aChildSize = getLayoutRequisition(*pChild);
237 
238  tools::Long nPrimaryDimension = getPrimaryDimension(aChildSize);
239  nPrimaryDimension += pChild->get_padding() * 2;
240  setPrimaryDimension(aChildSize, nPrimaryDimension);
241 
242  accumulateMaxes(aChildSize, aSize);
243  }
244 
245  return finalizeMaxes(aSize, nVisibleChildren);
246 }
247 
248 void VclBox::setAllocation(const Size &rAllocation)
249 {
250  sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;
251  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
252  {
253  if (!pChild->IsVisible())
254  continue;
255  ++nVisibleChildren;
256  bool bExpand = getPrimaryDimensionChildExpand(*pChild);
257  if (bExpand)
258  ++nExpandChildren;
259  }
260 
261  if (!nVisibleChildren)
262  return;
263 
264  tools::Long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
265 
266  tools::Long nHomogeneousDimension = 0, nExtraSpace = 0;
267  if (m_bHomogeneous)
268  {
269  nHomogeneousDimension = (nAllocPrimaryDimension -
270  (nVisibleChildren - 1) * m_nSpacing) / nVisibleChildren;
271  }
272  else if (nExpandChildren)
273  {
274  Size aRequisition = calculateRequisition();
275  nExtraSpace = (getPrimaryDimension(rAllocation) - getPrimaryDimension(aRequisition)) / nExpandChildren;
276 // In mobile, the screen size is small and extraSpace can become negative
277 // Though the dialogs are rendered in javascript for LOK Android some widgets like weld::DrawingArea
278 // is sent as bitmap but it is rendered from only the visible part
279 // when it gets negative, it shrinks instead of expands and it becomes invisible
280 #if HAVE_FEATURE_ANDROID_LOK
281  if (nExtraSpace < 0)
282  nExtraSpace = 0;
283 #endif
284  }
285 
286  //Split into those we pack from the start onwards, and those we pack from the end backwards
288  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
289  {
290  if (!pChild->IsVisible())
291  continue;
292 
293  VclPackType ePacking = pChild->get_pack_type();
294  aWindows[ePacking].push_back(pChild);
295  }
296 
297  //See VclBuilder::sortIntoBestTabTraversalOrder for why they are in visual
298  //order under the parent which requires us to reverse them here to
299  //pack from the end back
300  std::reverse(aWindows[VclPackType::End].begin(),aWindows[VclPackType::End].end());
301 
302  for (VclPackType ePackType : o3tl::enumrange<VclPackType>())
303  {
304  Point aPos(0, 0);
305  if (ePackType == VclPackType::End)
306  {
307  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
308  setPrimaryCoordinate(aPos, nPrimaryCoordinate + nAllocPrimaryDimension);
309  }
310 
311  for (auto const& window : aWindows[ePackType])
312  {
313  vcl::Window *pChild = window;
314 
315  tools::Long nPadding = pChild->get_padding();
316 
317  Size aBoxSize;
318  if (m_bHomogeneous)
319  setPrimaryDimension(aBoxSize, nHomogeneousDimension);
320  else
321  {
322  aBoxSize = getLayoutRequisition(*pChild);
323  tools::Long nPrimaryDimension = getPrimaryDimension(aBoxSize);
324  nPrimaryDimension += nPadding * 2;
325  if (getPrimaryDimensionChildExpand(*pChild))
326  nPrimaryDimension += nExtraSpace;
327  setPrimaryDimension(aBoxSize, nPrimaryDimension);
328  }
329  setSecondaryDimension(aBoxSize, getSecondaryDimension(rAllocation));
330 
331  Point aChildPos(aPos);
332  Size aChildSize(aBoxSize);
333  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
334 
335  bool bFill = pChild->get_fill();
336  if (bFill)
337  {
338  setPrimaryDimension(aChildSize, std::max(static_cast<tools::Long>(1),
339  std::min(getPrimaryDimension(rAllocation), getPrimaryDimension(aBoxSize) - nPadding * 2)));
340 
341  setPrimaryCoordinate(aChildPos, nPrimaryCoordinate + nPadding);
342  }
343  else
344  {
345  setPrimaryDimension(aChildSize,
347 
348  setPrimaryCoordinate(aChildPos, nPrimaryCoordinate +
349  (getPrimaryDimension(aBoxSize) - getPrimaryDimension(aChildSize)) / 2);
350  }
351 
352  tools::Long nDiff = getPrimaryDimension(aBoxSize) + m_nSpacing;
353  if (ePackType == VclPackType::Start)
354  setPrimaryCoordinate(aPos, nPrimaryCoordinate + nDiff);
355  else
356  {
357  setPrimaryCoordinate(aPos, nPrimaryCoordinate - nDiff);
358  setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) -
359  getPrimaryDimension(aBoxSize));
360  }
361 
362  setLayoutAllocation(*pChild, aChildPos, aChildSize);
363  }
364  }
365 }
366 
367 bool VclBox::set_property(const OString &rKey, const OUString &rValue)
368 {
369  if (rKey == "spacing")
370  set_spacing(rValue.toInt32());
371  else if (rKey == "homogeneous")
372  set_homogeneous(toBool(rValue));
373  else
374  return VclContainer::set_property(rKey, rValue);
375  return true;
376 }
377 
379 {
381  rJsonWriter.put("vertical", m_bVerticalContainer);
382 }
383 
385 {
386 #if defined(_WIN32)
387  //fdo#74284 call Boxes Panels, keep then as "Filler" under
388  //at least Linux seeing as that's what Gtk does for GtkBoxes
389  return css::accessibility::AccessibleRole::PANEL;
390 #else
391  return css::accessibility::AccessibleRole::FILLER;
392 #endif
393 }
394 
395 #define DEFAULT_CHILD_MIN_WIDTH 85
396 #define DEFAULT_CHILD_MIN_HEIGHT 27
397 
398 Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
399 {
400  Size aRet;
401 
402  if (nVisibleChildren)
403  {
404  tools::Long nPrimaryDimension = getPrimaryDimension(rSize);
405  if (m_bHomogeneous)
406  nPrimaryDimension *= nVisibleChildren;
407  setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
409  }
410 
411  return aRet;
412 }
413 
415 {
416  Size aRet;
417 
418  tools::Long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
419  tools::Long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
420 
421  setPrimaryDimension(aRet, nMainGroupDimension + nSubGroupDimension);
422 
426 
427  return aRet;
428 }
429 
430 static tools::Long getMaxNonOutlier(const std::vector<tools::Long> &rG, tools::Long nAvgDimension)
431 {
432  tools::Long nMaxDimensionNonOutlier = 0;
433  for (auto const& nPrimaryChildDimension : rG)
434  {
435  if (nPrimaryChildDimension < nAvgDimension * 1.5)
436  {
437  nMaxDimensionNonOutlier = std::max(nPrimaryChildDimension,
438  nMaxDimensionNonOutlier);
439  }
440  }
441  return nMaxDimensionNonOutlier;
442 }
443 
444 static std::vector<tools::Long> setButtonSizes(const std::vector<tools::Long> &rG,
445  const std::vector<bool> &rNonHomogeneous,
446  tools::Long nAvgDimension, tools::Long nMaxNonOutlier, tools::Long nMinWidth)
447 {
448  std::vector<tools::Long> aVec;
449  //set everything < 1.5 times the average to the same width, leave the
450  //outliers un-touched
451  std::vector<bool>::const_iterator aJ = rNonHomogeneous.begin();
452  auto nNonOutlierWidth = std::max(nMaxNonOutlier, nMinWidth);
453  for (auto const& nPrimaryChildDimension : rG)
454  {
455  bool bNonHomogeneous = *aJ;
456  if (!bNonHomogeneous && nPrimaryChildDimension < nAvgDimension * 1.5)
457  {
458  aVec.push_back(nNonOutlierWidth);
459  }
460  else
461  {
462  aVec.push_back(std::max(nPrimaryChildDimension, nMinWidth));
463  }
464  ++aJ;
465  }
466  return aVec;
467 }
468 
470 {
471  Requisition aReq;
472 
473  Size aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
474  Size aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
475 
476  tools::Long nMinMainGroupPrimary = getPrimaryDimension(aMainGroupSize);
477  tools::Long nMinSubGroupPrimary = getPrimaryDimension(aSubGroupSize);
478  tools::Long nMainGroupSecondary = getSecondaryDimension(aMainGroupSize);
479  tools::Long nSubGroupSecondary = getSecondaryDimension(aSubGroupSize);
480 
481  bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VclButtonBoxStyle::Spread || m_eLayoutStyle == VclButtonBoxStyle::Center);
482 
483  std::vector<tools::Long> aMainGroupSizes;
484  std::vector<bool> aMainGroupNonHomogeneous;
485  std::vector<tools::Long> aSubGroupSizes;
486  std::vector<bool> aSubGroupNonHomogeneous;
487 
488  for (const vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
489  {
490  if (!pChild->IsVisible())
491  continue;
492  Size aChildSize = getLayoutRequisition(*pChild);
493  if (bIgnoreSecondaryPacking || !pChild->get_secondary())
494  {
495  //set the max secondary dimension
496  nMainGroupSecondary = std::max(nMainGroupSecondary, getSecondaryDimension(aChildSize));
497  //collect the primary dimensions
498  aMainGroupSizes.push_back(getPrimaryDimension(aChildSize));
499  aMainGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
500  }
501  else
502  {
503  nSubGroupSecondary = std::max(nSubGroupSecondary, getSecondaryDimension(aChildSize));
504  aSubGroupSizes.push_back(getPrimaryDimension(aChildSize));
505  aSubGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
506  }
507  }
508 
509  if (m_bHomogeneous)
510  {
511  tools::Long nMaxMainDimension = aMainGroupSizes.empty() ? 0 :
512  *std::max_element(aMainGroupSizes.begin(), aMainGroupSizes.end());
513  nMaxMainDimension = std::max(nMaxMainDimension, nMinMainGroupPrimary);
514  tools::Long nMaxSubDimension = aSubGroupSizes.empty() ? 0 :
515  *std::max_element(aSubGroupSizes.begin(), aSubGroupSizes.end());
516  nMaxSubDimension = std::max(nMaxSubDimension, nMinSubGroupPrimary);
517  tools::Long nMaxDimension = std::max(nMaxMainDimension, nMaxSubDimension);
518  aReq.m_aMainGroupDimensions.resize(aMainGroupSizes.size(), nMaxDimension);
519  aReq.m_aSubGroupDimensions.resize(aSubGroupSizes.size(), nMaxDimension);
520  }
521  else
522  {
523  //Ideally set everything to the same size, but find outlier widgets
524  //that are way wider than the average and leave them
525  //at their natural size and set the remainder to share the
526  //max size of the remaining members of the buttonbox
527  tools::Long nAccDimension = std::accumulate(aMainGroupSizes.begin(),
528  aMainGroupSizes.end(), 0);
529  nAccDimension = std::accumulate(aSubGroupSizes.begin(),
530  aSubGroupSizes.end(), nAccDimension);
531 
532  size_t nTotalSize = aMainGroupSizes.size() + aSubGroupSizes.size();
533 
534  tools::Long nAvgDimension = nTotalSize ? nAccDimension / nTotalSize : 0;
535 
536  tools::Long nMaxMainNonOutlier = getMaxNonOutlier(aMainGroupSizes,
537  nAvgDimension);
538  tools::Long nMaxSubNonOutlier = getMaxNonOutlier(aSubGroupSizes,
539  nAvgDimension);
540  tools::Long nMaxNonOutlier = std::max(nMaxMainNonOutlier, nMaxSubNonOutlier);
541 
542  aReq.m_aMainGroupDimensions = setButtonSizes(aMainGroupSizes,
543  aMainGroupNonHomogeneous,
544  nAvgDimension, nMaxNonOutlier, nMinMainGroupPrimary);
545  aReq.m_aSubGroupDimensions = setButtonSizes(aSubGroupSizes,
546  aSubGroupNonHomogeneous,
547  nAvgDimension, nMaxNonOutlier, nMinSubGroupPrimary);
548  }
549 
550  if (!aReq.m_aMainGroupDimensions.empty())
551  {
552  setSecondaryDimension(aReq.m_aMainGroupSize, nMainGroupSecondary);
554  std::accumulate(aReq.m_aMainGroupDimensions.begin(),
555  aReq.m_aMainGroupDimensions.end(), 0));
556  }
557  if (!aReq.m_aSubGroupDimensions.empty())
558  {
559  setSecondaryDimension(aReq.m_aSubGroupSize, nSubGroupSecondary);
561  std::accumulate(aReq.m_aSubGroupDimensions.begin(),
562  aReq.m_aSubGroupDimensions.end(), 0));
563  }
564 
565  return aReq;
566 }
567 
568 Size VclButtonBox::addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
569 {
570  Size aRet;
571 
572  if (nVisibleChildren)
573  {
574  tools::Long nPrimaryDimension = getPrimaryDimension(rSize);
575  setPrimaryDimension(aRet,
576  nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
578  }
579 
580  return aRet;
581 }
582 
584 {
586  sal_uInt16 nVisibleChildren = aReq.m_aMainGroupDimensions.size() +
587  aReq.m_aSubGroupDimensions.size();
588  return addSpacing(addReqGroups(aReq), nVisibleChildren);
589 }
590 
591 bool VclButtonBox::set_property(const OString &rKey, const OUString &rValue)
592 {
593  if (rKey == "layout-style")
594  {
596  if (rValue == "spread")
597  eStyle = VclButtonBoxStyle::Spread;
598  else if (rValue == "edge")
599  eStyle = VclButtonBoxStyle::Edge;
600  else if (rValue == "start")
601  eStyle = VclButtonBoxStyle::Start;
602  else if (rValue == "end")
603  eStyle = VclButtonBoxStyle::End;
604  else if (rValue == "center")
605  eStyle = VclButtonBoxStyle::Center;
606  else
607  {
608  SAL_WARN("vcl.layout", "unknown layout style " << rValue);
609  }
610  m_eLayoutStyle = eStyle;
611  }
612  else
613  return VclBox::set_property(rKey, rValue);
614  return true;
615 }
616 
617 void VclButtonBox::setAllocation(const Size &rAllocation)
618 {
620 
621  if (aReq.m_aMainGroupDimensions.empty() && aReq.m_aSubGroupDimensions.empty())
622  return;
623 
624  tools::Long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
625 
626  Point aMainGroupPos, aOtherGroupPos;
627  int nSpacing = m_nSpacing;
628 
629  //To-Do, other layout styles
630  switch (m_eLayoutStyle)
631  {
633  if (!aReq.m_aSubGroupDimensions.empty())
634  {
635  tools::Long nOtherPrimaryDimension = getPrimaryDimension(
637  setPrimaryCoordinate(aOtherGroupPos,
638  nAllocPrimaryDimension - nOtherPrimaryDimension);
639  }
640  break;
642  if (!aReq.m_aMainGroupDimensions.empty())
643  {
644  tools::Long nMainPrimaryDimension = getPrimaryDimension(
646  tools::Long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
647  nExtraSpace += (aReq.m_aMainGroupDimensions.size()-1) * nSpacing;
648  nSpacing = nExtraSpace/(aReq.m_aMainGroupDimensions.size()+1);
649  setPrimaryCoordinate(aMainGroupPos, nSpacing);
650  }
651  break;
653  if (!aReq.m_aMainGroupDimensions.empty())
654  {
655  tools::Long nMainPrimaryDimension = getPrimaryDimension(
657  tools::Long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
658  setPrimaryCoordinate(aMainGroupPos, nExtraSpace/2);
659  }
660  break;
661  default:
662  SAL_WARN("vcl.layout", "todo unimplemented layout style");
663  [[fallthrough]];
666  if (!aReq.m_aMainGroupDimensions.empty())
667  {
668  tools::Long nMainPrimaryDimension = getPrimaryDimension(
670  setPrimaryCoordinate(aMainGroupPos,
671  nAllocPrimaryDimension - nMainPrimaryDimension);
672  }
673  break;
674  }
675 
676  Size aChildSize;
677  setSecondaryDimension(aChildSize, getSecondaryDimension(rAllocation));
678 
679  std::vector<tools::Long>::const_iterator aPrimaryI = aReq.m_aMainGroupDimensions.begin();
680  std::vector<tools::Long>::const_iterator aSecondaryI = aReq.m_aSubGroupDimensions.begin();
681  bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VclButtonBoxStyle::Spread || m_eLayoutStyle == VclButtonBoxStyle::Center);
682  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
683  {
684  if (!pChild->IsVisible())
685  continue;
686 
687  if (bIgnoreSecondaryPacking || !pChild->get_secondary())
688  {
689  tools::Long nMainGroupPrimaryDimension = *aPrimaryI++;
690  setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
691  setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
692  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
693  setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + nSpacing);
694  }
695  else
696  {
697  tools::Long nSubGroupPrimaryDimension = *aSecondaryI++;
698  setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
699  setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
700  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
701  setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + nSpacing);
702  }
703  }
704 }
705 
707 {
708  VclBox::DumpAsPropertyTree(rJsonWriter);
709  rJsonWriter.put("type", "buttonbox");
710 
711  switch(m_eLayoutStyle)
712  {
714  rJsonWriter.put("layoutstyle", "default");
715  break;
716 
718  rJsonWriter.put("layoutstyle", "spread");
719  break;
720 
722  rJsonWriter.put("layoutstyle", "edge");
723  break;
724 
726  rJsonWriter.put("layoutstyle", "center");
727  break;
728 
730  rJsonWriter.put("layoutstyle", "start");
731  break;
732 
734  rJsonWriter.put("layoutstyle", "end");
735  break;
736  }
737 }
738 
739 namespace {
740 
741 struct ButtonOrder
742 {
743  const char* m_aType;
744  int m_nPriority;
745 };
746 
747 }
748 
749 static int getButtonPriority(const OString &rType)
750 {
751  static const size_t N_TYPES = 6;
752  static const ButtonOrder aDiscardCancelSave[N_TYPES] =
753  {
754  { "/discard", 0 },
755  { "/cancel", 1 },
756  { "/no", 2 },
757  { "/save", 3 },
758  { "/yes", 3 },
759  { "/ok", 3 }
760  };
761 
762  static const ButtonOrder aSaveDiscardCancel[N_TYPES] =
763  {
764  { "/save", 0 },
765  { "/yes", 0 },
766  { "/ok", 0 },
767  { "/discard", 1 },
768  { "/no", 1 },
769  { "/cancel", 2 }
770  };
771 
772  const ButtonOrder* pOrder = &aDiscardCancelSave[0];
773 
774  const OUString &rEnv = Application::GetDesktopEnvironment();
775 
776  if (rEnv.equalsIgnoreAsciiCase("windows") ||
777  rEnv.equalsIgnoreAsciiCase("lxqt") ||
778  rEnv.startsWithIgnoreAsciiCase("plasma"))
779  {
780  pOrder = &aSaveDiscardCancel[0];
781  }
782 
783  for (size_t i = 0; i < N_TYPES; ++i, ++pOrder)
784  {
785  if (rType.endsWith(pOrder->m_aType))
786  return pOrder->m_nPriority;
787  }
788 
789  return -1;
790 }
791 
792 namespace {
793 
794 class sortButtons
795 {
796  bool m_bVerticalContainer;
797 public:
798  explicit sortButtons(bool bVerticalContainer)
799  : m_bVerticalContainer(bVerticalContainer)
800  {
801  }
802  bool operator()(const vcl::Window *pA, const vcl::Window *pB) const;
803 };
804 
805 }
806 
807 bool sortButtons::operator()(const vcl::Window *pA, const vcl::Window *pB) const
808 {
809  //sort into two groups of pack start and pack end
810  VclPackType ePackA = pA->get_pack_type();
811  VclPackType ePackB = pB->get_pack_type();
812  if (ePackA < ePackB)
813  return true;
814  if (ePackA > ePackB)
815  return false;
816  bool bPackA = pA->get_secondary();
817  bool bPackB = pB->get_secondary();
818  if (!m_bVerticalContainer)
819  {
820  //for horizontal boxes group secondaries before primaries
821  if (bPackA > bPackB)
822  return true;
823  if (bPackA < bPackB)
824  return false;
825  }
826  else
827  {
828  //for vertical boxes group secondaries after primaries
829  if (bPackA < bPackB)
830  return true;
831  if (bPackA > bPackB)
832  return false;
833  }
834 
835  //now order within groups according to platform rules
837 }
838 
839 void sort_native_button_order(const VclBox& rContainer)
840 {
841  std::vector<vcl::Window*> aChilds;
842  for (vcl::Window* pChild = rContainer.GetWindow(GetWindowType::FirstChild); pChild;
843  pChild = pChild->GetWindow(GetWindowType::Next))
844  {
845  aChilds.push_back(pChild);
846  }
847 
848  //sort child order within parent so that we match the platform
849  //button order
850  std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(rContainer.get_orientation()));
851  BuilderUtils::reorderWithinParent(aChilds, true);
852 }
853 
854 namespace {
855 
856 struct GridEntry
857 {
858  VclPtr<vcl::Window> pChild;
859  sal_Int32 nSpanWidth;
860  sal_Int32 nSpanHeight;
861  int x;
862  int y;
863  GridEntry()
864  : pChild(nullptr)
865  , nSpanWidth(0)
866  , nSpanHeight(0)
867  , x(-1)
868  , y(-1)
869  {
870  }
871 };
872 
873 }
874 
875 typedef boost::multi_array<GridEntry, 2> array_type;
876 
877 static array_type assembleGrid(const VclGrid &rGrid);
878 static bool isNullGrid(const array_type& A);
879 static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights);
880 
881 array_type assembleGrid(const VclGrid &rGrid)
882 {
883  array_type A;
884 
885  for (vcl::Window* pChild = rGrid.GetWindow(GetWindowType::FirstChild); pChild;
886  pChild = pChild->GetWindow(GetWindowType::Next))
887  {
888  sal_Int32 nLeftAttach = std::max<sal_Int32>(pChild->get_grid_left_attach(), 0);
889  sal_Int32 nWidth = pChild->get_grid_width();
890  sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
891 
892  sal_Int32 nTopAttach = std::max<sal_Int32>(pChild->get_grid_top_attach(), 0);
893  sal_Int32 nHeight = pChild->get_grid_height();
894  sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
895 
896  sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
897  sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
898  if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
899  {
900  nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
901  nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
902  A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
903  }
904 
905  GridEntry &rEntry = A[nLeftAttach][nTopAttach];
906  rEntry.pChild = pChild;
907  rEntry.nSpanWidth = nWidth;
908  rEntry.nSpanHeight = nHeight;
909  rEntry.x = nLeftAttach;
910  rEntry.y = nTopAttach;
911 
912  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
913  {
914  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
915  {
916  GridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
917  rSpan.x = nLeftAttach;
918  rSpan.y = nTopAttach;
919  }
920  }
921  }
922 
923  //see if we have any empty rows/cols
924  sal_Int32 nMaxX = A.shape()[0];
925  sal_Int32 nMaxY = A.shape()[1];
926 
927  std::vector<bool> aNonEmptyCols(nMaxX);
928  std::vector<bool> aNonEmptyRows(nMaxY);
929 
930  for (sal_Int32 x = 0; x < nMaxX; ++x)
931  {
932  for (sal_Int32 y = 0; y < nMaxY; ++y)
933  {
934  const GridEntry &rEntry = A[x][y];
935  const vcl::Window *pChild = rEntry.pChild;
936  if (pChild && pChild->IsVisible())
937  {
938  aNonEmptyCols[x] = true;
939  if (rGrid.get_column_homogeneous())
940  {
941  for (sal_Int32 nSpanX = 1; nSpanX < rEntry.nSpanWidth; ++nSpanX)
942  aNonEmptyCols[x+nSpanX] = true;
943  }
944  aNonEmptyRows[y] = true;
945  if (rGrid.get_row_homogeneous())
946  {
947  for (sal_Int32 nSpanY = 1; nSpanY < rEntry.nSpanHeight; ++nSpanY)
948  aNonEmptyRows[y+nSpanY] = true;
949  }
950  }
951  }
952  }
953 
954  if (!rGrid.get_column_homogeneous())
955  {
956  //reduce the spans of elements that span empty columns
957  for (sal_Int32 x = 0; x < nMaxX; ++x)
958  {
959  std::set<GridEntry*> candidates;
960  for (sal_Int32 y = 0; y < nMaxY; ++y)
961  {
962  if (aNonEmptyCols[x])
963  continue;
964  GridEntry &rSpan = A[x][y];
965  //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
966  //just points back to itself if there's no cell spanning
967  if ((rSpan.x == -1) || (rSpan.y == -1))
968  {
969  //there is no entry for this cell, i.e. this is a cell
970  //with no widget in it, or spanned by any other widget
971  continue;
972  }
973  GridEntry &rEntry = A[rSpan.x][rSpan.y];
974  candidates.insert(&rEntry);
975  }
976  for (auto const& candidate : candidates)
977  {
978  GridEntry *pEntry = candidate;
979  --pEntry->nSpanWidth;
980  }
981  }
982  }
983 
984  if (!rGrid.get_row_homogeneous())
985  {
986  //reduce the spans of elements that span empty rows
987  for (sal_Int32 y = 0; y < nMaxY; ++y)
988  {
989  std::set<GridEntry*> candidates;
990  for (sal_Int32 x = 0; x < nMaxX; ++x)
991  {
992  if (aNonEmptyRows[y])
993  continue;
994  GridEntry &rSpan = A[x][y];
995  //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
996  //just points back to itself if there's no cell spanning
997  if ((rSpan.x == -1) || (rSpan.y == -1))
998  {
999  //there is no entry for this cell, i.e. this is a cell
1000  //with no widget in it, or spanned by any other widget
1001  continue;
1002  }
1003  GridEntry &rEntry = A[rSpan.x][rSpan.y];
1004  candidates.insert(&rEntry);
1005  }
1006  for (auto const& candidate : candidates)
1007  {
1008  GridEntry *pEntry = candidate;
1009  --pEntry->nSpanHeight;
1010  }
1011  }
1012  }
1013 
1014  sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
1015  sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
1016 
1017  //make new grid without empty rows and columns
1018  array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
1019  for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
1020  {
1021  if (!aNonEmptyCols[x])
1022  continue;
1023  for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
1024  {
1025  if (!aNonEmptyRows[y])
1026  continue;
1027  GridEntry &rEntry = A[x][y];
1028  B[x2][y2++] = rEntry;
1029  }
1030  ++x2;
1031  }
1032 
1033  return B;
1034 }
1035 
1036 static bool isNullGrid(const array_type &A)
1037 {
1038  sal_Int32 nMaxX = A.shape()[0];
1039  sal_Int32 nMaxY = A.shape()[1];
1040 
1041  return !nMaxX || !nMaxY;
1042 }
1043 
1044 static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights)
1045 {
1046  sal_Int32 nMaxX = A.shape()[0];
1047  sal_Int32 nMaxY = A.shape()[1];
1048 
1049  rWidths.resize(nMaxX);
1050  rHeights.resize(nMaxY);
1051 
1052  //first use the non spanning entries to set default width/heights
1053  for (sal_Int32 x = 0; x < nMaxX; ++x)
1054  {
1055  for (sal_Int32 y = 0; y < nMaxY; ++y)
1056  {
1057  const GridEntry &rEntry = A[x][y];
1058  const vcl::Window *pChild = rEntry.pChild;
1059  if (!pChild || !pChild->IsVisible())
1060  continue;
1061 
1062  sal_Int32 nWidth = rEntry.nSpanWidth;
1063  sal_Int32 nHeight = rEntry.nSpanHeight;
1064 
1065  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1066  rWidths[x+nSpanX].m_bExpand |= pChild->get_hexpand();
1067 
1068  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1069  rHeights[y+nSpanY].m_bExpand |= pChild->get_vexpand();
1070 
1071  if (nWidth == 1 || nHeight == 1)
1072  {
1073  Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1074  if (nWidth == 1)
1075  rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
1076  if (nHeight == 1)
1077  rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
1078  }
1079  }
1080  }
1081 
1082  //now use the spanning entries and split any extra sizes across expanding rows/cols
1083  //where possible
1084  for (sal_Int32 x = 0; x < nMaxX; ++x)
1085  {
1086  for (sal_Int32 y = 0; y < nMaxY; ++y)
1087  {
1088  const GridEntry &rEntry = A[x][y];
1089  const vcl::Window *pChild = rEntry.pChild;
1090  if (!pChild || !pChild->IsVisible())
1091  continue;
1092 
1093  sal_Int32 nWidth = rEntry.nSpanWidth;
1094  sal_Int32 nHeight = rEntry.nSpanHeight;
1095 
1096  if (nWidth == 1 && nHeight == 1)
1097  continue;
1098 
1099  Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1100 
1101  if (nWidth > 1)
1102  {
1103  sal_Int32 nExistingWidth = 0;
1104  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1105  nExistingWidth += rWidths[x+nSpanX].m_nValue;
1106 
1107  sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
1108 
1109  if (nExtraWidth > 0)
1110  {
1111  bool bForceExpandAll = false;
1112  sal_Int32 nExpandables = 0;
1113  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1114  if (rWidths[x+nSpanX].m_bExpand)
1115  ++nExpandables;
1116  if (nExpandables == 0)
1117  {
1118  nExpandables = nWidth;
1119  bForceExpandAll = true;
1120  }
1121 
1122  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1123  {
1124  if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
1125  rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
1126  }
1127  }
1128  }
1129 
1130  if (nHeight > 1)
1131  {
1132  sal_Int32 nExistingHeight = 0;
1133  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1134  nExistingHeight += rHeights[y+nSpanY].m_nValue;
1135 
1136  sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
1137 
1138  if (nExtraHeight > 0)
1139  {
1140  bool bForceExpandAll = false;
1141  sal_Int32 nExpandables = 0;
1142  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1143  if (rHeights[y+nSpanY].m_bExpand)
1144  ++nExpandables;
1145  if (nExpandables == 0)
1146  {
1147  nExpandables = nHeight;
1148  bForceExpandAll = true;
1149  }
1150 
1151  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1152  {
1153  if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
1154  rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
1155  }
1156  }
1157  }
1158  }
1159  }
1160 }
1161 
1162 static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
1163 {
1164  return i.m_nValue < j.m_nValue;
1165 }
1166 
1168 {
1169  VclGrid::Value aRet;
1170  aRet.m_nValue = i.m_nValue + j.m_nValue;
1171  aRet.m_bExpand = i.m_bExpand || j.m_bExpand;
1172  return aRet;
1173 }
1174 
1176 {
1178 }
1179 
1180 Size VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
1181 {
1182  array_type A = assembleGrid(*this);
1183 
1184  if (isNullGrid(A))
1185  return Size();
1186 
1187  std::vector<Value> aWidths;
1188  std::vector<Value> aHeights;
1189  calcMaxs(A, aWidths, aHeights);
1190 
1191  tools::Long nTotalWidth = 0;
1192  if (get_column_homogeneous())
1193  {
1194  nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
1195  nTotalWidth *= aWidths.size();
1196  }
1197  else
1198  {
1199  nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
1200  }
1201 
1202  nTotalWidth += nColSpacing * (aWidths.size()-1);
1203 
1204  tools::Long nTotalHeight = 0;
1205  if (get_row_homogeneous())
1206  {
1207  nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
1208  nTotalHeight *= aHeights.size();
1209  }
1210  else
1211  {
1212  nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
1213  }
1214 
1215  nTotalHeight += nRowSpacing * (aHeights.size()-1);
1216 
1217  return Size(nTotalWidth, nTotalHeight);
1218 }
1219 
1220 void VclGrid::setAllocation(const Size& rAllocation)
1221 {
1222  array_type A = assembleGrid(*this);
1223 
1224  if (isNullGrid(A))
1225  return;
1226 
1227  sal_Int32 nMaxX = A.shape()[0];
1228  sal_Int32 nMaxY = A.shape()[1];
1229 
1230  Size aRequisition;
1231  std::vector<Value> aWidths(nMaxX);
1232  std::vector<Value> aHeights(nMaxY);
1234  {
1235  aRequisition = calculateRequisition();
1236  calcMaxs(A, aWidths, aHeights);
1237  }
1238 
1239  sal_Int32 nColSpacing(get_column_spacing());
1240  sal_Int32 nRowSpacing(get_row_spacing());
1241 
1242  tools::Long nAvailableWidth = rAllocation.Width();
1243  if (nMaxX)
1244  nAvailableWidth -= nColSpacing * (nMaxX - 1);
1245  if (get_column_homogeneous())
1246  {
1247  for (sal_Int32 x = 0; x < nMaxX; ++x)
1248  aWidths[x].m_nValue = nAvailableWidth/nMaxX;
1249  }
1250  else if (rAllocation.Width() != aRequisition.Width())
1251  {
1252  sal_Int32 nExpandables = 0;
1253  for (sal_Int32 x = 0; x < nMaxX; ++x)
1254  if (aWidths[x].m_bExpand)
1255  ++nExpandables;
1256  tools::Long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
1257 
1258  //We don't fit and there is no volunteer to be shrunk
1259  if (!nExpandables && rAllocation.Width() < aRequisition.Width())
1260  {
1261  //first reduce spacing
1262  while (nColSpacing)
1263  {
1264  nColSpacing /= 2;
1265  aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1266  if (aRequisition.Width() <= rAllocation.Width())
1267  break;
1268  }
1269 
1270  //share out the remaining pain to everyone
1271  tools::Long nExtraWidth = (rAllocation.Width() - aRequisition.Width()) / nMaxX;
1272 
1273  for (sal_Int32 x = 0; x < nMaxX; ++x)
1274  aWidths[x].m_nValue += nExtraWidth;
1275  }
1276 
1277  if (nExtraWidthForExpanders)
1278  {
1279  for (sal_Int32 x = 0; x < nMaxX; ++x)
1280  if (aWidths[x].m_bExpand)
1281  aWidths[x].m_nValue += nExtraWidthForExpanders;
1282  }
1283  }
1284 
1285  tools::Long nAvailableHeight = rAllocation.Height();
1286  if (nMaxY)
1287  nAvailableHeight -= nRowSpacing * (nMaxY - 1);
1288  if (get_row_homogeneous())
1289  {
1290  for (sal_Int32 y = 0; y < nMaxY; ++y)
1291  aHeights[y].m_nValue = nAvailableHeight/nMaxY;
1292  }
1293  else if (rAllocation.Height() != aRequisition.Height())
1294  {
1295  sal_Int32 nExpandables = 0;
1296  for (sal_Int32 y = 0; y < nMaxY; ++y)
1297  if (aHeights[y].m_bExpand)
1298  ++nExpandables;
1299  tools::Long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
1300 
1301  //We don't fit and there is no volunteer to be shrunk
1302  if (!nExpandables && rAllocation.Height() < aRequisition.Height())
1303  {
1304  //first reduce spacing
1305  while (nRowSpacing)
1306  {
1307  nRowSpacing /= 2;
1308  aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1309  if (aRequisition.Height() <= rAllocation.Height())
1310  break;
1311  }
1312 
1313  //share out the remaining pain to everyone
1314  tools::Long nExtraHeight = (rAllocation.Height() - aRequisition.Height()) / nMaxY;
1315 
1316  for (sal_Int32 y = 0; y < nMaxY; ++y)
1317  aHeights[y].m_nValue += nExtraHeight;
1318  }
1319 
1320  if (nExtraHeightForExpanders)
1321  {
1322  for (sal_Int32 y = 0; y < nMaxY; ++y)
1323  if (aHeights[y].m_bExpand)
1324  aHeights[y].m_nValue += nExtraHeightForExpanders;
1325  }
1326  }
1327 
1328  Point aAllocPos(0, 0);
1329  for (sal_Int32 x = 0; x < nMaxX; ++x)
1330  {
1331  for (sal_Int32 y = 0; y < nMaxY; ++y)
1332  {
1333  GridEntry &rEntry = A[x][y];
1334  vcl::Window *pChild = rEntry.pChild;
1335  if (pChild)
1336  {
1337  Size aChildAlloc(0, 0);
1338 
1339  sal_Int32 nWidth = rEntry.nSpanWidth;
1340  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1341  aChildAlloc.AdjustWidth(aWidths[x+nSpanX].m_nValue );
1342  aChildAlloc.AdjustWidth(nColSpacing*(nWidth-1) );
1343 
1344  sal_Int32 nHeight = rEntry.nSpanHeight;
1345  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1346  aChildAlloc.AdjustHeight(aHeights[y+nSpanY].m_nValue );
1347  aChildAlloc.AdjustHeight(nRowSpacing*(nHeight-1) );
1348 
1349  setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
1350  }
1351  aAllocPos.AdjustY(aHeights[y].m_nValue + nRowSpacing );
1352  }
1353  aAllocPos.AdjustX(aWidths[x].m_nValue + nColSpacing );
1354  aAllocPos.setY( 0 );
1355  }
1356 }
1357 
1359 {
1360  VclContainer::DumpAsPropertyTree(rJsonWriter);
1361  rJsonWriter.put("type", "grid");
1362 }
1363 
1364 bool toBool(std::u16string_view rValue)
1365 {
1366  return (!rValue.empty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
1367 }
1368 
1369 bool VclGrid::set_property(const OString &rKey, const OUString &rValue)
1370 {
1371  if (rKey == "row-spacing")
1372  set_row_spacing(rValue.toInt32());
1373  else if (rKey == "column-spacing")
1374  set_column_spacing(rValue.toInt32());
1375  else if (rKey == "row-homogeneous")
1376  m_bRowHomogeneous = toBool(rValue);
1377  else if (rKey == "column-homogeneous")
1378  m_bColumnHomogeneous = toBool(rValue);
1379  else if (rKey == "n-rows")
1380  /*nothing to do*/;
1381  else
1382  return VclContainer::set_property(rKey, rValue);
1383  return true;
1384 }
1385 
1386 const vcl::Window *VclBin::get_child() const
1387 {
1388  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1389 
1390  return pWindowImpl->mpFirstChild;
1391 }
1392 
1393 vcl::Window *VclBin::get_child()
1394 {
1395  return const_cast<vcl::Window*>(const_cast<const VclBin*>(this)->get_child());
1396 }
1397 
1398 Size VclBin::calculateRequisition() const
1399 {
1400  const vcl::Window *pChild = get_child();
1401  if (pChild && pChild->IsVisible())
1402  return getLayoutRequisition(*pChild);
1403  return Size(0, 0);
1404 }
1405 
1406 void VclBin::setAllocation(const Size &rAllocation)
1407 {
1408  vcl::Window *pChild = get_child();
1409  if (pChild && pChild->IsVisible())
1410  setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
1411 }
1412 
1414 {
1415  disposeOnce();
1416 }
1417 
1419 {
1420  m_pLabel.clear();
1421  VclBin::dispose();
1422 }
1423 
1424 //To-Do, hook a DecorationView into VclFrame ?
1425 
1427 {
1428  Size aRet(0, 0);
1429 
1430  const vcl::Window *pChild = get_child();
1431  const vcl::Window *pLabel = get_label_widget();
1432 
1433  if (pChild && pChild->IsVisible())
1434  aRet = getLayoutRequisition(*pChild);
1435 
1436  if (pLabel && pLabel->IsVisible())
1437  {
1438  Size aLabelSize = getLayoutRequisition(*pLabel);
1439  aRet.AdjustHeight(aLabelSize.Height() );
1440  aRet.setWidth( std::max(aLabelSize.Width(), aRet.Width()) );
1441  }
1442 
1443  return aRet;
1444 }
1445 
1446 void VclFrame::setAllocation(const Size &rAllocation)
1447 {
1448  //SetBackground( Color(0xFF, 0x00, 0xFF) );
1449 
1450  Size aAllocation(rAllocation);
1451  Point aChildPos;
1452 
1453  vcl::Window *pChild = get_child();
1454  vcl::Window *pLabel = get_label_widget();
1455 
1456  if (pLabel && pLabel->IsVisible())
1457  {
1458  Size aLabelSize = getLayoutRequisition(*pLabel);
1459  aLabelSize.setHeight( std::min(aLabelSize.Height(), aAllocation.Height()) );
1460  aLabelSize.setWidth( std::min(aLabelSize.Width(), aAllocation.Width()) );
1461  setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
1462  aAllocation.AdjustHeight( -(aLabelSize.Height()) );
1463  aChildPos.AdjustY(aLabelSize.Height() );
1464  }
1465 
1466  if (pChild && pChild->IsVisible())
1467  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1468 }
1469 
1470 IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent&, rEvent, void)
1471 {
1472  if (rEvent.GetId() == VclEventId::ObjectDying)
1473  designate_label(nullptr);
1474 }
1475 
1477 {
1478  assert(!pWindow || pWindow->GetParent() == this);
1479  if (m_pLabel)
1480  m_pLabel->RemoveEventListener(LINK(this, VclFrame, WindowEventListener));
1481  m_pLabel = pWindow;
1482  if (m_pLabel)
1483  m_pLabel->AddEventListener(LINK(this, VclFrame, WindowEventListener));
1484 }
1485 
1487 {
1488  if (m_pLabel)
1489  return m_pLabel;
1490  assert(GetChildCount() == 2);
1491  //The label widget is normally the first (of two) children
1492  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1493  if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
1494  return nullptr;
1495  return pWindowImpl->mpFirstChild;
1496 }
1497 
1499 {
1500  return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
1501 }
1502 
1504 {
1505  //The child widget is the normally the last (of two) children
1506  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1507  assert(GetChildCount() == 2 || pWindowImpl->mbInDispose);
1508  if (!m_pLabel)
1509  return pWindowImpl->mpLastChild;
1510  if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
1511  return nullptr;
1512  return pWindowImpl->mpLastChild;
1513 }
1514 
1516 {
1517  return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_child());
1518 }
1519 
1520 void VclFrame::set_label(const OUString &rLabel)
1521 {
1522  vcl::Window *pLabel = get_label_widget();
1523  assert(pLabel);
1524  pLabel->SetText(rLabel);
1525 }
1526 
1527 OUString VclFrame::get_label() const
1528 {
1529  const vcl::Window *pLabel = get_label_widget();
1530  assert(pLabel);
1531  return pLabel->GetText();
1532 }
1533 
1535 {
1536  const vcl::Window *pLabel = get_label_widget();
1537  if (pLabel)
1538  return pLabel->GetAccessibleName();
1539  return VclBin::getDefaultAccessibleName();
1540 }
1541 
1543 {
1544  VclBin::DumpAsPropertyTree(rJsonWriter);
1545  rJsonWriter.put("type", "frame");
1546 }
1547 
1548 class DisclosureButton final : public CheckBox
1549 {
1550  virtual void ImplDrawCheckBoxState(vcl::RenderContext& rRenderContext) override
1551  {
1552  /* HACK: DisclosureButton is currently assuming, that the disclosure sign
1553  will fit into the rectangle occupied by a normal checkbox on all themes.
1554  If this does not hold true for some theme, ImplGetCheckImageSize
1555  would have to be overridden for DisclosureButton; also GetNativeControlRegion
1556  for ControlType::ListNode would have to be implemented and taken into account
1557  */
1558 
1559  tools::Rectangle aStateRect(GetStateRect());
1560 
1562  tools::Rectangle aCtrlRegion(aStateRect);
1564 
1565  if (HasFocus())
1566  nState |= ControlState::FOCUSED;
1568  nState |= ControlState::DEFAULT;
1569  if (Window::IsEnabled())
1570  nState |= ControlState::ENABLED;
1571  if (IsMouseOver() && GetMouseRect().IsInside(GetPointerPosPixel()))
1572  nState |= ControlState::ROLLOVER;
1573 
1574  if (rRenderContext.DrawNativeControl(ControlType::ListNode, ControlPart::Entire, aCtrlRegion,
1575  nState, aControlValue, OUString()))
1576  return;
1577 
1578  ImplSVCtrlData& rCtrlData(ImplGetSVData()->maCtrlData);
1579  if (!rCtrlData.mpDisclosurePlus)
1580  rCtrlData.mpDisclosurePlus.reset(new Image(StockImage::Yes, SV_DISCLOSURE_PLUS));
1581  if (!rCtrlData.mpDisclosureMinus)
1582  rCtrlData.mpDisclosureMinus.reset(new Image(StockImage::Yes, SV_DISCLOSURE_MINUS));
1583 
1584  Image* pImg
1585  = IsChecked() ? rCtrlData.mpDisclosureMinus.get() : rCtrlData.mpDisclosurePlus.get();
1586 
1588  if (!IsEnabled())
1589  nStyle |= DrawImageFlags::Disable;
1590 
1591  Size aSize(aStateRect.GetSize());
1592  Size aImgSize(pImg->GetSizePixel());
1593  Point aOff((aSize.Width() - aImgSize.Width()) / 2,
1594  (aSize.Height() - aImgSize.Height()) / 2);
1595  aOff += aStateRect.TopLeft();
1596  rRenderContext.DrawImage(aOff, *pImg, nStyle);
1597  }
1598 
1599 public:
1600  explicit DisclosureButton(vcl::Window* pParent)
1601  : CheckBox(pParent, 0)
1602  {
1603  }
1604 
1605  virtual void KeyInput( const KeyEvent& rKEvt ) override
1606  {
1607  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1608 
1609  if( !aKeyCode.GetModifier() &&
1610  ( ( aKeyCode.GetCode() == KEY_ADD ) ||
1611  ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
1612  )
1613  {
1614  Check( aKeyCode.GetCode() == KEY_ADD );
1615  }
1616  else
1617  CheckBox::KeyInput( rKEvt );
1618  }
1619 };
1620 
1622  : VclBin(pParent)
1623  , m_bResizeTopLevel(false)
1624  , m_pDisclosureButton(VclPtr<DisclosureButton>::Create(this))
1625 {
1626  m_pDisclosureButton->SetToggleHdl(LINK(this, VclExpander, ClickHdl));
1628 }
1629 
1631 {
1632  disposeOnce();
1633 }
1634 
1636 {
1637  return m_pDisclosureButton->IsChecked();
1638 }
1639 
1640 void VclExpander::set_expanded(bool bExpanded)
1641 {
1642  m_pDisclosureButton->Check(bExpanded);
1643 }
1644 
1645 void VclExpander::set_label(const OUString& rLabel)
1646 {
1647  m_pDisclosureButton->SetText(rLabel);
1648 }
1649 
1650 OUString VclExpander::get_label() const
1651 {
1652  return m_pDisclosureButton->GetText();
1653 }
1654 
1656 {
1658  VclBin::dispose();
1659 }
1660 
1662 {
1663  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1664 
1665  assert(pWindowImpl->mpFirstChild == m_pDisclosureButton);
1666 
1667  return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
1668 }
1669 
1671 {
1672  return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_child());
1673 }
1674 
1676 {
1677  Size aRet(0, 0);
1678 
1679  WindowImpl* pWindowImpl = ImplGetWindowImpl();
1680 
1681  const vcl::Window *pChild = get_child();
1682  const vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild.get() : nullptr;
1683 
1684  if (pChild && pChild->IsVisible() && m_pDisclosureButton->IsChecked())
1685  aRet = getLayoutRequisition(*pChild);
1686 
1687  Size aExpanderSize = getLayoutRequisition(*m_pDisclosureButton);
1688 
1689  if (pLabel && pLabel->IsVisible())
1690  {
1691  Size aLabelSize = getLayoutRequisition(*pLabel);
1692  aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1693  aExpanderSize.AdjustWidth(aLabelSize.Width() );
1694  }
1695 
1696  aRet.AdjustHeight(aExpanderSize.Height() );
1697  aRet.setWidth( std::max(aExpanderSize.Width(), aRet.Width()) );
1698 
1699  return aRet;
1700 }
1701 
1702 void VclExpander::setAllocation(const Size &rAllocation)
1703 {
1704  Size aAllocation(rAllocation);
1705  Point aChildPos;
1706 
1707  WindowImpl* pWindowImpl = ImplGetWindowImpl();
1708 
1709  //The label widget is the last (of two) children
1710  vcl::Window *pChild = get_child();
1711  vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild.get() ? pWindowImpl->mpLastChild.get() : nullptr;
1712 
1713  Size aButtonSize = getLayoutRequisition(*m_pDisclosureButton);
1714  Size aLabelSize;
1715  Size aExpanderSize = aButtonSize;
1716  if (pLabel && pLabel->IsVisible())
1717  {
1718  aLabelSize = getLayoutRequisition(*pLabel);
1719  aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1720  aExpanderSize.AdjustWidth(aLabelSize.Width() );
1721  }
1722 
1723  aExpanderSize.setHeight( std::min(aExpanderSize.Height(), aAllocation.Height()) );
1724  aExpanderSize.setWidth( std::min(aExpanderSize.Width(), aAllocation.Width()) );
1725 
1726  aButtonSize.setHeight( std::min(aButtonSize.Height(), aExpanderSize.Height()) );
1727  aButtonSize.setWidth( std::min(aButtonSize.Width(), aExpanderSize.Width()) );
1728 
1729  tools::Long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
1730  Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
1731  setLayoutAllocation(*m_pDisclosureButton, aButtonPos, aButtonSize);
1732 
1733  if (pLabel && pLabel->IsVisible())
1734  {
1735  aLabelSize.setHeight( std::min(aLabelSize.Height(), aExpanderSize.Height()) );
1736  aLabelSize.setWidth( std::min(aLabelSize.Width(),
1737  aExpanderSize.Width() - aButtonSize.Width()) );
1738 
1739  tools::Long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
1740  Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
1741  setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
1742  }
1743 
1744  aAllocation.AdjustHeight( -(aExpanderSize.Height()) );
1745  aChildPos.AdjustY(aExpanderSize.Height() );
1746 
1747  if (pChild && pChild->IsVisible())
1748  {
1750  aAllocation = Size();
1751  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1752  }
1753 }
1754 
1755 bool VclExpander::set_property(const OString &rKey, const OUString &rValue)
1756 {
1757  if (rKey == "expanded")
1758  set_expanded(toBool(rValue));
1759  else if (rKey == "resize-toplevel")
1760  m_bResizeTopLevel = toBool(rValue);
1761  else
1762  return VclBin::set_property(rKey, rValue);
1763  return true;
1764 }
1765 
1767 {
1768  VclBin::StateChanged( nType );
1769 
1770  if (nType == StateChangedType::InitShow)
1771  {
1772  vcl::Window *pChild = get_child();
1773  if (pChild)
1774  pChild->Show(m_pDisclosureButton->IsChecked());
1775  }
1776 }
1777 
1779 {
1780  return m_pDisclosureButton;
1781 }
1782 
1784 {
1785  return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_label_widget());
1786 }
1787 
1789 {
1790  VclContainer::DumpAsPropertyTree(rJsonWriter);
1791  rJsonWriter.put("type", "expander");
1792 }
1793 
1794 IMPL_LINK( VclExpander, ClickHdl, CheckBox&, rBtn, void )
1795 {
1796  vcl::Window *pChild = get_child();
1797  if (pChild)
1798  {
1799  pChild->Show(rBtn.IsChecked());
1800  queue_resize();
1801  Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : nullptr;
1802  if (pResizeDialog)
1803  pResizeDialog->setOptimalLayoutSize();
1804  }
1805  maExpandedHdl.Call(*this);
1806 }
1807 
1810  , m_bUserManagedScrolling(false)
1811  , m_nBorderWidth(1)
1812  , m_eDrawFrameStyle(DrawFrameStyle::NONE)
1813  , m_eDrawFrameFlags(DrawFrameFlags::NONE)
1814  , m_pVScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_VERT))
1815  , m_pHScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_HORZ))
1816  , m_aScrollBarBox(VclPtr<ScrollBarBox>::Create(this, WB_HIDE))
1817 {
1818  SetType(WindowType::SCROLLWINDOW);
1819 
1820  AllSettings aAllSettings = GetSettings();
1821  StyleSettings aStyle = aAllSettings.GetStyleSettings();
1822  aStyle.SetMonoColor(aStyle.GetShadowColor());
1823  aAllSettings.SetStyleSettings(aStyle);
1824  GetOutDev()->SetSettings(aAllSettings);
1825 
1826  Link<ScrollBar*,void> aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) );
1827  m_pVScroll->SetScrollHdl(aLink);
1828  m_pHScroll->SetScrollHdl(aLink);
1829 }
1830 
1832 {
1836  VclBin::dispose();
1837 }
1838 
1840 {
1841  vcl::Window *pChild = get_child();
1842  if (!pChild)
1843  return;
1844 
1845  assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
1846 
1847  pChild = pChild->GetWindow(GetWindowType::FirstChild);
1848 
1849  if (!pChild)
1850  return;
1851 
1852  Point aWinPos(-m_pHScroll->GetThumbPos(), -m_pVScroll->GetThumbPos());
1853  pChild->SetPosPixel(aWinPos);
1854 }
1855 
1857 {
1858  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1859  assert(GetChildCount() == 4 || pWindowImpl->mbInDispose);
1860  return pWindowImpl->mpLastChild;
1861 }
1862 
1864 {
1865  return const_cast<vcl::Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
1866 }
1867 
1869 {
1870  Size aRet(0, 0);
1871 
1872  const vcl::Window *pChild = get_child();
1873  if (pChild && pChild->IsVisible())
1874  aRet = getLayoutRequisition(*pChild);
1875 
1876  if (GetStyle() & WB_VSCROLL)
1877  aRet.AdjustWidth(getLayoutRequisition(*m_pVScroll).Width() );
1878 
1879  if (GetStyle() & WB_HSCROLL)
1880  aRet.AdjustHeight(getLayoutRequisition(*m_pHScroll).Height() );
1881 
1882  aRet.AdjustHeight(2 * m_nBorderWidth);
1883  aRet.AdjustWidth(2 * m_nBorderWidth);
1884 
1885  return aRet;
1886 }
1887 
1889 {
1890  const vcl::Window *pChild = get_child();
1891  if (!pChild || !pChild->IsVisible())
1892  return;
1893 
1894  Size aOutSize(getVisibleChildSize());
1895 
1896  m_pVScroll->SetRangeMax(rRequest.Height());
1897  m_pVScroll->SetVisibleSize(aOutSize.Height());
1898  m_pVScroll->SetPageSize(16);
1899 
1900  m_pHScroll->SetRangeMax(rRequest.Width());
1901  m_pHScroll->SetVisibleSize(aOutSize.Width());
1902  m_pHScroll->SetPageSize(16);
1903 
1904  m_pVScroll->Scroll();
1905  m_pHScroll->Scroll();
1906 }
1907 
1908 void VclScrolledWindow::doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
1909 {
1910  Size aChildReq;
1911 
1912  vcl::Window *pChild = get_child();
1913  if (pChild && pChild->IsVisible())
1914  aChildReq = getLayoutRequisition(*pChild);
1915 
1916  tools::Long nAvailHeight = rAllocation.Height() - 2 * m_nBorderWidth;
1917  tools::Long nAvailWidth = rAllocation.Width() - 2 * m_nBorderWidth;
1918 
1919  // vert. ScrollBar
1920  bool bShowVScroll;
1921  if (GetStyle() & WB_AUTOVSCROLL)
1922  bShowVScroll = nAvailHeight < aChildReq.Height();
1923  else
1924  bShowVScroll = (GetStyle() & WB_VSCROLL) != 0;
1925 
1926  if (bShowVScroll)
1927  nAvailWidth -= getLayoutRequisition(*m_pVScroll).Width();
1928 
1929  // horz. ScrollBar
1930  bool bShowHScroll;
1931  if (GetStyle() & WB_AUTOHSCROLL)
1932  {
1933  bShowHScroll = nAvailWidth < aChildReq.Width();
1934 
1935  if (bShowHScroll)
1936  nAvailHeight -= getLayoutRequisition(*m_pHScroll).Height();
1937 
1938  if (GetStyle() & WB_AUTOVSCROLL)
1939  bShowVScroll = nAvailHeight < aChildReq.Height();
1940  }
1941  else
1942  bShowHScroll = (GetStyle() & WB_HSCROLL) != 0;
1943 
1944  if (m_pHScroll->IsVisible() != bShowHScroll)
1945  m_pHScroll->Show(bShowHScroll);
1946  if (m_pVScroll->IsVisible() != bShowVScroll)
1947  m_pVScroll->Show(bShowVScroll);
1948 
1949  Size aInnerSize(rAllocation);
1950  aInnerSize.AdjustWidth(-2 * m_nBorderWidth);
1951  aInnerSize.AdjustHeight(-2 * m_nBorderWidth);
1952 
1953  bool bBothVisible = m_pVScroll->IsVisible() && m_pHScroll->IsVisible();
1954  auto nScrollBarWidth = getLayoutRequisition(*m_pVScroll).Width();
1955  auto nScrollBarHeight = getLayoutRequisition(*m_pHScroll).Height();
1956 
1957  if (m_pVScroll->IsVisible())
1958  {
1959  Point aScrollPos(rAllocation.Width() - nScrollBarWidth - m_nBorderWidth, m_nBorderWidth);
1960  Size aScrollSize(nScrollBarWidth, rAllocation.Height() - 2 * m_nBorderWidth);
1961  if (bBothVisible)
1962  aScrollSize.AdjustHeight(-nScrollBarHeight);
1963  setLayoutAllocation(*m_pVScroll, aScrollPos, aScrollSize);
1964  aInnerSize.AdjustWidth( -nScrollBarWidth );
1965  }
1966 
1967  if (m_pHScroll->IsVisible())
1968  {
1969  Point aScrollPos(m_nBorderWidth, rAllocation.Height() - nScrollBarHeight);
1970  Size aScrollSize(rAllocation.Width() - 2 * m_nBorderWidth, nScrollBarHeight);
1971  if (bBothVisible)
1972  aScrollSize.AdjustWidth(-nScrollBarWidth);
1973  setLayoutAllocation(*m_pHScroll, aScrollPos, aScrollSize);
1974  aInnerSize.AdjustHeight( -nScrollBarHeight );
1975  }
1976 
1977  if (bBothVisible)
1978  {
1979  Point aBoxPos(aInnerSize.Width() + m_nBorderWidth, aInnerSize.Height() + m_nBorderWidth);
1980  m_aScrollBarBox->SetPosSizePixel(aBoxPos, Size(nScrollBarWidth, nScrollBarHeight));
1981  m_aScrollBarBox->Show();
1982  }
1983  else
1984  {
1985  m_aScrollBarBox->Hide();
1986  }
1987 
1988  if (pChild && pChild->IsVisible())
1989  {
1990  assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
1991 
1992  WinBits nOldBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
1993 
1994  setLayoutAllocation(*pChild, Point(m_nBorderWidth, m_nBorderWidth), aInnerSize);
1995 
1996  // tdf#128758 if the layout allocation triggered some callback that
1997  // immediately invalidates the layout by adding scrollbars then
1998  // normally this would simply retrigger layout and another toplevel
1999  // attempt is made later. But the initial layout attempt blocks
2000  // relayouts, so just make another single effort here.
2001  WinBits nNewBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
2002  if (nOldBits != nNewBits && bRetryOnFailure)
2003  {
2004  doSetAllocation(rAllocation, false);
2005  return;
2006  }
2007  }
2008 
2010  InitScrollBars(aChildReq);
2011 }
2012 
2013 void VclScrolledWindow::setAllocation(const Size &rAllocation)
2014 {
2015  doSetAllocation(rAllocation, true);
2016 }
2017 
2019 {
2020  Size aRet(GetSizePixel());
2021  if (m_pVScroll->IsVisible())
2022  aRet.AdjustWidth( -(m_pVScroll->GetSizePixel().Width()) );
2023  if (m_pHScroll->IsVisible())
2024  aRet.AdjustHeight( -(m_pHScroll->GetSizePixel().Height()) );
2025  aRet.AdjustHeight(-2 * m_nBorderWidth);
2026  aRet.AdjustWidth(-2 * m_nBorderWidth);
2027  return aRet;
2028 }
2029 
2030 bool VclScrolledWindow::set_property(const OString &rKey, const OUString &rValue)
2031 {
2032  if (rKey == "shadow-type")
2033  {
2034  // despite the style names, this looks like the best mapping
2035  if (rValue == "in")
2037  else if (rValue == "out")
2039  else if (rValue == "etched-in")
2041  else if (rValue == "etched-out")
2043  else if (rValue == "none")
2045  return true;
2046  }
2047  else if (rKey == "name")
2048  {
2049  m_eDrawFrameFlags = rValue == "monoborder" ? DrawFrameFlags::Mono : DrawFrameFlags::NONE;
2050  }
2051 
2052  bool bRet = VclBin::set_property(rKey, rValue);
2053  m_pVScroll->Show((GetStyle() & WB_VSCROLL) != 0);
2054  m_pHScroll->Show((GetStyle() & WB_HSCROLL) != 0);
2055  return bRet;
2056 }
2057 
2059 {
2060  bool bDone = false;
2061  if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
2062  {
2063  const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2064  if ( rCEvt.GetCommand() == CommandEventId::Wheel )
2065  {
2066  const CommandWheelData* pData = rCEvt.GetWheelData();
2067  if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
2068  {
2069  // tdf#140537 only handle scroll commands in the valid shown scrollbars
2070  bDone = HandleScrollCommand(rCEvt,
2071  m_pHScroll->IsVisible() ? m_pHScroll : nullptr,
2072  m_pVScroll->IsVisible() ? m_pVScroll : nullptr);
2073  }
2074  }
2075  }
2076 
2077  return bDone || VclBin::EventNotify( rNEvt );
2078 }
2079 
2081 {
2082  if (m_nBorderWidth == nBorderWidth || nBorderWidth < 1)
2083  return;
2084 
2085  m_nBorderWidth = nBorderWidth;
2086  // update scrollbars and child window
2087  doSetAllocation(GetSizePixel(), false);
2088 };
2089 
2091 {
2092  const tools::Rectangle aRect(tools::Rectangle(Point(0,0), GetSizePixel()));
2093  DecorationView aDecoView(&rRenderContext);
2094  const tools::Rectangle aContentRect = aDecoView.DrawFrame(aRect, m_eDrawFrameStyle, m_eDrawFrameFlags);
2095 
2096  // take potentially changed frame size into account before rendering content
2097  const tools::Long nFrameWidth = (aRect.GetWidth() - aContentRect.GetWidth()) / 2;
2098  updateBorderWidth(nFrameWidth);
2099 
2100  VclBin::Paint(rRenderContext, rRect);
2101 }
2102 
2103 void VclViewport::setAllocation(const Size &rAllocation)
2104 {
2105  vcl::Window *pChild = get_child();
2106  if (!(pChild && pChild->IsVisible()))
2107  return;
2108 
2109  Size aReq(getLayoutRequisition(*pChild));
2110  aReq.setWidth( std::max(aReq.Width(), rAllocation.Width()) );
2111  aReq.setHeight( std::max(aReq.Height(), rAllocation.Height()) );
2112  Point aKeepPos(pChild->GetPosPixel());
2114  {
2115  aKeepPos = Point(0, 0);
2116  m_bInitialAllocation = false;
2117  }
2118  setLayoutAllocation(*pChild, aKeepPos, aReq);
2119 }
2120 
2122 {
2123  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
2124 
2125  assert(pWindowImpl->mpFirstChild.get() == m_aEventBoxHelper.get());
2126 
2127  return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
2128 }
2129 
2131 {
2132  return const_cast<vcl::Window*>(const_cast<const VclEventBox*>(this)->get_child());
2133 }
2134 
2135 void VclEventBox::setAllocation(const Size& rAllocation)
2136 {
2137  Point aChildPos(0, 0);
2138  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
2139  {
2140  if (!pChild->IsVisible())
2141  continue;
2142  setLayoutAllocation(*pChild, aChildPos, rAllocation);
2143  }
2144 }
2145 
2147 {
2148  Size aRet(0, 0);
2149 
2150  for (const vcl::Window* pChild = get_child(); pChild;
2151  pChild = pChild->GetWindow(GetWindowType::Next))
2152  {
2153  if (!pChild->IsVisible())
2154  continue;
2155  Size aChildSize = getLayoutRequisition(*pChild);
2156  aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2157  aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2158  }
2159 
2160  return aRet;
2161 }
2162 
2164 {
2165  //discard events by default to block them reaching children
2166 }
2167 
2169 {
2170  disposeOnce();
2171 }
2172 
2174 {
2175  m_aEventBoxHelper.disposeAndClear();
2176  VclBin::dispose();
2177 }
2178 
2180 {
2181  //sufficient to trigger one widget to trigger all of them
2182  if (!m_aWindows.empty())
2183  {
2184  (*m_aWindows.begin())->queue_resize();
2185  }
2186 }
2187 
2188 void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden)
2189 {
2190  if (bIgnoreHidden != m_bIgnoreHidden)
2191  {
2192  m_bIgnoreHidden = bIgnoreHidden;
2194  }
2195 }
2196 
2198 {
2199  if (eMode != m_eMode)
2200  {
2201  m_eMode = eMode;
2203  }
2204 
2205 }
2206 
2207 void VclSizeGroup::set_property(const OString &rKey, const OUString &rValue)
2208 {
2209  if (rKey == "ignore-hidden")
2210  set_ignore_hidden(toBool(rValue));
2211  else if (rKey == "mode")
2212  {
2214  if (rValue == "none")
2215  eMode = VclSizeGroupMode::NONE;
2216  else if (rValue == "horizontal")
2218  else if (rValue == "vertical")
2220  else if (rValue == "both")
2221  eMode = VclSizeGroupMode::Both;
2222  else
2223  {
2224  SAL_WARN("vcl.layout", "unknown size group mode" << rValue);
2225  }
2226  set_mode(eMode);
2227  }
2228  else
2229  {
2230  SAL_INFO("vcl.layout", "unhandled property: " << rKey);
2231  }
2232 }
2233 
2235 {
2237 
2238  if (m_pGrid)
2239  return;
2240 
2241  VclContainer *pContainer = get_content_area();
2242  assert(pContainer);
2243 
2244  m_pGrid.set( VclPtr<VclGrid>::Create(pContainer) );
2251 
2253  switch (m_eMessageType)
2254  {
2255  case VclMessageType::Info:
2257  break;
2260  break;
2263  break;
2264  case VclMessageType::Error:
2266  break;
2267  case VclMessageType::Other:
2268  break;
2269  }
2274 
2276 
2277  bool bHasSecondaryText = !m_sSecondaryString.isEmpty();
2278 
2282 
2286 
2292  m_pSecondaryMessage->Show(bHasSecondaryText);
2293 
2294  MessageDialog::SetMessagesWidths(this, m_pPrimaryMessage, bHasSecondaryText ? m_pSecondaryMessage.get() : nullptr);
2295 
2296  VclButtonBox *pButtonBox = get_action_area();
2297  assert(pButtonBox);
2298 
2299  VclPtr<PushButton> pBtn;
2300  short nDefaultResponse = get_default_response();
2301  switch (m_eButtonsType)
2302  {
2303  case VclButtonsType::NONE:
2304  break;
2305  case VclButtonsType::Ok:
2306  pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2307  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2308  pBtn->Show();
2309  pBtn->set_id("ok");
2310  add_button(pBtn, RET_OK, true);
2311  nDefaultResponse = RET_OK;
2312  break;
2313  case VclButtonsType::Close:
2314  pBtn.set( VclPtr<CloseButton>::Create(pButtonBox) );
2315  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2316  pBtn->Show();
2317  pBtn->set_id("close");
2318  add_button(pBtn, RET_CLOSE, true);
2319  nDefaultResponse = RET_CLOSE;
2320  break;
2322  pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2323  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2324  pBtn->Show();
2325  pBtn->set_id("cancel");
2326  add_button(pBtn, RET_CANCEL, true);
2327  nDefaultResponse = RET_CANCEL;
2328  break;
2329  case VclButtonsType::YesNo:
2330  pBtn = VclPtr<PushButton>::Create(pButtonBox);
2331  pBtn->SetText(GetStandardText(StandardButtonType::Yes));
2332  pBtn->Show();
2333  pBtn->set_id("yes");
2334  add_button(pBtn, RET_YES, true);
2335 
2336  pBtn.set( VclPtr<PushButton>::Create(pButtonBox) );
2337  pBtn->SetText(GetStandardText(StandardButtonType::No));
2338  pBtn->Show();
2339  pBtn->set_id("no");
2340  add_button(pBtn, RET_NO, true);
2341  nDefaultResponse = RET_NO;
2342  break;
2344  pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2345  pBtn->Show();
2346  pBtn->set_id("ok");
2347  add_button(pBtn, RET_OK, true);
2348 
2349  pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2350  pBtn->Show();
2351  pBtn->set_id("cancel");
2352  add_button(pBtn, RET_CANCEL, true);
2353  nDefaultResponse = RET_CANCEL;
2354  break;
2355  }
2356  set_default_response(nDefaultResponse);
2357  sort_native_button_order(*pButtonBox);
2358  m_pMessageBox->Show();
2359  m_pGrid->Show();
2360 }
2361 
2363 {
2364 #if defined _WIN32
2365  set_border_width(3);
2366 #else
2367  set_border_width(12);
2368 #endif
2375 }
2376 
2378  : Dialog(pParent, nStyle)
2379  , m_eButtonsType(VclButtonsType::NONE)
2380  , m_eMessageType(VclMessageType::Info)
2381  , m_pOwnedContentArea(nullptr)
2382  , m_pOwnedActionArea(nullptr)
2383  , m_pGrid(nullptr)
2384  , m_pMessageBox(nullptr)
2385  , m_pImage(nullptr)
2386  , m_pPrimaryMessage(nullptr)
2387  , m_pSecondaryMessage(nullptr)
2388 {
2389  SetType(WindowType::MESSBOX);
2390 }
2391 
2393  const OUString &rMessage,
2394  VclMessageType eMessageType,
2395  VclButtonsType eButtonsType)
2396  : Dialog(pParent, WB_MOVEABLE | WB_3DLOOK | WB_CLOSEABLE)
2397  , m_eButtonsType(eButtonsType)
2398  , m_eMessageType(eMessageType)
2399  , m_pGrid(nullptr)
2400  , m_pMessageBox(nullptr)
2401  , m_pImage(nullptr)
2402  , m_pPrimaryMessage(nullptr)
2403  , m_pSecondaryMessage(nullptr)
2404  , m_sPrimaryString(rMessage)
2405 {
2406  SetType(WindowType::MESSBOX);
2409 
2410  switch (m_eMessageType)
2411  {
2412  case VclMessageType::Info:
2414  break;
2417  break;
2420  break;
2421  case VclMessageType::Error:
2423  break;
2424  case VclMessageType::Other:
2426  break;
2427  }
2428 }
2429 
2431 {
2440  Dialog::dispose();
2441 }
2442 
2444 {
2445  disposeOnce();
2446 }
2447 
2449  VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
2450 {
2451  if (pSecondaryMessage)
2452  {
2453  assert(pPrimaryMessage);
2454  vcl::Font aFont = pParent->GetSettings().GetStyleSettings().GetLabelFont();
2455  aFont.SetFontSize(Size(0, aFont.GetFontSize().Height() * 1.2));
2456  aFont.SetWeight(WEIGHT_BOLD);
2457  pPrimaryMessage->SetControlFont(aFont);
2458  pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 44);
2459  pSecondaryMessage->SetMaxTextWidth(pSecondaryMessage->approximate_char_width() * 60);
2460  }
2461  else
2462  pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 60);
2463 }
2464 
2465 OUString const & MessageDialog::get_primary_text() const
2466 {
2467  const_cast<MessageDialog*>(this)->setDeferredProperties();
2468 
2469  return m_sPrimaryString;
2470 }
2471 
2472 OUString const & MessageDialog::get_secondary_text() const
2473 {
2474  const_cast<MessageDialog*>(this)->setDeferredProperties();
2475 
2476  return m_sSecondaryString;
2477 }
2478 
2479 bool MessageDialog::set_property(const OString &rKey, const OUString &rValue)
2480 {
2481  if (rKey == "text")
2482  set_primary_text(rValue);
2483  else if (rKey == "secondary-text")
2484  set_secondary_text(rValue);
2485  else if (rKey == "message-type")
2486  {
2488  if (rValue == "info")
2489  eMode = VclMessageType::Info;
2490  else if (rValue == "warning")
2491  eMode = VclMessageType::Warning;
2492  else if (rValue == "question")
2493  eMode = VclMessageType::Question;
2494  else if (rValue == "error")
2495  eMode = VclMessageType::Error;
2496  else if (rValue == "other")
2497  eMode = VclMessageType::Other;
2498  else
2499  {
2500  SAL_WARN("vcl.layout", "unknown message type mode" << rValue);
2501  }
2502  m_eMessageType = eMode;
2503  }
2504  else if (rKey == "buttons")
2505  {
2507  if (rValue == "none")
2508  eMode = VclButtonsType::NONE;
2509  else if (rValue == "ok")
2510  eMode = VclButtonsType::Ok;
2511  else if (rValue == "cancel")
2512  eMode = VclButtonsType::Cancel;
2513  else if (rValue == "close")
2514  eMode = VclButtonsType::Close;
2515  else if (rValue == "yes-no")
2516  eMode = VclButtonsType::YesNo;
2517  else if (rValue == "ok-cancel")
2518  eMode = VclButtonsType::OkCancel;
2519  else
2520  {
2521  SAL_WARN("vcl.layout", "unknown buttons type mode" << rValue);
2522  }
2523  m_eButtonsType = eMode;
2524  }
2525  else
2526  return Dialog::set_property(rKey, rValue);
2527  return true;
2528 }
2529 
2530 void MessageDialog::set_primary_text(const OUString &rPrimaryString)
2531 {
2532  m_sPrimaryString = rPrimaryString;
2533  if (m_pPrimaryMessage)
2534  {
2538  }
2539 }
2540 
2541 void MessageDialog::set_secondary_text(const OUString &rSecondaryString)
2542 {
2543  m_sSecondaryString = rSecondaryString;
2544  if (m_pSecondaryMessage)
2545  {
2549  }
2550 }
2551 
2553 {
2554  Dialog::StateChanged(nType);
2555  if (nType == StateChangedType::InitShow)
2556  {
2557  // MessageBox should be at least as wide as to see the title
2558  auto nTitleWidth = CalcTitleWidth();
2559  // Extra-Width for Close button
2560  nTitleWidth += mpWindowImpl->mnTopBorder;
2561  if (get_preferred_size().Width() < nTitleWidth)
2562  {
2563  set_width_request(nTitleWidth);
2564  DoInitialLayout();
2565  }
2566  }
2567 }
2568 
2569 VclPaned::VclPaned(vcl::Window *pParent, bool bVertical)
2570  : VclContainer(pParent, WB_HIDE | WB_CLIPCHILDREN)
2571  , m_pSplitter(VclPtr<Splitter>::Create(this, bVertical ? WB_VSCROLL : WB_HSCROLL))
2572  , m_nPosition(-1)
2573 {
2574  m_pSplitter->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor()));
2575  m_pSplitter->Show();
2576 }
2577 
2579 {
2582 }
2583 
2585  : VclPaned(pParent, true)
2586 {
2587  m_pSplitter->SetSplitHdl(LINK(this, VclVPaned, SplitHdl));
2588 }
2589 
2590 IMPL_LINK(VclVPaned, SplitHdl, Splitter*, pSplitter, void)
2591 {
2592  tools::Long nSize = pSplitter->GetSplitPosPixel();
2593  Size aSplitterSize(m_pSplitter->GetSizePixel());
2594  Size aAllocation(GetSizePixel());
2595  arrange(aAllocation, nSize, aAllocation.Height() - nSize - aSplitterSize.Height());
2596 }
2597 
2598 void VclVPaned::arrange(const Size& rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
2599 {
2600  Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2601  Size aFirstChildSize(rAllocation.Width(), nFirstHeight);
2602  Size aSecondChildSize(rAllocation.Width(), nSecondHeight);
2603  int nElement = 0;
2604  for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2605  pChild = pChild->GetWindow(GetWindowType::Next))
2606  {
2607  if (!pChild->IsVisible())
2608  continue;
2609  if (nElement == 0)
2610  {
2611  Point aSplitterPos(0, aFirstChildSize.Height());
2612  setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2613  m_nPosition = aSplitterPos.Y() + aSplitterSize.Height() / 2;
2614  }
2615  else if (nElement == 1)
2616  {
2617  Point aChildPos(0, 0);
2618  setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2619  }
2620  else if (nElement == 2)
2621  {
2622  Point aChildPos(0, aFirstChildSize.Height() + aSplitterSize.Height());
2623  setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2624  }
2625  ++nElement;
2626  }
2627 }
2628 
2630 {
2631  VclPaned::set_position(nPosition);
2632 
2633  Size aAllocation(GetSizePixel());
2634  Size aSplitterSize(m_pSplitter->GetSizePixel());
2635 
2636  nPosition -= aSplitterSize.Height() / 2;
2637 
2638  arrange(aAllocation, nPosition, aAllocation.Height() - nPosition - aSplitterSize.Height());
2639 }
2640 
2641 void VclVPaned::setAllocation(const Size& rAllocation)
2642 {
2643  //supporting "shrink" could be done by adjusting the allowed drag rectangle
2644  m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2645  Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2646  const tools::Long nHeight = rAllocation.Height() - aSplitterSize.Height();
2647 
2648  tools::Long nFirstHeight = 0;
2649  tools::Long nSecondHeight = 0;
2650  bool bFirstCanResize = true;
2651  bool bSecondCanResize = true;
2652  const bool bInitialAllocation = get_position() < 0;
2653  int nElement = 0;
2654  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2655  pChild = pChild->GetWindow(GetWindowType::Next))
2656  {
2657  if (!pChild->IsVisible())
2658  continue;
2659  if (nElement == 1)
2660  {
2661  if (bInitialAllocation)
2662  nFirstHeight = getLayoutRequisition(*pChild).Height();
2663  else
2664  nFirstHeight = pChild->GetSizePixel().Height() + pChild->get_margin_top() + pChild->get_margin_bottom();
2665  bFirstCanResize = pChild->get_expand();
2666  }
2667  else if (nElement == 2)
2668  {
2669  if (bInitialAllocation)
2670  nSecondHeight = getLayoutRequisition(*pChild).Height();
2671  else
2672  nSecondHeight = pChild->GetSizePixel().Height() + pChild->get_margin_top() + pChild->get_margin_bottom();
2673  bSecondCanResize = pChild->get_expand();
2674  }
2675  ++nElement;
2676  }
2677  tools::Long nHeightRequest = nFirstHeight + nSecondHeight;
2678  tools::Long nHeightDiff = nHeight - nHeightRequest;
2679  if (bFirstCanResize == bSecondCanResize)
2680  nFirstHeight += nHeightDiff/2;
2681  else if (bFirstCanResize)
2682  nFirstHeight += nHeightDiff;
2683  arrange(rAllocation, nFirstHeight, rAllocation.Height() - nFirstHeight - aSplitterSize.Height());
2684 }
2685 
2687 {
2688  Size aRet(0, 0);
2689 
2690  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2691  pChild = pChild->GetWindow(GetWindowType::Next))
2692  {
2693  if (!pChild->IsVisible())
2694  continue;
2695  Size aChildSize = getLayoutRequisition(*pChild);
2696  aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2697  aRet.AdjustHeight(aChildSize.Height() );
2698  }
2699 
2700  return aRet;
2701 }
2702 
2704  : VclPaned(pParent, false)
2705 {
2706  m_pSplitter->SetSplitHdl(LINK(this, VclHPaned, SplitHdl));
2707 }
2708 
2709 IMPL_LINK(VclHPaned, SplitHdl, Splitter*, pSplitter, void)
2710 {
2711  tools::Long nSize = pSplitter->GetSplitPosPixel();
2712  Size aSplitterSize(m_pSplitter->GetSizePixel());
2713  Size aAllocation(GetSizePixel());
2714  arrange(aAllocation, nSize, aAllocation.Width() - nSize - aSplitterSize.Width());
2715 }
2716 
2717 void VclHPaned::arrange(const Size& rAllocation, tools::Long nFirstWidth, tools::Long nSecondWidth)
2718 {
2719  Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2720  Size aFirstChildSize(nFirstWidth, rAllocation.Height());
2721  Size aSecondChildSize(nSecondWidth, rAllocation.Height());
2722  int nElement = 0;
2723  for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2724  pChild = pChild->GetWindow(GetWindowType::Next))
2725  {
2726  if (!pChild->IsVisible())
2727  continue;
2728  if (nElement == 0)
2729  {
2730  Point aSplitterPos(aFirstChildSize.Width(), 0);
2731  setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2732  m_nPosition = aSplitterPos.X() + aSplitterSize.Width() / 2;
2733  }
2734  else if (nElement == 1)
2735  {
2736  Point aChildPos(0, 0);
2737  setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2738  }
2739  else if (nElement == 2)
2740  {
2741  Point aChildPos(aFirstChildSize.Width() + aSplitterSize.Width(), 0);
2742  setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2743  }
2744  ++nElement;
2745  }
2746 }
2747 
2749 {
2750  VclPaned::set_position(nPosition);
2751 
2752  Size aAllocation(GetSizePixel());
2753  Size aSplitterSize(m_pSplitter->GetSizePixel());
2754 
2755  nPosition -= aSplitterSize.Width() / 2;
2756 
2757  arrange(aAllocation, nPosition, aAllocation.Width() - nPosition - aSplitterSize.Width());
2758 }
2759 
2760 void VclHPaned::setAllocation(const Size& rAllocation)
2761 {
2762  //supporting "shrink" could be done by adjusting the allowed drag rectangle
2763  m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2764  Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2765  const tools::Long nWidth = rAllocation.Width() - aSplitterSize.Width();
2766 
2767  tools::Long nFirstWidth = 0;
2768  tools::Long nSecondWidth = 0;
2769  bool bFirstCanResize = true;
2770  bool bSecondCanResize = true;
2771  const bool bInitialAllocation = get_position() < 0;
2772  int nElement = 0;
2773  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2774  pChild = pChild->GetWindow(GetWindowType::Next))
2775  {
2776  if (!pChild->IsVisible())
2777  continue;
2778  if (nElement == 1)
2779  {
2780  if (bInitialAllocation)
2781  nFirstWidth = getLayoutRequisition(*pChild).Width();
2782  else
2783  nFirstWidth = pChild->GetSizePixel().Width() + pChild->get_margin_start() + pChild->get_margin_end();
2784  bFirstCanResize = pChild->get_expand();
2785  }
2786  else if (nElement == 2)
2787  {
2788  if (bInitialAllocation)
2789  nSecondWidth = getLayoutRequisition(*pChild).Width();
2790  else
2791  nSecondWidth = pChild->GetSizePixel().Width() + pChild->get_margin_start() + pChild->get_margin_end();
2792  bSecondCanResize = pChild->get_expand();
2793  }
2794  ++nElement;
2795  }
2796  tools::Long nWidthRequest = nFirstWidth + nSecondWidth;
2797  tools::Long nWidthDiff = nWidth - nWidthRequest;
2798  if (bFirstCanResize == bSecondCanResize)
2799  nFirstWidth += nWidthDiff/2;
2800  else if (bFirstCanResize)
2801  nFirstWidth += nWidthDiff;
2802  arrange(rAllocation, nFirstWidth, rAllocation.Width() - nFirstWidth - aSplitterSize.Width());
2803 }
2804 
2806 {
2807  Size aRet(0, 0);
2808 
2809  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2810  pChild = pChild->GetWindow(GetWindowType::Next))
2811  {
2812  if (!pChild->IsVisible())
2813  continue;
2814  Size aChildSize = getLayoutRequisition(*pChild);
2815  aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2816  aRet.AdjustWidth(aChildSize.Width() );
2817  }
2818 
2819  return aRet;
2820 }
2821 
2823 {
2824  tools::Rectangle aBounds;
2825 
2826  for (const vcl::Window* pChild = rWindow.GetWindow(GetWindowType::FirstChild); pChild;
2827  pChild = pChild->GetWindow(GetWindowType::Next))
2828  {
2829  if (!pChild->IsVisible())
2830  continue;
2831 
2832  tools::Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
2833  aBounds.Union(aChildBounds);
2834  }
2835 
2836  if (aBounds.IsEmpty())
2837  return rWindow.GetSizePixel();
2838 
2839  Size aRet(aBounds.GetSize());
2840  Point aTopLeft(aBounds.TopLeft());
2841  aRet.AdjustWidth(aTopLeft.X()*2 );
2842  aRet.AdjustHeight(aTopLeft.Y()*2 );
2843 
2844  return aRet;
2845 }
2846 
2848 {
2849  while (pWindow)
2850  {
2851  pWindow = pWindow->GetParent();
2852  if (!pWindow || !isContainerWindow(*pWindow))
2853  break;
2854  }
2855  return pWindow;
2856 }
2857 
2858 bool isVisibleInLayout(const vcl::Window *pWindow)
2859 {
2860  bool bVisible = true;
2861  while (bVisible)
2862  {
2863  bVisible = pWindow->IsVisible();
2864  pWindow = pWindow->GetParent();
2865  if (!pWindow || !isContainerWindow(*pWindow))
2866  break;
2867  }
2868  return bVisible;
2869 }
2870 
2871 bool isEnabledInLayout(const vcl::Window *pWindow)
2872 {
2873  bool bEnabled = true;
2874  while (bEnabled)
2875  {
2876  bEnabled = pWindow->IsEnabled();
2877  pWindow = pWindow->GetParent();
2878  if (!pWindow || !isContainerWindow(*pWindow))
2879  break;
2880  }
2881  return bEnabled;
2882 }
2883 
2884 bool isLayoutEnabled(const vcl::Window *pWindow)
2885 {
2886  //Child is a container => we're layout enabled
2887  const vcl::Window *pChild = pWindow ? pWindow->GetWindow(GetWindowType::FirstChild) : nullptr;
2888  return pChild && isContainerWindow(*pChild) && !pChild->GetWindow(GetWindowType::Next);
2889 }
2890 
2892 {
2893  if (m_aStartDragHdl.Call(this))
2894  return;
2895 
2897  if (!m_xTransferHelper.is())
2898  return;
2899 
2900  xContainer->StartDrag(this, m_nDragAction);
2901 }
2902 
2904 {
2905  if (!m_aGetSurroundingHdl.IsSet())
2906  return Control::GetSurroundingText();
2907  OUString sSurroundingText;
2908  m_aGetSurroundingHdl.Call(sSurroundingText);
2909  return sSurroundingText;
2910 }
2911 
2913 {
2914  if (!m_aGetSurroundingHdl.IsSet())
2916  OUString sSurroundingText;
2917  int nCursor = m_aGetSurroundingHdl.Call(sSurroundingText);
2918  return Selection(nCursor, nCursor);
2919 }
2920 
2922 {
2924  return Control::DeleteSurroundingText(rSelection);
2925  return m_aDeleteSurroundingHdl.Call(rSelection);
2926 }
2927 
2929 {
2930 }
2931 
2933 {
2934 }
2935 
2937 {
2938  disposeOnce();
2939 }
2940 
2942 {
2943  disposeOnce();
2944 }
2945 
2947 {
2948  Control::DumpAsPropertyTree(rJsonWriter);
2949  rJsonWriter.put("type", "drawingarea");
2950 
2952  pDevice->SetOutputSize( GetSizePixel() );
2953  tools::Rectangle aRect(Point(0,0), GetSizePixel());
2954  Paint(*pDevice, aRect);
2955  BitmapEx aImage = pDevice->GetBitmapEx( Point(0,0), GetSizePixel() );
2956  SvMemoryStream aOStm(65535, 65535);
2958  {
2959  css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
2960  OUStringBuffer aBuffer("data:image/png;base64,");
2962  rJsonWriter.put("image", aBuffer.makeStringAndClear());
2963  }
2964  rJsonWriter.put("text", GetQuickHelpText());
2965 }
2966 
2968 {
2969  if (m_pFactoryFunction)
2970  return m_pFactoryFunction;
2972 }
2973 
2974 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void set_position(tools::Long nPosition)
Definition: layout.hxx:392
virtual Point GetPosPixel() const
Definition: window.cxx:2780
static OUString GetDisplayName()
Get the default name of the application for message dialogs and printing.
Definition: svapp.cxx:1212
virtual void SetText(const OUString &rStr)
Definition: window.cxx:3015
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: window3.cxx:65
virtual Selection GetSurroundingTextSelection() const override
Definition: layout.cxx:2912
Size GetSizePixel() const
Definition: Image.cxx:86
const Color & GetShadowColor() const
virtual sal_uInt16 getDefaultAccessibleRole() const override
Definition: layout.cxx:48
Image const & GetStandardInfoBoxImage()
Definition: stdtext.cxx:49
virtual ~VclExpander() override
Definition: layout.cxx:1630
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:2479
tools::Long m_nPosition
Definition: layout.hxx:385
bool m_bColumnHomogeneous
Definition: layout.hxx:317
virtual void setAllocation(const Size &rAllocation)=0
void SetBackground()
Definition: window3.cxx:100
int get_column_spacing() const
Definition: layout.hxx:361
void SetDragRectPixel(const tools::Rectangle &rDragRect, vcl::Window *pRefWin=nullptr)
Definition: split.cxx:445
Point GetPointerPosPixel()
Definition: mouse.cxx:556
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:1369
sal_Int32 get_padding() const
Definition: window2.cxx:1763
void setDeferredProperties()
Definition: dialog.cxx:1572
static VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1167
virtual void SetPosPixel(const Point &rAllocPos) override
Definition: layout.cxx:161
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:2030
static void setLayoutAllocation(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
Definition: layout.cxx:70
Image const & GetStandardWarningBoxImage()
Definition: stdtext.cxx:60
void sort_native_button_order(const VclBox &rContainer)
Definition: layout.cxx:839
DrawFrameFlags m_eDrawFrameFlags
Definition: layout.hxx:511
void SetFontSize(const Size &)
Definition: font/font.cxx:127
bool get_vexpand() const
Definition: window2.cxx:1727
void arrange(const Size &rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
Definition: layout.cxx:2717
bool bVisible
bool isVisibleInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2858
void InitScrollBars(const Size &rRequest)
Definition: layout.cxx:1888
WinBits const WB_NOLABEL
VclPtr< ScrollBar > m_pHScroll
Definition: layout.hxx:513
virtual void setSecondaryDimension(Size &rSize, tools::Long) const =0
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void set_border_width(sal_Int32 nBorderWidth)
Definition: window2.cxx:1835
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: layout.cxx:2578
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:1755
OUString const & get_secondary_text() const
Definition: layout.cxx:2472
static void SetMessagesWidths(vcl::Window const *pParent, VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
Definition: layout.cxx:2448
sal_Int32 get_margin_bottom() const
Definition: window2.cxx:1905
void setWidth(tools::Long nWidth)
void designate_label(vcl::Window *pWindow)
Definition: layout.cxx:1476
VclButtonsType
Definition: vclenum.hxx:244
static array_type assembleGrid(const VclGrid &rGrid)
Definition: layout.cxx:881
VclBox * get_content_area()
Definition: dialog.hxx:117
void create_message_area()
Definition: layout.cxx:2234
virtual Size GetOptimalSize() const override
Definition: layout.cxx:53
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1446
const CommandEvent * GetCommandEvent() const
Definition: event.hxx:332
std::unique_ptr< ContentProperties > pData
VclPtr< vcl::Window > m_pLabel
Definition: layout.hxx:426
void set_grid_left_attach(sal_Int32 nAttach)
Definition: window2.cxx:1805
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:617
OUString GetStandardText(StandardButtonType eButton)
Definition: stdtext.cxx:93
void SetStyleSettings(const StyleSettings &rSet)
signed char sal_Int8
SAL_DLLPRIVATE float approximate_char_width() const
Definition: window3.cxx:61
void SetMonoColor(const Color &rColor)
bool m_bVerticalContainer
Definition: layout.hxx:74
virtual ~VclPaned() override
Definition: layout.cxx:2936
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
OUString GetStandardErrorBoxText()
Definition: stdtext.cxx:77
VclPtr< DisclosureButton > m_pDisclosureButton
Definition: layout.hxx:477
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:2552
bool get_hexpand() const
Definition: window2.cxx:1715
static Size getLayoutRequisition(const vcl::Window &rWindow)
Definition: layout.cxx:145
long Long
OUString const & get_primary_text() const
Definition: layout.cxx:2465
VclPtr< VclMultiLineEdit > m_pSecondaryMessage
void disposeAndClear()
Definition: vclptr.hxx:200
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:733
SAL_DLLPRIVATE void disposeOwnedButtons()
Definition: dialog.cxx:380
VclPtr< VclVBox > m_pMessageBox
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:824
SAL_DLLPRIVATE const tools::Rectangle & GetStateRect() const
Definition: button.hxx:317
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1231
VclButtonsType m_eButtonsType
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
virtual Size GetSizePixel() const
Definition: window.cxx:2391
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:2946
void updateBorderWidth(tools::Long nBorderWidth)
Definition: layout.cxx:2080
void EnableCursor(bool bEnable)
Definition: vclmedit.cxx:1460
void SetWeight(FontWeight)
Definition: font/font.cxx:225
bool m_bRowHomogeneous
Definition: layout.hxx:316
WinBits const WB_AUTOVSCROLL
void set_row_spacing(int nSpacing)
Definition: layout.hxx:349
virtual Size calculateRequisition() const override
Definition: layout.cxx:1426
tools::Long CalcTitleWidth() const
Definition: window.cxx:2038
sal_uInt16 GetCode() const
Definition: keycod.hxx:51
VclPtr< VclBox > m_pOwnedContentArea
void set_spacing(int nSpacing)
Definition: layout.hxx:84
virtual vcl::Window * get_child() override
Definition: layout.cxx:1515
WinBits const WB_VSCROLL
Info
const CommandWheelData * GetWheelData() const
bool m_bExpand
Definition: layout.hxx:325
VclButtonBoxStyle
Definition: layout.hxx:198
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: window.cxx:137
void SetRangeMax(tools::Long nNewRange)
Definition: scrbar.cxx:1333
void SetType(WindowType nType)
Definition: window2.cxx:967
constexpr sal_uInt16 KEY_ADD
Definition: keycodes.hxx:127
virtual void dispose() override
Definition: layout.cxx:1831
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1702
float x
TRISTATE_TRUE
tools::Long m_nBorderWidth
Definition: layout.hxx:509
VclContainer(vcl::Window *pParent, WinBits nStyle=WB_HIDE|WB_CLIPCHILDREN)
Definition: layout.cxx:38
bool get_fill() const
Definition: window2.cxx:1775
virtual tools::Long getSecondaryDimension(const Size &rSize) const =0
static const OUString & GetDesktopEnvironment()
Get the desktop environment the process is currently running in.
Definition: svapp.cxx:1602
void create_owned_areas()
Definition: layout.cxx:2362
NONE
virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const =0
sal_Int32 get_margin_start() const
Definition: window2.cxx:1857
std::vector< tools::Long > m_aMainGroupDimensions
Definition: layout.hxx:226
virtual void set_position(tools::Long nPosition) override
Definition: layout.cxx:2748
static std::vector< tools::Long > setButtonSizes(const std::vector< tools::Long > &rG, const std::vector< bool > &rNonHomogeneous, tools::Long nAvgDimension, tools::Long nMaxNonOutlier, tools::Long nMinWidth)
Definition: layout.cxx:444
OUString GetStandardQueryBoxText()
Definition: stdtext.cxx:88
WEIGHT_BOLD
StateChangedType
Definition: window.hxx:289
const sal_uInt8 A
constexpr tools::Long Width() const
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3216
rtl::Reference< TransferDataContainer > m_xTransferHelper
Definition: layout.hxx:625
OUString GetAccessibleName() const
sal_Int64 WinBits
virtual void dispose() override
Definition: layout.cxx:2173
Link< OUString &, int > m_aGetSurroundingHdl
Definition: layout.hxx:637
void SetControlFont()
Definition: window2.cxx:403
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: dialog.cxx:620
std::set< VclPtr< vcl::Window > > m_aWindows
Definition: layout.hxx:579
virtual void dispose() override
Definition: layout.cxx:1418
void SetPageSize(tools::Long nNewSize)
Definition: scrbar.hxx:125
bool m_bLayoutDirty
Definition: layout.hxx:67
void set_ignore_hidden(bool bIgnoreHidden)
Definition: layout.cxx:2188
const vcl::Font & GetLabelFont() const
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: window.cxx:3347
virtual Size calculateRequisition() const =0
WinBits const WB_DEFBUTTON
OUString get_label() const
Definition: layout.cxx:1650
enumrange< T >::Iterator begin(enumrange< T >)
Size addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
Definition: layout.cxx:568
uno::Type m_aType
WinBits const WB_VERT
VclMessageType m_eMessageType
DrawImageFlags
WinBits const WB_HSCROLL
bool IsMouseEvent() const
boost::multi_array< GridEntry, 2 > array_type
Definition: layout.cxx:875
virtual OUString GetSurroundingText() const override
Definition: layout.cxx:2903
void reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
Definition: builder.cxx:2274
void Hide()
Definition: window.hxx:897
virtual FactoryFunction GetUITestFactory() const override
Definition: layout.cxx:2967
VclSizeGroupMode
Definition: vclenum.hxx:263
VclPtr< vcl::Window > mpLastChild
Definition: window.h:233
void set_default_response(int nResponse)
Definition: dialog.cxx:1524
constexpr tools::Long GetWidth() const
virtual ~VclHPaned() override
Definition: layout.cxx:2928
Mode eMode
sal_Int8 m_nDragAction
Definition: layout.hxx:626
static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1162
void set_width_request(sal_Int32 nWidthRequest)
Definition: window2.cxx:1624
sal_uInt16 GetModifier() const
Definition: keycod.hxx:54
virtual OUString GetText() const
Definition: window.cxx:3044
void set_mode(VclSizeGroupMode eMode)
Definition: layout.cxx:2197
VclMessageType
Definition: vclenum.hxx:254
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:2163
static tools::Long getMaxNonOutlier(const std::vector< tools::Long > &rG, tools::Long nAvgDimension)
Definition: layout.cxx:430
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
void * GetEventData() const
virtual void setPrimaryDimension(Size &rSize, tools::Long) const =0
bool get_secondary() const
Definition: window2.cxx:1923
WinBits const WB_HIDE
TriState GetState() const
Definition: button.hxx:341
virtual Selection GetSurroundingTextSelection() const
Definition: window.cxx:3764
Link< VclDrawingArea *, bool > m_aStartDragHdl
Definition: layout.hxx:639
bool m_bResizeTopLevel
Definition: layout.hxx:476
bool isContainerWindow(const vcl::Window &rWindow)
Definition: layout.hxx:835
constexpr bool IsEmpty() const
float y
bool mbInDispose
Definition: window.h:312
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
Size getLegacyBestSizeForChildren(const vcl::Window &rWindow)
Definition: layout.cxx:2822
const OString & GetHelpId() const
Definition: window2.cxx:822
Size finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
Definition: layout.cxx:398
virtual Size calculateRequisition() const override
Definition: layout.cxx:2686
void clear()
Definition: vclptr.hxx:190
virtual bool DeleteSurroundingText(const Selection &rSelection)
Definition: window.cxx:3793
virtual bool DeleteSurroundingText(const Selection &rSelection) override
Definition: layout.cxx:2921
bool isEnabledInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2871
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:706
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: dialog.cxx:1382
virtual ~VclFrame() override
Definition: layout.cxx:1413
VclPackType
Definition: vclenum.hxx:222
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:248
void set_property(const OString &rKey, const OUString &rValue)
Definition: layout.cxx:2207
int i
virtual OUString GetSurroundingText() const
Definition: window.cxx:3759
VclPtr< ScrollBarBox > m_aScrollBarBox
Definition: layout.hxx:514
VclPtr< VclButtonBox > m_pOwnedActionArea
DrawFrameStyle m_eDrawFrameStyle
Definition: layout.hxx:510
VclPtr< ScrollBar > m_pVScroll
Definition: layout.hxx:512
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: layout.cxx:2058
bool get_expanded() const
Definition: layout.cxx:1635
virtual void DumpAsPropertyTree(tools::JsonWriter &rJsonWriter) override
Definition: layout.cxx:1788
int get_default_response() const
Definition: dialog.cxx:1484
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:1358
bool m_bIgnoreHidden
Definition: layout.hxx:580
virtual ~VclScrolledWindow() override
Definition: layout.cxx:2941
std::unique_ptr< Image > mpDisclosureMinus
Definition: svdata.hxx:274
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:95
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2641
void SetVisibleSize(tools::Long nNewSize)
Definition: scrbar.cxx:1376
void SetSplitHdl(const Link< Splitter *, void > &rLink)
Definition: split.hxx:99
OUString get_label() const
Definition: layout.cxx:1527
CommandWheelMode GetMode() const
WinBits const WB_VCENTER
virtual void SetSizePixel(const Size &rAllocation) override
Definition: layout.cxx:172
sal_Int32 get_margin_top() const
Definition: window2.cxx:1889
#define DEFAULT_CHILD_MIN_WIDTH
Definition: layout.cxx:395
virtual sal_uInt16 getDefaultAccessibleRole() const override
Definition: layout.cxx:384
void arrange(const Size &rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
Definition: layout.cxx:2598
Size calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
Definition: layout.cxx:1180
Requisition calculatePrimarySecondaryRequisitions() const
Definition: layout.cxx:469
Image const & GetStandardErrorBoxImage()
Definition: stdtext.cxx:71
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:162
const AllSettings & GetSettings() const
Definition: window3.cxx:129
CommandEventId GetCommand() const
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1220
sal_uInt16 GetModifier() const
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:195
bool IsChecked() const
Definition: button.hxx:348
void add_button(PushButton *pButton, int nResponse, bool bTransferOwnership)
Definition: dialog.cxx:1414
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:496
const Size & GetFontSize() const
Definition: font/font.cxx:832
Size get_preferred_size() const
Definition: window2.cxx:1660
VclSizeGroupMode m_eMode
Definition: layout.hxx:581
bool isLayoutEnabled(const vcl::Window *pWindow)
Definition: layout.cxx:2884
MouseNotifyEvent GetType() const
Definition: event.hxx:308
VclPtr< FixedImage > m_pImage
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:591
virtual void setPrimaryCoordinate(Point &rPos, tools::Long) const =0
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
void SetToggleHdl(const Link< CheckBox &, void > &rLink)
Definition: button.hxx:361
void set_homogeneous(bool bHomogeneous)
Definition: layout.hxx:92
virtual void dispose() override
Definition: layout.cxx:1655
virtual Size calculateRequisition() const override
Definition: layout.cxx:583
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1026
void SetImage(const Image &rImage)
Definition: fixed.cxx:937
VclPtr< Splitter > m_pSplitter
Definition: layout.hxx:384
bool get_row_homogeneous() const
Definition: layout.hxx:341
virtual bool set_property(const OString &rKey, const OUString &rValue)
Definition: window2.cxx:1444
static void setLayoutPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
Definition: layout.cxx:58
void reorderWithinParent(sal_uInt16 nNewPosition)
Definition: stacking.cxx:162
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: layout.cxx:1605
FactoryFunction m_pFactoryFunction
Definition: layout.hxx:623
void Check(bool bCheck=true)
Definition: button.hxx:343
VclPackType get_pack_type() const
Definition: window2.cxx:1751
bool get_orientation() const
Definition: layout.hxx:96
vcl::Window * GetParent() const
Definition: window2.cxx:1096
sal_Int32 get_margin_end() const
Definition: window2.cxx:1873
virtual void ImplDrawCheckBoxState(vcl::RenderContext &rRenderContext) override
Definition: layout.cxx:1550
WinBits const WB_LEFT
void SetStyle(WinBits nStyle)
Definition: window.cxx:1952
enumrange< T >::Iterator end(enumrange< T >)
void put(const char *pPropName, const OUString &rPropValue)
void setOptimalLayoutSize()
Definition: syswin.cxx:1073
void Scroll()
Definition: scrbar.cxx:1293
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1267
constexpr Point TopLeft() const
bool get_expand() const
Definition: window2.cxx:1739
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.hxx:641
virtual tools::Long getPrimaryCoordinate(const Point &rPos) const =0
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
DrawFrameStyle
Definition: vclenum.hxx:336
Size getVisibleChildSize() const
Definition: layout.cxx:2018
const Point & GetMousePosPixel() const
DisclosureButton(vcl::Window *pParent)
Definition: layout.cxx:1600
virtual Size calculateRequisition() const override
Definition: layout.cxx:2805
void set_grid_top_attach(sal_Int32 nAttach)
Definition: window2.cxx:1829
bool m_bInitialAllocation
Definition: layout.hxx:527
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:935
#define DEFAULT_CHILD_MIN_HEIGHT
Definition: layout.cxx:396
WinBits const WB_3DLOOK
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2135
VclScrolledWindow(vcl::Window *pParent)
Definition: layout.cxx:1808
DrawButtonFlags GetButtonState() const
Definition: button.cxx:520
VclButtonBox * get_action_area()
Definition: dialog.hxx:116
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3912
static ErrCode Export(SvStream &rOStm, const Graphic &rGraphic, ConvertDataFormat nFormat)
Definition: cvtgrf.cxx:55
VclPtr< VclGrid > m_pGrid
void AddEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:302
void set_valign(VclAlign eAlign)
Definition: window2.cxx:1709
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
constexpr Size GetSize() const
virtual void StateChanged(StateChangedType nStateChange) override
Definition: dialog.cxx:754
virtual ~VclVPaned() override
Definition: layout.cxx:2932
std::unique_ptr< char[]> aBuffer
OUString GetStandardInfoBoxText()
Definition: stdtext.cxx:55
void SetMaxTextWidth(tools::Long nMaxWidth)
Definition: vclmedit.cxx:1058
virtual ~MessageDialog() override
Definition: layout.cxx:2443
bool IsMouseOver() const
Definition: mouse.cxx:612
virtual vcl::Window * get_child() override
Definition: layout.cxx:1863
virtual vcl::Window * get_child() override
Definition: layout.cxx:2130
constexpr sal_uInt16 KEY_SUBTRACT
Definition: keycodes.hxx:128
VclVPaned(vcl::Window *pParent)
Definition: layout.cxx:2584
sal_Int32 m_nPosition
void set_hexpand(bool bExpand)
Definition: window2.cxx:1721
WindowType
virtual Size calculateRequisition() const override
Definition: layout.cxx:1868
tools::Rectangle & Union(const tools::Rectangle &rRect)
bool get_column_homogeneous() const
Definition: layout.hxx:345
#define ERRCODE_NONE
Definition: errcode.hxx:196
constexpr tools::Long Height() const
void set_expanded(bool bExpanded)
Definition: layout.cxx:1640
void set_label(const OUString &rLabel)
Definition: layout.cxx:1645
virtual tools::Long getPrimaryDimension(const Size &rSize) const =0
int m_nSpacing
Definition: layout.hxx:75
VclExpander(vcl::Window *pParent)
Definition: layout.cxx:1621
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2103
bool toBool(std::u16string_view rValue)
Definition: layout.cxx:1364
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:378
Size addReqGroups(const VclButtonBox::Requisition &rReq) const
Definition: layout.cxx:414
vcl::Window * get_label_widget()
Definition: layout.cxx:1498
bool IsVisible() const
Definition: window2.cxx:1101
virtual vcl::Window * get_child() override
Definition: layout.cxx:1670
#define SAL_INFO(area, stream)
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2013
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
Definition: layout.cxx:2891
VclPtr< EventBoxHelper > m_aEventBoxHelper
Definition: layout.hxx:558
void set_column_spacing(int nSpacing)
Definition: layout.hxx:353
virtual Size calculateRequisition() const override
Definition: layout.cxx:2146
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1021
virtual OUString getDefaultAccessibleName() const override
Definition: layout.cxx:1534
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: layout.cxx:2430
VclPtr< VclMultiLineEdit > m_pPrimaryMessage
virtual void SetText(const OUString &rStr) override
Definition: syswin.cxx:1057
tools::Long AdjustWidth(tools::Long n)
void SetScrollHdl(const Link< ScrollBar *, void > &rLink)
Definition: scrbar.hxx:133
Definition: image.hxx:39
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
virtual Size calculateRequisition() const override
Definition: layout.cxx:1675
void set_content_area(VclBox *pBox)
Definition: dialog.cxx:602
sal_uInt64 Tell() const
void set_action_area(VclButtonBox *pBox)
Definition: dialog.cxx:591
Sequence< sal_Int8 > aSeq
virtual Size calculateRequisition() const override
Definition: layout.cxx:1175
VclAlign get_valign() const
Definition: window2.cxx:1703
MessageDialog(vcl::Window *pParent, WinBits nStyle)
Definition: layout.cxx:2377
WinBits const WB_AUTOHSCROLL
void set(reference_type *pBody)
Definition: vclptr.hxx:148
VclPtr< vcl::Window > mpFirstChild
Definition: window.h:232
tools::Long AdjustHeight(tools::Long n)
virtual ~VclEventBox() override
Definition: layout.cxx:2168
SAL_DLLPRIVATE const tools::Rectangle & GetMouseRect() const
Definition: button.hxx:318
Link< const Selection &, bool > m_aDeleteSurroundingHdl
Definition: layout.hxx:638
WinBits const WB_TABSTOP
Size GetOutputSizePixel() const
Definition: window3.cxx:89
IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent &, rEvent, void)
Definition: layout.cxx:1470
std::unique_ptr< Image > mpDisclosurePlus
Definition: svdata.hxx:273
vcl::Window * getNonLayoutParent(vcl::Window *pWindow)
Definition: layout.cxx:2847
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize) override
Definition: layout.cxx:150
void setHeight(tools::Long nHeight)
virtual void set_position(tools::Long nPosition) override
Definition: layout.cxx:2629
void doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
Definition: layout.cxx:1908
VclAlign
Definition: vclenum.hxx:214
WinBits const WB_CENTER
std::vector< tools::Long > m_aSubGroupDimensions
Definition: layout.hxx:227
OUString GetStandardWarningBoxText()
Definition: stdtext.cxx:66
void set_secondary_text(const OUString &rSecondaryString)
Definition: layout.cxx:2541
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool IsEnabled() const
Definition: window2.cxx:1121
#define SAL_WARN(area, stream)
void RemoveEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:307
virtual Size calculateRequisition() const override
Definition: layout.cxx:226
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2760
WinBits GetStyle() const
Definition: window2.cxx:952
OUString m_sPrimaryString
void set_primary_text(const OUString &rPrimaryString)
Definition: layout.cxx:2530
static int getButtonPriority(const OString &rType)
Definition: layout.cxx:749
WinBits const WB_CLOSEABLE
WinBits const WB_MOVEABLE
virtual void queue_resize(StateChangedType eReason=StateChangedType::Layout) override
Definition: layout.cxx:188
Image const & GetStandardQueryBoxImage()
Definition: stdtext.cxx:82
void accumulateMaxes(const Size &rChildSize, Size &rSize) const
Definition: layout.cxx:212
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Definition: layout.cxx:1542
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:1766
DrawFrameFlags
Definition: vclenum.hxx:348
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
int get_row_spacing() const
Definition: layout.hxx:357
WinBits const WB_HORZ
bool HasFocus() const
Definition: window.cxx:2970
bool m_bUserManagedScrolling
Definition: layout.hxx:508
bool m_bHomogeneous
Definition: layout.hxx:73
void set_label(const OUString &rLabel)
Definition: layout.cxx:1520
WinBits const WB_CLIPCHILDREN
sal_Int32 nState
WinBits const WB_NOTABSTOP
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.cxx:2090
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1256
IMPL_LINK_NOARG(VclScrolledWindow, ScrollBarHdl, ScrollBar *, void)
Definition: layout.cxx:1839
VclButtonBoxStyle m_eLayoutStyle
Definition: layout.hxx:223
virtual void SetText(const OUString &rStr) override
Definition: vclmedit.cxx:1103
sal_Int32 get_border_width() const
Definition: window2.cxx:1841
VclPaned(vcl::Window *pParent, bool bVertical)
Definition: layout.cxx:2569
SAL_DLLPRIVATE void DoInitialLayout()
Definition: syswin.cxx:1094
void trigger_queue_resize()
Definition: layout.cxx:2179
VclHPaned(vcl::Window *pParent)
Definition: layout.cxx:2703
const void * GetData()
tools::Long m_nValue
Definition: layout.hxx:324
tools::Long get_position() const
Definition: layout.hxx:391
static bool isNullGrid(const array_type &A)
Definition: layout.cxx:1036
VclAlign get_halign() const
Definition: window2.cxx:1691
static void calcMaxs(const array_type &A, std::vector< VclGrid::Value > &rWidths, std::vector< VclGrid::Value > &rHeights)
Definition: layout.cxx:1044
OUString m_sSecondaryString
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2177
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:367
vcl::Window * get_label_widget()
Definition: layout.cxx:1783