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