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 OUString &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 // fdo#74284 call Boxes Panels, keep them as "Filler" under
405 // at least Linux seeing as that's what Gtk3 did for GtkBoxes.
406 // Though now with Gtk4 that uses GTK_ACCESSIBLE_ROLE_GROUP
407 // which maps to ATSPI_ROLE_PANEL
408#if defined(_WIN32)
409 return css::accessibility::AccessibleRole::PANEL;
410#else
411 static sal_uInt16 eRole = Application::GetToolkitName() == "gtk4" ?
412 css::accessibility::AccessibleRole::PANEL :
413 css::accessibility::AccessibleRole::FILLER;
414 return eRole;
415#endif
416}
417
418#define DEFAULT_CHILD_MIN_WIDTH 85
419#define DEFAULT_CHILD_MIN_HEIGHT 27
420
421Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
422{
423 Size aRet;
424
425 if (nVisibleChildren)
426 {
427 tools::Long nPrimaryDimension = getPrimaryDimension(rSize);
428 if (m_bHomogeneous)
429 nPrimaryDimension *= nVisibleChildren;
430 setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
432 }
433
434 return aRet;
435}
436
438{
439 Size aRet;
440
441 tools::Long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
442 tools::Long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
443
444 setPrimaryDimension(aRet, nMainGroupDimension + nSubGroupDimension);
445
449
450 return aRet;
451}
452
453static tools::Long getMaxNonOutlier(const std::vector<tools::Long> &rG, tools::Long nAvgDimension)
454{
455 tools::Long nMaxDimensionNonOutlier = 0;
456 for (auto const& nPrimaryChildDimension : rG)
457 {
458 if (nPrimaryChildDimension < nAvgDimension * 1.5)
459 {
460 nMaxDimensionNonOutlier = std::max(nPrimaryChildDimension,
461 nMaxDimensionNonOutlier);
462 }
463 }
464 return nMaxDimensionNonOutlier;
465}
466
467static std::vector<tools::Long> setButtonSizes(const std::vector<tools::Long> &rG,
468 const std::vector<bool> &rNonHomogeneous,
469 tools::Long nAvgDimension, tools::Long nMaxNonOutlier, tools::Long nMinWidth)
470{
471 std::vector<tools::Long> aVec;
472 //set everything < 1.5 times the average to the same width, leave the
473 //outliers un-touched
474 std::vector<bool>::const_iterator aJ = rNonHomogeneous.begin();
475 auto nNonOutlierWidth = std::max(nMaxNonOutlier, nMinWidth);
476 for (auto const& nPrimaryChildDimension : rG)
477 {
478 bool bNonHomogeneous = *aJ;
479 if (!bNonHomogeneous && nPrimaryChildDimension < nAvgDimension * 1.5)
480 {
481 aVec.push_back(nNonOutlierWidth);
482 }
483 else
484 {
485 aVec.push_back(std::max(nPrimaryChildDimension, nMinWidth));
486 }
487 ++aJ;
488 }
489 return aVec;
490}
491
493{
494 Requisition aReq;
495
496 Size aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
497 Size aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
498
499 tools::Long nMinMainGroupPrimary = getPrimaryDimension(aMainGroupSize);
500 tools::Long nMinSubGroupPrimary = getPrimaryDimension(aSubGroupSize);
501 tools::Long nMainGroupSecondary = getSecondaryDimension(aMainGroupSize);
502 tools::Long nSubGroupSecondary = getSecondaryDimension(aSubGroupSize);
503
505
506 std::vector<tools::Long> aMainGroupSizes;
507 std::vector<bool> aMainGroupNonHomogeneous;
508 std::vector<tools::Long> aSubGroupSizes;
509 std::vector<bool> aSubGroupNonHomogeneous;
510
511 for (const vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
512 {
513 if (!pChild->IsVisible())
514 continue;
515 Size aChildSize = getLayoutRequisition(*pChild);
516 if (bIgnoreSecondaryPacking || !pChild->get_secondary())
517 {
518 //set the max secondary dimension
519 nMainGroupSecondary = std::max(nMainGroupSecondary, getSecondaryDimension(aChildSize));
520 //collect the primary dimensions
521 aMainGroupSizes.push_back(getPrimaryDimension(aChildSize));
522 aMainGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
523 }
524 else
525 {
526 nSubGroupSecondary = std::max(nSubGroupSecondary, getSecondaryDimension(aChildSize));
527 aSubGroupSizes.push_back(getPrimaryDimension(aChildSize));
528 aSubGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
529 }
530 }
531
532 if (m_bHomogeneous)
533 {
534 tools::Long nMaxMainDimension = aMainGroupSizes.empty() ? 0 :
535 *std::max_element(aMainGroupSizes.begin(), aMainGroupSizes.end());
536 nMaxMainDimension = std::max(nMaxMainDimension, nMinMainGroupPrimary);
537 tools::Long nMaxSubDimension = aSubGroupSizes.empty() ? 0 :
538 *std::max_element(aSubGroupSizes.begin(), aSubGroupSizes.end());
539 nMaxSubDimension = std::max(nMaxSubDimension, nMinSubGroupPrimary);
540 tools::Long nMaxDimension = std::max(nMaxMainDimension, nMaxSubDimension);
541 aReq.m_aMainGroupDimensions.resize(aMainGroupSizes.size(), nMaxDimension);
542 aReq.m_aSubGroupDimensions.resize(aSubGroupSizes.size(), nMaxDimension);
543 }
544 else
545 {
546 //Ideally set everything to the same size, but find outlier widgets
547 //that are way wider than the average and leave them
548 //at their natural size and set the remainder to share the
549 //max size of the remaining members of the buttonbox
550 tools::Long nAccDimension = std::accumulate(aMainGroupSizes.begin(),
551 aMainGroupSizes.end(), 0);
552 nAccDimension = std::accumulate(aSubGroupSizes.begin(),
553 aSubGroupSizes.end(), nAccDimension);
554
555 size_t nTotalSize = aMainGroupSizes.size() + aSubGroupSizes.size();
556
557 tools::Long nAvgDimension = nTotalSize ? nAccDimension / nTotalSize : 0;
558
559 tools::Long nMaxMainNonOutlier = getMaxNonOutlier(aMainGroupSizes,
560 nAvgDimension);
561 tools::Long nMaxSubNonOutlier = getMaxNonOutlier(aSubGroupSizes,
562 nAvgDimension);
563 tools::Long nMaxNonOutlier = std::max(nMaxMainNonOutlier, nMaxSubNonOutlier);
564
565 aReq.m_aMainGroupDimensions = setButtonSizes(aMainGroupSizes,
566 aMainGroupNonHomogeneous,
567 nAvgDimension, nMaxNonOutlier, nMinMainGroupPrimary);
568 aReq.m_aSubGroupDimensions = setButtonSizes(aSubGroupSizes,
569 aSubGroupNonHomogeneous,
570 nAvgDimension, nMaxNonOutlier, nMinSubGroupPrimary);
571 }
572
573 if (!aReq.m_aMainGroupDimensions.empty())
574 {
575 setSecondaryDimension(aReq.m_aMainGroupSize, nMainGroupSecondary);
577 std::accumulate(aReq.m_aMainGroupDimensions.begin(),
578 aReq.m_aMainGroupDimensions.end(), 0));
579 }
580 if (!aReq.m_aSubGroupDimensions.empty())
581 {
582 setSecondaryDimension(aReq.m_aSubGroupSize, nSubGroupSecondary);
584 std::accumulate(aReq.m_aSubGroupDimensions.begin(),
585 aReq.m_aSubGroupDimensions.end(), 0));
586 }
587
588 return aReq;
589}
590
591Size VclButtonBox::addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
592{
593 Size aRet;
594
595 if (nVisibleChildren)
596 {
597 tools::Long nPrimaryDimension = getPrimaryDimension(rSize);
599 nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
601 }
602
603 return aRet;
604}
605
607{
609 sal_uInt16 nVisibleChildren = aReq.m_aMainGroupDimensions.size() +
610 aReq.m_aSubGroupDimensions.size();
611 return addSpacing(addReqGroups(aReq), nVisibleChildren);
612}
613
614bool VclButtonBox::set_property(const OUString &rKey, const OUString &rValue)
615{
616 if (rKey == "layout-style")
617 {
619 if (rValue == "spread")
621 else if (rValue == "edge")
623 else if (rValue == "start")
625 else if (rValue == "end")
626 eStyle = VclButtonBoxStyle::End;
627 else if (rValue == "center")
629 else
630 {
631 SAL_WARN("vcl.layout", "unknown layout style " << rValue);
632 }
633 m_eLayoutStyle = eStyle;
634 }
635 else
636 return VclBox::set_property(rKey, rValue);
637 return true;
638}
639
640void VclButtonBox::setAllocation(const Size &rAllocation)
641{
643
644 if (aReq.m_aMainGroupDimensions.empty() && aReq.m_aSubGroupDimensions.empty())
645 return;
646
647 tools::Long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
648
649 Point aMainGroupPos, aOtherGroupPos;
650 int nSpacing = m_nSpacing;
651
652 //To-Do, other layout styles
653 switch (m_eLayoutStyle)
654 {
656 if (!aReq.m_aSubGroupDimensions.empty())
657 {
658 tools::Long nOtherPrimaryDimension = getPrimaryDimension(
660 setPrimaryCoordinate(aOtherGroupPos,
661 nAllocPrimaryDimension - nOtherPrimaryDimension);
662 }
663 break;
665 if (!aReq.m_aMainGroupDimensions.empty())
666 {
667 tools::Long nMainPrimaryDimension = getPrimaryDimension(
669 tools::Long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
670 nExtraSpace += (aReq.m_aMainGroupDimensions.size()-1) * nSpacing;
671 nSpacing = nExtraSpace/(aReq.m_aMainGroupDimensions.size()+1);
672 setPrimaryCoordinate(aMainGroupPos, nSpacing);
673 }
674 break;
676 if (!aReq.m_aMainGroupDimensions.empty())
677 {
678 tools::Long nMainPrimaryDimension = getPrimaryDimension(
680 tools::Long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
681 setPrimaryCoordinate(aMainGroupPos, nExtraSpace/2);
682 }
683 break;
684 default:
685 SAL_WARN("vcl.layout", "todo unimplemented layout style");
686 [[fallthrough]];
689 if (!aReq.m_aMainGroupDimensions.empty())
690 {
691 tools::Long nMainPrimaryDimension = getPrimaryDimension(
693 setPrimaryCoordinate(aMainGroupPos,
694 nAllocPrimaryDimension - nMainPrimaryDimension);
695 }
696 break;
697 }
698
699 Size aChildSize;
700 setSecondaryDimension(aChildSize, getSecondaryDimension(rAllocation));
701
702 std::vector<tools::Long>::const_iterator aPrimaryI = aReq.m_aMainGroupDimensions.begin();
703 std::vector<tools::Long>::const_iterator aSecondaryI = aReq.m_aSubGroupDimensions.begin();
705 for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
706 {
707 if (!pChild->IsVisible())
708 continue;
709
710 if (bIgnoreSecondaryPacking || !pChild->get_secondary())
711 {
712 tools::Long nMainGroupPrimaryDimension = *aPrimaryI++;
713 setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
714 setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
715 tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
716 setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + nSpacing);
717 }
718 else
719 {
720 tools::Long nSubGroupPrimaryDimension = *aSecondaryI++;
721 setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
722 setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
723 tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
724 setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + nSpacing);
725 }
726 }
727}
728
730{
731 VclBox::DumpAsPropertyTree(rJsonWriter);
732 rJsonWriter.put("type", "buttonbox");
733
734 switch(m_eLayoutStyle)
735 {
737 rJsonWriter.put("layoutstyle", "default");
738 break;
739
741 rJsonWriter.put("layoutstyle", "spread");
742 break;
743
745 rJsonWriter.put("layoutstyle", "edge");
746 break;
747
749 rJsonWriter.put("layoutstyle", "center");
750 break;
751
753 rJsonWriter.put("layoutstyle", "start");
754 break;
755
757 rJsonWriter.put("layoutstyle", "end");
758 break;
759 }
760}
761
762namespace {
763
764struct ButtonOrder
765{
766 std::u16string_view m_aType;
767 int m_nPriority;
768};
769
770}
771
772static int getButtonPriority(std::u16string_view rType)
773{
774 static const size_t N_TYPES = 6;
775 static const ButtonOrder aDiscardCancelSave[N_TYPES] =
776 {
777 { u"discard", 0 },
778 { u"cancel", 1 },
779 { u"no", 2 },
780 { u"save", 3 },
781 { u"yes", 3 },
782 { u"ok", 3 }
783 };
784
785 static const ButtonOrder aSaveDiscardCancel[N_TYPES] =
786 {
787 { u"save", 0 },
788 { u"yes", 0 },
789 { u"ok", 0 },
790 { u"discard", 1 },
791 { u"no", 1 },
792 { u"cancel", 2 }
793 };
794
795 const ButtonOrder* pOrder = &aDiscardCancelSave[0];
796
797 const OUString &rEnv = Application::GetDesktopEnvironment();
798
799 if (rEnv.equalsIgnoreAsciiCase("windows") ||
800 rEnv.equalsIgnoreAsciiCase("lxqt") ||
801 rEnv.startsWithIgnoreAsciiCase("plasma"))
802 {
803 pOrder = &aSaveDiscardCancel[0];
804 }
805
806 for (size_t i = 0; i < N_TYPES; ++i, ++pOrder)
807 {
808 if (rType == pOrder->m_aType)
809 return pOrder->m_nPriority;
810 }
811
812 return -1;
813}
814
815namespace {
816
817class sortButtons
818{
819 bool m_bVerticalContainer;
820public:
821 explicit sortButtons(bool bVerticalContainer)
822 : m_bVerticalContainer(bVerticalContainer)
823 {
824 }
825 bool operator()(const vcl::Window *pA, const vcl::Window *pB) const;
826};
827
828}
829
830bool sortButtons::operator()(const vcl::Window *pA, const vcl::Window *pB) const
831{
832 //sort into two groups of pack start and pack end
833 VclPackType ePackA = pA->get_pack_type();
834 VclPackType ePackB = pB->get_pack_type();
835 if (ePackA < ePackB)
836 return true;
837 if (ePackA > ePackB)
838 return false;
839 bool bPackA = pA->get_secondary();
840 bool bPackB = pB->get_secondary();
841 if (!m_bVerticalContainer)
842 {
843 //for horizontal boxes group secondaries before primaries
844 if (bPackA > bPackB)
845 return true;
846 if (bPackA < bPackB)
847 return false;
848 }
849 else
850 {
851 //for vertical boxes group secondaries after primaries
852 if (bPackA < bPackB)
853 return true;
854 if (bPackA > bPackB)
855 return false;
856 }
857
858 //now order within groups according to platform rules
859 return getButtonPriority(pA->get_id()) < getButtonPriority(pB->get_id());
860}
861
862void sort_native_button_order(const VclBox& rContainer)
863{
864 std::vector<vcl::Window*> aChilds;
865 for (vcl::Window* pChild = rContainer.GetWindow(GetWindowType::FirstChild); pChild;
866 pChild = pChild->GetWindow(GetWindowType::Next))
867 {
868 aChilds.push_back(pChild);
869 }
870
871 //sort child order within parent so that we match the platform
872 //button order
873 std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(rContainer.get_orientation()));
875}
876
877namespace {
878
879struct GridEntry
880{
881 VclPtr<vcl::Window> pChild;
882 sal_Int32 nSpanWidth;
883 sal_Int32 nSpanHeight;
884 int x;
885 int y;
886 GridEntry()
887 : pChild(nullptr)
888 , nSpanWidth(0)
889 , nSpanHeight(0)
890 , x(-1)
891 , y(-1)
892 {
893 }
894};
895
896}
897
898typedef boost::multi_array<GridEntry, 2> array_type;
899
900static array_type assembleGrid(const VclGrid &rGrid);
901static bool isNullGrid(const array_type& A);
902static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights);
903
905{
907
908 for (vcl::Window* pChild = rGrid.GetWindow(GetWindowType::FirstChild); pChild;
909 pChild = pChild->GetWindow(GetWindowType::Next))
910 {
911 sal_Int32 nLeftAttach = std::max<sal_Int32>(pChild->get_grid_left_attach(), 0);
912 sal_Int32 nWidth = pChild->get_grid_width();
913 sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
914
915 sal_Int32 nTopAttach = std::max<sal_Int32>(pChild->get_grid_top_attach(), 0);
916 sal_Int32 nHeight = pChild->get_grid_height();
917 sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
918
919 sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
920 sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
921 if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
922 {
923 nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
924 nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
925 A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
926 }
927
928 GridEntry &rEntry = A[nLeftAttach][nTopAttach];
929 rEntry.pChild = pChild;
930 rEntry.nSpanWidth = nWidth;
931 rEntry.nSpanHeight = nHeight;
932 rEntry.x = nLeftAttach;
933 rEntry.y = nTopAttach;
934
935 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
936 {
937 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
938 {
939 GridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
940 rSpan.x = nLeftAttach;
941 rSpan.y = nTopAttach;
942 }
943 }
944 }
945
946 //see if we have any empty rows/cols
947 sal_Int32 nMaxX = A.shape()[0];
948 sal_Int32 nMaxY = A.shape()[1];
949
950 std::vector<bool> aNonEmptyCols(nMaxX);
951 std::vector<bool> aNonEmptyRows(nMaxY);
952
953 for (sal_Int32 x = 0; x < nMaxX; ++x)
954 {
955 for (sal_Int32 y = 0; y < nMaxY; ++y)
956 {
957#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
958#pragma GCC diagnostic push
959#pragma GCC diagnostic ignored "-Wdangling-reference"
960#endif
961 const GridEntry &rEntry = A[x][y];
962#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
963#pragma GCC diagnostic pop
964#endif
965 const vcl::Window *pChild = rEntry.pChild;
966 if (pChild && pChild->IsVisible())
967 {
968 aNonEmptyCols[x] = true;
969 if (rGrid.get_column_homogeneous())
970 {
971 for (sal_Int32 nSpanX = 1; nSpanX < rEntry.nSpanWidth; ++nSpanX)
972 aNonEmptyCols[x+nSpanX] = true;
973 }
974 aNonEmptyRows[y] = true;
975 if (rGrid.get_row_homogeneous())
976 {
977 for (sal_Int32 nSpanY = 1; nSpanY < rEntry.nSpanHeight; ++nSpanY)
978 aNonEmptyRows[y+nSpanY] = true;
979 }
980 }
981 }
982 }
983
984 if (!rGrid.get_column_homogeneous())
985 {
986 //reduce the spans of elements that span empty columns
987 for (sal_Int32 x = 0; x < nMaxX; ++x)
988 {
989 std::set<GridEntry*> candidates;
990 for (sal_Int32 y = 0; y < nMaxY; ++y)
991 {
992 if (aNonEmptyCols[x])
993 continue;
994 GridEntry &rSpan = A[x][y];
995 //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
996 //just points back to itself if there's no cell spanning
997 if ((rSpan.x == -1) || (rSpan.y == -1))
998 {
999 //there is no entry for this cell, i.e. this is a cell
1000 //with no widget in it, or spanned by any other widget
1001 continue;
1002 }
1003 GridEntry &rEntry = A[rSpan.x][rSpan.y];
1004 candidates.insert(&rEntry);
1005 }
1006 for (auto const& candidate : candidates)
1007 {
1008 GridEntry *pEntry = candidate;
1009 --pEntry->nSpanWidth;
1010 }
1011 }
1012 }
1013
1014 if (!rGrid.get_row_homogeneous())
1015 {
1016 //reduce the spans of elements that span empty rows
1017 for (sal_Int32 y = 0; y < nMaxY; ++y)
1018 {
1019 std::set<GridEntry*> candidates;
1020 for (sal_Int32 x = 0; x < nMaxX; ++x)
1021 {
1022 if (aNonEmptyRows[y])
1023 continue;
1024 GridEntry &rSpan = A[x][y];
1025 //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
1026 //just points back to itself if there's no cell spanning
1027 if ((rSpan.x == -1) || (rSpan.y == -1))
1028 {
1029 //there is no entry for this cell, i.e. this is a cell
1030 //with no widget in it, or spanned by any other widget
1031 continue;
1032 }
1033 GridEntry &rEntry = A[rSpan.x][rSpan.y];
1034 candidates.insert(&rEntry);
1035 }
1036 for (auto const& candidate : candidates)
1037 {
1038 GridEntry *pEntry = candidate;
1039 --pEntry->nSpanHeight;
1040 }
1041 }
1042 }
1043
1044 sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
1045 sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
1046
1047 //make new grid without empty rows and columns
1048 array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
1049 for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
1050 {
1051 if (!aNonEmptyCols[x])
1052 continue;
1053 for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
1054 {
1055 if (!aNonEmptyRows[y])
1056 continue;
1057 GridEntry &rEntry = A[x][y];
1058 B[x2][y2++] = rEntry;
1059 }
1060 ++x2;
1061 }
1062
1063 return B;
1064}
1065
1066static bool isNullGrid(const array_type &A)
1067{
1068 sal_Int32 nMaxX = A.shape()[0];
1069 sal_Int32 nMaxY = A.shape()[1];
1070
1071 return !nMaxX || !nMaxY;
1072}
1073
1074static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights)
1075{
1076 sal_Int32 nMaxX = A.shape()[0];
1077 sal_Int32 nMaxY = A.shape()[1];
1078
1079 rWidths.resize(nMaxX);
1080 rHeights.resize(nMaxY);
1081
1082 //first use the non spanning entries to set default width/heights
1083 for (sal_Int32 x = 0; x < nMaxX; ++x)
1084 {
1085 for (sal_Int32 y = 0; y < nMaxY; ++y)
1086 {
1087#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
1088#pragma GCC diagnostic push
1089#pragma GCC diagnostic ignored "-Wdangling-reference"
1090#endif
1091 const GridEntry &rEntry = A[x][y];
1092#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
1093#pragma GCC diagnostic pop
1094#endif
1095 const vcl::Window *pChild = rEntry.pChild;
1096 if (!pChild || !pChild->IsVisible())
1097 continue;
1098
1099 sal_Int32 nWidth = rEntry.nSpanWidth;
1100 sal_Int32 nHeight = rEntry.nSpanHeight;
1101
1102 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1103 rWidths[x+nSpanX].m_bExpand |= pChild->get_hexpand();
1104
1105 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1106 rHeights[y+nSpanY].m_bExpand |= pChild->get_vexpand();
1107
1108 if (nWidth == 1 || nHeight == 1)
1109 {
1110 Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1111 if (nWidth == 1)
1112 rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
1113 if (nHeight == 1)
1114 rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
1115 }
1116 }
1117 }
1118
1119 //now use the spanning entries and split any extra sizes across expanding rows/cols
1120 //where possible
1121 for (sal_Int32 x = 0; x < nMaxX; ++x)
1122 {
1123 for (sal_Int32 y = 0; y < nMaxY; ++y)
1124 {
1125#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
1126#pragma GCC diagnostic push
1127#pragma GCC diagnostic ignored "-Wdangling-reference"
1128#endif
1129 const GridEntry &rEntry = A[x][y];
1130#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
1131#pragma GCC diagnostic pop
1132#endif
1133 const vcl::Window *pChild = rEntry.pChild;
1134 if (!pChild || !pChild->IsVisible())
1135 continue;
1136
1137 sal_Int32 nWidth = rEntry.nSpanWidth;
1138 sal_Int32 nHeight = rEntry.nSpanHeight;
1139
1140 if (nWidth == 1 && nHeight == 1)
1141 continue;
1142
1143 Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1144
1145 if (nWidth > 1)
1146 {
1147 sal_Int32 nExistingWidth = 0;
1148 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1149 nExistingWidth += rWidths[x+nSpanX].m_nValue;
1150
1151 sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
1152
1153 if (nExtraWidth > 0)
1154 {
1155 bool bForceExpandAll = false;
1156 sal_Int32 nExpandables = 0;
1157 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1158 if (rWidths[x+nSpanX].m_bExpand)
1159 ++nExpandables;
1160 if (nExpandables == 0)
1161 {
1162 nExpandables = nWidth;
1163 bForceExpandAll = true;
1164 }
1165
1166 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1167 {
1168 if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
1169 rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
1170 }
1171 }
1172 }
1173
1174 if (nHeight > 1)
1175 {
1176 sal_Int32 nExistingHeight = 0;
1177 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1178 nExistingHeight += rHeights[y+nSpanY].m_nValue;
1179
1180 sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
1181
1182 if (nExtraHeight > 0)
1183 {
1184 bool bForceExpandAll = false;
1185 sal_Int32 nExpandables = 0;
1186 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1187 if (rHeights[y+nSpanY].m_bExpand)
1188 ++nExpandables;
1189 if (nExpandables == 0)
1190 {
1191 nExpandables = nHeight;
1192 bForceExpandAll = true;
1193 }
1194
1195 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1196 {
1197 if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
1198 rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
1199 }
1200 }
1201 }
1202 }
1203 }
1204}
1205
1206static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
1207{
1208 return i.m_nValue < j.m_nValue;
1209}
1210
1212{
1213 VclGrid::Value aRet;
1214 aRet.m_nValue = i.m_nValue + j.m_nValue;
1215 aRet.m_bExpand = i.m_bExpand || j.m_bExpand;
1216 return aRet;
1217}
1218
1220{
1222}
1223
1224Size VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
1225{
1226 array_type A = assembleGrid(*this);
1227
1228 if (isNullGrid(A))
1229 return Size();
1230
1231 std::vector<Value> aWidths;
1232 std::vector<Value> aHeights;
1233 calcMaxs(A, aWidths, aHeights);
1234
1235 tools::Long nTotalWidth = 0;
1237 {
1238 nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
1239 nTotalWidth *= aWidths.size();
1240 }
1241 else
1242 {
1243 nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
1244 }
1245
1246 nTotalWidth += nColSpacing * (aWidths.size()-1);
1247
1248 tools::Long nTotalHeight = 0;
1249 if (get_row_homogeneous())
1250 {
1251 nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
1252 nTotalHeight *= aHeights.size();
1253 }
1254 else
1255 {
1256 nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
1257 }
1258
1259 nTotalHeight += nRowSpacing * (aHeights.size()-1);
1260
1261 return Size(nTotalWidth, nTotalHeight);
1262}
1263
1264void VclGrid::setAllocation(const Size& rAllocation)
1265{
1266 array_type A = assembleGrid(*this);
1267
1268 if (isNullGrid(A))
1269 return;
1270
1271 sal_Int32 nMaxX = A.shape()[0];
1272 sal_Int32 nMaxY = A.shape()[1];
1273
1274 Size aRequisition;
1275 std::vector<Value> aWidths(nMaxX);
1276 std::vector<Value> aHeights(nMaxY);
1278 {
1279 aRequisition = calculateRequisition();
1280 calcMaxs(A, aWidths, aHeights);
1281 }
1282
1283 sal_Int32 nColSpacing(get_column_spacing());
1284 sal_Int32 nRowSpacing(get_row_spacing());
1285
1286 tools::Long nAvailableWidth = rAllocation.Width();
1287 if (nMaxX)
1288 nAvailableWidth -= nColSpacing * (nMaxX - 1);
1290 {
1291 for (sal_Int32 x = 0; x < nMaxX; ++x)
1292 aWidths[x].m_nValue = nAvailableWidth/nMaxX;
1293 }
1294 else if (rAllocation.Width() != aRequisition.Width())
1295 {
1296 sal_Int32 nExpandables = 0;
1297 for (sal_Int32 x = 0; x < nMaxX; ++x)
1298 if (aWidths[x].m_bExpand)
1299 ++nExpandables;
1300 tools::Long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
1301
1302 //We don't fit and there is no volunteer to be shrunk
1303 if (!nExpandables && rAllocation.Width() < aRequisition.Width())
1304 {
1305 //first reduce spacing
1306 while (nColSpacing)
1307 {
1308 nColSpacing /= 2;
1309 aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1310 if (aRequisition.Width() <= rAllocation.Width())
1311 break;
1312 }
1313
1314 //share out the remaining pain to everyone
1315 tools::Long nExtraWidth = (rAllocation.Width() - aRequisition.Width()) / nMaxX;
1316
1317 for (sal_Int32 x = 0; x < nMaxX; ++x)
1318 aWidths[x].m_nValue += nExtraWidth;
1319 }
1320
1321 if (nExtraWidthForExpanders)
1322 {
1323 for (sal_Int32 x = 0; x < nMaxX; ++x)
1324 if (aWidths[x].m_bExpand)
1325 aWidths[x].m_nValue += nExtraWidthForExpanders;
1326 }
1327 }
1328
1329 tools::Long nAvailableHeight = rAllocation.Height();
1330 if (nMaxY)
1331 nAvailableHeight -= nRowSpacing * (nMaxY - 1);
1332 if (get_row_homogeneous())
1333 {
1334 for (sal_Int32 y = 0; y < nMaxY; ++y)
1335 aHeights[y].m_nValue = nAvailableHeight/nMaxY;
1336 }
1337 else if (rAllocation.Height() != aRequisition.Height())
1338 {
1339 sal_Int32 nExpandables = 0;
1340 for (sal_Int32 y = 0; y < nMaxY; ++y)
1341 if (aHeights[y].m_bExpand)
1342 ++nExpandables;
1343 tools::Long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
1344
1345 //We don't fit and there is no volunteer to be shrunk
1346 if (!nExpandables && rAllocation.Height() < aRequisition.Height())
1347 {
1348 //first reduce spacing
1349 while (nRowSpacing)
1350 {
1351 nRowSpacing /= 2;
1352 aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1353 if (aRequisition.Height() <= rAllocation.Height())
1354 break;
1355 }
1356
1357 //share out the remaining pain to everyone
1358 tools::Long nExtraHeight = (rAllocation.Height() - aRequisition.Height()) / nMaxY;
1359
1360 for (sal_Int32 y = 0; y < nMaxY; ++y)
1361 aHeights[y].m_nValue += nExtraHeight;
1362 }
1363
1364 if (nExtraHeightForExpanders)
1365 {
1366 for (sal_Int32 y = 0; y < nMaxY; ++y)
1367 if (aHeights[y].m_bExpand)
1368 aHeights[y].m_nValue += nExtraHeightForExpanders;
1369 }
1370 }
1371
1372 Point aAllocPos(0, 0);
1373 for (sal_Int32 x = 0; x < nMaxX; ++x)
1374 {
1375 for (sal_Int32 y = 0; y < nMaxY; ++y)
1376 {
1377#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
1378#pragma GCC diagnostic push
1379#pragma GCC diagnostic ignored "-Wdangling-reference"
1380#endif
1381 GridEntry &rEntry = A[x][y];
1382#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
1383#pragma GCC diagnostic pop
1384#endif
1385 vcl::Window *pChild = rEntry.pChild;
1386 if (pChild)
1387 {
1388 Size aChildAlloc(0, 0);
1389
1390 sal_Int32 nWidth = rEntry.nSpanWidth;
1391 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1392 aChildAlloc.AdjustWidth(aWidths[x+nSpanX].m_nValue );
1393 aChildAlloc.AdjustWidth(nColSpacing*(nWidth-1) );
1394
1395 sal_Int32 nHeight = rEntry.nSpanHeight;
1396 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1397 aChildAlloc.AdjustHeight(aHeights[y+nSpanY].m_nValue );
1398 aChildAlloc.AdjustHeight(nRowSpacing*(nHeight-1) );
1399
1400 setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
1401 }
1402 aAllocPos.AdjustY(aHeights[y].m_nValue + nRowSpacing );
1403 }
1404 aAllocPos.AdjustX(aWidths[x].m_nValue + nColSpacing );
1405 aAllocPos.setY( 0 );
1406 }
1407}
1408
1410{
1412 rJsonWriter.put("type", "grid");
1413}
1414
1415bool toBool(std::u16string_view rValue)
1416{
1417 return (!rValue.empty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
1418}
1419
1420bool VclGrid::set_property(const OUString &rKey, const OUString &rValue)
1421{
1422 if (rKey == "row-spacing")
1423 set_row_spacing(rValue.toInt32());
1424 else if (rKey == "column-spacing")
1425 set_column_spacing(rValue.toInt32());
1426 else if (rKey == "row-homogeneous")
1427 m_bRowHomogeneous = toBool(rValue);
1428 else if (rKey == "column-homogeneous")
1429 m_bColumnHomogeneous = toBool(rValue);
1430 else if (rKey == "n-rows")
1431 /*nothing to do*/;
1432 else
1433 return VclContainer::set_property(rKey, rValue);
1434 return true;
1435}
1436
1437const vcl::Window *VclBin::get_child() const
1438{
1439 const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1440
1441 return pWindowImpl->mpFirstChild;
1442}
1443
1444vcl::Window *VclBin::get_child()
1445{
1446 return const_cast<vcl::Window*>(const_cast<const VclBin*>(this)->get_child());
1447}
1448
1449Size VclBin::calculateRequisition() const
1450{
1451 const vcl::Window *pChild = get_child();
1452 if (pChild && pChild->IsVisible())
1453 return getLayoutRequisition(*pChild);
1454 return Size(0, 0);
1455}
1456
1457void VclBin::setAllocation(const Size &rAllocation)
1458{
1459 vcl::Window *pChild = get_child();
1460 if (pChild && pChild->IsVisible())
1461 setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
1462}
1463
1465{
1466 disposeOnce();
1467}
1468
1470{
1471 m_pLabel.clear();
1472 VclBin::dispose();
1473}
1474
1475//To-Do, hook a DecorationView into VclFrame ?
1476
1478{
1479 Size aRet(0, 0);
1480
1481 const vcl::Window *pChild = get_child();
1482 const vcl::Window *pLabel = get_label_widget();
1483
1484 if (pChild && pChild->IsVisible())
1485 aRet = getLayoutRequisition(*pChild);
1486
1487 if (pLabel && pLabel->IsVisible())
1488 {
1489 Size aLabelSize = getLayoutRequisition(*pLabel);
1490 aRet.AdjustHeight(aLabelSize.Height() );
1491 aRet.setWidth( std::max(aLabelSize.Width(), aRet.Width()) );
1492 }
1493
1494 return aRet;
1495}
1496
1497void VclFrame::setAllocation(const Size &rAllocation)
1498{
1499 //SetBackground( Color(0xFF, 0x00, 0xFF) );
1500
1501 Size aAllocation(rAllocation);
1502 Point aChildPos;
1503
1504 vcl::Window *pChild = get_child();
1505 vcl::Window *pLabel = get_label_widget();
1506
1507 if (pLabel && pLabel->IsVisible())
1508 {
1509 Size aLabelSize = getLayoutRequisition(*pLabel);
1510 aLabelSize.setHeight( std::min(aLabelSize.Height(), aAllocation.Height()) );
1511 aLabelSize.setWidth( std::min(aLabelSize.Width(), aAllocation.Width()) );
1512 setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
1513 aAllocation.AdjustHeight( -(aLabelSize.Height()) );
1514 aChildPos.AdjustY(aLabelSize.Height() );
1515 }
1516
1517 if (pChild && pChild->IsVisible())
1518 setLayoutAllocation(*pChild, aChildPos, aAllocation);
1519}
1520
1521IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent&, rEvent, void)
1522{
1523 if (rEvent.GetId() == VclEventId::ObjectDying)
1524 designate_label(nullptr);
1525}
1526
1528{
1529 assert(!pWindow || pWindow->GetParent() == this);
1530 if (m_pLabel)
1531 m_pLabel->RemoveEventListener(LINK(this, VclFrame, WindowEventListener));
1532 m_pLabel = pWindow;
1533 if (m_pLabel)
1534 m_pLabel->AddEventListener(LINK(this, VclFrame, WindowEventListener));
1535}
1536
1538{
1539 if (m_pLabel)
1540 return m_pLabel;
1541 assert(GetChildCount() <= 2);
1542 //The label widget is normally the first (of two) children
1543 const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1544 if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
1545 return nullptr;
1546 return pWindowImpl->mpFirstChild;
1547}
1548
1550{
1551 return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
1552}
1553
1555{
1556 //The child widget is the normally the last (of two) children
1557 const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1558 assert(GetChildCount() == 2 || pWindowImpl->mbInDispose);
1559 if (!m_pLabel)
1560 return pWindowImpl->mpLastChild;
1561 if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
1562 return nullptr;
1563 return pWindowImpl->mpLastChild;
1564}
1565
1567{
1568 return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_child());
1569}
1570
1571void VclFrame::set_label(const OUString &rLabel)
1572{
1573 vcl::Window *pLabel = get_label_widget();
1574 assert(pLabel);
1575 pLabel->SetText(rLabel);
1576}
1577
1578OUString VclFrame::get_label() const
1579{
1580 const vcl::Window *pLabel = get_label_widget();
1581 assert(pLabel);
1582 return pLabel->GetText();
1583}
1584
1586{
1587 const vcl::Window *pLabel = get_label_widget();
1588 if (pLabel)
1589 return pLabel->GetAccessibleName();
1590 return VclBin::getDefaultAccessibleName();
1591}
1592
1594{
1595 VclBin::DumpAsPropertyTree(rJsonWriter);
1596 rJsonWriter.put("type", "frame");
1597}
1598
1599class DisclosureButton final : public CheckBox
1600{
1601 virtual void ImplDrawCheckBoxState(vcl::RenderContext& rRenderContext) override
1602 {
1603 /* HACK: DisclosureButton is currently assuming, that the disclosure sign
1604 will fit into the rectangle occupied by a normal checkbox on all themes.
1605 If this does not hold true for some theme, ImplGetCheckImageSize
1606 would have to be overridden for DisclosureButton; also GetNativeControlRegion
1607 for ControlType::ListNode would have to be implemented and taken into account
1608 */
1609
1610 tools::Rectangle aStateRect(GetStateRect());
1611
1613 tools::Rectangle aCtrlRegion(aStateRect);
1615
1616 if (HasFocus())
1620 if (Window::IsEnabled())
1622 if (IsMouseOver() && GetMouseRect().Contains(GetPointerPosPixel()))
1624
1625 if (rRenderContext.DrawNativeControl(ControlType::ListNode, ControlPart::Entire, aCtrlRegion,
1626 nState, aControlValue, OUString()))
1627 return;
1628
1629 ImplSVCtrlData& rCtrlData(ImplGetSVData()->maCtrlData);
1630 if (!rCtrlData.moDisclosurePlus)
1631 rCtrlData.moDisclosurePlus.emplace(StockImage::Yes, SV_DISCLOSURE_PLUS);
1632 if (!rCtrlData.moDisclosureMinus)
1633 rCtrlData.moDisclosureMinus.emplace(StockImage::Yes, SV_DISCLOSURE_MINUS);
1634
1635 Image* pImg
1636 = IsChecked() ? &*rCtrlData.moDisclosureMinus : &*rCtrlData.moDisclosurePlus;
1637
1639 if (!IsEnabled())
1640 nStyle |= DrawImageFlags::Disable;
1641
1642 Size aSize(aStateRect.GetSize());
1643 Size aImgSize(pImg->GetSizePixel());
1644 Point aOff((aSize.Width() - aImgSize.Width()) / 2,
1645 (aSize.Height() - aImgSize.Height()) / 2);
1646 aOff += aStateRect.TopLeft();
1647 rRenderContext.DrawImage(aOff, *pImg, nStyle);
1648 }
1649
1650public:
1652 : CheckBox(pParent, 0)
1653 {
1654 }
1655
1656 virtual void KeyInput( const KeyEvent& rKEvt ) override
1657 {
1658 vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1659
1660 if( !aKeyCode.GetModifier() &&
1661 ( ( aKeyCode.GetCode() == KEY_ADD ) ||
1662 ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
1663 )
1664 {
1665 Check( aKeyCode.GetCode() == KEY_ADD );
1666 }
1667 else
1668 CheckBox::KeyInput( rKEvt );
1669 }
1670};
1671
1673 : VclBin(pParent)
1674 , m_bResizeTopLevel(false)
1675 , m_pDisclosureButton(VclPtr<DisclosureButton>::Create(this))
1676{
1679}
1680
1682{
1683 disposeOnce();
1684}
1685
1687{
1689}
1690
1691void VclExpander::set_expanded(bool bExpanded)
1692{
1693 m_pDisclosureButton->Check(bExpanded);
1694}
1695
1696void VclExpander::set_label(const OUString& rLabel)
1697{
1699}
1700
1702{
1703 return m_pDisclosureButton->GetText();
1704}
1705
1707{
1709 VclBin::dispose();
1710}
1711
1713{
1714 const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1715
1716 assert(pWindowImpl->mpFirstChild == m_pDisclosureButton);
1717
1718 return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
1719}
1720
1722{
1723 return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_child());
1724}
1725
1727{
1728 Size aRet(0, 0);
1729
1730 WindowImpl* pWindowImpl = ImplGetWindowImpl();
1731
1732 const vcl::Window *pChild = get_child();
1733 const vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild.get() : nullptr;
1734
1735 if (pChild && pChild->IsVisible() && m_pDisclosureButton->IsChecked())
1736 aRet = getLayoutRequisition(*pChild);
1737
1738 Size aExpanderSize = getLayoutRequisition(*m_pDisclosureButton);
1739
1740 if (pLabel && pLabel->IsVisible())
1741 {
1742 Size aLabelSize = getLayoutRequisition(*pLabel);
1743 aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1744 aExpanderSize.AdjustWidth(aLabelSize.Width() );
1745 }
1746
1747 aRet.AdjustHeight(aExpanderSize.Height() );
1748 aRet.setWidth( std::max(aExpanderSize.Width(), aRet.Width()) );
1749
1750 return aRet;
1751}
1752
1753void VclExpander::setAllocation(const Size &rAllocation)
1754{
1755 Size aAllocation(rAllocation);
1756 Point aChildPos;
1757
1758 WindowImpl* pWindowImpl = ImplGetWindowImpl();
1759
1760 //The label widget is the last (of two) children
1761 vcl::Window *pChild = get_child();
1762 vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild.get() ? pWindowImpl->mpLastChild.get() : nullptr;
1763
1764 Size aButtonSize = getLayoutRequisition(*m_pDisclosureButton);
1765 Size aLabelSize;
1766 Size aExpanderSize = aButtonSize;
1767 if (pLabel && pLabel->IsVisible())
1768 {
1769 aLabelSize = getLayoutRequisition(*pLabel);
1770 aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1771 aExpanderSize.AdjustWidth(aLabelSize.Width() );
1772 }
1773
1774 aExpanderSize.setHeight( std::min(aExpanderSize.Height(), aAllocation.Height()) );
1775 aExpanderSize.setWidth( std::min(aExpanderSize.Width(), aAllocation.Width()) );
1776
1777 aButtonSize.setHeight( std::min(aButtonSize.Height(), aExpanderSize.Height()) );
1778 aButtonSize.setWidth( std::min(aButtonSize.Width(), aExpanderSize.Width()) );
1779
1780 tools::Long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
1781 Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
1782 setLayoutAllocation(*m_pDisclosureButton, aButtonPos, aButtonSize);
1783
1784 if (pLabel && pLabel->IsVisible())
1785 {
1786 aLabelSize.setHeight( std::min(aLabelSize.Height(), aExpanderSize.Height()) );
1787 aLabelSize.setWidth( std::min(aLabelSize.Width(),
1788 aExpanderSize.Width() - aButtonSize.Width()) );
1789
1790 tools::Long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
1791 Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
1792 setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
1793 }
1794
1795 aAllocation.AdjustHeight( -(aExpanderSize.Height()) );
1796 aChildPos.AdjustY(aExpanderSize.Height() );
1797
1798 if (pChild && pChild->IsVisible())
1799 {
1801 aAllocation = Size();
1802 setLayoutAllocation(*pChild, aChildPos, aAllocation);
1803 }
1804}
1805
1806bool VclExpander::set_property(const OUString &rKey, const OUString &rValue)
1807{
1808 if (rKey == "expanded")
1809 set_expanded(toBool(rValue));
1810 else if (rKey == "resize-toplevel")
1811 m_bResizeTopLevel = toBool(rValue);
1812 else
1813 return VclBin::set_property(rKey, rValue);
1814 return true;
1815}
1816
1818{
1819 VclBin::StateChanged( nType );
1820
1822 {
1823 vcl::Window *pChild = get_child();
1824 if (pChild)
1826 }
1827}
1828
1830{
1831 return m_pDisclosureButton;
1832}
1833
1835{
1836 return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_label_widget());
1837}
1838
1840{
1842 rJsonWriter.put("type", "expander");
1843}
1844
1846{
1848}
1849
1850IMPL_LINK( VclExpander, ClickHdl, CheckBox&, rBtn, void )
1851{
1852 vcl::Window *pChild = get_child();
1853 if (pChild)
1854 {
1855 pChild->Show(rBtn.IsChecked());
1856 queue_resize();
1857 Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : nullptr;
1858 if (pResizeDialog)
1859 pResizeDialog->setOptimalLayoutSize(true);
1860 }
1861 maExpandedHdl.Call(*this);
1862}
1863
1866 , m_bUserManagedScrolling(false)
1867 , m_eDrawFrameStyle(DrawFrameStyle::NONE)
1868 , m_eDrawFrameFlags(DrawFrameFlags::WindowBorder)
1869 , m_pVScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_VERT))
1870 , m_pHScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_HORZ))
1871 , m_aScrollBarBox(VclPtr<ScrollBarBox>::Create(this, WB_HIDE))
1872{
1873 SetType(WindowType::SCROLLWINDOW);
1874
1875 AllSettings aAllSettings = GetSettings();
1876 StyleSettings aStyle = aAllSettings.GetStyleSettings();
1877 aStyle.SetMonoColor(aStyle.GetShadowColor());
1878 aAllSettings.SetStyleSettings(aStyle);
1879 GetOutDev()->SetSettings(aAllSettings);
1880
1881 Link<ScrollBar*,void> aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) );
1882 m_pVScroll->SetScrollHdl(aLink);
1883 m_pHScroll->SetScrollHdl(aLink);
1884
1886}
1887
1889{
1891 return 0;
1892 const tools::Rectangle aRect(tools::Rectangle(Point(0, 0), Size(100, 100)));
1893 DecorationView aDecoView(const_cast<OutputDevice*>(GetOutDev()));
1894 // don't actually draw anything, just measure what size it would be and the diff is the desired border size to reserve
1896 const auto nBorderWidth = (aRect.GetWidth() - aContentRect.GetWidth()) / 2;
1897 return std::max<int>(nBorderWidth, 1);
1898}
1899
1901{
1905 VclBin::dispose();
1906}
1907
1909{
1910 vcl::Window *pChild = get_child();
1911 if (!pChild)
1912 return;
1913
1914 assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
1915
1916 pChild = pChild->GetWindow(GetWindowType::FirstChild);
1917
1918 if (!pChild)
1919 return;
1920
1921 Point aWinPos(-m_pHScroll->GetThumbPos(), -m_pVScroll->GetThumbPos());
1922 pChild->SetPosPixel(aWinPos);
1923}
1924
1926{
1927 const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1928 assert(GetChildCount() == 4 || pWindowImpl->mbInDispose);
1929 return pWindowImpl->mpLastChild;
1930}
1931
1933{
1934 return const_cast<vcl::Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
1935}
1936
1938{
1939 Size aRet(0, 0);
1940
1941 const vcl::Window *pChild = get_child();
1942 if (pChild && pChild->IsVisible())
1943 aRet = getLayoutRequisition(*pChild);
1944
1945 if (GetStyle() & WB_VSCROLL)
1946 aRet.AdjustWidth(getLayoutRequisition(*m_pVScroll).Width() );
1947
1948 if (GetStyle() & WB_HSCROLL)
1949 aRet.AdjustHeight(getLayoutRequisition(*m_pHScroll).Height() );
1950
1951 aRet.AdjustHeight(2 * m_nBorderWidth);
1952 aRet.AdjustWidth(2 * m_nBorderWidth);
1953
1954 return aRet;
1955}
1956
1958{
1959 const vcl::Window *pChild = get_child();
1960 if (!pChild || !pChild->IsVisible())
1961 return;
1962
1963 Size aOutSize(getVisibleChildSize());
1964
1965 m_pVScroll->SetRangeMax(rRequest.Height());
1966 m_pVScroll->SetVisibleSize(aOutSize.Height());
1968
1969 m_pHScroll->SetRangeMax(rRequest.Width());
1970 m_pHScroll->SetVisibleSize(aOutSize.Width());
1972
1973 m_pVScroll->Scroll();
1974 m_pHScroll->Scroll();
1975}
1976
1977void VclScrolledWindow::doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
1978{
1979 Size aChildReq;
1980
1981 vcl::Window *pChild = get_child();
1982 if (pChild && pChild->IsVisible())
1983 aChildReq = getLayoutRequisition(*pChild);
1984
1985 tools::Long nAvailHeight = rAllocation.Height() - 2 * m_nBorderWidth;
1986 tools::Long nAvailWidth = rAllocation.Width() - 2 * m_nBorderWidth;
1987
1988 // vert. ScrollBar
1989 bool bShowVScroll;
1990 if (GetStyle() & WB_AUTOVSCROLL)
1991 bShowVScroll = nAvailHeight < aChildReq.Height();
1992 else
1993 bShowVScroll = (GetStyle() & WB_VSCROLL) != 0;
1994
1995 if (bShowVScroll)
1996 nAvailWidth -= getLayoutRequisition(*m_pVScroll).Width();
1997
1998 // horz. ScrollBar
1999 bool bShowHScroll;
2000 if (GetStyle() & WB_AUTOHSCROLL)
2001 {
2002 bShowHScroll = nAvailWidth < aChildReq.Width();
2003
2004 if (bShowHScroll)
2005 nAvailHeight -= getLayoutRequisition(*m_pHScroll).Height();
2006
2007 if (GetStyle() & WB_AUTOVSCROLL)
2008 bShowVScroll = nAvailHeight < aChildReq.Height();
2009 }
2010 else
2011 bShowHScroll = (GetStyle() & WB_HSCROLL) != 0;
2012
2013 if (m_pHScroll->IsVisible() != bShowHScroll)
2014 m_pHScroll->Show(bShowHScroll);
2015 if (m_pVScroll->IsVisible() != bShowVScroll)
2016 m_pVScroll->Show(bShowVScroll);
2017
2018 Size aInnerSize(rAllocation);
2019 aInnerSize.AdjustWidth(-2 * m_nBorderWidth);
2020 aInnerSize.AdjustHeight(-2 * m_nBorderWidth);
2021
2022 bool bBothVisible = m_pVScroll->IsVisible() && m_pHScroll->IsVisible();
2023 auto nScrollBarWidth = getLayoutRequisition(*m_pVScroll).Width();
2024 auto nScrollBarHeight = getLayoutRequisition(*m_pHScroll).Height();
2025
2026 if (m_pVScroll->IsVisible())
2027 {
2028 Point aScrollPos(rAllocation.Width() - nScrollBarWidth - m_nBorderWidth, m_nBorderWidth);
2029 Size aScrollSize(nScrollBarWidth, rAllocation.Height() - 2 * m_nBorderWidth);
2030 if (bBothVisible)
2031 aScrollSize.AdjustHeight(-nScrollBarHeight);
2032 setLayoutAllocation(*m_pVScroll, aScrollPos, aScrollSize);
2033 aInnerSize.AdjustWidth( -nScrollBarWidth );
2034 }
2035
2036 if (m_pHScroll->IsVisible())
2037 {
2038 Point aScrollPos(m_nBorderWidth, rAllocation.Height() - nScrollBarHeight);
2039 Size aScrollSize(rAllocation.Width() - 2 * m_nBorderWidth, nScrollBarHeight);
2040 if (bBothVisible)
2041 aScrollSize.AdjustWidth(-nScrollBarWidth);
2042 setLayoutAllocation(*m_pHScroll, aScrollPos, aScrollSize);
2043 aInnerSize.AdjustHeight( -nScrollBarHeight );
2044 }
2045
2046 if (bBothVisible)
2047 {
2048 Point aBoxPos(aInnerSize.Width() + m_nBorderWidth, aInnerSize.Height() + m_nBorderWidth);
2049 m_aScrollBarBox->SetPosSizePixel(aBoxPos, Size(nScrollBarWidth, nScrollBarHeight));
2051 }
2052 else
2053 {
2055 }
2056
2057 if (pChild && pChild->IsVisible())
2058 {
2059 assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
2060
2061 WinBits nOldBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
2062
2063 setLayoutAllocation(*pChild, Point(m_nBorderWidth, m_nBorderWidth), aInnerSize);
2064
2065 // tdf#128758 if the layout allocation triggered some callback that
2066 // immediately invalidates the layout by adding scrollbars then
2067 // normally this would simply retrigger layout and another toplevel
2068 // attempt is made later. But the initial layout attempt blocks
2069 // relayouts, so just make another single effort here.
2070 WinBits nNewBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
2071 if (nOldBits != nNewBits && bRetryOnFailure)
2072 {
2073 doSetAllocation(rAllocation, false);
2074 return;
2075 }
2076 }
2077
2079 InitScrollBars(aChildReq);
2080}
2081
2083{
2084 doSetAllocation(rAllocation, true);
2085}
2086
2088{
2089 Size aRet(GetSizePixel());
2090 if (m_pVScroll->IsVisible())
2091 aRet.AdjustWidth( -(m_pVScroll->GetSizePixel().Width()) );
2092 if (m_pHScroll->IsVisible())
2094 aRet.AdjustHeight(-2 * m_nBorderWidth);
2095 aRet.AdjustWidth(-2 * m_nBorderWidth);
2096 return aRet;
2097}
2098
2099bool VclScrolledWindow::set_property(const OUString &rKey, const OUString &rValue)
2100{
2101 if (rKey == "shadow-type" || rKey == "name")
2102 {
2103 if (rKey == "shadow-type")
2104 {
2105 // despite the style names, this looks like the best mapping
2106 if (rValue == "in")
2108 else if (rValue == "out")
2110 else if (rValue == "etched-in")
2112 else if (rValue == "etched-out")
2114 else if (rValue == "none")
2116 }
2117 else if (rKey == "name")
2118 {
2120 if (rValue == "monoborder")
2122 }
2123
2126 {
2128 queue_resize();
2129 }
2130
2131 return true;
2132 }
2133
2134 bool bRet = VclBin::set_property(rKey, rValue);
2135 m_pVScroll->Show((GetStyle() & WB_VSCROLL) != 0);
2136 m_pHScroll->Show((GetStyle() & WB_HSCROLL) != 0);
2137 return bRet;
2138}
2139
2141{
2142 bool bDone = false;
2143 if ( rNEvt.GetType() == NotifyEventType::COMMAND )
2144 {
2145 const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2146 if ( rCEvt.GetCommand() == CommandEventId::Wheel )
2147 {
2148 const CommandWheelData* pData = rCEvt.GetWheelData();
2149 if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
2150 {
2151 // tdf#140537 only handle scroll commands in the valid shown scrollbars
2152 bDone = HandleScrollCommand(rCEvt,
2153 m_pHScroll->IsVisible() ? m_pHScroll : nullptr,
2154 m_pVScroll->IsVisible() ? m_pVScroll : nullptr);
2155 }
2156 }
2157 }
2158
2159 return bDone || VclBin::EventNotify( rNEvt );
2160}
2161
2163{
2164 VclBin::Paint(rRenderContext, rRect);
2166 return;
2167 const tools::Rectangle aRect(tools::Rectangle(Point(0,0), GetSizePixel()));
2168 DecorationView aDecoView(&rRenderContext);
2169 const tools::Rectangle aContentRect = aDecoView.DrawFrame(aRect, m_eDrawFrameStyle, m_eDrawFrameFlags);
2170 const auto nBorderWidth = (aRect.GetWidth() - aContentRect.GetWidth()) / 2;
2171 SAL_WARN_IF(nBorderWidth > m_nBorderWidth, "vcl.layout", "desired border at paint " <<
2172 nBorderWidth << " is larger than expected " << m_nBorderWidth);
2173}
2174
2175namespace {
2176void lcl_dumpScrollbar(::tools::JsonWriter& rJsonWriter, ScrollBar& rScrollBar)
2177{
2178 rJsonWriter.put("lower", rScrollBar.GetRangeMin());
2179 rJsonWriter.put("upper", rScrollBar.GetRangeMax());
2180 rJsonWriter.put("step_increment", rScrollBar.GetLineSize());
2181 rJsonWriter.put("page_increment", rScrollBar.GetPageSize());
2182 rJsonWriter.put("value", rScrollBar.GetThumbPos());
2183 rJsonWriter.put("page_size", rScrollBar.GetVisibleSize());
2184}
2185};
2186
2188{
2189 VclBin::DumpAsPropertyTree(rJsonWriter);
2190
2191 rJsonWriter.put("user_managed_scrolling", m_bUserManagedScrolling);
2192
2193 {
2194 auto aVertical = rJsonWriter.startNode("vertical");
2195
2196 ScrollBar& rScrollBar = getVertScrollBar();
2197 lcl_dumpScrollbar(rJsonWriter, rScrollBar);
2198
2199 WinBits nWinBits = GetStyle();
2200 if (nWinBits & WB_VSCROLL)
2201 rJsonWriter.put("policy", "always");
2202 else if (nWinBits & WB_AUTOVSCROLL)
2203 rJsonWriter.put("policy", "auto");
2204 else
2205 rJsonWriter.put("policy", "never");
2206 }
2207
2208 {
2209 auto aHorizontal = rJsonWriter.startNode("horizontal");
2210
2211 ScrollBar& rScrollBar = getHorzScrollBar();
2212 lcl_dumpScrollbar(rJsonWriter, rScrollBar);
2213
2214 WinBits nWinBits = GetStyle();
2215 if (nWinBits & WB_HSCROLL)
2216 rJsonWriter.put("policy", "always");
2217 else if (nWinBits & WB_AUTOHSCROLL)
2218 rJsonWriter.put("policy", "auto");
2219 else
2220 rJsonWriter.put("policy", "never");
2221 }
2222}
2223
2224void VclViewport::setAllocation(const Size &rAllocation)
2225{
2226 vcl::Window *pChild = get_child();
2227 if (!(pChild && pChild->IsVisible()))
2228 return;
2229
2230 Size aReq(getLayoutRequisition(*pChild));
2231 aReq.setWidth( std::max(aReq.Width(), rAllocation.Width()) );
2232 aReq.setHeight( std::max(aReq.Height(), rAllocation.Height()) );
2233 Point aKeepPos(pChild->GetPosPixel());
2235 {
2236 aKeepPos = Point(0, 0);
2237 m_bInitialAllocation = false;
2238 }
2239 setLayoutAllocation(*pChild, aKeepPos, aReq);
2240}
2241
2243{
2244 const WindowImpl* pWindowImpl = ImplGetWindowImpl();
2245
2246 assert(pWindowImpl->mpFirstChild.get() == m_aEventBoxHelper.get());
2247
2248 return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
2249}
2250
2252{
2253 return const_cast<vcl::Window*>(const_cast<const VclEventBox*>(this)->get_child());
2254}
2255
2256void VclEventBox::setAllocation(const Size& rAllocation)
2257{
2258 Point aChildPos(0, 0);
2259 for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
2260 {
2261 if (!pChild->IsVisible())
2262 continue;
2263 setLayoutAllocation(*pChild, aChildPos, rAllocation);
2264 }
2265}
2266
2268{
2269 Size aRet(0, 0);
2270
2271 for (const vcl::Window* pChild = get_child(); pChild;
2272 pChild = pChild->GetWindow(GetWindowType::Next))
2273 {
2274 if (!pChild->IsVisible())
2275 continue;
2276 Size aChildSize = getLayoutRequisition(*pChild);
2277 aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2278 aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2279 }
2280
2281 return aRet;
2282}
2283
2285{
2286 //discard events by default to block them reaching children
2287}
2288
2290{
2291 disposeOnce();
2292}
2293
2295{
2296 m_aEventBoxHelper.disposeAndClear();
2297 VclBin::dispose();
2298}
2299
2301{
2302 //sufficient to trigger one widget to trigger all of them
2303 if (!m_aWindows.empty())
2304 {
2305 (*m_aWindows.begin())->queue_resize();
2306 }
2307}
2308
2309void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden)
2310{
2311 if (bIgnoreHidden != m_bIgnoreHidden)
2312 {
2313 m_bIgnoreHidden = bIgnoreHidden;
2315 }
2316}
2317
2319{
2320 if (eMode != m_eMode)
2321 {
2322 m_eMode = eMode;
2324 }
2325
2326}
2327
2328void VclSizeGroup::set_property(const OUString &rKey, const OUString &rValue)
2329{
2330 if (rKey == "ignore-hidden")
2331 set_ignore_hidden(toBool(rValue));
2332 else if (rKey == "mode")
2333 {
2335 if (rValue == "none")
2337 else if (rValue == "horizontal")
2339 else if (rValue == "vertical")
2341 else if (rValue == "both")
2343 else
2344 {
2345 SAL_WARN("vcl.layout", "unknown size group mode" << rValue);
2346 }
2347 set_mode(eMode);
2348 }
2349 else
2350 {
2351 SAL_INFO("vcl.layout", "unhandled property: " << rKey);
2352 }
2353}
2354
2356{
2357 setDeferredProperties();
2358
2359 if (m_pGrid)
2360 return;
2361
2362 VclContainer *pContainer = get_content_area();
2363 assert(pContainer);
2364
2365 m_pGrid.set( VclPtr<VclGrid>::Create(pContainer) );
2372
2374 switch (m_eMessageType)
2375 {
2378 break;
2381 break;
2384 break;
2387 break;
2389 break;
2390 }
2395
2397
2398 bool bHasSecondaryText = !m_sSecondaryString.isEmpty();
2399
2403
2407
2413 m_pSecondaryMessage->Show(bHasSecondaryText);
2414
2415 MessageDialog::SetMessagesWidths(this, m_pPrimaryMessage, bHasSecondaryText ? m_pSecondaryMessage.get() : nullptr);
2416
2417 VclButtonBox *pButtonBox = get_action_area();
2418 assert(pButtonBox);
2419
2420 VclPtr<PushButton> pBtn;
2421 short nDefaultResponse = get_default_response();
2422 switch (m_eButtonsType)
2423 {
2425 break;
2426 case VclButtonsType::Ok:
2427 pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2428 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2429 pBtn->Show();
2430 pBtn->set_id("ok");
2431 add_button(pBtn, RET_OK, true);
2432 nDefaultResponse = RET_OK;
2433 break;
2435 pBtn.set( VclPtr<CloseButton>::Create(pButtonBox) );
2436 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2437 pBtn->Show();
2438 pBtn->set_id("close");
2439 add_button(pBtn, RET_CLOSE, true);
2440 nDefaultResponse = RET_CLOSE;
2441 break;
2443 pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2444 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2445 pBtn->Show();
2446 pBtn->set_id("cancel");
2447 add_button(pBtn, RET_CANCEL, true);
2448 nDefaultResponse = RET_CANCEL;
2449 break;
2451 pBtn = VclPtr<PushButton>::Create(pButtonBox);
2453 pBtn->Show();
2454 pBtn->set_id("yes");
2455 add_button(pBtn, RET_YES, true);
2456
2457 pBtn.set( VclPtr<PushButton>::Create(pButtonBox) );
2459 pBtn->Show();
2460 pBtn->set_id("no");
2461 add_button(pBtn, RET_NO, true);
2462 nDefaultResponse = RET_NO;
2463 break;
2465 pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2466 pBtn->Show();
2467 pBtn->set_id("ok");
2468 add_button(pBtn, RET_OK, true);
2469
2470 pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2471 pBtn->Show();
2472 pBtn->set_id("cancel");
2473 add_button(pBtn, RET_CANCEL, true);
2474 nDefaultResponse = RET_CANCEL;
2475 break;
2476 }
2477 set_default_response(nDefaultResponse);
2478 sort_native_button_order(*pButtonBox);
2480 m_pGrid->Show();
2481}
2482
2484{
2485#if defined _WIN32
2487#else
2488 set_border_width(12);
2489#endif
2496}
2497
2499 : Dialog(pParent, nStyle)
2500 , m_eButtonsType(VclButtonsType::NONE)
2501 , m_eMessageType(VclMessageType::Info)
2502 , m_pOwnedContentArea(nullptr)
2503 , m_pOwnedActionArea(nullptr)
2504 , m_pGrid(nullptr)
2505 , m_pMessageBox(nullptr)
2506 , m_pImage(nullptr)
2507 , m_pPrimaryMessage(nullptr)
2508 , m_pSecondaryMessage(nullptr)
2509{
2511}
2512
2514 OUString aMessage,
2515 VclMessageType eMessageType,
2516 VclButtonsType eButtonsType)
2518 , m_eButtonsType(eButtonsType)
2519 , m_eMessageType(eMessageType)
2520 , m_pGrid(nullptr)
2521 , m_pMessageBox(nullptr)
2522 , m_pImage(nullptr)
2523 , m_pPrimaryMessage(nullptr)
2524 , m_pSecondaryMessage(nullptr)
2525 , m_sPrimaryString(std::move(aMessage))
2526{
2530
2531 switch (m_eMessageType)
2532 {
2535 break;
2538 break;
2541 break;
2544 break;
2547 break;
2548 }
2549}
2550
2552{
2562}
2563
2565{
2566 disposeOnce();
2567}
2568
2570 VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
2571{
2572 if (pSecondaryMessage)
2573 {
2574 assert(pPrimaryMessage);
2575 vcl::Font aFont = pParent->GetSettings().GetStyleSettings().GetLabelFont();
2576 aFont.SetFontSize(Size(0, aFont.GetFontSize().Height() * 1.2));
2577 aFont.SetWeight(WEIGHT_BOLD);
2578 pPrimaryMessage->SetControlFont(aFont);
2579 pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 44);
2580 pSecondaryMessage->SetMaxTextWidth(pSecondaryMessage->approximate_char_width() * 60);
2581 }
2582 else
2583 pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 60);
2584}
2585
2586OUString const & MessageDialog::get_primary_text() const
2587{
2588 const_cast<MessageDialog*>(this)->setDeferredProperties();
2589
2590 return m_sPrimaryString;
2591}
2592
2594{
2595 const_cast<MessageDialog*>(this)->setDeferredProperties();
2596
2597 return m_sSecondaryString;
2598}
2599
2600bool MessageDialog::set_property(const OUString &rKey, const OUString &rValue)
2601{
2602 if (rKey == "text")
2603 set_primary_text(rValue);
2604 else if (rKey == "secondary-text")
2605 set_secondary_text(rValue);
2606 else if (rKey == "message-type")
2607 {
2609 if (rValue == "info")
2611 else if (rValue == "warning")
2613 else if (rValue == "question")
2615 else if (rValue == "error")
2617 else if (rValue == "other")
2619 else
2620 {
2621 SAL_WARN("vcl.layout", "unknown message type mode" << rValue);
2622 }
2624 }
2625 else if (rKey == "buttons")
2626 {
2628 if (rValue == "none")
2630 else if (rValue == "ok")
2632 else if (rValue == "cancel")
2634 else if (rValue == "close")
2636 else if (rValue == "yes-no")
2638 else if (rValue == "ok-cancel")
2640 else
2641 {
2642 SAL_WARN("vcl.layout", "unknown buttons type mode" << rValue);
2643 }
2645 }
2646 else
2647 return Dialog::set_property(rKey, rValue);
2648 return true;
2649}
2650
2651void MessageDialog::set_primary_text(const OUString &rPrimaryString)
2652{
2653 m_sPrimaryString = rPrimaryString;
2655 {
2659 }
2660}
2661
2662void MessageDialog::set_secondary_text(const OUString &rSecondaryString)
2663{
2664 m_sSecondaryString = rSecondaryString;
2666 {
2670 }
2671}
2672
2674{
2677 {
2678 // MessageBox should be at least as wide as to see the title
2679 auto nTitleWidth = CalcTitleWidth();
2680 // Extra-Width for Close button
2681 nTitleWidth += mpWindowImpl->mnTopBorder;
2682 if (get_preferred_size().Width() < nTitleWidth)
2683 {
2684 set_width_request(nTitleWidth);
2686 }
2687 }
2688}
2689
2690VclPaned::VclPaned(vcl::Window *pParent, bool bVertical)
2692 , m_pSplitter(VclPtr<Splitter>::Create(this, bVertical ? WB_VSCROLL : WB_HSCROLL))
2693 , m_nPosition(-1)
2694{
2695 m_pSplitter->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor()));
2696 m_pSplitter->Show();
2697}
2698
2700{
2703}
2704
2706 : VclPaned(pParent, true)
2707{
2708 m_pSplitter->SetSplitHdl(LINK(this, VclVPaned, SplitHdl));
2709}
2710
2711IMPL_LINK(VclVPaned, SplitHdl, Splitter*, pSplitter, void)
2712{
2713 tools::Long nSize = pSplitter->GetSplitPosPixel();
2714 Size aSplitterSize(m_pSplitter->GetSizePixel());
2715 Size aAllocation(GetSizePixel());
2716 arrange(aAllocation, nSize, aAllocation.Height() - nSize - aSplitterSize.Height());
2717}
2718
2719void VclVPaned::arrange(const Size& rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
2720{
2721 Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2722 Size aFirstChildSize(rAllocation.Width(), nFirstHeight);
2723 Size aSecondChildSize(rAllocation.Width(), nSecondHeight);
2724 int nElement = 0;
2725 for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2726 pChild = pChild->GetWindow(GetWindowType::Next))
2727 {
2728 if (!pChild->IsVisible())
2729 continue;
2730 if (nElement == 0)
2731 {
2732 Point aSplitterPos(0, aFirstChildSize.Height());
2733 setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2734 m_nPosition = aSplitterPos.Y() + aSplitterSize.Height() / 2;
2735 }
2736 else if (nElement == 1)
2737 {
2738 Point aChildPos(0, 0);
2739 setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2740 }
2741 else if (nElement == 2)
2742 {
2743 Point aChildPos(0, aFirstChildSize.Height() + aSplitterSize.Height());
2744 setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2745 }
2746 ++nElement;
2747 }
2748}
2749
2751{
2752 VclPaned::set_position(nPosition);
2753
2754 Size aAllocation(GetSizePixel());
2755 Size aSplitterSize(m_pSplitter->GetSizePixel());
2756
2757 nPosition -= aSplitterSize.Height() / 2;
2758
2759 arrange(aAllocation, nPosition, aAllocation.Height() - nPosition - aSplitterSize.Height());
2760}
2761
2762void VclVPaned::setAllocation(const Size& rAllocation)
2763{
2764 //supporting "shrink" could be done by adjusting the allowed drag rectangle
2765 m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2766 Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2767 const tools::Long nHeight = rAllocation.Height() - aSplitterSize.Height();
2768
2769 tools::Long nFirstHeight = 0;
2770 tools::Long nSecondHeight = 0;
2771 bool bFirstCanResize = true;
2772 bool bSecondCanResize = true;
2773 const bool bInitialAllocation = get_position() < 0;
2774 int nElement = 0;
2775 for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2776 pChild = pChild->GetWindow(GetWindowType::Next))
2777 {
2778 if (!pChild->IsVisible())
2779 continue;
2780 if (nElement == 1)
2781 {
2782 if (bInitialAllocation)
2783 nFirstHeight = getLayoutRequisition(*pChild).Height();
2784 else
2785 nFirstHeight = pChild->GetSizePixel().Height() + pChild->get_margin_top() + pChild->get_margin_bottom();
2786 bFirstCanResize = pChild->get_expand();
2787 }
2788 else if (nElement == 2)
2789 {
2790 if (bInitialAllocation)
2791 nSecondHeight = getLayoutRequisition(*pChild).Height();
2792 else
2793 nSecondHeight = pChild->GetSizePixel().Height() + pChild->get_margin_top() + pChild->get_margin_bottom();
2794 bSecondCanResize = pChild->get_expand();
2795 }
2796 ++nElement;
2797 }
2798 tools::Long nHeightRequest = nFirstHeight + nSecondHeight;
2799 tools::Long nHeightDiff = nHeight - nHeightRequest;
2800 if (bFirstCanResize == bSecondCanResize)
2801 nFirstHeight += nHeightDiff/2;
2802 else if (bFirstCanResize)
2803 nFirstHeight += nHeightDiff;
2804 arrange(rAllocation, nFirstHeight, rAllocation.Height() - nFirstHeight - aSplitterSize.Height());
2805}
2806
2808{
2809 Size aRet(0, 0);
2810
2811 for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2812 pChild = pChild->GetWindow(GetWindowType::Next))
2813 {
2814 if (!pChild->IsVisible())
2815 continue;
2816 Size aChildSize = getLayoutRequisition(*pChild);
2817 aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2818 aRet.AdjustHeight(aChildSize.Height() );
2819 }
2820
2821 return aRet;
2822}
2823
2825 : VclPaned(pParent, false)
2826{
2827 m_pSplitter->SetSplitHdl(LINK(this, VclHPaned, SplitHdl));
2828}
2829
2830IMPL_LINK(VclHPaned, SplitHdl, Splitter*, pSplitter, void)
2831{
2832 tools::Long nSize = pSplitter->GetSplitPosPixel();
2833 Size aSplitterSize(m_pSplitter->GetSizePixel());
2834 Size aAllocation(GetSizePixel());
2835 arrange(aAllocation, nSize, aAllocation.Width() - nSize - aSplitterSize.Width());
2836}
2837
2838void VclHPaned::arrange(const Size& rAllocation, tools::Long nFirstWidth, tools::Long nSecondWidth)
2839{
2840 Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2841 Size aFirstChildSize(nFirstWidth, rAllocation.Height());
2842 Size aSecondChildSize(nSecondWidth, rAllocation.Height());
2843 int nElement = 0;
2844 for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2845 pChild = pChild->GetWindow(GetWindowType::Next))
2846 {
2847 if (!pChild->IsVisible())
2848 continue;
2849 if (nElement == 0)
2850 {
2851 Point aSplitterPos(aFirstChildSize.Width(), 0);
2852 setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2853 m_nPosition = aSplitterPos.X() + aSplitterSize.Width() / 2;
2854 }
2855 else if (nElement == 1)
2856 {
2857 Point aChildPos(0, 0);
2858 setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2859 }
2860 else if (nElement == 2)
2861 {
2862 Point aChildPos(aFirstChildSize.Width() + aSplitterSize.Width(), 0);
2863 setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2864 }
2865 ++nElement;
2866 }
2867}
2868
2870{
2871 VclPaned::set_position(nPosition);
2872
2873 Size aAllocation(GetSizePixel());
2874 Size aSplitterSize(m_pSplitter->GetSizePixel());
2875
2876 nPosition -= aSplitterSize.Width() / 2;
2877
2878 arrange(aAllocation, nPosition, aAllocation.Width() - nPosition - aSplitterSize.Width());
2879}
2880
2881void VclHPaned::setAllocation(const Size& rAllocation)
2882{
2883 //supporting "shrink" could be done by adjusting the allowed drag rectangle
2884 m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2885 Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2886 const tools::Long nWidth = rAllocation.Width() - aSplitterSize.Width();
2887
2888 tools::Long nFirstWidth = 0;
2889 tools::Long nSecondWidth = 0;
2890 bool bFirstCanResize = true;
2891 bool bSecondCanResize = true;
2892 const bool bInitialAllocation = get_position() < 0;
2893 int nElement = 0;
2894 for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2895 pChild = pChild->GetWindow(GetWindowType::Next))
2896 {
2897 if (!pChild->IsVisible())
2898 continue;
2899 if (nElement == 1)
2900 {
2901 if (bInitialAllocation)
2902 nFirstWidth = getLayoutRequisition(*pChild).Width();
2903 else
2904 nFirstWidth = pChild->GetSizePixel().Width() + pChild->get_margin_start() + pChild->get_margin_end();
2905 bFirstCanResize = pChild->get_expand();
2906 }
2907 else if (nElement == 2)
2908 {
2909 if (bInitialAllocation)
2910 nSecondWidth = getLayoutRequisition(*pChild).Width();
2911 else
2912 nSecondWidth = pChild->GetSizePixel().Width() + pChild->get_margin_start() + pChild->get_margin_end();
2913 bSecondCanResize = pChild->get_expand();
2914 }
2915 ++nElement;
2916 }
2917 tools::Long nWidthRequest = nFirstWidth + nSecondWidth;
2918 tools::Long nWidthDiff = nWidth - nWidthRequest;
2919 if (bFirstCanResize == bSecondCanResize)
2920 nFirstWidth += nWidthDiff/2;
2921 else if (bFirstCanResize)
2922 nFirstWidth += nWidthDiff;
2923 arrange(rAllocation, nFirstWidth, rAllocation.Width() - nFirstWidth - aSplitterSize.Width());
2924}
2925
2927{
2928 Size aRet(0, 0);
2929
2930 for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2931 pChild = pChild->GetWindow(GetWindowType::Next))
2932 {
2933 if (!pChild->IsVisible())
2934 continue;
2935 Size aChildSize = getLayoutRequisition(*pChild);
2936 aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2937 aRet.AdjustWidth(aChildSize.Width() );
2938 }
2939
2940 return aRet;
2941}
2942
2944{
2945 tools::Rectangle aBounds;
2946
2947 for (const vcl::Window* pChild = rWindow.GetWindow(GetWindowType::FirstChild); pChild;
2948 pChild = pChild->GetWindow(GetWindowType::Next))
2949 {
2950 if (!pChild->IsVisible())
2951 continue;
2952
2953 tools::Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
2954 aBounds.Union(aChildBounds);
2955 }
2956
2957 if (aBounds.IsEmpty())
2958 return rWindow.GetSizePixel();
2959
2960 Size aRet(aBounds.GetSize());
2961 Point aTopLeft(aBounds.TopLeft());
2962 aRet.AdjustWidth(aTopLeft.X()*2 );
2963 aRet.AdjustHeight(aTopLeft.Y()*2 );
2964
2965 return aRet;
2966}
2967
2969{
2970 while (pWindow)
2971 {
2972 pWindow = pWindow->GetParent();
2973 if (!pWindow || !isContainerWindow(*pWindow))
2974 break;
2975 }
2976 return pWindow;
2977}
2978
2979bool isVisibleInLayout(const vcl::Window *pWindow)
2980{
2981 bool bVisible = true;
2982 while (bVisible)
2983 {
2984 bVisible = pWindow->IsVisible();
2985 pWindow = pWindow->GetParent();
2986 if (!pWindow || !isContainerWindow(*pWindow))
2987 break;
2988 }
2989 return bVisible;
2990}
2991
2992bool isEnabledInLayout(const vcl::Window *pWindow)
2993{
2994 bool bEnabled = true;
2995 while (bEnabled)
2996 {
2997 bEnabled = pWindow->IsEnabled();
2998 pWindow = pWindow->GetParent();
2999 if (!pWindow || !isContainerWindow(*pWindow))
3000 break;
3001 }
3002 return bEnabled;
3003}
3004
3005bool isLayoutEnabled(const vcl::Window *pWindow)
3006{
3007 //Child is a container => we're layout enabled
3008 const vcl::Window *pChild = pWindow ? pWindow->GetWindow(GetWindowType::FirstChild) : nullptr;
3009 return pChild && isContainerWindow(*pChild) && !pChild->GetWindow(GetWindowType::Next);
3010}
3011
3013{
3014 if (!(rHelpEvent.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON)))
3015 return;
3016
3017 Point aPos(ScreenToOutputPixel(rHelpEvent.GetMousePosPixel()));
3018 tools::Rectangle aHelpArea(aPos.X(), aPos.Y());
3019 OUString sHelpTip = m_aQueryTooltipHdl.Call(aHelpArea);
3020 if (sHelpTip.isEmpty())
3021 return;
3022 Point aPt = OutputToScreenPixel(aHelpArea.TopLeft());
3023 aHelpArea.SetLeft(aPt.X());
3024 aHelpArea.SetTop(aPt.Y());
3025 aPt = OutputToScreenPixel(aHelpArea.BottomRight());
3026 aHelpArea.SetRight(aPt.X());
3027 aHelpArea.SetBottom(aPt.Y());
3028 // tdf#125369 recover newline support of tdf#101779
3029 QuickHelpFlags eHelpWinStyle = sHelpTip.indexOf('\n') != -1 ? QuickHelpFlags::TipStyleBalloon : QuickHelpFlags::NONE;
3030 Help::ShowQuickHelp(this, aHelpArea, sHelpTip, eHelpWinStyle);
3031}
3032
3034{
3035 if (m_aStartDragHdl.Call(this))
3036 return;
3037
3039 if (!m_xTransferHelper.is())
3040 return;
3041
3042 xContainer->StartDrag(this, m_nDragAction);
3043}
3044
3046{
3049 OUString sSurroundingText;
3050 m_aGetSurroundingHdl.Call(sSurroundingText);
3051 return sSurroundingText;
3052}
3053
3055{
3058 OUString sSurroundingText;
3059 int nCursor = m_aGetSurroundingHdl.Call(sSurroundingText);
3060 return Selection(nCursor, nCursor);
3061}
3062
3064{
3066 return Control::DeleteSurroundingText(rSelection);
3067 return m_aDeleteSurroundingHdl.Call(rSelection);
3068}
3069
3071{
3072}
3073
3075{
3076}
3077
3079{
3080 disposeOnce();
3081}
3082
3084{
3085 disposeOnce();
3086}
3087
3089{
3090 Control::DumpAsPropertyTree(rJsonWriter);
3091 rJsonWriter.put("type", "drawingarea");
3092
3094 OutputDevice* pRefDevice = GetOutDev();
3095 Size aRenderSize(pRefDevice->PixelToLogic(GetOutputSizePixel()));
3096 Size aOutputSize = GetSizePixel();
3097 pDevice->SetOutputSize(aRenderSize);
3098 tools::Rectangle aRect(Point(0,0), aRenderSize);
3099
3100 // Dark mode support
3101 pDevice->DrawWallpaper(aRect, pRefDevice->GetBackground());
3102
3103 Paint(*pDevice, aRect);
3104
3105 BitmapEx aImage = pDevice->GetBitmapEx(Point(0,0), aRenderSize);
3106 aImage.Scale(aOutputSize);
3107
3108 SvMemoryStream aOStm(65535, 65535);
3110 {
3111 css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
3112 OStringBuffer aBuffer("data:image/png;base64,");
3114 rJsonWriter.put("image", aBuffer);
3115 }
3116 rJsonWriter.put("text", GetQuickHelpText());
3117}
3118
3120{
3122 return m_pFactoryFunction;
3124}
3125
3126/* 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 GetToolkitName()
Get the toolkit's name.
Definition: svapp.cxx:1357
static OUString GetDisplayName()
Get the default name of the application for message dialogs and printing.
Definition: svapp.cxx:1208
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:638
static const OUString & GetDesktopEnvironment()
Get the desktop environment the process is currently running in.
Definition: svapp.cxx:1583
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: BitmapEx.cxx:305
DrawButtonFlags GetButtonState() const
Definition: button.cxx:519
void SetToggleHdl(const Link< CheckBox &, void > &rLink)
Definition: button.hxx:367
SAL_DLLPRIVATE const tools::Rectangle & GetStateRect() const
Definition: button.hxx:323
void Check(bool bCheck=true)
Definition: button.hxx:349
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3308
TriState GetState() const
Definition: button.hxx:347
bool IsChecked() const
Definition: button.hxx:354
SAL_DLLPRIVATE const tools::Rectangle & GetMouseRect() const
Definition: button.hxx:324
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:98
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:811
VclBox * get_content_area()
Definition: dialog.hxx:120
void set_content_area(VclBox *pBox)
Definition: dialog.cxx:603
int get_default_response() const
Definition: dialog.cxx:1526
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 bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: dialog.cxx:1424
virtual void StateChanged(StateChangedType nStateChange) override
Definition: dialog.cxx:755
VclButtonBox * get_action_area()
Definition: dialog.hxx:119
void set_default_response(int nResponse)
Definition: dialog.cxx:1566
void add_button(PushButton *pButton, int nResponse, bool bTransferOwnership)
Definition: dialog.cxx:1456
void set_action_area(VclButtonBox *pBox)
Definition: dialog.cxx:592
virtual void ImplDrawCheckBoxState(vcl::RenderContext &rRenderContext) override
Definition: layout.cxx:1601
DisclosureButton(vcl::Window *pParent)
Definition: layout.cxx:1651
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: layout.cxx:1656
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:88
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:2593
virtual ~MessageDialog() override
Definition: layout.cxx:2564
VclPtr< VclMultiLineEdit > m_pPrimaryMessage
OUString const & get_primary_text() const
Definition: layout.cxx:2586
void set_primary_text(const OUString &rPrimaryString)
Definition: layout.cxx:2651
VclPtr< VclVBox > m_pMessageBox
void create_message_area()
Definition: layout.cxx:2355
VclPtr< VclGrid > m_pGrid
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:2673
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:2551
VclPtr< VclBox > m_pOwnedContentArea
VclPtr< FixedImage > m_pImage
static void SetMessagesWidths(vcl::Window const *pParent, VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
Definition: layout.cxx:2569
void create_owned_areas()
Definition: layout.cxx:2483
VclPtr< VclMultiLineEdit > m_pSecondaryMessage
void set_secondary_text(const OUString &rSecondaryString)
Definition: layout.cxx:2662
OUString m_sSecondaryString
virtual bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: layout.cxx:2600
MessageDialog(vcl::Window *pParent, WinBits nStyle)
Definition: layout.cxx:2498
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:170
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1110
const Wallpaper & GetBackground() const
Definition: outdev.hxx:523
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.
constexpr tools::Long Y() const
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
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
tools::Long GetLineSize() const override
Definition: scrbar.hxx:119
void SetRangeMax(tools::Long nNewRange) override
Definition: scrbar.cxx:1333
void SetPageSize(tools::Long nNewSize) override
Definition: scrbar.hxx:120
tools::Long GetRangeMin() const override
Definition: scrbar.hxx:111
tools::Long GetPageSize() const override
Definition: scrbar.hxx:121
tools::Long GetVisibleSize() const override
Definition: scrbar.hxx:123
tools::Long GetRangeMax() const override
Definition: scrbar.hxx:113
tools::Long GetThumbPos() const override
Definition: scrbar.hxx:117
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:1045
SAL_DLLPRIVATE void DoInitialLayout()
Definition: syswin.cxx:1090
void setOptimalLayoutSize(bool bAllowWindowShrink)
Definition: syswin.cxx:1061
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:421
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
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 bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: layout.cxx:385
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
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:729
Size addReqGroups(const VclButtonBox::Requisition &rReq) const
Definition: layout.cxx:437
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:640
virtual bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: layout.cxx:614
VclButtonBoxStyle m_eLayoutStyle
Definition: layout.hxx:223
Requisition calculatePrimarySecondaryRequisitions() const
Definition: layout.cxx:492
Size addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
Definition: layout.cxx:591
virtual Size calculateRequisition() const override
Definition: layout.cxx:606
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:642
rtl::Reference< TransferDataContainer > m_xTransferHelper
Definition: layout.hxx:626
virtual bool DeleteSurroundingText(const Selection &rSelection) override
Definition: layout.cxx:3063
virtual void RequestHelp(const HelpEvent &rHelpEvent) override
Definition: layout.cxx:3012
Link< VclDrawingArea *, bool > m_aStartDragHdl
Definition: layout.hxx:640
Link< const Selection &, bool > m_aDeleteSurroundingHdl
Definition: layout.hxx:639
Link< OUString &, int > m_aGetSurroundingHdl
Definition: layout.hxx:638
FactoryFunction m_pFactoryFunction
Definition: layout.hxx:624
Link< tools::Rectangle &, OUString > m_aQueryTooltipHdl
Definition: layout.hxx:637
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:3088
virtual FactoryFunction GetUITestFactory() const override
Definition: layout.cxx:3119
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
Definition: layout.cxx:3033
sal_Int8 m_nDragAction
Definition: layout.hxx:627
virtual OUString GetSurroundingText() const override
Definition: layout.cxx:3045
virtual Selection GetSurroundingTextSelection() const override
Definition: layout.cxx:3054
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:2284
VclPtr< EventBoxHelper > m_aEventBoxHelper
Definition: layout.hxx:559
virtual void dispose() override
Definition: layout.cxx:2294
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2256
virtual ~VclEventBox() override
Definition: layout.cxx:2289
virtual Size calculateRequisition() const override
Definition: layout.cxx:2267
virtual vcl::Window * get_child() override
Definition: layout.cxx:2251
virtual Size calculateRequisition() const override
Definition: layout.cxx:1726
OUString get_label() const
Definition: layout.cxx:1701
virtual void DumpAsPropertyTree(tools::JsonWriter &rJsonWriter) override
Definition: layout.cxx:1839
bool get_expanded() const
Definition: layout.cxx:1686
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1753
VclPtr< DisclosureButton > m_pDisclosureButton
Definition: layout.hxx:478
virtual void dispose() override
Definition: layout.cxx:1706
vcl::Window * get_label_widget()
Definition: layout.cxx:1834
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:1817
bool m_bResizeTopLevel
Definition: layout.hxx:477
void set_expanded(bool bExpanded)
Definition: layout.cxx:1691
virtual ~VclExpander() override
Definition: layout.cxx:1681
virtual vcl::Window * get_child() override
Definition: layout.cxx:1721
void set_label(const OUString &rLabel)
Definition: layout.cxx:1696
VclExpander(vcl::Window *pParent)
Definition: layout.cxx:1672
virtual FactoryFunction GetUITestFactory() const override
Definition: layout.cxx:1845
virtual bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: layout.cxx:1806
void designate_label(vcl::Window *pWindow)
Definition: layout.cxx:1527
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1497
void set_label(const OUString &rLabel)
Definition: layout.cxx:1571
VclPtr< vcl::Window > m_pLabel
Definition: layout.hxx:426
vcl::Window * get_label_widget()
Definition: layout.cxx:1549
virtual vcl::Window * get_child() override
Definition: layout.cxx:1566
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Definition: layout.cxx:1593
virtual OUString getDefaultAccessibleName() const override
Definition: layout.cxx:1585
virtual void dispose() override
Definition: layout.cxx:1469
OUString get_label() const
Definition: layout.cxx:1578
virtual ~VclFrame() override
Definition: layout.cxx:1464
virtual Size calculateRequisition() const override
Definition: layout.cxx:1477
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:1409
int get_column_spacing() const
Definition: layout.hxx:361
bool get_column_homogeneous() const
Definition: layout.hxx:345
virtual bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: layout.cxx:1420
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:1224
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1264
virtual Size calculateRequisition() const override
Definition: layout.cxx:1219
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
void arrange(const Size &rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
Definition: layout.cxx:2838
virtual void set_position(tools::Long nPosition) override
Definition: layout.cxx:2869
VclHPaned(vcl::Window *pParent)
Definition: layout.cxx:2824
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2881
virtual Size calculateRequisition() const override
Definition: layout.cxx:2926
virtual ~VclHPaned() override
Definition: layout.cxx:3070
void EnableCursor(bool bEnable)
Definition: vclmedit.cxx:1456
void SetMaxTextWidth(tools::Long nMaxWidth)
Definition: vclmedit.cxx:1069
virtual void SetText(const OUString &rStr) override
Definition: vclmedit.cxx:1114
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:2690
virtual ~VclPaned() override
Definition: layout.cxx:3078
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
Definition: layout.cxx:2699
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
ScrollBar & getHorzScrollBar()
Definition: layout.hxx:495
VclPtr< ScrollBar > m_pVScroll
Definition: layout.hxx:513
VclScrolledWindow(vcl::Window *pParent)
Definition: layout.cxx:1864
virtual vcl::Window * get_child() override
Definition: layout.cxx:1932
Size getVisibleChildSize() const
Definition: layout.cxx:2087
void doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
Definition: layout.cxx:1977
virtual void dispose() override
Definition: layout.cxx:1900
void InitScrollBars(const Size &rRequest)
Definition: layout.cxx:1957
virtual void DumpAsPropertyTree(::tools::JsonWriter &rJsonWriter) override
Definition: layout.cxx:2187
bool m_bUserManagedScrolling
Definition: layout.hxx:509
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2082
DrawFrameFlags m_eDrawFrameFlags
Definition: layout.hxx:512
virtual ~VclScrolledWindow() override
Definition: layout.cxx:3083
VclPtr< ScrollBarBox > m_aScrollBarBox
Definition: layout.hxx:515
tools::Long m_nBorderWidth
Definition: layout.hxx:510
virtual Size calculateRequisition() const override
Definition: layout.cxx:1937
virtual bool set_property(const OUString &rKey, const OUString &rValue) override
Definition: layout.cxx:2099
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: layout.cxx:2140
ScrollBar & getVertScrollBar()
Definition: layout.hxx:494
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.cxx:2162
VclPtr< ScrollBar > m_pHScroll
Definition: layout.hxx:514
int CalcBorderWidth() const
Definition: layout.cxx:1888
DrawFrameStyle m_eDrawFrameStyle
Definition: layout.hxx:511
std::set< VclPtr< vcl::Window > > m_aWindows
Definition: layout.hxx:580
VclSizeGroupMode m_eMode
Definition: layout.hxx:582
void set_ignore_hidden(bool bIgnoreHidden)
Definition: layout.cxx:2309
bool m_bIgnoreHidden
Definition: layout.hxx:581
void set_property(const OUString &rKey, const OUString &rValue)
Definition: layout.cxx:2328
void set_mode(VclSizeGroupMode eMode)
Definition: layout.cxx:2318
void trigger_queue_resize()
Definition: layout.cxx:2300
virtual Size calculateRequisition() const override
Definition: layout.cxx:2807
virtual void set_position(tools::Long nPosition) override
Definition: layout.cxx:2750
VclVPaned(vcl::Window *pParent)
Definition: layout.cxx:2705
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2762
void arrange(const Size &rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
Definition: layout.cxx:2719
virtual ~VclVPaned() override
Definition: layout.cxx:3074
bool m_bInitialAllocation
Definition: layout.hxx:528
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2224
VclPtr< vcl::Window > mpFirstChild
Definition: window.h:237
bool mbInDispose
Definition: window.h:372
VclPtr< vcl::Window > mpLastChild
Definition: window.h:238
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
void put(std::u16string_view pPropName, const OUString &rPropValue)
ScopedJsonWriterNode startNode(std::string_view)
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:236
const Size & GetFontSize() const
Definition: font/font.cxx:907
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:2806
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:1962
vcl::Window * GetParent() const
Definition: window2.cxx:1123
sal_Int32 get_padding() const
Definition: window2.cxx:1797
virtual Selection GetSurroundingTextSelection() const
Definition: window.cxx:3782
void RemoveEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:312
void SetControlFont()
Definition: window2.cxx:438
bool IsMouseOver() const
Definition: mouse.cxx:596
const OUString & get_id() const
Get the ID of the window.
Definition: window.cxx:3935
Size get_preferred_size() const
Definition: window2.cxx:1694
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1036
void set_border_width(sal_Int32 nBorderWidth)
Definition: window2.cxx:1869
void set_grid_left_attach(sal_Int32 nAttach)
Definition: window2.cxx:1839
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3930
bool HasFocus() const
Definition: window.cxx:2981
VclPackType get_pack_type() const
Definition: window2.cxx:1785
sal_Int32 get_margin_end() const
Definition: window2.cxx:1907
void reorderWithinParent(sal_uInt16 nNewPosition)
Definition: stacking.cxx:163
void set_hexpand(bool bExpand)
Definition: window2.cxx:1755
virtual Point GetPosPixel() const
Definition: window.cxx:2794
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:979
const AllSettings & GetSettings() const
Definition: window3.cxx:129
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2187
virtual OUString GetSurroundingText() const
Definition: window.cxx:3777
bool get_vexpand() const
Definition: window2.cxx:1761
tools::Long CalcTitleWidth() const
Definition: window.cxx:2048
::OutputDevice const * GetOutDev() const
Definition: window.cxx:567
SAL_DLLPRIVATE float approximate_char_width() const
Definition: window3.cxx:61
void Hide()
Definition: window.hxx:879
sal_Int32 get_margin_top() const
Definition: window2.cxx:1923
bool get_fill() const
Definition: window2.cxx:1809
bool get_secondary() const
Definition: window2.cxx:1957
virtual bool DeleteSurroundingText(const Selection &rSelection)
Definition: window.cxx:3811
sal_Int32 get_margin_start() const
Definition: window2.cxx:1891
void AddEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:307
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:484
void set_width_request(sal_Int32 nWidthRequest)
Definition: window2.cxx:1658
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON.
Definition: window.cxx:3356
sal_Int32 get_border_width() const
Definition: window2.cxx:1875
virtual Size GetSizePixel() const
Definition: window.cxx:2402
Size GetOutputSizePixel() const
Definition: window3.cxx:89
Point GetPointerPosPixel()
Definition: mouse.cxx:540
OUString GetAccessibleName() const
VclAlign get_halign() const
Definition: window2.cxx:1725
sal_Int32 get_margin_bottom() const
Definition: window2.cxx:1939
bool get_expand() const
Definition: window2.cxx:1773
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1025
bool IsVisible() const
Definition: window2.cxx:1128
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1283
void set_grid_top_attach(sal_Int32 nAttach)
Definition: window2.cxx:1863
void set_valign(VclAlign eAlign)
Definition: window2.cxx:1743
virtual void SetText(const OUString &rStr)
Definition: window.cxx:3026
virtual OUString GetText() const
Definition: window.cxx:3055
void SetType(WindowType nType)
Definition: window2.cxx:994
virtual bool set_property(const OUString &rKey, const OUString &rValue)
Definition: window2.cxx:1478
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2812
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1258
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1294
VclAlign get_valign() const
Definition: window2.cxx:1737
bool IsEnabled() const
Definition: window2.cxx:1148
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:941
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1048
void SetBackground()
Definition: window3.cxx:100
bool get_hexpand() const
Definition: window2.cxx:1749
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:1211
IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent &, rEvent, void)
Definition: layout.cxx:1521
bool toBool(std::u16string_view rValue)
Definition: layout.cxx:1415
boost::multi_array< GridEntry, 2 > array_type
Definition: layout.cxx:898
bool isLayoutEnabled(const vcl::Window *pWindow)
Definition: layout.cxx:3005
vcl::Window * getNonLayoutParent(vcl::Window *pWindow)
Definition: layout.cxx:2968
Size getLegacyBestSizeForChildren(const vcl::Window &rWindow)
Definition: layout.cxx:2943
IMPL_LINK_NOARG(VclScrolledWindow, ScrollBarHdl, ScrollBar *, void)
Definition: layout.cxx:1908
static bool isNullGrid(const array_type &A)
Definition: layout.cxx:1066
void sort_native_button_order(const VclBox &rContainer)
Definition: layout.cxx:862
bool isEnabledInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2992
bool isVisibleInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2979
static void calcMaxs(const array_type &A, std::vector< VclGrid::Value > &rWidths, std::vector< VclGrid::Value > &rHeights)
Definition: layout.cxx:1074
static array_type assembleGrid(const VclGrid &rGrid)
Definition: layout.cxx:904
#define DEFAULT_CHILD_MIN_HEIGHT
Definition: layout.cxx:419
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:467
static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1206
#define DEFAULT_CHILD_MIN_WIDTH
Definition: layout.cxx:418
static tools::Long getMaxNonOutlier(const std::vector< tools::Long > &rG, tools::Long nAvgDimension)
Definition: layout.cxx:453
static int getButtonPriority(std::u16string_view rType)
Definition: layout.cxx:772
VclButtonBoxStyle
Definition: layout.hxx:199
bool isContainerWindow(const vcl::Window &rWindow)
Definition: layout.hxx:817
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:2299
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::optional< Image > moDisclosureMinus
Definition: svdata.hxx:278
std::optional< Image > moDisclosurePlus
Definition: svdata.hxx:277
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:77
bool bVisible
signed char sal_Int8
DrawFrameStyle
Definition: vclenum.hxx:290
@ RET_OK
Definition: vclenum.hxx:206
@ RET_CLOSE
Definition: vclenum.hxx:211
@ RET_CANCEL
Definition: vclenum.hxx:205
@ RET_NO
Definition: vclenum.hxx:208
@ RET_YES
Definition: vclenum.hxx:207
VclAlign
Definition: vclenum.hxx:186
VclMessageType
Definition: vclenum.hxx:226
VclPackType
Definition: vclenum.hxx:194
DrawFrameFlags
Definition: vclenum.hxx:302
VclButtonsType
Definition: vclenum.hxx:216
VclSizeGroupMode
Definition: vclenum.hxx:235
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