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