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/toolkit/button.hxx>
16 #include <vcl/cvtgrf.hxx>
17 #include <vcl/decoview.hxx>
18 #include <vcl/toolkit/dialog.hxx>
19 #include <vcl/layout.hxx>
20 #include <vcl/scrbar.hxx>
21 #include <vcl/stdtext.hxx>
22 #include <vcl/split.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/virdev.hxx>
26 #include <bitmaps.hlst>
27 #include <messagedialog.hxx>
28 #include <svdata.hxx>
29 #include <window.h>
30 #include <boost/multi_array.hpp>
31 #include <boost/property_tree/ptree.hpp>
32 #include <vcl/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_left() + nBorderWidth;
60  sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
61  sal_Int32 nRight = rWindow.get_margin_right() + 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_left() + nBorderWidth;
135  sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
136  sal_Int32 nRight = rWindow.get_margin_right() + 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_left() );
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_left() + get_margin_right()) );
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  long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
213  long nSecondaryBoxDimension = getSecondaryDimension(rSize);
214  setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
215 
216  long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
217  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  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  long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
263 
264  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  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  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  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  long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
324 
325  bool bFill = pChild->get_fill();
326  if (bFill)
327  {
328  setPrimaryDimension(aChildSize, std::max(static_cast<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  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  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  long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
409  long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
410 
411  setPrimaryDimension(aRet, nMainGroupDimension + nSubGroupDimension);
412 
416 
417  return aRet;
418 }
419 
420 static long getMaxNonOutlier(const std::vector<long> &rG, long nAvgDimension)
421 {
422  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<long> setButtonSizes(const std::vector<long> &rG,
435  const std::vector<bool> &rNonHomogeneous,
436  long nAvgDimension, long nMaxNonOutlier, long nMinWidth)
437 {
438  std::vector<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  long nMinMainGroupPrimary = getPrimaryDimension(aMainGroupSize);
467  long nMinSubGroupPrimary = getPrimaryDimension(aSubGroupSize);
468  long nMainGroupSecondary = getSecondaryDimension(aMainGroupSize);
469  long nSubGroupSecondary = getSecondaryDimension(aSubGroupSize);
470 
471  bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VclButtonBoxStyle::Spread || m_eLayoutStyle == VclButtonBoxStyle::Center);
472 
473  std::vector<long> aMainGroupSizes;
474  std::vector<bool> aMainGroupNonHomogeneous;
475  std::vector<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  long nMaxMainDimension = aMainGroupSizes.empty() ? 0 :
502  *std::max_element(aMainGroupSizes.begin(), aMainGroupSizes.end());
503  nMaxMainDimension = std::max(nMaxMainDimension, nMinMainGroupPrimary);
504  long nMaxSubDimension = aSubGroupSizes.empty() ? 0 :
505  *std::max_element(aSubGroupSizes.begin(), aSubGroupSizes.end());
506  nMaxSubDimension = std::max(nMaxSubDimension, nMinSubGroupPrimary);
507  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  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  long nAvgDimension = nTotalSize ? nAccDimension / nTotalSize : 0;
525 
526  long nMaxMainNonOutlier = getMaxNonOutlier(aMainGroupSizes,
527  nAvgDimension);
528  long nMaxSubNonOutlier = getMaxNonOutlier(aSubGroupSizes,
529  nAvgDimension);
530  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  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  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  long nOtherPrimaryDimension = getPrimaryDimension(
627  setPrimaryCoordinate(aOtherGroupPos,
628  nAllocPrimaryDimension - nOtherPrimaryDimension);
629  }
630  break;
632  if (!aReq.m_aMainGroupDimensions.empty())
633  {
634  long nMainPrimaryDimension = getPrimaryDimension(
636  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  long nMainPrimaryDimension = getPrimaryDimension(
647  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  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<long>::const_iterator aPrimaryI = aReq.m_aMainGroupDimensions.begin();
670  std::vector<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  long nMainGroupPrimaryDimension = *aPrimaryI++;
680  setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
681  setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
682  long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
683  setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + nSpacing);
684  }
685  else
686  {
687  long nSubGroupPrimaryDimension = *aSecondaryI++;
688  setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
689  setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
690  long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
691  setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + nSpacing);
692  }
693  }
694 }
695 
696 namespace {
697 
698 struct ButtonOrder
699 {
700  const char* m_aType;
701  int m_nPriority;
702 };
703 
704 }
705 
706 static int getButtonPriority(const OString &rType)
707 {
708  static const size_t N_TYPES = 6;
709  static const ButtonOrder aDiscardCancelSave[N_TYPES] =
710  {
711  { "/discard", 0 },
712  { "/cancel", 1 },
713  { "/no", 2 },
714  { "/save", 3 },
715  { "/yes", 3 },
716  { "/ok", 3 }
717  };
718 
719  static const ButtonOrder aSaveDiscardCancel[N_TYPES] =
720  {
721  { "/save", 0 },
722  { "/yes", 0 },
723  { "/ok", 0 },
724  { "/discard", 1 },
725  { "/no", 1 },
726  { "/cancel", 2 }
727  };
728 
729  const ButtonOrder* pOrder = &aDiscardCancelSave[0];
730 
731  const OUString &rEnv = Application::GetDesktopEnvironment();
732 
733  if (rEnv.equalsIgnoreAsciiCase("windows") ||
734  rEnv.equalsIgnoreAsciiCase("lxqt") ||
735  rEnv.startsWithIgnoreAsciiCase("plasma"))
736  {
737  pOrder = &aSaveDiscardCancel[0];
738  }
739 
740  for (size_t i = 0; i < N_TYPES; ++i, ++pOrder)
741  {
742  if (rType.endsWith(pOrder->m_aType))
743  return pOrder->m_nPriority;
744  }
745 
746  return -1;
747 }
748 
749 namespace {
750 
751 class sortButtons
752 {
753  bool m_bVerticalContainer;
754 public:
755  explicit sortButtons(bool bVerticalContainer)
756  : m_bVerticalContainer(bVerticalContainer)
757  {
758  }
759  bool operator()(const vcl::Window *pA, const vcl::Window *pB) const;
760 };
761 
762 }
763 
764 bool sortButtons::operator()(const vcl::Window *pA, const vcl::Window *pB) const
765 {
766  //sort into two groups of pack start and pack end
767  VclPackType ePackA = pA->get_pack_type();
768  VclPackType ePackB = pB->get_pack_type();
769  if (ePackA < ePackB)
770  return true;
771  if (ePackA > ePackB)
772  return false;
773  bool bPackA = pA->get_secondary();
774  bool bPackB = pB->get_secondary();
775  if (!m_bVerticalContainer)
776  {
777  //for horizontal boxes group secondaries before primaries
778  if (bPackA > bPackB)
779  return true;
780  if (bPackA < bPackB)
781  return false;
782  }
783  else
784  {
785  //for vertical boxes group secondaries after primaries
786  if (bPackA < bPackB)
787  return true;
788  if (bPackA > bPackB)
789  return false;
790  }
791 
792  //now order within groups according to platform rules
794 }
795 
797 {
798  std::vector<vcl::Window*> aChilds;
799  for (vcl::Window* pChild = rContainer.GetWindow(GetWindowType::FirstChild); pChild;
800  pChild = pChild->GetWindow(GetWindowType::Next))
801  {
802  aChilds.push_back(pChild);
803  }
804 
805  //sort child order within parent so that we match the platform
806  //button order
807  std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(rContainer.get_orientation()));
808  BuilderUtils::reorderWithinParent(aChilds, true);
809 }
810 
811 namespace {
812 
813 struct GridEntry
814 {
815  VclPtr<vcl::Window> pChild;
816  sal_Int32 nSpanWidth;
817  sal_Int32 nSpanHeight;
818  int x;
819  int y;
820  GridEntry()
821  : pChild(nullptr)
822  , nSpanWidth(0)
823  , nSpanHeight(0)
824  , x(-1)
825  , y(-1)
826  {
827  }
828 };
829 
830 }
831 
832 typedef boost::multi_array<GridEntry, 2> array_type;
833 
834 static array_type assembleGrid(const VclGrid &rGrid);
835 static bool isNullGrid(const array_type& A);
836 static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights);
837 
838 array_type assembleGrid(const VclGrid &rGrid)
839 {
840  array_type A;
841 
842  for (vcl::Window* pChild = rGrid.GetWindow(GetWindowType::FirstChild); pChild;
843  pChild = pChild->GetWindow(GetWindowType::Next))
844  {
845  sal_Int32 nLeftAttach = std::max<sal_Int32>(pChild->get_grid_left_attach(), 0);
846  sal_Int32 nWidth = pChild->get_grid_width();
847  sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
848 
849  sal_Int32 nTopAttach = std::max<sal_Int32>(pChild->get_grid_top_attach(), 0);
850  sal_Int32 nHeight = pChild->get_grid_height();
851  sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
852 
853  sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
854  sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
855  if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
856  {
857  nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
858  nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
859  A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
860  }
861 
862  GridEntry &rEntry = A[nLeftAttach][nTopAttach];
863  rEntry.pChild = pChild;
864  rEntry.nSpanWidth = nWidth;
865  rEntry.nSpanHeight = nHeight;
866  rEntry.x = nLeftAttach;
867  rEntry.y = nTopAttach;
868 
869  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
870  {
871  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
872  {
873  GridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
874  rSpan.x = nLeftAttach;
875  rSpan.y = nTopAttach;
876  }
877  }
878  }
879 
880  //see if we have any empty rows/cols
881  sal_Int32 nMaxX = A.shape()[0];
882  sal_Int32 nMaxY = A.shape()[1];
883 
884  std::vector<bool> aNonEmptyCols(nMaxX);
885  std::vector<bool> aNonEmptyRows(nMaxY);
886 
887  for (sal_Int32 x = 0; x < nMaxX; ++x)
888  {
889  for (sal_Int32 y = 0; y < nMaxY; ++y)
890  {
891  const GridEntry &rEntry = A[x][y];
892  const vcl::Window *pChild = rEntry.pChild;
893  if (pChild && pChild->IsVisible())
894  {
895  aNonEmptyCols[x] = true;
896  if (rGrid.get_column_homogeneous())
897  {
898  for (sal_Int32 nSpanX = 1; nSpanX < rEntry.nSpanWidth; ++nSpanX)
899  aNonEmptyCols[x+nSpanX] = true;
900  }
901  aNonEmptyRows[y] = true;
902  if (rGrid.get_row_homogeneous())
903  {
904  for (sal_Int32 nSpanY = 1; nSpanY < rEntry.nSpanHeight; ++nSpanY)
905  aNonEmptyRows[y+nSpanY] = true;
906  }
907  }
908  }
909  }
910 
911  if (!rGrid.get_column_homogeneous())
912  {
913  //reduce the spans of elements that span empty columns
914  for (sal_Int32 x = 0; x < nMaxX; ++x)
915  {
916  std::set<GridEntry*> candidates;
917  for (sal_Int32 y = 0; y < nMaxY; ++y)
918  {
919  if (aNonEmptyCols[x])
920  continue;
921  GridEntry &rSpan = A[x][y];
922  //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
923  //just points back to itself if there's no cell spanning
924  if ((rSpan.x == -1) || (rSpan.y == -1))
925  {
926  //there is no entry for this cell, i.e. this is a cell
927  //with no widget in it, or spanned by any other widget
928  continue;
929  }
930  GridEntry &rEntry = A[rSpan.x][rSpan.y];
931  candidates.insert(&rEntry);
932  }
933  for (auto const& candidate : candidates)
934  {
935  GridEntry *pEntry = candidate;
936  --pEntry->nSpanWidth;
937  }
938  }
939  }
940 
941  if (!rGrid.get_row_homogeneous())
942  {
943  //reduce the spans of elements that span empty rows
944  for (sal_Int32 y = 0; y < nMaxY; ++y)
945  {
946  std::set<GridEntry*> candidates;
947  for (sal_Int32 x = 0; x < nMaxX; ++x)
948  {
949  if (aNonEmptyRows[y])
950  continue;
951  GridEntry &rSpan = A[x][y];
952  //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
953  //just points back to itself if there's no cell spanning
954  if ((rSpan.x == -1) || (rSpan.y == -1))
955  {
956  //there is no entry for this cell, i.e. this is a cell
957  //with no widget in it, or spanned by any other widget
958  continue;
959  }
960  GridEntry &rEntry = A[rSpan.x][rSpan.y];
961  candidates.insert(&rEntry);
962  }
963  for (auto const& candidate : candidates)
964  {
965  GridEntry *pEntry = candidate;
966  --pEntry->nSpanHeight;
967  }
968  }
969  }
970 
971  sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
972  sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
973 
974  //make new grid without empty rows and columns
975  array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
976  for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
977  {
978  if (!aNonEmptyCols[x])
979  continue;
980  for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
981  {
982  if (!aNonEmptyRows[y])
983  continue;
984  GridEntry &rEntry = A[x][y];
985  B[x2][y2++] = rEntry;
986  }
987  ++x2;
988  }
989 
990  return B;
991 }
992 
993 static bool isNullGrid(const array_type &A)
994 {
995  sal_Int32 nMaxX = A.shape()[0];
996  sal_Int32 nMaxY = A.shape()[1];
997 
998  return !nMaxX || !nMaxY;
999 }
1000 
1001 static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights)
1002 {
1003  sal_Int32 nMaxX = A.shape()[0];
1004  sal_Int32 nMaxY = A.shape()[1];
1005 
1006  rWidths.resize(nMaxX);
1007  rHeights.resize(nMaxY);
1008 
1009  //first use the non spanning entries to set default width/heights
1010  for (sal_Int32 x = 0; x < nMaxX; ++x)
1011  {
1012  for (sal_Int32 y = 0; y < nMaxY; ++y)
1013  {
1014  const GridEntry &rEntry = A[x][y];
1015  const vcl::Window *pChild = rEntry.pChild;
1016  if (!pChild || !pChild->IsVisible())
1017  continue;
1018 
1019  sal_Int32 nWidth = rEntry.nSpanWidth;
1020  sal_Int32 nHeight = rEntry.nSpanHeight;
1021 
1022  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1023  rWidths[x+nSpanX].m_bExpand |= pChild->get_hexpand();
1024 
1025  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1026  rHeights[y+nSpanY].m_bExpand |= pChild->get_vexpand();
1027 
1028  if (nWidth == 1 || nHeight == 1)
1029  {
1030  Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1031  if (nWidth == 1)
1032  rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
1033  if (nHeight == 1)
1034  rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
1035  }
1036  }
1037  }
1038 
1039  //now use the spanning entries and split any extra sizes across expanding rows/cols
1040  //where possible
1041  for (sal_Int32 x = 0; x < nMaxX; ++x)
1042  {
1043  for (sal_Int32 y = 0; y < nMaxY; ++y)
1044  {
1045  const GridEntry &rEntry = A[x][y];
1046  const vcl::Window *pChild = rEntry.pChild;
1047  if (!pChild || !pChild->IsVisible())
1048  continue;
1049 
1050  sal_Int32 nWidth = rEntry.nSpanWidth;
1051  sal_Int32 nHeight = rEntry.nSpanHeight;
1052 
1053  if (nWidth == 1 && nHeight == 1)
1054  continue;
1055 
1056  Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1057 
1058  if (nWidth > 1)
1059  {
1060  sal_Int32 nExistingWidth = 0;
1061  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1062  nExistingWidth += rWidths[x+nSpanX].m_nValue;
1063 
1064  sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
1065 
1066  if (nExtraWidth > 0)
1067  {
1068  bool bForceExpandAll = false;
1069  sal_Int32 nExpandables = 0;
1070  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1071  if (rWidths[x+nSpanX].m_bExpand)
1072  ++nExpandables;
1073  if (nExpandables == 0)
1074  {
1075  nExpandables = nWidth;
1076  bForceExpandAll = true;
1077  }
1078 
1079  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1080  {
1081  if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
1082  rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
1083  }
1084  }
1085  }
1086 
1087  if (nHeight > 1)
1088  {
1089  sal_Int32 nExistingHeight = 0;
1090  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1091  nExistingHeight += rHeights[y+nSpanY].m_nValue;
1092 
1093  sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
1094 
1095  if (nExtraHeight > 0)
1096  {
1097  bool bForceExpandAll = false;
1098  sal_Int32 nExpandables = 0;
1099  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1100  if (rHeights[y+nSpanY].m_bExpand)
1101  ++nExpandables;
1102  if (nExpandables == 0)
1103  {
1104  nExpandables = nHeight;
1105  bForceExpandAll = true;
1106  }
1107 
1108  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1109  {
1110  if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
1111  rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
1112  }
1113  }
1114  }
1115  }
1116  }
1117 }
1118 
1119 static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
1120 {
1121  return i.m_nValue < j.m_nValue;
1122 }
1123 
1125 {
1126  VclGrid::Value aRet;
1127  aRet.m_nValue = i.m_nValue + j.m_nValue;
1128  aRet.m_bExpand = i.m_bExpand || j.m_bExpand;
1129  return aRet;
1130 }
1131 
1133 {
1135 }
1136 
1137 Size VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
1138 {
1139  array_type A = assembleGrid(*this);
1140 
1141  if (isNullGrid(A))
1142  return Size();
1143 
1144  std::vector<Value> aWidths;
1145  std::vector<Value> aHeights;
1146  calcMaxs(A, aWidths, aHeights);
1147 
1148  long nTotalWidth = 0;
1149  if (get_column_homogeneous())
1150  {
1151  nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
1152  nTotalWidth *= aWidths.size();
1153  }
1154  else
1155  {
1156  nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
1157  }
1158 
1159  nTotalWidth += nColSpacing * (aWidths.size()-1);
1160 
1161  long nTotalHeight = 0;
1162  if (get_row_homogeneous())
1163  {
1164  nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
1165  nTotalHeight *= aHeights.size();
1166  }
1167  else
1168  {
1169  nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
1170  }
1171 
1172  nTotalHeight += nRowSpacing * (aHeights.size()-1);
1173 
1174  return Size(nTotalWidth, nTotalHeight);
1175 }
1176 
1177 void VclGrid::setAllocation(const Size& rAllocation)
1178 {
1179  array_type A = assembleGrid(*this);
1180 
1181  if (isNullGrid(A))
1182  return;
1183 
1184  sal_Int32 nMaxX = A.shape()[0];
1185  sal_Int32 nMaxY = A.shape()[1];
1186 
1187  Size aRequisition;
1188  std::vector<Value> aWidths(nMaxX);
1189  std::vector<Value> aHeights(nMaxY);
1191  {
1192  aRequisition = calculateRequisition();
1193  calcMaxs(A, aWidths, aHeights);
1194  }
1195 
1196  sal_Int32 nColSpacing(get_column_spacing());
1197  sal_Int32 nRowSpacing(get_row_spacing());
1198 
1199  long nAvailableWidth = rAllocation.Width();
1200  if (nMaxX)
1201  nAvailableWidth -= nColSpacing * (nMaxX - 1);
1202  if (get_column_homogeneous())
1203  {
1204  for (sal_Int32 x = 0; x < nMaxX; ++x)
1205  aWidths[x].m_nValue = nAvailableWidth/nMaxX;
1206  }
1207  else if (rAllocation.Width() != aRequisition.Width())
1208  {
1209  sal_Int32 nExpandables = 0;
1210  for (sal_Int32 x = 0; x < nMaxX; ++x)
1211  if (aWidths[x].m_bExpand)
1212  ++nExpandables;
1213  long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
1214 
1215  //We don't fit and there is no volunteer to be shrunk
1216  if (!nExpandables && rAllocation.Width() < aRequisition.Width())
1217  {
1218  //first reduce spacing
1219  while (nColSpacing)
1220  {
1221  nColSpacing /= 2;
1222  aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1223  if (aRequisition.Width() <= rAllocation.Width())
1224  break;
1225  }
1226 
1227  //share out the remaining pain to everyone
1228  long nExtraWidth = (rAllocation.Width() - aRequisition.Width()) / nMaxX;
1229 
1230  for (sal_Int32 x = 0; x < nMaxX; ++x)
1231  aWidths[x].m_nValue += nExtraWidth;
1232  }
1233 
1234  if (nExtraWidthForExpanders)
1235  {
1236  for (sal_Int32 x = 0; x < nMaxX; ++x)
1237  if (aWidths[x].m_bExpand)
1238  aWidths[x].m_nValue += nExtraWidthForExpanders;
1239  }
1240  }
1241 
1242  long nAvailableHeight = rAllocation.Height();
1243  if (nMaxY)
1244  nAvailableHeight -= nRowSpacing * (nMaxY - 1);
1245  if (get_row_homogeneous())
1246  {
1247  for (sal_Int32 y = 0; y < nMaxY; ++y)
1248  aHeights[y].m_nValue = nAvailableHeight/nMaxY;
1249  }
1250  else if (rAllocation.Height() != aRequisition.Height())
1251  {
1252  sal_Int32 nExpandables = 0;
1253  for (sal_Int32 y = 0; y < nMaxY; ++y)
1254  if (aHeights[y].m_bExpand)
1255  ++nExpandables;
1256  long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
1257 
1258  //We don't fit and there is no volunteer to be shrunk
1259  if (!nExpandables && rAllocation.Height() < aRequisition.Height())
1260  {
1261  //first reduce spacing
1262  while (nRowSpacing)
1263  {
1264  nRowSpacing /= 2;
1265  aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1266  if (aRequisition.Height() <= rAllocation.Height())
1267  break;
1268  }
1269 
1270  //share out the remaining pain to everyone
1271  long nExtraHeight = (rAllocation.Height() - aRequisition.Height()) / nMaxY;
1272 
1273  for (sal_Int32 y = 0; y < nMaxY; ++y)
1274  aHeights[y].m_nValue += nExtraHeight;
1275  }
1276 
1277  if (nExtraHeightForExpanders)
1278  {
1279  for (sal_Int32 y = 0; y < nMaxY; ++y)
1280  if (aHeights[y].m_bExpand)
1281  aHeights[y].m_nValue += nExtraHeightForExpanders;
1282  }
1283  }
1284 
1285  Point aAllocPos(0, 0);
1286  for (sal_Int32 x = 0; x < nMaxX; ++x)
1287  {
1288  for (sal_Int32 y = 0; y < nMaxY; ++y)
1289  {
1290  GridEntry &rEntry = A[x][y];
1291  vcl::Window *pChild = rEntry.pChild;
1292  if (pChild)
1293  {
1294  Size aChildAlloc(0, 0);
1295 
1296  sal_Int32 nWidth = rEntry.nSpanWidth;
1297  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1298  aChildAlloc.AdjustWidth(aWidths[x+nSpanX].m_nValue );
1299  aChildAlloc.AdjustWidth(nColSpacing*(nWidth-1) );
1300 
1301  sal_Int32 nHeight = rEntry.nSpanHeight;
1302  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1303  aChildAlloc.AdjustHeight(aHeights[y+nSpanY].m_nValue );
1304  aChildAlloc.AdjustHeight(nRowSpacing*(nHeight-1) );
1305 
1306  setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
1307  }
1308  aAllocPos.AdjustY(aHeights[y].m_nValue + nRowSpacing );
1309  }
1310  aAllocPos.AdjustX(aWidths[x].m_nValue + nColSpacing );
1311  aAllocPos.setY( 0 );
1312  }
1313 }
1314 
1316 {
1317  VclContainer::DumpAsPropertyTree(rJsonWriter);
1318  rJsonWriter.put("type", "grid");
1319 }
1320 
1321 bool toBool(const OUString &rValue)
1322 {
1323  return (!rValue.isEmpty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
1324 }
1325 
1326 bool VclGrid::set_property(const OString &rKey, const OUString &rValue)
1327 {
1328  if (rKey == "row-spacing")
1329  set_row_spacing(rValue.toInt32());
1330  else if (rKey == "column-spacing")
1331  set_column_spacing(rValue.toInt32());
1332  else if (rKey == "row-homogeneous")
1333  m_bRowHomogeneous = toBool(rValue);
1334  else if (rKey == "column-homogeneous")
1335  m_bColumnHomogeneous = toBool(rValue);
1336  else if (rKey == "n-rows")
1337  /*nothing to do*/;
1338  else
1339  return VclContainer::set_property(rKey, rValue);
1340  return true;
1341 }
1342 
1343 const vcl::Window *VclBin::get_child() const
1344 {
1345  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1346 
1347  return pWindowImpl->mpFirstChild;
1348 }
1349 
1350 vcl::Window *VclBin::get_child()
1351 {
1352  return const_cast<vcl::Window*>(const_cast<const VclBin*>(this)->get_child());
1353 }
1354 
1355 Size VclBin::calculateRequisition() const
1356 {
1357  const vcl::Window *pChild = get_child();
1358  if (pChild && pChild->IsVisible())
1359  return getLayoutRequisition(*pChild);
1360  return Size(0, 0);
1361 }
1362 
1363 void VclBin::setAllocation(const Size &rAllocation)
1364 {
1365  vcl::Window *pChild = get_child();
1366  if (pChild && pChild->IsVisible())
1367  setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
1368 }
1369 
1371 {
1372  disposeOnce();
1373 }
1374 
1376 {
1377  m_pLabel.clear();
1378  VclBin::dispose();
1379 }
1380 
1381 //To-Do, hook a DecorationView into VclFrame ?
1382 
1384 {
1385  Size aRet(0, 0);
1386 
1387  const vcl::Window *pChild = get_child();
1388  const vcl::Window *pLabel = get_label_widget();
1389 
1390  if (pChild && pChild->IsVisible())
1391  aRet = getLayoutRequisition(*pChild);
1392 
1393  if (pLabel && pLabel->IsVisible())
1394  {
1395  Size aLabelSize = getLayoutRequisition(*pLabel);
1396  aRet.AdjustHeight(aLabelSize.Height() );
1397  aRet.setWidth( std::max(aLabelSize.Width(), aRet.Width()) );
1398  }
1399 
1400  return aRet;
1401 }
1402 
1403 void VclFrame::setAllocation(const Size &rAllocation)
1404 {
1405  //SetBackground( Color(0xFF, 0x00, 0xFF) );
1406 
1407  Size aAllocation(rAllocation);
1408  Point aChildPos;
1409 
1410  vcl::Window *pChild = get_child();
1411  vcl::Window *pLabel = get_label_widget();
1412 
1413  if (pLabel && pLabel->IsVisible())
1414  {
1415  Size aLabelSize = getLayoutRequisition(*pLabel);
1416  aLabelSize.setHeight( std::min(aLabelSize.Height(), aAllocation.Height()) );
1417  aLabelSize.setWidth( std::min(aLabelSize.Width(), aAllocation.Width()) );
1418  setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
1419  aAllocation.AdjustHeight( -(aLabelSize.Height()) );
1420  aChildPos.AdjustY(aLabelSize.Height() );
1421  }
1422 
1423  if (pChild && pChild->IsVisible())
1424  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1425 }
1426 
1427 IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent&, rEvent, void)
1428 {
1429  if (rEvent.GetId() == VclEventId::ObjectDying)
1430  designate_label(nullptr);
1431 }
1432 
1434 {
1435  assert(!pWindow || pWindow->GetParent() == this);
1436  if (m_pLabel)
1437  m_pLabel->RemoveEventListener(LINK(this, VclFrame, WindowEventListener));
1438  m_pLabel = pWindow;
1439  if (m_pLabel)
1440  m_pLabel->AddEventListener(LINK(this, VclFrame, WindowEventListener));
1441 }
1442 
1444 {
1445  assert(GetChildCount() == 2);
1446  if (m_pLabel)
1447  return m_pLabel;
1448  //The label widget is normally the first (of two) children
1449  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1450  if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
1451  return nullptr;
1452  return pWindowImpl->mpFirstChild;
1453 }
1454 
1456 {
1457  return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
1458 }
1459 
1461 {
1462  //The child widget is the normally the last (of two) children
1463  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1464  assert(GetChildCount() == 2 || pWindowImpl->mbInDispose);
1465  if (!m_pLabel)
1466  return pWindowImpl->mpLastChild;
1467  if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
1468  return nullptr;
1469  return pWindowImpl->mpLastChild;
1470 }
1471 
1473 {
1474  return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_child());
1475 }
1476 
1477 void VclFrame::set_label(const OUString &rLabel)
1478 {
1479  vcl::Window *pLabel = get_label_widget();
1480  assert(pLabel);
1481  pLabel->SetText(rLabel);
1482 }
1483 
1484 OUString VclFrame::get_label() const
1485 {
1486  const vcl::Window *pLabel = get_label_widget();
1487  assert(pLabel);
1488  return pLabel->GetText();
1489 }
1490 
1492 {
1493  const vcl::Window *pLabel = get_label_widget();
1494  if (pLabel)
1495  return pLabel->GetAccessibleName();
1496  return VclBin::getDefaultAccessibleName();
1497 }
1498 
1500 {
1501  VclBin::DumpAsPropertyTree(rJsonWriter);
1502  rJsonWriter.put("type", "frame");
1503 }
1504 
1505 Size VclAlignment::calculateRequisition() const
1506 {
1507  Size aRet(m_nLeftPadding + m_nRightPadding,
1508  m_nTopPadding + m_nBottomPadding);
1509 
1510  const vcl::Window *pChild = get_child();
1511  if (pChild && pChild->IsVisible())
1512  {
1513  Size aChildSize = getLayoutRequisition(*pChild);
1514  aRet.AdjustWidth(aChildSize.Width() );
1515  aRet.AdjustHeight(aChildSize.Height() );
1516  }
1517 
1518  return aRet;
1519 }
1520 
1521 void VclAlignment::setAllocation(const Size &rAllocation)
1522 {
1523  vcl::Window *pChild = get_child();
1524  if (!pChild || !pChild->IsVisible())
1525  return;
1526 
1527  Point aChildPos(m_nLeftPadding, m_nTopPadding);
1528 
1529  Size aAllocation;
1530  aAllocation.setWidth( rAllocation.Width() - (m_nLeftPadding + m_nRightPadding) );
1531  aAllocation.setHeight( rAllocation.Height() - (m_nTopPadding + m_nBottomPadding) );
1532 
1533  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1534 }
1535 
1536 bool VclAlignment::set_property(const OString &rKey, const OUString &rValue)
1537 {
1538  if (rKey == "bottom-padding")
1539  m_nBottomPadding = rValue.toInt32();
1540  else if (rKey == "left-padding")
1541  m_nLeftPadding = rValue.toInt32();
1542  else if (rKey == "right-padding")
1543  m_nRightPadding = rValue.toInt32();
1544  else if (rKey == "top-padding")
1545  m_nTopPadding = rValue.toInt32();
1546  else
1547  return VclBin::set_property(rKey, rValue);
1548  return true;
1549 }
1550 
1551 class DisclosureButton final : public CheckBox
1552 {
1553  virtual void ImplDrawCheckBoxState(vcl::RenderContext& rRenderContext) override
1554  {
1555  /* HACK: DisclosureButton is currently assuming, that the disclosure sign
1556  will fit into the rectangle occupied by a normal checkbox on all themes.
1557  If this does not hold true for some theme, ImplGetCheckImageSize
1558  would have to be overridden for DisclosureButton; also GetNativeControlRegion
1559  for ControlType::ListNode would have to be implemented and taken into account
1560  */
1561 
1562  tools::Rectangle aStateRect(GetStateRect());
1563 
1565  tools::Rectangle aCtrlRegion(aStateRect);
1567 
1568  if (HasFocus())
1569  nState |= ControlState::FOCUSED;
1571  nState |= ControlState::DEFAULT;
1572  if (Window::IsEnabled())
1573  nState |= ControlState::ENABLED;
1574  if (IsMouseOver() && GetMouseRect().IsInside(GetPointerPosPixel()))
1575  nState |= ControlState::ROLLOVER;
1576 
1577  if (rRenderContext.DrawNativeControl(ControlType::ListNode, ControlPart::Entire, aCtrlRegion,
1578  nState, aControlValue, OUString()))
1579  return;
1580 
1581  ImplSVCtrlData& rCtrlData(ImplGetSVData()->maCtrlData);
1582  if (!rCtrlData.mpDisclosurePlus)
1583  rCtrlData.mpDisclosurePlus.reset(new Image(StockImage::Yes, SV_DISCLOSURE_PLUS));
1584  if (!rCtrlData.mpDisclosureMinus)
1585  rCtrlData.mpDisclosureMinus.reset(new Image(StockImage::Yes, SV_DISCLOSURE_MINUS));
1586 
1587  Image* pImg
1588  = IsChecked() ? rCtrlData.mpDisclosureMinus.get() : rCtrlData.mpDisclosurePlus.get();
1589 
1591  if (!IsEnabled())
1592  nStyle |= DrawImageFlags::Disable;
1593 
1594  Size aSize(aStateRect.GetSize());
1595  Size aImgSize(pImg->GetSizePixel());
1596  Point aOff((aSize.Width() - aImgSize.Width()) / 2,
1597  (aSize.Height() - aImgSize.Height()) / 2);
1598  aOff += aStateRect.TopLeft();
1599  rRenderContext.DrawImage(aOff, *pImg, nStyle);
1600  }
1601 
1602 public:
1603  explicit DisclosureButton(vcl::Window* pParent)
1604  : CheckBox(pParent, 0)
1605  {
1606  }
1607 
1608  virtual void KeyInput( const KeyEvent& rKEvt ) override
1609  {
1610  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1611 
1612  if( !aKeyCode.GetModifier() &&
1613  ( ( aKeyCode.GetCode() == KEY_ADD ) ||
1614  ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
1615  )
1616  {
1617  Check( aKeyCode.GetCode() == KEY_ADD );
1618  }
1619  else
1620  CheckBox::KeyInput( rKEvt );
1621  }
1622 };
1623 
1625  : VclBin(pParent)
1626  , m_bResizeTopLevel(true)
1627  , m_pDisclosureButton(VclPtr<DisclosureButton>::Create(this))
1628 {
1629  m_pDisclosureButton->SetToggleHdl(LINK(this, VclExpander, ClickHdl));
1631 }
1632 
1634 {
1635  disposeOnce();
1636 }
1637 
1639 {
1640  return m_pDisclosureButton->IsChecked();
1641 }
1642 
1643 void VclExpander::set_expanded(bool bExpanded)
1644 {
1645  m_pDisclosureButton->Check(bExpanded);
1646 }
1647 
1648 void VclExpander::set_label(const OUString& rLabel)
1649 {
1650  m_pDisclosureButton->SetText(rLabel);
1651 }
1652 
1654 {
1656  VclBin::dispose();
1657 }
1658 
1660 {
1661  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1662 
1663  assert(pWindowImpl->mpFirstChild == m_pDisclosureButton);
1664 
1665  return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
1666 }
1667 
1669 {
1670  return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_child());
1671 }
1672 
1674 {
1675  Size aRet(0, 0);
1676 
1677  WindowImpl* pWindowImpl = ImplGetWindowImpl();
1678 
1679  const vcl::Window *pChild = get_child();
1680  const vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild.get() : nullptr;
1681 
1682  if (pChild && pChild->IsVisible() && m_pDisclosureButton->IsChecked())
1683  aRet = getLayoutRequisition(*pChild);
1684 
1685  Size aExpanderSize = getLayoutRequisition(*m_pDisclosureButton);
1686 
1687  if (pLabel && pLabel->IsVisible())
1688  {
1689  Size aLabelSize = getLayoutRequisition(*pLabel);
1690  aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1691  aExpanderSize.AdjustWidth(aLabelSize.Width() );
1692  }
1693 
1694  aRet.AdjustHeight(aExpanderSize.Height() );
1695  aRet.setWidth( std::max(aExpanderSize.Width(), aRet.Width()) );
1696 
1697  return aRet;
1698 }
1699 
1700 void VclExpander::setAllocation(const Size &rAllocation)
1701 {
1702  Size aAllocation(rAllocation);
1703  Point aChildPos;
1704 
1705  WindowImpl* pWindowImpl = ImplGetWindowImpl();
1706 
1707  //The label widget is the last (of two) children
1708  vcl::Window *pChild = get_child();
1709  vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild.get() ? pWindowImpl->mpLastChild.get() : nullptr;
1710 
1711  Size aButtonSize = getLayoutRequisition(*m_pDisclosureButton);
1712  Size aLabelSize;
1713  Size aExpanderSize = aButtonSize;
1714  if (pLabel && pLabel->IsVisible())
1715  {
1716  aLabelSize = getLayoutRequisition(*pLabel);
1717  aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1718  aExpanderSize.AdjustWidth(aLabelSize.Width() );
1719  }
1720 
1721  aExpanderSize.setHeight( std::min(aExpanderSize.Height(), aAllocation.Height()) );
1722  aExpanderSize.setWidth( std::min(aExpanderSize.Width(), aAllocation.Width()) );
1723 
1724  aButtonSize.setHeight( std::min(aButtonSize.Height(), aExpanderSize.Height()) );
1725  aButtonSize.setWidth( std::min(aButtonSize.Width(), aExpanderSize.Width()) );
1726 
1727  long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
1728  Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
1729  setLayoutAllocation(*m_pDisclosureButton, aButtonPos, aButtonSize);
1730 
1731  if (pLabel && pLabel->IsVisible())
1732  {
1733  aLabelSize.setHeight( std::min(aLabelSize.Height(), aExpanderSize.Height()) );
1734  aLabelSize.setWidth( std::min(aLabelSize.Width(),
1735  aExpanderSize.Width() - aButtonSize.Width()) );
1736 
1737  long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
1738  Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
1739  setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
1740  }
1741 
1742  aAllocation.AdjustHeight( -(aExpanderSize.Height()) );
1743  aChildPos.AdjustY(aExpanderSize.Height() );
1744 
1745  if (pChild && pChild->IsVisible())
1746  {
1748  aAllocation = Size();
1749  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1750  }
1751 }
1752 
1753 bool VclExpander::set_property(const OString &rKey, const OUString &rValue)
1754 {
1755  if (rKey == "expanded")
1756  set_expanded(toBool(rValue));
1757  else if (rKey == "resize-toplevel")
1758  m_bResizeTopLevel = toBool(rValue);
1759  else
1760  return VclBin::set_property(rKey, rValue);
1761  return true;
1762 }
1763 
1765 {
1766  VclBin::StateChanged( nType );
1767 
1768  if (nType == StateChangedType::InitShow)
1769  {
1770  vcl::Window *pChild = get_child();
1771  if (pChild)
1772  pChild->Show(m_pDisclosureButton->IsChecked());
1773  }
1774 }
1775 
1776 IMPL_LINK( VclExpander, ClickHdl, CheckBox&, rBtn, void )
1777 {
1778  vcl::Window *pChild = get_child();
1779  if (pChild)
1780  {
1781  pChild->Show(rBtn.IsChecked());
1782  queue_resize();
1783  Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : nullptr;
1784  if (pResizeDialog)
1785  pResizeDialog->setOptimalLayoutSize();
1786  }
1787  maExpandedHdl.Call(*this);
1788 }
1789 
1792  , m_bUserManagedScrolling(false)
1793  , m_eDrawFrameStyle(DrawFrameStyle::NONE)
1794  , m_pVScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_VERT))
1795  , m_pHScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_HORZ))
1796  , m_aScrollBarBox(VclPtr<ScrollBarBox>::Create(this, WB_HIDE))
1797 {
1798  SetType(WindowType::SCROLLWINDOW);
1799 
1800  Link<ScrollBar*,void> aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) );
1801  m_pVScroll->SetScrollHdl(aLink);
1802  m_pHScroll->SetScrollHdl(aLink);
1803 }
1804 
1806 {
1810  VclBin::dispose();
1811 }
1812 
1814 {
1815  vcl::Window *pChild = get_child();
1816  if (!pChild)
1817  return;
1818 
1819  assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
1820 
1821  pChild = pChild->GetWindow(GetWindowType::FirstChild);
1822 
1823  if (!pChild)
1824  return;
1825 
1826  Point aWinPos(-m_pHScroll->GetThumbPos(), -m_pVScroll->GetThumbPos());
1827  pChild->SetPosPixel(aWinPos);
1828 }
1829 
1831 {
1832  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1833  assert(GetChildCount() == 4 || pWindowImpl->mbInDispose);
1834  return pWindowImpl->mpLastChild;
1835 }
1836 
1838 {
1839  return const_cast<vcl::Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
1840 }
1841 
1843 {
1844  Size aRet(0, 0);
1845 
1846  const vcl::Window *pChild = get_child();
1847  if (pChild && pChild->IsVisible())
1848  aRet = getLayoutRequisition(*pChild);
1849 
1850  if (GetStyle() & WB_VSCROLL)
1851  aRet.AdjustWidth(getLayoutRequisition(*m_pVScroll).Width() );
1852 
1853  if (GetStyle() & WB_HSCROLL)
1854  aRet.AdjustHeight(getLayoutRequisition(*m_pHScroll).Height() );
1855 
1856  aRet.AdjustHeight(2);
1857  aRet.AdjustWidth(2);
1858 
1859  return aRet;
1860 }
1861 
1863 {
1864  const vcl::Window *pChild = get_child();
1865  if (!pChild || !pChild->IsVisible())
1866  return;
1867 
1868  Size aOutSize(getVisibleChildSize());
1869 
1870  m_pVScroll->SetRangeMax(rRequest.Height());
1871  m_pVScroll->SetVisibleSize(aOutSize.Height());
1872  m_pVScroll->SetPageSize(16);
1873 
1874  m_pHScroll->SetRangeMax(rRequest.Width());
1875  m_pHScroll->SetVisibleSize(aOutSize.Width());
1876  m_pHScroll->SetPageSize(16);
1877 
1878  m_pVScroll->Scroll();
1879  m_pHScroll->Scroll();
1880 }
1881 
1882 void VclScrolledWindow::doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
1883 {
1884  Size aChildReq;
1885 
1886  vcl::Window *pChild = get_child();
1887  if (pChild && pChild->IsVisible())
1888  aChildReq = getLayoutRequisition(*pChild);
1889 
1890  long nAvailHeight = rAllocation.Height() - 2;
1891  long nAvailWidth = rAllocation.Width() - 2;
1892  // vert. ScrollBar
1893  if (GetStyle() & WB_AUTOVSCROLL)
1894  {
1895  m_pVScroll->Show(nAvailHeight < aChildReq.Height());
1896  }
1897  else if (m_pVScroll->IsVisible() != bool(GetStyle() & WB_VSCROLL))
1898  m_pVScroll->Show((GetStyle() & WB_VSCROLL) != 0);
1899 
1900  if (m_pVScroll->IsVisible())
1901  nAvailWidth -= getLayoutRequisition(*m_pVScroll).Width();
1902 
1903  // horz. ScrollBar
1904  if (GetStyle() & WB_AUTOHSCROLL)
1905  {
1906  bool bShowHScroll = nAvailWidth < aChildReq.Width();
1907  m_pHScroll->Show(bShowHScroll);
1908 
1909  if (bShowHScroll)
1910  nAvailHeight -= getLayoutRequisition(*m_pHScroll).Height();
1911 
1912  if (GetStyle() & WB_AUTOVSCROLL)
1913  m_pVScroll->Show(nAvailHeight < aChildReq.Height());
1914  }
1915  else if (m_pHScroll->IsVisible() != bool(GetStyle() & WB_HSCROLL))
1916  m_pHScroll->Show((GetStyle() & WB_HSCROLL) != 0);
1917 
1918  Size aInnerSize(rAllocation);
1919  aInnerSize.AdjustWidth(-2);
1920  aInnerSize.AdjustHeight(-2);
1921 
1922  bool bBothVisible = m_pVScroll->IsVisible() && m_pHScroll->IsVisible();
1923  auto nScrollBarWidth = getLayoutRequisition(*m_pVScroll).Width();
1924  auto nScrollBarHeight = getLayoutRequisition(*m_pHScroll).Height();
1925 
1926  if (m_pVScroll->IsVisible())
1927  {
1928  Point aScrollPos(rAllocation.Width() - nScrollBarWidth - 2, 1);
1929  Size aScrollSize(nScrollBarWidth, rAllocation.Height() - 2);
1930  if (bBothVisible)
1931  aScrollSize.AdjustHeight(-nScrollBarHeight);
1932  setLayoutAllocation(*m_pVScroll, aScrollPos, aScrollSize);
1933  aInnerSize.AdjustWidth( -nScrollBarWidth );
1934  }
1935 
1936  if (m_pHScroll->IsVisible())
1937  {
1938  Point aScrollPos(1, rAllocation.Height() - nScrollBarHeight);
1939  Size aScrollSize(rAllocation.Width() - 2, nScrollBarHeight);
1940  if (bBothVisible)
1941  aScrollSize.AdjustWidth(-nScrollBarWidth);
1942  setLayoutAllocation(*m_pHScroll, aScrollPos, aScrollSize);
1943  aInnerSize.AdjustHeight( -nScrollBarHeight );
1944  }
1945 
1946  if (bBothVisible)
1947  {
1948  Point aBoxPos(aInnerSize.Width() + 1, aInnerSize.Height() + 1);
1949  m_aScrollBarBox->SetPosSizePixel(aBoxPos, Size(nScrollBarWidth, nScrollBarHeight));
1950  m_aScrollBarBox->Show();
1951  }
1952  else
1953  {
1954  m_aScrollBarBox->Hide();
1955  }
1956 
1957  if (pChild && pChild->IsVisible())
1958  {
1959  assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
1960 
1961  WinBits nOldBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
1962 
1963  setLayoutAllocation(*pChild, Point(1, 1), aInnerSize);
1964 
1965  // tdf#128758 if the layout allocation triggered some callback that
1966  // immediately invalidates the layout by adding scrollbars then
1967  // normally this would simply retrigger layout and another toplevel
1968  // attempt is made later. But the initial layout attempt blocks
1969  // relayouts, so just make another single effort here.
1970  WinBits nNewBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
1971  if (nOldBits != nNewBits && bRetryOnFailure)
1972  {
1973  doSetAllocation(rAllocation, false);
1974  return;
1975  }
1976  }
1977 
1979  InitScrollBars(aChildReq);
1980 }
1981 
1982 void VclScrolledWindow::setAllocation(const Size &rAllocation)
1983 {
1984  doSetAllocation(rAllocation, true);
1985 }
1986 
1988 {
1989  Size aRet(GetSizePixel());
1990  if (m_pVScroll->IsVisible())
1991  aRet.AdjustWidth( -(m_pVScroll->GetSizePixel().Width()) );
1992  if (m_pHScroll->IsVisible())
1993  aRet.AdjustHeight( -(m_pHScroll->GetSizePixel().Height()) );
1994  aRet.AdjustHeight(-2);
1995  aRet.AdjustWidth(-2);
1996  return aRet;
1997 }
1998 
1999 bool VclScrolledWindow::set_property(const OString &rKey, const OUString &rValue)
2000 {
2001  if (rKey == "shadow-type")
2002  {
2003  // despite the style names, this looks like the best mapping
2004  if (rValue == "in")
2006  else if (rValue == "out")
2008  else if (rValue == "etched-in")
2010  else if (rValue == "etched-out")
2012  else if (rValue == "none")
2014  return true;
2015  }
2016 
2017  bool bRet = VclBin::set_property(rKey, rValue);
2018  m_pVScroll->Show((GetStyle() & WB_VSCROLL) != 0);
2019  m_pHScroll->Show((GetStyle() & WB_HSCROLL) != 0);
2020  return bRet;
2021 }
2022 
2024 {
2025  bool bDone = false;
2026  if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
2027  {
2028  const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2029  if ( rCEvt.GetCommand() == CommandEventId::Wheel )
2030  {
2031  const CommandWheelData* pData = rCEvt.GetWheelData();
2032  if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
2033  {
2034  bDone = HandleScrollCommand(rCEvt, m_pHScroll, m_pVScroll);
2035  }
2036  }
2037  }
2038 
2039  return bDone || VclBin::EventNotify( rNEvt );
2040 }
2041 
2043 {
2044  VclBin::Paint(rRenderContext, rRect);
2045  DecorationView aDecoView(&rRenderContext);
2046  aDecoView.DrawFrame(tools::Rectangle(Point(0,0), GetSizePixel()), m_eDrawFrameStyle);
2047 }
2048 
2049 void VclViewport::setAllocation(const Size &rAllocation)
2050 {
2051  vcl::Window *pChild = get_child();
2052  if (!(pChild && pChild->IsVisible()))
2053  return;
2054 
2055  Size aReq(getLayoutRequisition(*pChild));
2056  aReq.setWidth( std::max(aReq.Width(), rAllocation.Width()) );
2057  aReq.setHeight( std::max(aReq.Height(), rAllocation.Height()) );
2058  Point aKeepPos(pChild->GetPosPixel());
2060  {
2061  aKeepPos = Point(0, 0);
2062  m_bInitialAllocation = false;
2063  }
2064  setLayoutAllocation(*pChild, aKeepPos, aReq);
2065 }
2066 
2068 {
2069  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
2070 
2071  assert(pWindowImpl->mpFirstChild.get() == m_aEventBoxHelper.get());
2072 
2073  return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
2074 }
2075 
2077 {
2078  return const_cast<vcl::Window*>(const_cast<const VclEventBox*>(this)->get_child());
2079 }
2080 
2081 void VclEventBox::setAllocation(const Size& rAllocation)
2082 {
2083  Point aChildPos(0, 0);
2084  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
2085  {
2086  if (!pChild->IsVisible())
2087  continue;
2088  setLayoutAllocation(*pChild, aChildPos, rAllocation);
2089  }
2090 }
2091 
2093 {
2094  Size aRet(0, 0);
2095 
2096  for (const vcl::Window* pChild = get_child(); pChild;
2097  pChild = pChild->GetWindow(GetWindowType::Next))
2098  {
2099  if (!pChild->IsVisible())
2100  continue;
2101  Size aChildSize = getLayoutRequisition(*pChild);
2102  aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2103  aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2104  }
2105 
2106  return aRet;
2107 }
2108 
2110 {
2111  //discard events by default to block them reaching children
2112 }
2113 
2115 {
2116  disposeOnce();
2117 }
2118 
2120 {
2121  m_aEventBoxHelper.disposeAndClear();
2122  VclBin::dispose();
2123 }
2124 
2126 {
2127  //sufficient to trigger one widget to trigger all of them
2128  if (!m_aWindows.empty())
2129  {
2130  (*m_aWindows.begin())->queue_resize();
2131  }
2132 }
2133 
2134 void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden)
2135 {
2136  if (bIgnoreHidden != m_bIgnoreHidden)
2137  {
2138  m_bIgnoreHidden = bIgnoreHidden;
2140  }
2141 }
2142 
2144 {
2145  if (eMode != m_eMode)
2146  {
2147  m_eMode = eMode;
2149  }
2150 
2151 }
2152 
2153 void VclSizeGroup::set_property(const OString &rKey, const OUString &rValue)
2154 {
2155  if (rKey == "ignore-hidden")
2156  set_ignore_hidden(toBool(rValue));
2157  else if (rKey == "mode")
2158  {
2160  if (rValue == "none")
2161  eMode = VclSizeGroupMode::NONE;
2162  else if (rValue == "horizontal")
2164  else if (rValue == "vertical")
2166  else if (rValue == "both")
2167  eMode = VclSizeGroupMode::Both;
2168  else
2169  {
2170  SAL_WARN("vcl.layout", "unknown size group mode" << rValue);
2171  }
2172  set_mode(eMode);
2173  }
2174  else
2175  {
2176  SAL_INFO("vcl.layout", "unhandled property: " << rKey);
2177  }
2178 }
2179 
2181 {
2183 
2184  if (m_pGrid)
2185  return;
2186 
2187  VclContainer *pContainer = get_content_area();
2188  assert(pContainer);
2189 
2190  m_pGrid.set( VclPtr<VclGrid>::Create(pContainer) );
2197 
2199  switch (m_eMessageType)
2200  {
2201  case VclMessageType::Info:
2203  break;
2206  break;
2209  break;
2210  case VclMessageType::Error:
2212  break;
2213  }
2217  m_pImage->Show();
2218 
2220 
2221  bool bHasSecondaryText = !m_sSecondaryString.isEmpty();
2222 
2226 
2230 
2236  m_pSecondaryMessage->Show(bHasSecondaryText);
2237 
2238  MessageDialog::SetMessagesWidths(this, m_pPrimaryMessage, bHasSecondaryText ? m_pSecondaryMessage.get() : nullptr);
2239 
2240  VclButtonBox *pButtonBox = get_action_area();
2241  assert(pButtonBox);
2242 
2243  VclPtr<PushButton> pBtn;
2244  short nDefaultResponse = get_default_response();
2245  switch (m_eButtonsType)
2246  {
2247  case VclButtonsType::NONE:
2248  break;
2249  case VclButtonsType::Ok:
2250  pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2251  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2252  pBtn->Show();
2253  pBtn->set_id("ok");
2254  add_button(pBtn, RET_OK, true);
2255  nDefaultResponse = RET_OK;
2256  break;
2257  case VclButtonsType::Close:
2258  pBtn.set( VclPtr<CloseButton>::Create(pButtonBox) );
2259  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2260  pBtn->Show();
2261  pBtn->set_id("close");
2262  add_button(pBtn, RET_CLOSE, true);
2263  nDefaultResponse = RET_CLOSE;
2264  break;
2266  pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2267  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2268  pBtn->Show();
2269  pBtn->set_id("cancel");
2270  add_button(pBtn, RET_CANCEL, true);
2271  nDefaultResponse = RET_CANCEL;
2272  break;
2273  case VclButtonsType::YesNo:
2274  pBtn = VclPtr<PushButton>::Create(pButtonBox);
2275  pBtn->SetText(GetStandardText(StandardButtonType::Yes));
2276  pBtn->Show();
2277  pBtn->set_id("yes");
2278  add_button(pBtn, RET_YES, true);
2279 
2280  pBtn.set( VclPtr<PushButton>::Create(pButtonBox) );
2281  pBtn->SetText(GetStandardText(StandardButtonType::No));
2282  pBtn->Show();
2283  pBtn->set_id("no");
2284  add_button(pBtn, RET_NO, true);
2285  nDefaultResponse = RET_NO;
2286  break;
2288  pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2289  pBtn->Show();
2290  pBtn->set_id("ok");
2291  add_button(pBtn, RET_OK, true);
2292 
2293  pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2294  pBtn->Show();
2295  pBtn->set_id("cancel");
2296  add_button(pBtn, RET_CANCEL, true);
2297  nDefaultResponse = RET_CANCEL;
2298  break;
2299  }
2300  set_default_response(nDefaultResponse);
2301  sort_native_button_order(*pButtonBox);
2302  m_pMessageBox->Show();
2303  m_pGrid->Show();
2304 }
2305 
2307 {
2308 #if defined _WIN32
2309  set_border_width(3);
2310 #else
2311  set_border_width(12);
2312 #endif
2319 }
2320 
2322  : Dialog(pParent, nStyle)
2323  , m_eButtonsType(VclButtonsType::NONE)
2324  , m_eMessageType(VclMessageType::Info)
2325  , m_pOwnedContentArea(nullptr)
2326  , m_pOwnedActionArea(nullptr)
2327  , m_pGrid(nullptr)
2328  , m_pMessageBox(nullptr)
2329  , m_pImage(nullptr)
2330  , m_pPrimaryMessage(nullptr)
2331  , m_pSecondaryMessage(nullptr)
2332 {
2333  SetType(WindowType::MESSBOX);
2334 }
2335 
2337  const OUString &rMessage,
2338  VclMessageType eMessageType,
2339  VclButtonsType eButtonsType)
2340  : Dialog(pParent, WB_MOVEABLE | WB_3DLOOK | WB_CLOSEABLE)
2341  , m_eButtonsType(eButtonsType)
2342  , m_eMessageType(eMessageType)
2343  , m_pGrid(nullptr)
2344  , m_pMessageBox(nullptr)
2345  , m_pImage(nullptr)
2346  , m_pPrimaryMessage(nullptr)
2347  , m_pSecondaryMessage(nullptr)
2348  , m_sPrimaryString(rMessage)
2349 {
2350  SetType(WindowType::MESSBOX);
2353 
2354  switch (m_eMessageType)
2355  {
2356  case VclMessageType::Info:
2358  break;
2361  break;
2364  break;
2365  case VclMessageType::Error:
2367  break;
2368  }
2369 }
2370 
2372 {
2381  Dialog::dispose();
2382 }
2383 
2385 {
2386  disposeOnce();
2387 }
2388 
2390  VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
2391 {
2392  if (pSecondaryMessage)
2393  {
2394  assert(pPrimaryMessage);
2395  vcl::Font aFont = pParent->GetSettings().GetStyleSettings().GetLabelFont();
2396  aFont.SetFontSize(Size(0, aFont.GetFontSize().Height() * 1.2));
2397  aFont.SetWeight(WEIGHT_BOLD);
2398  pPrimaryMessage->SetControlFont(aFont);
2399  pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 44);
2400  pSecondaryMessage->SetMaxTextWidth(pSecondaryMessage->approximate_char_width() * 60);
2401  }
2402  else
2403  pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 60);
2404 }
2405 
2406 OUString const & MessageDialog::get_primary_text() const
2407 {
2408  const_cast<MessageDialog*>(this)->setDeferredProperties();
2409 
2410  return m_sPrimaryString;
2411 }
2412 
2413 OUString const & MessageDialog::get_secondary_text() const
2414 {
2415  const_cast<MessageDialog*>(this)->setDeferredProperties();
2416 
2417  return m_sSecondaryString;
2418 }
2419 
2420 bool MessageDialog::set_property(const OString &rKey, const OUString &rValue)
2421 {
2422  if (rKey == "text")
2423  set_primary_text(rValue);
2424  else if (rKey == "secondary-text")
2425  set_secondary_text(rValue);
2426  else if (rKey == "message-type")
2427  {
2429  if (rValue == "info")
2430  eMode = VclMessageType::Info;
2431  else if (rValue == "warning")
2432  eMode = VclMessageType::Warning;
2433  else if (rValue == "question")
2434  eMode = VclMessageType::Question;
2435  else if (rValue == "error")
2436  eMode = VclMessageType::Error;
2437  else
2438  {
2439  SAL_WARN("vcl.layout", "unknown message type mode" << rValue);
2440  }
2441  m_eMessageType = eMode;
2442  }
2443  else if (rKey == "buttons")
2444  {
2446  if (rValue == "none")
2447  eMode = VclButtonsType::NONE;
2448  else if (rValue == "ok")
2449  eMode = VclButtonsType::Ok;
2450  else if (rValue == "cancel")
2451  eMode = VclButtonsType::Cancel;
2452  else if (rValue == "close")
2453  eMode = VclButtonsType::Close;
2454  else if (rValue == "yes-no")
2455  eMode = VclButtonsType::YesNo;
2456  else if (rValue == "ok-cancel")
2457  eMode = VclButtonsType::OkCancel;
2458  else
2459  {
2460  SAL_WARN("vcl.layout", "unknown buttons type mode" << rValue);
2461  }
2462  m_eButtonsType = eMode;
2463  }
2464  else
2465  return Dialog::set_property(rKey, rValue);
2466  return true;
2467 }
2468 
2469 void MessageDialog::set_primary_text(const OUString &rPrimaryString)
2470 {
2471  m_sPrimaryString = rPrimaryString;
2472  if (m_pPrimaryMessage)
2473  {
2477  }
2478 }
2479 
2480 void MessageDialog::set_secondary_text(const OUString &rSecondaryString)
2481 {
2482  m_sSecondaryString = rSecondaryString;
2483  if (m_pSecondaryMessage)
2484  {
2488  }
2489 }
2490 
2492 {
2493  Dialog::StateChanged(nType);
2494  if (nType == StateChangedType::InitShow)
2495  {
2496  // MessageBox should be at least as wide as to see the title
2497  auto nTitleWidth = CalcTitleWidth();
2498  // Extra-Width for Close button
2499  nTitleWidth += mpWindowImpl->mnTopBorder;
2500  if (get_preferred_size().Width() < nTitleWidth)
2501  {
2502  set_width_request(nTitleWidth);
2503  DoInitialLayout();
2504  }
2505  }
2506 }
2507 
2508 VclPaned::VclPaned(vcl::Window *pParent, bool bVertical)
2509  : VclContainer(pParent, WB_HIDE | WB_CLIPCHILDREN)
2510  , m_pSplitter(VclPtr<Splitter>::Create(this, bVertical ? WB_VSCROLL : WB_HSCROLL))
2511  , m_nPosition(-1)
2512 {
2513  m_pSplitter->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor()));
2514  m_pSplitter->Show();
2515 }
2516 
2518 {
2521 }
2522 
2524  : VclPaned(pParent, true)
2525 {
2526  m_pSplitter->SetSplitHdl(LINK(this, VclVPaned, SplitHdl));
2527 }
2528 
2529 IMPL_LINK(VclVPaned, SplitHdl, Splitter*, pSplitter, void)
2530 {
2531  long nSize = pSplitter->GetSplitPosPixel();
2532  Size aSplitterSize(m_pSplitter->GetSizePixel());
2533  Size aAllocation(GetSizePixel());
2534  arrange(aAllocation, nSize, aAllocation.Height() - nSize - aSplitterSize.Height());
2535 }
2536 
2537 void VclVPaned::arrange(const Size& rAllocation, long nFirstHeight, long nSecondHeight)
2538 {
2539  Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2540  Size aFirstChildSize(rAllocation.Width(), nFirstHeight);
2541  Size aSecondChildSize(rAllocation.Width(), nSecondHeight);
2542  int nElement = 0;
2543  for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2544  pChild = pChild->GetWindow(GetWindowType::Next))
2545  {
2546  if (!pChild->IsVisible())
2547  continue;
2548  if (nElement == 0)
2549  {
2550  Point aSplitterPos(0, aFirstChildSize.Height());
2551  setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2552  m_nPosition = aSplitterPos.Y() + aSplitterSize.Height() / 2;
2553  }
2554  else if (nElement == 1)
2555  {
2556  Point aChildPos(0, 0);
2557  setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2558  }
2559  else if (nElement == 2)
2560  {
2561  Point aChildPos(0, aFirstChildSize.Height() + aSplitterSize.Height());
2562  setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2563  }
2564  ++nElement;
2565  }
2566 }
2567 
2568 void VclVPaned::set_position(long nPosition)
2569 {
2570  VclPaned::set_position(nPosition);
2571 
2572  Size aAllocation(GetSizePixel());
2573  Size aSplitterSize(m_pSplitter->GetSizePixel());
2574 
2575  nPosition -= aSplitterSize.Height() / 2;
2576 
2577  arrange(aAllocation, nPosition, aAllocation.Height() - nPosition - aSplitterSize.Height());
2578 }
2579 
2580 void VclVPaned::setAllocation(const Size& rAllocation)
2581 {
2582  //supporting "shrink" could be done by adjusting the allowed drag rectangle
2583  m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2584  Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2585  const long nHeight = rAllocation.Height() - aSplitterSize.Height();
2586 
2587  long nFirstHeight = 0;
2588  long nSecondHeight = 0;
2589  bool bFirstCanResize = true;
2590  bool bSecondCanResize = true;
2591  const bool bInitialAllocation = get_position() < 0;
2592  int nElement = 0;
2593  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2594  pChild = pChild->GetWindow(GetWindowType::Next))
2595  {
2596  if (!pChild->IsVisible())
2597  continue;
2598  if (nElement == 1)
2599  {
2600  if (bInitialAllocation)
2601  nFirstHeight = getLayoutRequisition(*pChild).Height();
2602  else
2603  nFirstHeight = pChild->GetSizePixel().Height();
2604  bFirstCanResize = pChild->get_expand();
2605  }
2606  else if (nElement == 2)
2607  {
2608  if (bInitialAllocation)
2609  nSecondHeight = getLayoutRequisition(*pChild).Height();
2610  else
2611  nSecondHeight = pChild->GetSizePixel().Height();
2612  bSecondCanResize = pChild->get_expand();
2613  }
2614  ++nElement;
2615  }
2616  long nHeightRequest = nFirstHeight + nSecondHeight;
2617  long nHeightDiff = nHeight - nHeightRequest;
2618  if (bFirstCanResize == bSecondCanResize)
2619  nFirstHeight += nHeightDiff/2;
2620  else if (bFirstCanResize)
2621  nFirstHeight += nHeightDiff;
2622  arrange(rAllocation, nFirstHeight, rAllocation.Height() - nFirstHeight - aSplitterSize.Height());
2623 }
2624 
2626 {
2627  Size aRet(0, 0);
2628 
2629  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2630  pChild = pChild->GetWindow(GetWindowType::Next))
2631  {
2632  if (!pChild->IsVisible())
2633  continue;
2634  Size aChildSize = getLayoutRequisition(*pChild);
2635  aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2636  aRet.AdjustHeight(aChildSize.Height() );
2637  }
2638 
2639  return aRet;
2640 }
2641 
2643  : VclPaned(pParent, false)
2644 {
2645  m_pSplitter->SetSplitHdl(LINK(this, VclHPaned, SplitHdl));
2646 }
2647 
2648 IMPL_LINK(VclHPaned, SplitHdl, Splitter*, pSplitter, void)
2649 {
2650  long nSize = pSplitter->GetSplitPosPixel();
2651  Size aSplitterSize(m_pSplitter->GetSizePixel());
2652  Size aAllocation(GetSizePixel());
2653  arrange(aAllocation, nSize, aAllocation.Width() - nSize - aSplitterSize.Width());
2654 }
2655 
2656 void VclHPaned::arrange(const Size& rAllocation, long nFirstWidth, long nSecondWidth)
2657 {
2658  Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2659  Size aFirstChildSize(nFirstWidth, rAllocation.Height());
2660  Size aSecondChildSize(nSecondWidth, rAllocation.Height());
2661  int nElement = 0;
2662  for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2663  pChild = pChild->GetWindow(GetWindowType::Next))
2664  {
2665  if (!pChild->IsVisible())
2666  continue;
2667  if (nElement == 0)
2668  {
2669  Point aSplitterPos(aFirstChildSize.Width(), 0);
2670  setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2671  m_nPosition = aSplitterPos.X() + aSplitterSize.Width() / 2;
2672  }
2673  else if (nElement == 1)
2674  {
2675  Point aChildPos(0, 0);
2676  setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2677  }
2678  else if (nElement == 2)
2679  {
2680  Point aChildPos(aFirstChildSize.Width() + aSplitterSize.Width(), 0);
2681  setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2682  }
2683  ++nElement;
2684  }
2685 }
2686 
2687 void VclHPaned::set_position(long nPosition)
2688 {
2689  VclPaned::set_position(nPosition);
2690 
2691  Size aAllocation(GetSizePixel());
2692  Size aSplitterSize(m_pSplitter->GetSizePixel());
2693 
2694  nPosition -= aSplitterSize.Width() / 2;
2695 
2696  arrange(aAllocation, nPosition, aAllocation.Width() - nPosition - aSplitterSize.Width());
2697 }
2698 
2699 void VclHPaned::setAllocation(const Size& rAllocation)
2700 {
2701  //supporting "shrink" could be done by adjusting the allowed drag rectangle
2702  m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2703  Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2704  const long nWidth = rAllocation.Width() - aSplitterSize.Width();
2705 
2706  long nFirstWidth = 0;
2707  long nSecondWidth = 0;
2708  bool bFirstCanResize = true;
2709  bool bSecondCanResize = true;
2710  const bool bInitialAllocation = get_position() < 0;
2711  int nElement = 0;
2712  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2713  pChild = pChild->GetWindow(GetWindowType::Next))
2714  {
2715  if (!pChild->IsVisible())
2716  continue;
2717  if (nElement == 1)
2718  {
2719  if (bInitialAllocation)
2720  nFirstWidth = getLayoutRequisition(*pChild).Width();
2721  else
2722  nFirstWidth = pChild->GetSizePixel().Width();
2723  bFirstCanResize = pChild->get_expand();
2724  }
2725  else if (nElement == 2)
2726  {
2727  if (bInitialAllocation)
2728  nSecondWidth = getLayoutRequisition(*pChild).Width();
2729  else
2730  nSecondWidth = pChild->GetSizePixel().Width();
2731  bSecondCanResize = pChild->get_expand();
2732  }
2733  ++nElement;
2734  }
2735  long nWidthRequest = nFirstWidth + nSecondWidth;
2736  long nWidthDiff = nWidth - nWidthRequest;
2737  if (bFirstCanResize == bSecondCanResize)
2738  nFirstWidth += nWidthDiff/2;
2739  else if (bFirstCanResize)
2740  nFirstWidth += nWidthDiff;
2741  arrange(rAllocation, nFirstWidth, rAllocation.Width() - nFirstWidth - aSplitterSize.Width());
2742 }
2743 
2745 {
2746  Size aRet(0, 0);
2747 
2748  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2749  pChild = pChild->GetWindow(GetWindowType::Next))
2750  {
2751  if (!pChild->IsVisible())
2752  continue;
2753  Size aChildSize = getLayoutRequisition(*pChild);
2754  aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2755  aRet.AdjustWidth(aChildSize.Width() );
2756  }
2757 
2758  return aRet;
2759 }
2760 
2762 {
2763  tools::Rectangle aBounds;
2764 
2765  for (const vcl::Window* pChild = rWindow.GetWindow(GetWindowType::FirstChild); pChild;
2766  pChild = pChild->GetWindow(GetWindowType::Next))
2767  {
2768  if (!pChild->IsVisible())
2769  continue;
2770 
2771  tools::Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
2772  aBounds.Union(aChildBounds);
2773  }
2774 
2775  if (aBounds.IsEmpty())
2776  return rWindow.GetSizePixel();
2777 
2778  Size aRet(aBounds.GetSize());
2779  Point aTopLeft(aBounds.TopLeft());
2780  aRet.AdjustWidth(aTopLeft.X()*2 );
2781  aRet.AdjustHeight(aTopLeft.Y()*2 );
2782 
2783  return aRet;
2784 }
2785 
2787 {
2788  while (pWindow)
2789  {
2790  pWindow = pWindow->GetParent();
2791  if (!pWindow || !isContainerWindow(*pWindow))
2792  break;
2793  }
2794  return pWindow;
2795 }
2796 
2797 bool isVisibleInLayout(const vcl::Window *pWindow)
2798 {
2799  bool bVisible = true;
2800  while (bVisible)
2801  {
2802  bVisible = pWindow->IsVisible();
2803  pWindow = pWindow->GetParent();
2804  if (!pWindow || !isContainerWindow(*pWindow))
2805  break;
2806  }
2807  return bVisible;
2808 }
2809 
2810 bool isEnabledInLayout(const vcl::Window *pWindow)
2811 {
2812  bool bEnabled = true;
2813  while (bEnabled)
2814  {
2815  bEnabled = pWindow->IsEnabled();
2816  pWindow = pWindow->GetParent();
2817  if (!pWindow || !isContainerWindow(*pWindow))
2818  break;
2819  }
2820  return bEnabled;
2821 }
2822 
2823 bool isLayoutEnabled(const vcl::Window *pWindow)
2824 {
2825  //Child is a container => we're layout enabled
2826  const vcl::Window *pChild = pWindow ? pWindow->GetWindow(GetWindowType::FirstChild) : nullptr;
2827  return pChild && isContainerWindow(*pChild) && !pChild->GetWindow(GetWindowType::Next);
2828 }
2829 
2831 {
2832  if (m_aStartDragHdl.Call(this))
2833  return;
2834 
2836  if (!m_xTransferHelper.is())
2837  return;
2838 
2839  xContainer->StartDrag(this, m_nDragAction);
2840 }
2841 
2843 {
2844 }
2845 
2847 {
2848 }
2849 
2851 {
2852  disposeOnce();
2853 }
2854 
2856 {
2857  disposeOnce();
2858 }
2859 
2861 {
2862  Control::DumpAsPropertyTree(rJsonWriter);
2863  rJsonWriter.put("type", "drawingarea");
2864 
2866  pDevice->SetOutputSize( GetSizePixel() );
2867  tools::Rectangle aRect(Point(0,0), GetSizePixel());
2868  Paint(*pDevice, aRect);
2869  BitmapEx aImage = pDevice->GetBitmapEx( Point(0,0), GetSizePixel() );
2870  SvMemoryStream aOStm(65535, 65535);
2872  {
2873  css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
2874  OUStringBuffer aBuffer("data:image/png;base64,");
2876  rJsonWriter.put("image", aBuffer.makeStringAndClear());
2877  }
2878 }
2879 
2880 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Definition: window.cxx:2838
virtual void SetText(const OUString &rStr)
Definition: window.cxx:3056
Point TopLeft() const
long Width() const
Size GetSizePixel() const
Definition: Image.cxx:86
virtual sal_uInt16 getDefaultAccessibleRole() const override
Definition: layout.cxx:46
Image const & GetStandardInfoBoxImage()
Definition: stdtext.cxx:49
virtual ~VclExpander() override
Definition: layout.cxx:1633
virtual void set_position(long nPosition) override
Definition: layout.cxx:2568
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:2420
bool m_bColumnHomogeneous
Definition: layout.hxx:317
SAL_DLLPRIVATE float approximate_char_width() const
Definition: text.cxx:908
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:550
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:1326
sal_Int32 get_padding() const
Definition: window2.cxx:1742
void setDeferredProperties()
Definition: builder.hxx:473
static VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1124
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:1999
static void setLayoutAllocation(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
Definition: layout.cxx:68
Image const & GetStandardWarningBoxImage()
Definition: stdtext.cxx:60
void SetFontSize(const Size &)
Definition: font/font.cxx:117
bool get_vexpand() const
Definition: window2.cxx:1706
bool bVisible
bool isVisibleInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2797
void InitScrollBars(const Size &rRequest)
Definition: layout.cxx:1862
WinBits const WB_NOLABEL
VclPtr< ScrollBar > m_pHScroll
Definition: layout.hxx:526
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:1814
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: layout.cxx:2517
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:1753
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption)
Request rendering of a particular control and/or part.
OUString const & get_secondary_text() const
Definition: layout.cxx:2413
static void SetMessagesWidths(vcl::Window const *pParent, VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
Definition: layout.cxx:2389
sal_Int32 get_margin_bottom() const
Definition: window2.cxx:1884
long AdjustWidth(long n)
void designate_label(vcl::Window *pWindow)
Definition: layout.cxx:1433
VclButtonsType
Definition: vclenum.hxx:246
static array_type assembleGrid(const VclGrid &rGrid)
Definition: layout.cxx:838
VclBox * get_content_area()
Definition: dialog.hxx:114
void create_message_area()
Definition: layout.cxx:2180
virtual Size GetOptimalSize() const override
Definition: layout.cxx:51
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1403
const CommandEvent * GetCommandEvent() const
Definition: event.hxx:327
std::unique_ptr< ContentProperties > pData
virtual void setSecondaryDimension(Size &rSize, long) const =0
VclPtr< vcl::Window > m_pLabel
Definition: layout.hxx:426
void set_grid_left_attach(sal_Int32 nAttach)
Definition: window2.cxx:1784
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:607
OUString GetStandardText(StandardButtonType eButton)
Definition: stdtext.cxx:93
long Height() const
signed char sal_Int8
bool m_bVerticalContainer
Definition: layout.hxx:75
virtual ~VclPaned() override
Definition: layout.cxx:2850
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
OUString GetStandardErrorBoxText()
Definition: stdtext.cxx:77
VclPtr< DisclosureButton > m_pDisclosureButton
Definition: layout.hxx:494
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:2491
bool get_hexpand() const
Definition: window2.cxx:1694
static Size getLayoutRequisition(const vcl::Window &rWindow)
Definition: layout.cxx:143
OUString const & get_primary_text() const
Definition: layout.cxx:2406
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:715
SAL_DLLPRIVATE void disposeOwnedButtons()
Definition: dialog.cxx:378
VclPtr< VclVBox > m_pMessageBox
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:837
SAL_DLLPRIVATE const tools::Rectangle & GetStateRect() const
VclButtonsType m_eButtonsType
virtual Size GetSizePixel() const
Definition: window.cxx:2396
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:2860
void EnableCursor(bool bEnable)
Definition: vclmedit.cxx:1503
void SetWeight(FontWeight)
Definition: font/font.cxx:215
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:1383
sal_uInt16 GetCode() const
Definition: keycod.hxx:53
VclPtr< VclBox > m_pOwnedContentArea
void set_spacing(int nSpacing)
Definition: layout.hxx:85
virtual vcl::Window * get_child() override
Definition: layout.cxx:1472
WinBits const WB_VSCROLL
Info
const CommandWheelData * GetWheelData() const
bool m_bExpand
Definition: layout.hxx:325
VclButtonBoxStyle
Definition: layout.hxx:199
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: window.cxx:145
void SetType(WindowType nType)
Definition: window2.cxx:968
constexpr sal_uInt16 KEY_ADD
Definition: keycodes.hxx:127
virtual void dispose() override
Definition: layout.cxx:1805
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1700
float x
TRISTATE_TRUE
long AdjustHeight(long n)
VclContainer(vcl::Window *pParent, WinBits nStyle=WB_HIDE|WB_CLIPCHILDREN)
Definition: layout.cxx:36
bool get_fill() const
Definition: window2.cxx:1754
static const OUString & GetDesktopEnvironment()
Get the desktop environment the process is currently running in.
Definition: svapp.cxx:1598
void create_owned_areas()
Definition: layout.cxx:2306
NONE
virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const =0
OUString GetStandardQueryBoxText()
Definition: stdtext.cxx:88
WEIGHT_BOLD
bool IsEmpty() const
StateChangedType
Definition: window.hxx:310
const sal_uInt8 A
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3144
rtl::Reference< TransferDataContainer > m_xTransferHelper
Definition: layout.hxx:638
OUString GetAccessibleName() const
sal_Int64 WinBits
virtual void dispose() override
Definition: layout.cxx:2119
sal_Int32 get_margin_right() const
Definition: window2.cxx:1852
void SetBackground()
void SetControlFont()
Definition: window2.cxx:409
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: dialog.cxx:610
std::set< VclPtr< vcl::Window > > m_aWindows
Definition: layout.hxx:592
virtual void dispose() override
Definition: layout.cxx:1375
bool m_bLayoutDirty
Definition: layout.hxx:68
void set_ignore_hidden(bool bIgnoreHidden)
Definition: layout.cxx:2134
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:3380
virtual Size calculateRequisition() const =0
WinBits const WB_DEFBUTTON
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:832
void reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
Definition: builder.cxx:2351
void Hide()
Definition: window.hxx:936
virtual long getPrimaryDimension(const Size &rSize) const =0
VclSizeGroupMode
Definition: vclenum.hxx:264
VclPtr< vcl::Window > mpLastChild
Definition: window.h:235
void set_default_response(int nResponse)
Definition: dialog.cxx:1503
virtual ~VclHPaned() override
Definition: layout.cxx:2842
Mode eMode
sal_Int8 m_nDragAction
Definition: layout.hxx:639
virtual long getSecondaryDimension(const Size &rSize) const =0
static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1119
void set_width_request(sal_Int32 nWidthRequest)
Definition: window2.cxx:1603
sal_uInt16 GetModifier() const
Definition: keycod.hxx:56
virtual OUString GetText() const
Definition: window.cxx:3085
void set_mode(VclSizeGroupMode eMode)
Definition: layout.cxx:2143
VclMessageType
Definition: vclenum.hxx:256
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:2109
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
void * GetEventData() const
std::vector< long > m_aMainGroupDimensions
Definition: layout.hxx:226
bool get_secondary() const
Definition: window2.cxx:1902
WinBits const WB_HIDE
TriState GetState() const
Link< VclDrawingArea *, bool > m_aStartDragHdl
Definition: layout.hxx:650
bool m_bResizeTopLevel
Definition: layout.hxx:493
bool isContainerWindow(const vcl::Window &rWindow)
Definition: layout.hxx:840
float y
sal_Int32 get_margin_left() const
Definition: window2.cxx:1836
bool mbInDispose
Definition: window.h:317
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
Size getLegacyBestSizeForChildren(const vcl::Window &rWindow)
Definition: layout.cxx:2761
const OString & GetHelpId() const
Definition: window2.cxx:828
Size finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
Definition: layout.cxx:388
virtual Size calculateRequisition() const override
Definition: layout.cxx:2625
void clear()
Definition: vclptr.hxx:190
bool isEnabledInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2810
void arrange(const Size &rAllocation, long nFirstHeight, long nSecondHeight)
Definition: layout.cxx:2656
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: dialog.cxx:1361
virtual ~VclFrame() override
Definition: layout.cxx:1370
VclPackType
Definition: vclenum.hxx:224
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:246
void set_property(const OString &rKey, const OUString &rValue)
Definition: layout.cxx:2153
int i
VclPtr< ScrollBarBox > m_aScrollBarBox
Definition: layout.hxx:527
VclPtr< VclButtonBox > m_pOwnedActionArea
void SetMaxTextWidth(long nMaxWidth)
Definition: vclmedit.cxx:1092
DrawFrameStyle m_eDrawFrameStyle
Definition: layout.hxx:524
VclPtr< ScrollBar > m_pVScroll
Definition: layout.hxx:525
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: layout.cxx:2023
bool get_expanded() const
Definition: layout.cxx:1638
int get_default_response() const
Definition: dialog.cxx:1463
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:1315
bool m_bIgnoreHidden
Definition: layout.hxx:593
virtual ~VclScrolledWindow() override
Definition: layout.cxx:2855
void SetRangeMax(long nNewRange)
Definition: scrbar.cxx:1333
std::unique_ptr< Image > mpDisclosureMinus
Definition: svdata.hxx:273
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:95
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2580
void SetVisibleSize(long nNewSize)
Definition: scrbar.cxx:1376
void SetSplitHdl(const Link< Splitter *, void > &rLink)
Definition: split.hxx:99
OUString get_label() const
Definition: layout.cxx:1484
CommandWheelMode GetMode() const
WinBits const WB_VCENTER
virtual void setPrimaryDimension(Size &rSize, long) const =0
virtual void SetSizePixel(const Size &rAllocation) override
Definition: layout.cxx:170
sal_Int32 get_margin_top() const
Definition: window2.cxx:1868
#define DEFAULT_CHILD_MIN_WIDTH
Definition: layout.cxx:385
virtual sal_uInt16 getDefaultAccessibleRole() const override
Definition: layout.cxx:374
Size calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
Definition: layout.cxx:1137
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:302
CommandEventId GetCommand() const
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1177
sal_uInt16 GetModifier() const
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:193
bool IsChecked() const
void add_button(PushButton *pButton, int nResponse, bool bTransferOwnership)
Definition: dialog.cxx:1393
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:510
const Size & GetFontSize() const
Definition: font/font.cxx:673
Size get_preferred_size() const
Definition: window2.cxx:1639
VclSizeGroupMode m_eMode
Definition: layout.hxx:594
bool isLayoutEnabled(const vcl::Window *pWindow)
Definition: layout.cxx:2823
MouseNotifyEvent GetType() const
Definition: event.hxx:303
void SetPageSize(long nNewSize)
Definition: scrbar.hxx:125
VclPtr< FixedImage > m_pImage
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:581
void SetToggleHdl(const Link< CheckBox &, void > &rLink)
void set_homogeneous(bool bHomogeneous)
Definition: layout.hxx:93
virtual void dispose() override
Definition: layout.cxx:1653
const AllSettings & GetSettings() const
Definition: outdev.hxx:418
virtual Size calculateRequisition() const override
Definition: layout.cxx:573
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1024
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
void SetImage(const Image &rImage)
Definition: fixed.cxx:933
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:1431
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:1608
void Check(bool bCheck=true)
VclPackType get_pack_type() const
Definition: window2.cxx:1730
bool get_orientation() const
Definition: layout.hxx:97
long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:895
vcl::Window * GetParent() const
Definition: window2.cxx:1097
virtual void ImplDrawCheckBoxState(vcl::RenderContext &rRenderContext) override
Definition: layout.cxx:1553
WinBits const WB_LEFT
void SetStyle(WinBits nStyle)
Definition: window.cxx:1957
Size GetSize() const
enumrange< T >::Iterator end(enumrange< T >)
void put(const char *pPropName, const OUString &rPropValue)
void setOptimalLayoutSize()
Definition: syswin.cxx:1119
void Scroll()
Definition: scrbar.cxx:1293
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1268
bool get_expand() const
Definition: window2.cxx:1718
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.hxx:652
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1039
void arrange(const Size &rAllocation, long nFirstHeight, long nSecondHeight)
Definition: layout.cxx:2537
DrawFrameStyle
Definition: vclenum.hxx:335
void sort_native_button_order(VclBox &rContainer)
Definition: layout.cxx:796
Size getVisibleChildSize() const
Definition: layout.cxx:1987
const Point & GetMousePosPixel() const
DisclosureButton(vcl::Window *pParent)
Definition: layout.cxx:1603
virtual Size calculateRequisition() const override
Definition: layout.cxx:2744
virtual void set_position(long nPosition)
Definition: layout.hxx:392
void set_grid_top_attach(sal_Int32 nAttach)
Definition: window2.cxx:1808
bool m_bInitialAllocation
Definition: layout.hxx:540
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:936
#define DEFAULT_CHILD_MIN_HEIGHT
Definition: layout.cxx:386
WinBits const WB_3DLOOK
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2081
VclScrolledWindow(vcl::Window *pParent)
Definition: layout.cxx:1790
DrawButtonFlags GetButtonState() const
Definition: button.cxx:494
VclButtonBox * get_action_area()
Definition: dialog.hxx:113
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3900
long CalcTitleWidth() const
Definition: window.cxx:2043
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:301
void set_valign(VclAlign eAlign)
Definition: window2.cxx:1688
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:54
static std::vector< long > setButtonSizes(const std::vector< long > &rG, const std::vector< bool > &rNonHomogeneous, long nAvgDimension, long nMaxNonOutlier, long nMinWidth)
Definition: layout.cxx:434
virtual void set_position(long nPosition) override
Definition: layout.cxx:2687
virtual void StateChanged(StateChangedType nStateChange) override
Definition: dialog.cxx:736
virtual ~VclVPaned() override
Definition: layout.cxx:2846
std::unique_ptr< char[]> aBuffer
OUString GetStandardInfoBoxText()
Definition: stdtext.cxx:55
virtual ~MessageDialog() override
Definition: layout.cxx:2384
bool IsMouseOver() const
Definition: mouse.cxx:606
virtual vcl::Window * get_child() override
Definition: layout.cxx:1837
virtual vcl::Window * get_child() override
Definition: layout.cxx:2076
constexpr sal_uInt16 KEY_SUBTRACT
Definition: keycodes.hxx:128
VclVPaned(vcl::Window *pParent)
Definition: layout.cxx:2523
sal_Int32 m_nPosition
void set_hexpand(bool bExpand)
Definition: window2.cxx:1700
WindowType
virtual Size calculateRequisition() const override
Definition: layout.cxx:1842
tools::Rectangle & Union(const tools::Rectangle &rRect)
bool get_column_homogeneous() const
Definition: layout.hxx:345
#define ERRCODE_NONE
Definition: errcode.hxx:198
void set_expanded(bool bExpanded)
Definition: layout.cxx:1643
void set_label(const OUString &rLabel)
Definition: layout.cxx:1648
int m_nSpacing
Definition: layout.hxx:76
VclExpander(vcl::Window *pParent)
Definition: layout.cxx:1624
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2049
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
virtual long getPrimaryCoordinate(const Point &rPos) const =0
Size addReqGroups(const VclButtonBox::Requisition &rReq) const
Definition: layout.cxx:404
vcl::Window * get_label_widget()
Definition: layout.cxx:1455
long m_nPosition
Definition: layout.hxx:385
bool IsVisible() const
Definition: window2.cxx:1102
virtual vcl::Window * get_child() override
Definition: layout.cxx:1668
#define SAL_INFO(area, stream)
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1982
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
Definition: layout.cxx:2830
VclPtr< EventBoxHelper > m_aEventBoxHelper
Definition: layout.hxx:571
void set_column_spacing(int nSpacing)
Definition: layout.hxx:353
virtual Size calculateRequisition() const override
Definition: layout.cxx:2092
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1022
virtual OUString getDefaultAccessibleName() const override
Definition: layout.cxx:1491
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: layout.cxx:2371
VclPtr< VclMultiLineEdit > m_pPrimaryMessage
virtual void SetText(const OUString &rStr) override
Definition: syswin.cxx:1103
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 void setPrimaryCoordinate(Point &rPos, long) const =0
virtual Size calculateRequisition() const override
Definition: layout.cxx:1673
virtual void set_content_area(VclBox *pBox)
Definition: dialog.cxx:592
sal_uInt64 Tell() const
void set_action_area(VclButtonBox *pBox)
Definition: dialog.cxx:581
Sequence< sal_Int8 > aSeq
virtual Size calculateRequisition() const override
Definition: layout.cxx:1132
VclAlign get_valign() const
Definition: window2.cxx:1682
MessageDialog(vcl::Window *pParent, WinBits nStyle)
Definition: layout.cxx:2321
WinBits const WB_AUTOHSCROLL
void set(reference_type *pBody)
Definition: vclptr.hxx:148
VclPtr< vcl::Window > mpFirstChild
Definition: window.h:234
virtual ~VclEventBox() override
Definition: layout.cxx:2114
SAL_DLLPRIVATE const tools::Rectangle & GetMouseRect() const
WinBits const WB_TABSTOP
std::vector< long > m_aSubGroupDimensions
Definition: layout.hxx:227
IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent &, rEvent, void)
Definition: layout.cxx:1427
std::unique_ptr< Image > mpDisclosurePlus
Definition: svdata.hxx:272
vcl::Window * getNonLayoutParent(vcl::Window *pWindow)
Definition: layout.cxx:2786
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize) override
Definition: layout.cxx:148
void doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
Definition: layout.cxx:1882
VclAlign
Definition: vclenum.hxx:216
WinBits const WB_CENTER
OUString GetStandardWarningBoxText()
Definition: stdtext.cxx:66
void set_secondary_text(const OUString &rSecondaryString)
Definition: layout.cxx:2480
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool IsEnabled() const
Definition: window2.cxx:1122
#define SAL_WARN(area, stream)
void RemoveEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:306
virtual Size calculateRequisition() const override
Definition: layout.cxx:224
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2699
WinBits GetStyle() const
Definition: window2.cxx:953
OUString m_sPrimaryString
void set_primary_text(const OUString &rPrimaryString)
Definition: layout.cxx:2469
static int getButtonPriority(const OString &rType)
Definition: layout.cxx:706
static long getMaxNonOutlier(const std::vector< long > &rG, long nAvgDimension)
Definition: layout.cxx:420
long get_position() const
Definition: layout.hxx:391
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:1499
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:1764
int get_row_spacing() const
Definition: layout.hxx:357
WinBits const WB_HORZ
bool HasFocus() const
Definition: window.cxx:3011
bool m_bUserManagedScrolling
Definition: layout.hxx:523
void setWidth(long nWidth)
bool m_bHomogeneous
Definition: layout.hxx:74
void set_label(const OUString &rLabel)
Definition: layout.cxx:1477
WinBits const WB_CLIPCHILDREN
sal_Int32 nState
DrawImageFlags
Definition: outdev.hxx:170
WinBits const WB_NOTABSTOP
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.cxx:2042
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1257
IMPL_LINK_NOARG(VclScrolledWindow, ScrollBarHdl, ScrollBar *, void)
Definition: layout.cxx:1813
VclButtonBoxStyle m_eLayoutStyle
Definition: layout.hxx:223
virtual void SetText(const OUString &rStr) override
Definition: vclmedit.cxx:1137
sal_Int32 get_border_width() const
Definition: window2.cxx:1820
VclPaned(vcl::Window *pParent, bool bVertical)
Definition: layout.cxx:2508
SAL_DLLPRIVATE void DoInitialLayout()
Definition: syswin.cxx:1140
void trigger_queue_resize()
Definition: layout.cxx:2125
VclHPaned(vcl::Window *pParent)
Definition: layout.cxx:2642
const void * GetData()
static bool isNullGrid(const array_type &A)
Definition: layout.cxx:993
VclAlign get_halign() const
Definition: window2.cxx:1670
static void calcMaxs(const array_type &A, std::vector< VclGrid::Value > &rWidths, std::vector< VclGrid::Value > &rHeights)
Definition: layout.cxx:1001
OUString m_sSecondaryString
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2182
bool toBool(const OUString &rValue)
Definition: layout.cxx:1321
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:357
void setHeight(long nHeight)