1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <com/sun/star/accessibility/AccessibleRole.hpp>
11 #include <vcl/dialog.hxx>
12 #include <vcl/layout.hxx>
13 #include <vcl/msgbox.hxx>
14 #include <vcl/svapp.hxx>
17 VclContainer::VclContainer(Window
*pParent
, WinBits nStyle
)
18 : Window(WINDOW_CONTAINER
)
19 , m_bLayoutDirty(true)
21 ImplInit(pParent
, nStyle
, NULL
);
22 EnableChildTransparentMode();
23 SetPaintTransparent(true);
27 sal_uInt16
VclContainer::getDefaultAccessibleRole() const
29 return com::sun::star::accessibility::AccessibleRole::PANEL
;
32 Size
VclContainer::GetOptimalSize() const
34 return calculateRequisition();
37 void VclContainer::setLayoutPosSize(Window
&rWindow
, const Point
&rPos
, const Size
&rSize
)
39 sal_Int32 nBorderWidth
= rWindow
.get_border_width();
40 sal_Int32 nLeft
= rWindow
.get_margin_left() + nBorderWidth
;
41 sal_Int32 nTop
= rWindow
.get_margin_top() + nBorderWidth
;
42 sal_Int32 nRight
= rWindow
.get_margin_right() + nBorderWidth
;
43 sal_Int32 nBottom
= rWindow
.get_margin_bottom() + nBorderWidth
;
44 Point
aPos(rPos
.X() + nLeft
, rPos
.Y() + nTop
);
45 Size
aSize(rSize
.Width() - nLeft
- nRight
, rSize
.Height() - nTop
- nBottom
);
46 rWindow
.SetPosSizePixel(aPos
, aSize
);
49 void VclContainer::setLayoutAllocation(Window
&rChild
, const Point
&rAllocPos
, const Size
&rChildAlloc
)
51 VclAlign eHalign
= rChild
.get_halign();
52 VclAlign eValign
= rChild
.get_valign();
55 if (eHalign
== VCL_ALIGN_FILL
&& eValign
== VCL_ALIGN_FILL
)
57 setLayoutPosSize(rChild
, rAllocPos
, rChildAlloc
);
61 Point
aChildPos(rAllocPos
);
62 Size
aChildSize(rChildAlloc
);
63 Size
aChildPreferredSize(getLayoutRequisition(rChild
));
70 if (aChildPreferredSize
.Width() < rChildAlloc
.Width())
71 aChildSize
.Width() = aChildPreferredSize
.Width();
74 if (aChildPreferredSize
.Width() < rChildAlloc
.Width())
75 aChildSize
.Width() = aChildPreferredSize
.Width();
76 aChildPos
.X() += rChildAlloc
.Width();
77 aChildPos
.X() -= aChildSize
.Width();
79 case VCL_ALIGN_CENTER
:
80 if (aChildPreferredSize
.Width() < aChildSize
.Width())
81 aChildSize
.Width() = aChildPreferredSize
.Width();
82 aChildPos
.X() += (rChildAlloc
.Width() - aChildSize
.Width()) / 2;
91 if (aChildPreferredSize
.Height() < rChildAlloc
.Height())
92 aChildSize
.Height() = aChildPreferredSize
.Height();
95 if (aChildPreferredSize
.Height() < rChildAlloc
.Height())
96 aChildSize
.Height() = aChildPreferredSize
.Height();
97 aChildPos
.Y() += rChildAlloc
.Height();
98 aChildPos
.Y() -= aChildSize
.Height();
100 case VCL_ALIGN_CENTER
:
101 if (aChildPreferredSize
.Height() < aChildSize
.Height())
102 aChildSize
.Height() = aChildPreferredSize
.Height();
103 aChildPos
.Y() += (rChildAlloc
.Height() - aChildSize
.Height()) / 2;
107 setLayoutPosSize(rChild
, aChildPos
, aChildSize
);
110 Size
VclContainer::getLayoutRequisition(const Window
&rWindow
)
112 sal_Int32 nBorderWidth
= rWindow
.get_border_width();
113 sal_Int32 nLeft
= rWindow
.get_margin_left() + nBorderWidth
;
114 sal_Int32 nTop
= rWindow
.get_margin_top() + nBorderWidth
;
115 sal_Int32 nRight
= rWindow
.get_margin_right() + nBorderWidth
;
116 sal_Int32 nBottom
= rWindow
.get_margin_bottom() + nBorderWidth
;
117 Size
aSize(rWindow
.get_preferred_size());
118 return Size(aSize
.Width() + nLeft
+ nRight
, aSize
.Height() + nTop
+ nBottom
);
121 void VclContainer::SetPosSizePixel(const Point
& rAllocPos
, const Size
& rAllocation
)
123 bool bSizeChanged
= rAllocation
!= GetOutputSizePixel();
124 Window::SetPosSizePixel(rAllocPos
, rAllocation
);
125 if (m_bLayoutDirty
|| bSizeChanged
)
127 m_bLayoutDirty
= false;
128 setAllocation(rAllocation
);
132 void VclContainer::SetPosPixel(const Point
& rAllocPos
)
134 Point aAllocPos
= rAllocPos
;
135 sal_Int32 nBorderWidth
= get_border_width();
136 aAllocPos
.X() += nBorderWidth
+ get_margin_left();
137 aAllocPos
.Y() += nBorderWidth
+ get_margin_top();
139 if (aAllocPos
!= GetPosPixel())
140 Window::SetPosPixel(aAllocPos
);
143 void VclContainer::SetSizePixel(const Size
& rAllocation
)
145 Size aAllocation
= rAllocation
;
146 sal_Int32 nBorderWidth
= get_border_width();
147 aAllocation
.Width() -= nBorderWidth
*2 + get_margin_left() + get_margin_right();
148 aAllocation
.Height() -= nBorderWidth
*2 + get_margin_top() + get_margin_bottom();
149 bool bSizeChanged
= aAllocation
!= GetSizePixel();
151 Window::SetSizePixel(aAllocation
);
152 if (m_bLayoutDirty
|| bSizeChanged
)
154 m_bLayoutDirty
= false;
155 setAllocation(aAllocation
);
159 void VclBox::accumulateMaxes(const Size
&rChildSize
, Size
&rSize
) const
161 long nSecondaryChildDimension
= getSecondaryDimension(rChildSize
);
162 long nSecondaryBoxDimension
= getSecondaryDimension(rSize
);
163 setSecondaryDimension(rSize
, std::max(nSecondaryChildDimension
, nSecondaryBoxDimension
));
165 long nPrimaryChildDimension
= getPrimaryDimension(rChildSize
);
166 long nPrimaryBoxDimension
= getPrimaryDimension(rSize
);
168 setPrimaryDimension(rSize
, std::max(nPrimaryBoxDimension
, nPrimaryChildDimension
));
170 setPrimaryDimension(rSize
, nPrimaryBoxDimension
+ nPrimaryChildDimension
);
173 Size
VclBox::calculateRequisition() const
175 sal_uInt16 nVisibleChildren
= 0;
178 for (Window
*pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
; pChild
= pChild
->GetWindow(WINDOW_NEXT
))
180 if (!pChild
->IsVisible())
183 Size aChildSize
= getLayoutRequisition(*pChild
);
185 long nPrimaryDimension
= getPrimaryDimension(aChildSize
);
186 nPrimaryDimension
+= pChild
->get_padding() * 2;
187 setPrimaryDimension(aChildSize
, nPrimaryDimension
);
189 accumulateMaxes(aChildSize
, aSize
);
192 return finalizeMaxes(aSize
, nVisibleChildren
);
195 void VclBox::setAllocation(const Size
&rAllocation
)
197 sal_uInt16 nVisibleChildren
= 0, nExpandChildren
= 0;
198 for (Window
*pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
; pChild
= pChild
->GetWindow(WINDOW_NEXT
))
200 if (!pChild
->IsVisible())
203 bool bExpand
= getPrimaryDimensionChildExpand(*pChild
);
208 if (!nVisibleChildren
)
211 long nAllocPrimaryDimension
= getPrimaryDimension(rAllocation
);
213 long nHomogeneousDimension
= 0, nExtraSpace
= 0;
216 nHomogeneousDimension
= ((nAllocPrimaryDimension
-
217 (nVisibleChildren
- 1) * m_nSpacing
)) / nVisibleChildren
;
219 else if (nExpandChildren
)
221 Size aRequisition
= calculateRequisition();
222 nExtraSpace
= (getPrimaryDimension(rAllocation
) - getPrimaryDimension(aRequisition
)) / nExpandChildren
;
225 for (sal_Int32 ePackType
= VCL_PACK_START
; ePackType
<= VCL_PACK_END
; ++ePackType
)
228 if (ePackType
== VCL_PACK_END
)
230 long nPrimaryCoordinate
= getPrimaryCoordinate(aPos
);
231 setPrimaryCoordinate(aPos
, nPrimaryCoordinate
+ nAllocPrimaryDimension
);
234 for (Window
*pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
; pChild
= pChild
->GetWindow(WINDOW_NEXT
))
236 if (!pChild
->IsVisible())
239 sal_Int32 ePacking
= pChild
->get_pack_type();
241 if (ePacking
!= ePackType
)
244 long nPadding
= pChild
->get_padding();
248 setPrimaryDimension(aBoxSize
, nHomogeneousDimension
);
251 aBoxSize
= getLayoutRequisition(*pChild
);
252 long nPrimaryDimension
= getPrimaryDimension(aBoxSize
);
253 nPrimaryDimension
+= nPadding
* 2;
254 if (getPrimaryDimensionChildExpand(*pChild
))
255 nPrimaryDimension
+= nExtraSpace
;
256 setPrimaryDimension(aBoxSize
, nPrimaryDimension
);
258 setSecondaryDimension(aBoxSize
, getSecondaryDimension(rAllocation
));
260 Point
aChildPos(aPos
);
261 Size
aChildSize(aBoxSize
);
262 long nPrimaryCoordinate
= getPrimaryCoordinate(aPos
);
264 bool bFill
= pChild
->get_fill();
267 setPrimaryDimension(aChildSize
, std::max(static_cast<long>(1),
268 getPrimaryDimension(aBoxSize
) - nPadding
* 2));
270 setPrimaryCoordinate(aChildPos
, nPrimaryCoordinate
+ nPadding
);
274 setPrimaryDimension(aChildSize
,
275 getPrimaryDimension(getLayoutRequisition(*pChild
)));
277 setPrimaryCoordinate(aChildPos
, nPrimaryCoordinate
+
278 (getPrimaryDimension(aBoxSize
) - getPrimaryDimension(aChildSize
)) / 2);
281 long nDiff
= getPrimaryDimension(aBoxSize
) + m_nSpacing
;
282 if (ePackType
== VCL_PACK_START
)
283 setPrimaryCoordinate(aPos
, nPrimaryCoordinate
+ nDiff
);
286 setPrimaryCoordinate(aPos
, nPrimaryCoordinate
- nDiff
);
287 setPrimaryCoordinate(aChildPos
, getPrimaryCoordinate(aChildPos
) -
288 getPrimaryDimension(aBoxSize
));
291 setLayoutAllocation(*pChild
, aChildPos
, aChildSize
);
296 bool VclBox::set_property(const OString
&rKey
, const OString
&rValue
)
298 if (rKey
== "spacing")
299 set_spacing(rValue
.toInt32());
300 else if (rKey
== "homogeneous")
301 set_homogeneous(toBool(rValue
));
303 return VclContainer::set_property(rKey
, rValue
);
307 sal_uInt16
VclBox::getDefaultAccessibleRole() const
309 return com::sun::star::accessibility::AccessibleRole::FILLER
;
312 #define DEFAULT_CHILD_MIN_WIDTH 85
313 #define DEFAULT_CHILD_MIN_HEIGHT 27
315 Size
VclBox::finalizeMaxes(const Size
&rSize
, sal_uInt16 nVisibleChildren
) const
319 if (nVisibleChildren
)
321 long nPrimaryDimension
= getPrimaryDimension(rSize
);
323 nPrimaryDimension
*= nVisibleChildren
;
324 setPrimaryDimension(aRet
, nPrimaryDimension
+ m_nSpacing
* (nVisibleChildren
-1));
325 setSecondaryDimension(aRet
, getSecondaryDimension(rSize
));
331 Size
VclButtonBox::addReqGroups(const VclButtonBox::Requisition
&rReq
) const
335 long nMainGroupDimension
= getPrimaryDimension(rReq
.m_aMainGroupSize
);
336 long nSubGroupDimension
= getPrimaryDimension(rReq
.m_aSubGroupSize
);
338 setPrimaryDimension(aRet
, nMainGroupDimension
+ nSubGroupDimension
);
340 setSecondaryDimension(aRet
,
341 std::max(getSecondaryDimension(rReq
.m_aMainGroupSize
),
342 getSecondaryDimension(rReq
.m_aSubGroupSize
)));
347 static long getMaxNonOutlier(const std::vector
<long> &rG
, long nAvgDimension
)
349 long nMaxDimensionNonOutlier
= 0;
350 for (std::vector
<long>::const_iterator aI
= rG
.begin(),
351 aEnd
= rG
.end(); aI
!= aEnd
; ++aI
)
353 long nPrimaryChildDimension
= *aI
;
354 if (nPrimaryChildDimension
< nAvgDimension
* 1.5)
356 nMaxDimensionNonOutlier
= std::max(nPrimaryChildDimension
,
357 nMaxDimensionNonOutlier
);
360 return nMaxDimensionNonOutlier
;
363 static std::vector
<long> setButtonSizes(const std::vector
<long> &rG
,
364 long nAvgDimension
, long nMaxNonOutlier
, long nMinWidth
)
366 std::vector
<long> aVec
;
367 //set everything < 1.5 times the average to the same width, leave the
368 //outliers un-touched
369 for (std::vector
<long>::const_iterator aI
= rG
.begin(), aEnd
= rG
.end();
372 long nPrimaryChildDimension
= *aI
;
373 if (nPrimaryChildDimension
< nAvgDimension
* 1.5)
375 aVec
.push_back(std::max(nMaxNonOutlier
, nMinWidth
));
379 aVec
.push_back(std::max(nPrimaryChildDimension
, nMinWidth
));
385 VclButtonBox::Requisition
VclButtonBox::calculatePrimarySecondaryRequisitions() const
389 Size
aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH
, DEFAULT_CHILD_MIN_HEIGHT
); //to-do, pull from theme
390 Size
aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH
, DEFAULT_CHILD_MIN_HEIGHT
); //to-do, pull from theme
392 long nMinMainGroupPrimary
= getPrimaryDimension(aMainGroupSize
);
393 long nMinSubGroupPrimary
= getPrimaryDimension(aSubGroupSize
);
394 long nMainGroupSecondary
= getSecondaryDimension(aMainGroupSize
);
395 long nSubGroupSecondary
= getSecondaryDimension(aSubGroupSize
);
397 bool bIgnoreSecondaryPacking
= (m_eLayoutStyle
== VCL_BUTTONBOX_SPREAD
|| m_eLayoutStyle
== VCL_BUTTONBOX_CENTER
);
399 std::vector
<long> aMainGroupSizes
;
400 std::vector
<long> aSubGroupSizes
;
402 for (const Window
*pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
; pChild
= pChild
->GetWindow(WINDOW_NEXT
))
404 if (!pChild
->IsVisible())
406 Size aChildSize
= getLayoutRequisition(*pChild
);
407 if (bIgnoreSecondaryPacking
|| !pChild
->get_secondary())
409 //set the max secondary dimension
410 nMainGroupSecondary
= std::max(nMainGroupSecondary
, getSecondaryDimension(aChildSize
));
411 //collect the primary dimensions
412 aMainGroupSizes
.push_back(getPrimaryDimension(aChildSize
));
416 nSubGroupSecondary
= std::max(nSubGroupSecondary
, getSecondaryDimension(aChildSize
));
417 aSubGroupSizes
.push_back(getPrimaryDimension(aChildSize
));
423 long nMaxMainDimension
= aMainGroupSizes
.empty() ? 0 :
424 *std::max_element(aMainGroupSizes
.begin(), aMainGroupSizes
.end());
425 nMaxMainDimension
= std::max(nMaxMainDimension
, nMinMainGroupPrimary
);
426 long nMaxSubDimension
= aSubGroupSizes
.empty() ? 0 :
427 *std::max_element(aSubGroupSizes
.begin(), aSubGroupSizes
.end());
428 nMaxSubDimension
= std::max(nMaxSubDimension
, nMinSubGroupPrimary
);
429 long nMaxDimension
= std::max(nMaxMainDimension
, nMaxSubDimension
);
430 aReq
.m_aMainGroupDimensions
.resize(aMainGroupSizes
.size(), nMaxDimension
);
431 aReq
.m_aSubGroupDimensions
.resize(aSubGroupSizes
.size(), nMaxDimension
);
435 //Ideally set everything to the same size, but find outlier widgets
436 //that are way wider than the average and leave them
437 //at their natural size and set the remainder to share the
438 //max size of the remaining members of the buttonbox
439 long nAccDimension
= std::accumulate(aMainGroupSizes
.begin(),
440 aMainGroupSizes
.end(), 0);
441 nAccDimension
= std::accumulate(aSubGroupSizes
.begin(),
442 aSubGroupSizes
.end(), nAccDimension
);
444 size_t nTotalSize
= aMainGroupSizes
.size() + aSubGroupSizes
.size();
446 long nAvgDimension
= nTotalSize
? nAccDimension
/ nTotalSize
: 0;
448 long nMaxMainNonOutlier
= getMaxNonOutlier(aMainGroupSizes
,
450 long nMaxSubNonOutlier
= getMaxNonOutlier(aSubGroupSizes
,
452 long nMaxNonOutlier
= std::max(nMaxMainNonOutlier
, nMaxSubNonOutlier
);
454 aReq
.m_aMainGroupDimensions
= setButtonSizes(aMainGroupSizes
,
455 nAvgDimension
, nMaxNonOutlier
, nMinMainGroupPrimary
);
456 aReq
.m_aSubGroupDimensions
= setButtonSizes(aSubGroupSizes
,
457 nAvgDimension
, nMaxNonOutlier
, nMinSubGroupPrimary
);
460 if (!aReq
.m_aMainGroupDimensions
.empty())
462 setSecondaryDimension(aReq
.m_aMainGroupSize
, nMainGroupSecondary
);
463 setPrimaryDimension(aReq
.m_aMainGroupSize
,
464 std::accumulate(aReq
.m_aMainGroupDimensions
.begin(),
465 aReq
.m_aMainGroupDimensions
.end(), 0));
467 if (!aReq
.m_aSubGroupDimensions
.empty())
469 setSecondaryDimension(aReq
.m_aSubGroupSize
, nSubGroupSecondary
);
470 setPrimaryDimension(aReq
.m_aSubGroupSize
,
471 std::accumulate(aReq
.m_aSubGroupDimensions
.begin(),
472 aReq
.m_aSubGroupDimensions
.end(), 0));
478 Size
VclButtonBox::addSpacing(const Size
&rSize
, sal_uInt16 nVisibleChildren
) const
482 if (nVisibleChildren
)
484 long nPrimaryDimension
= getPrimaryDimension(rSize
);
485 setPrimaryDimension(aRet
,
486 nPrimaryDimension
+ m_nSpacing
* (nVisibleChildren
-1));
487 setSecondaryDimension(aRet
, getSecondaryDimension(rSize
));
493 Size
VclButtonBox::calculateRequisition() const
495 Requisition
aReq(calculatePrimarySecondaryRequisitions());
496 sal_uInt16 nVisibleChildren
= aReq
.m_aMainGroupDimensions
.size() +
497 aReq
.m_aSubGroupDimensions
.size();
498 return addSpacing(addReqGroups(aReq
), nVisibleChildren
);
501 bool VclButtonBox::set_property(const OString
&rKey
, const OString
&rValue
)
503 if (rKey
== "layout-style")
505 VclButtonBoxStyle eStyle
= VCL_BUTTONBOX_DEFAULT_STYLE
;
506 if (rValue
== "spread")
507 eStyle
= VCL_BUTTONBOX_SPREAD
;
508 else if (rValue
== "edge")
509 eStyle
= VCL_BUTTONBOX_EDGE
;
510 else if (rValue
== "start")
511 eStyle
= VCL_BUTTONBOX_START
;
512 else if (rValue
== "end")
513 eStyle
= VCL_BUTTONBOX_END
;
514 else if (rValue
== "center")
515 eStyle
= VCL_BUTTONBOX_CENTER
;
518 SAL_WARN("vcl.layout", "unknown layout style " << rValue
.getStr());
523 return VclBox::set_property(rKey
, rValue
);
527 void VclButtonBox::setAllocation(const Size
&rAllocation
)
529 Requisition
aReq(calculatePrimarySecondaryRequisitions());
531 if (aReq
.m_aMainGroupDimensions
.empty() && aReq
.m_aSubGroupDimensions
.empty())
534 long nAllocPrimaryDimension
= getPrimaryDimension(rAllocation
);
536 Point aMainGroupPos
, aOtherGroupPos
;
537 int nSpacing
= m_nSpacing
;
539 //To-Do, other layout styles
540 switch (m_eLayoutStyle
)
542 case VCL_BUTTONBOX_START
:
543 if (!aReq
.m_aSubGroupDimensions
.empty())
545 long nOtherPrimaryDimension
= getPrimaryDimension(
546 addSpacing(aReq
.m_aSubGroupSize
, aReq
.m_aSubGroupDimensions
.size()));
547 setPrimaryCoordinate(aOtherGroupPos
,
548 nAllocPrimaryDimension
- nOtherPrimaryDimension
);
551 case VCL_BUTTONBOX_SPREAD
:
552 if (!aReq
.m_aMainGroupDimensions
.empty())
554 long nMainPrimaryDimension
= getPrimaryDimension(
555 addSpacing(aReq
.m_aMainGroupSize
, aReq
.m_aMainGroupDimensions
.size()));
556 long nExtraSpace
= nAllocPrimaryDimension
- nMainPrimaryDimension
;
557 nExtraSpace
+= (aReq
.m_aMainGroupDimensions
.size()-1) * nSpacing
;
558 nSpacing
= nExtraSpace
/(aReq
.m_aMainGroupDimensions
.size()+1);
559 setPrimaryCoordinate(aMainGroupPos
, nSpacing
);
563 SAL_WARN("vcl.layout", "todo unimplemented layout style");
564 case VCL_BUTTONBOX_DEFAULT_STYLE
:
565 case VCL_BUTTONBOX_END
:
566 if (!aReq
.m_aMainGroupDimensions
.empty())
568 long nMainPrimaryDimension
= getPrimaryDimension(
569 addSpacing(aReq
.m_aMainGroupSize
, aReq
.m_aMainGroupDimensions
.size()));
570 setPrimaryCoordinate(aMainGroupPos
,
571 nAllocPrimaryDimension
- nMainPrimaryDimension
);
577 setSecondaryDimension(aChildSize
, getSecondaryDimension(rAllocation
));
579 std::vector
<long>::const_iterator aPrimaryI
= aReq
.m_aMainGroupDimensions
.begin();
580 std::vector
<long>::const_iterator aSecondaryI
= aReq
.m_aSubGroupDimensions
.begin();
581 bool bIgnoreSecondaryPacking
= (m_eLayoutStyle
== VCL_BUTTONBOX_SPREAD
|| m_eLayoutStyle
== VCL_BUTTONBOX_CENTER
);
582 for (Window
*pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
; pChild
= pChild
->GetWindow(WINDOW_NEXT
))
584 if (!pChild
->IsVisible())
587 if (bIgnoreSecondaryPacking
|| !pChild
->get_secondary())
589 long nMainGroupPrimaryDimension
= *aPrimaryI
++;
590 setPrimaryDimension(aChildSize
, nMainGroupPrimaryDimension
);
591 setLayoutAllocation(*pChild
, aMainGroupPos
, aChildSize
);
592 long nPrimaryCoordinate
= getPrimaryCoordinate(aMainGroupPos
);
593 setPrimaryCoordinate(aMainGroupPos
, nPrimaryCoordinate
+ nMainGroupPrimaryDimension
+ nSpacing
);
597 long nSubGroupPrimaryDimension
= *aSecondaryI
++;
598 setPrimaryDimension(aChildSize
, nSubGroupPrimaryDimension
);
599 setLayoutAllocation(*pChild
, aOtherGroupPos
, aChildSize
);
600 long nPrimaryCoordinate
= getPrimaryCoordinate(aOtherGroupPos
);
601 setPrimaryCoordinate(aOtherGroupPos
, nPrimaryCoordinate
+ nSubGroupPrimaryDimension
+ nSpacing
);
612 int getButtonPriority(const OString
&rType
)
614 const size_t N_TYPES
= 3;
615 static const ButtonOrder aDiscardCancelSave
[N_TYPES
] =
622 static const ButtonOrder aSaveDiscardCancel
[N_TYPES
] =
629 const ButtonOrder
* pOrder
= &aDiscardCancelSave
[0];
631 const OUString
&rEnv
= Application::GetDesktopEnvironment();
633 if (rEnv
.equalsIgnoreAsciiCase("windows") ||
634 rEnv
.equalsIgnoreAsciiCase("kde4") ||
635 rEnv
.equalsIgnoreAsciiCase("tde") ||
636 rEnv
.equalsIgnoreAsciiCase("kde"))
638 pOrder
= &aSaveDiscardCancel
[0];
641 for (size_t i
= 0; i
< N_TYPES
; ++i
, ++pOrder
)
643 if (rType
.endsWith(pOrder
->m_aType
))
644 return pOrder
->m_nPriority
;
651 : public std::binary_function
<const Window
*, const Window
*, bool>
653 bool m_bVerticalContainer
;
655 sortButtons(bool bVerticalContainer
)
656 : m_bVerticalContainer(bVerticalContainer
)
659 bool operator()(const Window
*pA
, const Window
*pB
) const;
662 bool sortButtons::operator()(const Window
*pA
, const Window
*pB
) const
664 //sort into two groups of pack start and pack end
665 VclPackType ePackA
= pA
->get_pack_type();
666 VclPackType ePackB
= pB
->get_pack_type();
671 bool bPackA
= pA
->get_secondary();
672 bool bPackB
= pB
->get_secondary();
673 if (!m_bVerticalContainer
)
675 //for horizontal boxes group secondaries before primaries
683 //for vertical boxes group secondaries after primaries
690 //now order within groups according to platform rules
691 return getButtonPriority(pA
->GetHelpId()) < getButtonPriority(pB
->GetHelpId());
694 void VclButtonBox::sort_native_button_order()
696 std::vector
<Window
*> aChilds
;
697 for (Window
* pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
;
698 pChild
= pChild
->GetWindow(WINDOW_NEXT
))
700 aChilds
.push_back(pChild
);
703 //sort child order within parent so that we match the platform
705 std::stable_sort(aChilds
.begin(), aChilds
.end(), sortButtons(m_bVerticalContainer
));
706 VclBuilder::reorderWithinParent(aChilds
, true);
709 VclGrid::array_type
VclGrid::assembleGrid() const
713 for (Window
* pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
;
714 pChild
= pChild
->GetWindow(WINDOW_NEXT
))
716 sal_Int32 nLeftAttach
= pChild
->get_grid_left_attach();
717 sal_Int32 nWidth
= pChild
->get_grid_width();
718 sal_Int32 nMaxXPos
= nLeftAttach
+nWidth
-1;
720 sal_Int32 nTopAttach
= pChild
->get_grid_top_attach();
721 sal_Int32 nHeight
= pChild
->get_grid_height();
722 sal_Int32 nMaxYPos
= nTopAttach
+nHeight
-1;
724 sal_Int32 nCurrentMaxXPos
= A
.shape()[0]-1;
725 sal_Int32 nCurrentMaxYPos
= A
.shape()[1]-1;
726 if (nMaxXPos
> nCurrentMaxXPos
|| nMaxYPos
> nCurrentMaxYPos
)
728 nCurrentMaxXPos
= std::max(nMaxXPos
, nCurrentMaxXPos
);
729 nCurrentMaxYPos
= std::max(nMaxYPos
, nCurrentMaxYPos
);
730 A
.resize(boost::extents
[nCurrentMaxXPos
+1][nCurrentMaxYPos
+1]);
733 ExtendedGridEntry
&rEntry
= A
[nLeftAttach
][nTopAttach
];
734 rEntry
.pChild
= pChild
;
735 rEntry
.nSpanWidth
= nWidth
;
736 rEntry
.nSpanHeight
= nHeight
;
737 rEntry
.x
= nLeftAttach
;
738 rEntry
.y
= nTopAttach
;
740 for (sal_Int32 nSpanX
= 0; nSpanX
< nWidth
; ++nSpanX
)
742 for (sal_Int32 nSpanY
= 0; nSpanY
< nHeight
; ++nSpanY
)
744 ExtendedGridEntry
&rSpan
= A
[nLeftAttach
+nSpanX
][nTopAttach
+nSpanY
];
745 rSpan
.x
= nLeftAttach
;
746 rSpan
.y
= nTopAttach
;
751 //see if we have any empty rows/cols
752 sal_Int32 nMaxX
= A
.shape()[0];
753 sal_Int32 nMaxY
= A
.shape()[1];
755 std::vector
<bool> aNonEmptyCols(nMaxX
);
756 std::vector
<bool> aNonEmptyRows(nMaxY
);
758 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
760 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
762 const GridEntry
&rEntry
= A
[x
][y
];
763 const Window
*pChild
= rEntry
.pChild
;
764 if (pChild
&& pChild
->IsVisible())
766 aNonEmptyCols
[x
] = true;
767 aNonEmptyRows
[y
] = true;
772 //reduce the spans of elements that span empty columns
773 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
775 std::set
<ExtendedGridEntry
*> candidates
;
776 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
778 if (aNonEmptyCols
[x
])
780 ExtendedGridEntry
&rSpan
= A
[x
][y
];
781 //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
782 //just points back to itself if there's no cell spanning
783 if ((rSpan
.x
== -1) || (rSpan
.y
== -1))
785 //there is no entry for this cell, i.e. this is a cell
786 //with no widget in it, or spanned by any other widget
789 ExtendedGridEntry
&rEntry
= A
[rSpan
.x
][rSpan
.y
];
790 candidates
.insert(&rEntry
);
792 for (std::set
<ExtendedGridEntry
*>::iterator aI
= candidates
.begin(), aEnd
= candidates
.end();
795 ExtendedGridEntry
*pEntry
= *aI
;
796 --pEntry
->nSpanWidth
;
800 //reduce the spans of elements that span empty rows
801 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
803 std::set
<ExtendedGridEntry
*> candidates
;
804 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
806 if (aNonEmptyRows
[y
])
808 ExtendedGridEntry
&rSpan
= A
[x
][y
];
809 //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
810 //just points back to itself if there's no cell spanning
811 if ((rSpan
.x
== -1) || (rSpan
.y
== -1))
813 //there is no entry for this cell, i.e. this is a cell
814 //with no widget in it, or spanned by any other widget
817 ExtendedGridEntry
&rEntry
= A
[rSpan
.x
][rSpan
.y
];
818 candidates
.insert(&rEntry
);
820 for (std::set
<ExtendedGridEntry
*>::iterator aI
= candidates
.begin(), aEnd
= candidates
.end();
823 ExtendedGridEntry
*pEntry
= *aI
;
824 --pEntry
->nSpanHeight
;
828 sal_Int32 nNonEmptyCols
= std::count(aNonEmptyCols
.begin(), aNonEmptyCols
.end(), true);
829 sal_Int32 nNonEmptyRows
= std::count(aNonEmptyRows
.begin(), aNonEmptyRows
.end(), true);
831 //make new grid without empty rows and columns
832 array_type
B(boost::extents
[nNonEmptyCols
][nNonEmptyRows
]);
833 for (sal_Int32 x
= 0, x2
= 0; x
< nMaxX
; ++x
)
835 if (aNonEmptyCols
[x
] == false)
837 for (sal_Int32 y
= 0, y2
= 0; y
< nMaxY
; ++y
)
839 if (aNonEmptyRows
[y
] == false)
841 GridEntry
&rEntry
= A
[x
][y
];
842 B
[x2
][y2
++] = rEntry
;
850 bool VclGrid::isNullGrid(const array_type
&A
) const
852 sal_Int32 nMaxX
= A
.shape()[0];
853 sal_Int32 nMaxY
= A
.shape()[1];
855 if (!nMaxX
|| !nMaxY
)
860 void VclGrid::calcMaxs(const array_type
&A
, std::vector
<Value
> &rWidths
, std::vector
<Value
> &rHeights
) const
862 sal_Int32 nMaxX
= A
.shape()[0];
863 sal_Int32 nMaxY
= A
.shape()[1];
865 rWidths
.resize(nMaxX
);
866 rHeights
.resize(nMaxY
);
868 //first use the non spanning entries to set default width/heights
869 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
871 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
873 const GridEntry
&rEntry
= A
[x
][y
];
874 const Window
*pChild
= rEntry
.pChild
;
875 if (!pChild
|| !pChild
->IsVisible())
878 sal_Int32 nWidth
= rEntry
.nSpanWidth
;
879 sal_Int32 nHeight
= rEntry
.nSpanHeight
;
881 for (sal_Int32 nSpanX
= 0; nSpanX
< nWidth
; ++nSpanX
)
882 rWidths
[x
+nSpanX
].m_bExpand
= rWidths
[x
+nSpanX
].m_bExpand
| pChild
->get_hexpand();
884 for (sal_Int32 nSpanY
= 0; nSpanY
< nHeight
; ++nSpanY
)
885 rHeights
[y
+nSpanY
].m_bExpand
= rHeights
[y
+nSpanY
].m_bExpand
| pChild
->get_vexpand();
887 if (nWidth
== 1 || nHeight
== 1)
889 Size aChildSize
= getLayoutRequisition(*pChild
);
891 rWidths
[x
].m_nValue
= std::max(rWidths
[x
].m_nValue
, aChildSize
.Width());
893 rHeights
[y
].m_nValue
= std::max(rHeights
[y
].m_nValue
, aChildSize
.Height());
898 //now use the spanning entries and split any extra sizes across expanding rows/cols
900 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
902 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
904 const GridEntry
&rEntry
= A
[x
][y
];
905 const Window
*pChild
= rEntry
.pChild
;
906 if (!pChild
|| !pChild
->IsVisible())
909 sal_Int32 nWidth
= rEntry
.nSpanWidth
;
910 sal_Int32 nHeight
= rEntry
.nSpanHeight
;
912 if (nWidth
== 1 && nHeight
== 1)
915 Size aChildSize
= getLayoutRequisition(*pChild
);
919 sal_Int32 nExistingWidth
= 0;
920 for (sal_Int32 nSpanX
= 0; nSpanX
< nWidth
; ++nSpanX
)
921 nExistingWidth
+= rWidths
[x
+nSpanX
].m_nValue
;
923 sal_Int32 nExtraWidth
= aChildSize
.Width() - nExistingWidth
;
927 bool bForceExpandAll
= false;
928 sal_Int32 nExpandables
= 0;
929 for (sal_Int32 nSpanX
= 0; nSpanX
< nWidth
; ++nSpanX
)
930 if (rWidths
[x
+nSpanX
].m_bExpand
)
932 if (nExpandables
== 0)
934 nExpandables
= nWidth
;
935 bForceExpandAll
= true;
938 for (sal_Int32 nSpanX
= 0; nSpanX
< nWidth
; ++nSpanX
)
940 if (rWidths
[x
+nSpanX
].m_bExpand
|| bForceExpandAll
)
941 rWidths
[x
+nSpanX
].m_nValue
+= nExtraWidth
/nExpandables
;
948 sal_Int32 nExistingHeight
= 0;
949 for (sal_Int32 nSpanY
= 0; nSpanY
< nHeight
; ++nSpanY
)
950 nExistingHeight
+= rHeights
[y
+nSpanY
].m_nValue
;
952 sal_Int32 nExtraHeight
= aChildSize
.Height() - nExistingHeight
;
954 if (nExtraHeight
> 0)
956 bool bForceExpandAll
= false;
957 sal_Int32 nExpandables
= 0;
958 for (sal_Int32 nSpanY
= 0; nSpanY
< nHeight
; ++nSpanY
)
959 if (rHeights
[y
+nSpanY
].m_bExpand
)
961 if (nExpandables
== 0)
963 nExpandables
= nHeight
;
964 bForceExpandAll
= true;
967 for (sal_Int32 nSpanY
= 0; nSpanY
< nHeight
; ++nSpanY
)
969 if (rHeights
[y
+nSpanY
].m_bExpand
|| bForceExpandAll
)
970 rHeights
[y
+nSpanY
].m_nValue
+= nExtraHeight
/nExpandables
;
978 bool compareValues(const VclGrid::Value
&i
, const VclGrid::Value
&j
)
980 return i
.m_nValue
< j
.m_nValue
;
983 VclGrid::Value
accumulateValues(const VclGrid::Value
&i
, const VclGrid::Value
&j
)
986 aRet
.m_nValue
= i
.m_nValue
+ j
.m_nValue
;
987 aRet
.m_bExpand
= i
.m_bExpand
| j
.m_bExpand
;
991 Size
VclGrid::calculateRequisition() const
993 return calculateRequisitionForSpacings(get_row_spacing(), get_column_spacing());
996 Size
VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing
, sal_Int32 nColSpacing
) const
998 array_type A
= assembleGrid();
1003 std::vector
<Value
> aWidths
;
1004 std::vector
<Value
> aHeights
;
1005 calcMaxs(A
, aWidths
, aHeights
);
1007 long nTotalWidth
= 0;
1008 if (get_column_homogeneous())
1010 nTotalWidth
= std::max_element(aWidths
.begin(), aWidths
.end(), compareValues
)->m_nValue
;
1011 nTotalWidth
*= aWidths
.size();
1015 nTotalWidth
= std::accumulate(aWidths
.begin(), aWidths
.end(), Value(), accumulateValues
).m_nValue
;
1018 nTotalWidth
+= nColSpacing
* (aWidths
.size()-1);
1020 long nTotalHeight
= 0;
1021 if (get_row_homogeneous())
1023 nTotalHeight
= std::max_element(aHeights
.begin(), aHeights
.end(), compareValues
)->m_nValue
;
1024 nTotalHeight
*= aHeights
.size();
1028 nTotalHeight
= std::accumulate(aHeights
.begin(), aHeights
.end(), Value(), accumulateValues
).m_nValue
;
1031 nTotalHeight
+= nRowSpacing
* (aHeights
.size()-1);
1033 return Size(nTotalWidth
, nTotalHeight
);
1036 void VclGrid::setAllocation(const Size
& rAllocation
)
1038 array_type A
= assembleGrid();
1043 sal_Int32 nMaxX
= A
.shape()[0];
1044 sal_Int32 nMaxY
= A
.shape()[1];
1047 std::vector
<Value
> aWidths(nMaxX
);
1048 std::vector
<Value
> aHeights(nMaxY
);
1049 if (!get_column_homogeneous() || !get_row_homogeneous())
1051 aRequisition
= calculateRequisition();
1052 calcMaxs(A
, aWidths
, aHeights
);
1055 sal_Int32
nColSpacing(get_column_spacing());
1056 sal_Int32
nRowSpacing(get_row_spacing());
1058 long nAvailableWidth
= rAllocation
.Width();
1060 nAvailableWidth
-= nColSpacing
* (nMaxX
- 1);
1061 if (get_column_homogeneous())
1063 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
1064 aWidths
[x
].m_nValue
= nAvailableWidth
/nMaxX
;
1066 else if (rAllocation
.Width() != aRequisition
.Width())
1068 sal_Int32 nExpandables
= 0;
1069 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
1070 if (aWidths
[x
].m_bExpand
)
1072 long nExtraWidthForExpanders
= nExpandables
? (rAllocation
.Width() - aRequisition
.Width()) / nExpandables
: 0;
1074 //We don't fit and there is no volunteer to be shrunk
1075 if (!nExpandables
&& rAllocation
.Width() < aRequisition
.Width())
1077 //first reduce spacing, to a min of 3
1078 while (nColSpacing
>= 6)
1081 aRequisition
= calculateRequisitionForSpacings(nRowSpacing
, nColSpacing
);
1082 if (aRequisition
.Width() >= rAllocation
.Width())
1086 //share out the remaining pain to everyone
1087 long nExtraWidth
= (rAllocation
.Width() - aRequisition
.Width()) / nMaxX
;
1089 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
1090 aWidths
[x
].m_nValue
+= nExtraWidth
;
1093 if (nExtraWidthForExpanders
)
1095 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
1096 if (aWidths
[x
].m_bExpand
)
1097 aWidths
[x
].m_nValue
+= nExtraWidthForExpanders
;
1101 long nAvailableHeight
= rAllocation
.Height();
1103 nAvailableHeight
-= nRowSpacing
* (nMaxY
- 1);
1104 if (get_row_homogeneous())
1106 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
1107 aHeights
[y
].m_nValue
= nAvailableHeight
/nMaxY
;
1109 else if (rAllocation
.Height() != aRequisition
.Height())
1111 sal_Int32 nExpandables
= 0;
1112 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
1113 if (aHeights
[y
].m_bExpand
)
1115 long nExtraHeightForExpanders
= nExpandables
? (rAllocation
.Height() - aRequisition
.Height()) / nExpandables
: 0;
1117 //We don't fit and there is no volunteer to be shrunk
1118 if (!nExpandables
&& rAllocation
.Height() < aRequisition
.Height())
1120 //first reduce spacing, to a min of 3
1121 while (nRowSpacing
>= 6)
1124 aRequisition
= calculateRequisitionForSpacings(nRowSpacing
, nColSpacing
);
1125 if (aRequisition
.Height() >= rAllocation
.Height())
1129 //share out the remaining pain to everyone
1130 long nExtraHeight
= (rAllocation
.Height() - aRequisition
.Height()) / nMaxY
;
1132 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
1133 aHeights
[y
].m_nValue
+= nExtraHeight
;
1136 if (nExtraHeightForExpanders
)
1138 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
1139 if (aHeights
[y
].m_bExpand
)
1140 aHeights
[y
].m_nValue
+= nExtraHeightForExpanders
;
1144 Point
aAllocPos(0, 0);
1145 for (sal_Int32 x
= 0; x
< nMaxX
; ++x
)
1147 for (sal_Int32 y
= 0; y
< nMaxY
; ++y
)
1149 GridEntry
&rEntry
= A
[x
][y
];
1150 Window
*pChild
= rEntry
.pChild
;
1153 Size
aChildAlloc(0, 0);
1155 sal_Int32 nWidth
= rEntry
.nSpanWidth
;
1156 for (sal_Int32 nSpanX
= 0; nSpanX
< nWidth
; ++nSpanX
)
1157 aChildAlloc
.Width() += aWidths
[x
+nSpanX
].m_nValue
;
1158 aChildAlloc
.Width() += nColSpacing
*(nWidth
-1);
1160 sal_Int32 nHeight
= rEntry
.nSpanHeight
;
1161 for (sal_Int32 nSpanY
= 0; nSpanY
< nHeight
; ++nSpanY
)
1162 aChildAlloc
.Height() += aHeights
[y
+nSpanY
].m_nValue
;
1163 aChildAlloc
.Height() += nRowSpacing
*(nHeight
-1);
1165 setLayoutAllocation(*pChild
, aAllocPos
, aChildAlloc
);
1167 aAllocPos
.Y() += aHeights
[y
].m_nValue
+ nRowSpacing
;
1169 aAllocPos
.X() += aWidths
[x
].m_nValue
+ nColSpacing
;
1174 bool toBool(const OString
&rValue
)
1176 return (rValue
[0] == 't' || rValue
[0] == 'T' || rValue
[0] == '1');
1179 bool VclGrid::set_property(const OString
&rKey
, const OString
&rValue
)
1181 if (rKey
== "row-spacing")
1182 set_row_spacing(rValue
.toInt32());
1183 else if (rKey
== "column-spacing")
1184 set_column_spacing(rValue
.toInt32());
1185 else if (rKey
== "row-homogeneous")
1186 set_row_homogeneous(toBool(rValue
));
1187 else if (rKey
== "column-homogeneous")
1188 set_column_homogeneous(toBool(rValue
));
1189 else if (rKey
== "n-rows")
1192 return VclContainer::set_property(rKey
, rValue
);
1196 void setGridAttach(Window
&rWidget
, sal_Int32 nLeft
, sal_Int32 nTop
, sal_Int32 nWidth
, sal_Int32 nHeight
)
1198 rWidget
.set_grid_left_attach(nLeft
);
1199 rWidget
.set_grid_top_attach(nTop
);
1200 rWidget
.set_grid_width(nWidth
);
1201 rWidget
.set_grid_height(nHeight
);
1204 const Window
*VclBin::get_child() const
1206 const WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1208 return pWindowImpl
->mpFirstChild
;
1211 Window
*VclBin::get_child()
1213 return const_cast<Window
*>(const_cast<const VclBin
*>(this)->get_child());
1216 Size
VclBin::calculateRequisition() const
1218 const Window
*pChild
= get_child();
1219 if (pChild
&& pChild
->IsVisible())
1220 return getLayoutRequisition(*pChild
);
1224 void VclBin::setAllocation(const Size
&rAllocation
)
1226 Window
*pChild
= get_child();
1227 if (pChild
&& pChild
->IsVisible())
1228 setLayoutAllocation(*pChild
, Point(0, 0), rAllocation
);
1231 //To-Do, hook a DecorationView into VclFrame ?
1233 Size
VclFrame::calculateRequisition() const
1237 const Window
*pChild
= get_child();
1238 const Window
*pLabel
= get_label_widget();
1240 if (pChild
&& pChild
->IsVisible())
1241 aRet
= getLayoutRequisition(*pChild
);
1243 if (pLabel
&& pLabel
->IsVisible())
1245 Size aLabelSize
= getLayoutRequisition(*pLabel
);
1246 aRet
.Height() += aLabelSize
.Height();
1247 aRet
.Width() = std::max(aLabelSize
.Width(), aRet
.Width());
1250 const FrameStyle
&rFrameStyle
=
1251 GetSettings().GetStyleSettings().GetFrameStyle();
1252 aRet
.Width() += rFrameStyle
.left
+ rFrameStyle
.right
;
1253 aRet
.Height() += rFrameStyle
.top
+ rFrameStyle
.bottom
;
1258 void VclFrame::setAllocation(const Size
&rAllocation
)
1260 //SetBackground( Color(0xFF, 0x00, 0xFF) );
1262 const FrameStyle
&rFrameStyle
=
1263 GetSettings().GetStyleSettings().GetFrameStyle();
1264 Size
aAllocation(rAllocation
.Width() - rFrameStyle
.left
- rFrameStyle
.right
,
1265 rAllocation
.Height() - rFrameStyle
.top
- rFrameStyle
.bottom
);
1266 Point
aChildPos(rFrameStyle
.left
, rFrameStyle
.top
);
1268 Window
*pChild
= get_child();
1269 Window
*pLabel
= get_label_widget();
1271 if (pLabel
&& pLabel
->IsVisible())
1273 Size aLabelSize
= getLayoutRequisition(*pLabel
);
1274 aLabelSize
.Height() = std::min(aLabelSize
.Height(), aAllocation
.Height());
1275 aLabelSize
.Width() = std::min(aLabelSize
.Width(), aAllocation
.Width());
1276 setLayoutAllocation(*pLabel
, aChildPos
, aLabelSize
);
1277 aAllocation
.Height() -= aLabelSize
.Height();
1278 aChildPos
.Y() += aLabelSize
.Height();
1281 if (pChild
&& pChild
->IsVisible())
1282 setLayoutAllocation(*pChild
, aChildPos
, aAllocation
);
1285 void VclFrame::designate_label(Window
*pWindow
)
1287 assert(pWindow
->GetParent() == this);
1291 const Window
*VclFrame::get_label_widget() const
1293 assert(GetChildCount() == 2);
1296 //The label widget is normally the first (of two) children
1297 const WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1298 if (pWindowImpl
->mpFirstChild
== pWindowImpl
->mpLastChild
) //no label exists
1300 return pWindowImpl
->mpFirstChild
;
1303 Window
*VclFrame::get_label_widget()
1305 return const_cast<Window
*>(const_cast<const VclFrame
*>(this)->get_label_widget());
1308 const Window
*VclFrame::get_child() const
1310 assert(GetChildCount() == 2);
1311 //The child widget is the normally the last (of two) children
1312 const WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1314 return pWindowImpl
->mpLastChild
;
1315 if (pWindowImpl
->mpFirstChild
== pWindowImpl
->mpLastChild
) //only label exists
1317 return pWindowImpl
->mpLastChild
;
1320 Window
*VclFrame::get_child()
1322 return const_cast<Window
*>(const_cast<const VclFrame
*>(this)->get_child());
1325 void VclFrame::set_label(const OUString
&rLabel
)
1327 Window
*pLabel
= get_label_widget();
1329 pLabel
->SetText(rLabel
);
1332 OUString
VclFrame::getDefaultAccessibleName() const
1334 const Window
*pLabel
= get_label_widget();
1336 return pLabel
->GetAccessibleName();
1337 return VclBin::getDefaultAccessibleName();
1340 Size
VclAlignment::calculateRequisition() const
1342 Size
aRet(m_nLeftPadding
+ m_nRightPadding
,
1343 m_nTopPadding
+ m_nBottomPadding
);
1345 const Window
*pChild
= get_child();
1346 if (pChild
&& pChild
->IsVisible())
1348 Size aChildSize
= getLayoutRequisition(*pChild
);
1349 aRet
.Width() += aChildSize
.Width();
1350 aRet
.Height() += aChildSize
.Height();
1356 void VclAlignment::setAllocation(const Size
&rAllocation
)
1358 Window
*pChild
= get_child();
1359 if (!pChild
|| !pChild
->IsVisible())
1362 Point
aChildPos(m_nLeftPadding
, m_nTopPadding
);
1365 aAllocation
.Width() = rAllocation
.Width() - (m_nLeftPadding
+ m_nRightPadding
);
1366 aAllocation
.Height() = rAllocation
.Height() - (m_nTopPadding
+ m_nBottomPadding
);
1368 setLayoutAllocation(*pChild
, aChildPos
, aAllocation
);
1371 bool VclAlignment::set_property(const OString
&rKey
, const OString
&rValue
)
1373 if (rKey
== "bottom-padding")
1374 m_nBottomPadding
= rValue
.toInt32();
1375 else if (rKey
== "left-padding")
1376 m_nLeftPadding
= rValue
.toInt32();
1377 else if (rKey
== "right-padding")
1378 m_nRightPadding
= rValue
.toInt32();
1379 else if (rKey
== "top-padding")
1380 m_nTopPadding
= rValue
.toInt32();
1381 else if (rKey
== "xalign")
1382 m_fXAlign
= rValue
.toFloat();
1383 else if (rKey
== "xscale")
1384 m_fXScale
= rValue
.toFloat();
1385 else if (rKey
== "yalign")
1386 m_fYAlign
= rValue
.toFloat();
1387 else if (rKey
== "yscale")
1388 m_fYScale
= rValue
.toFloat();
1390 return VclBin::set_property(rKey
, rValue
);
1394 const Window
*VclExpander::get_child() const
1396 const WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1398 assert(pWindowImpl
->mpFirstChild
== &m_aDisclosureButton
);
1400 return pWindowImpl
->mpFirstChild
->GetWindow(WINDOW_NEXT
);
1403 Window
*VclExpander::get_child()
1405 return const_cast<Window
*>(const_cast<const VclExpander
*>(this)->get_child());
1408 Size
VclExpander::calculateRequisition() const
1412 WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1414 const Window
*pChild
= get_child();
1415 const Window
*pLabel
= pChild
!= pWindowImpl
->mpLastChild
? pWindowImpl
->mpLastChild
: NULL
;
1417 if (pChild
&& pChild
->IsVisible() && m_aDisclosureButton
.IsChecked())
1418 aRet
= getLayoutRequisition(*pChild
);
1420 Size aExpanderSize
= getLayoutRequisition(m_aDisclosureButton
);
1422 if (pLabel
&& pLabel
->IsVisible())
1424 Size aLabelSize
= getLayoutRequisition(*pLabel
);
1425 aExpanderSize
.Height() = std::max(aExpanderSize
.Height(), aLabelSize
.Height());
1426 aExpanderSize
.Width() += aLabelSize
.Width();
1429 aRet
.Height() += aExpanderSize
.Height();
1430 aRet
.Width() = std::max(aExpanderSize
.Width(), aRet
.Width());
1432 const FrameStyle
&rFrameStyle
=
1433 GetSettings().GetStyleSettings().GetFrameStyle();
1434 aRet
.Width() += rFrameStyle
.left
+ rFrameStyle
.right
;
1435 aRet
.Height() += rFrameStyle
.top
+ rFrameStyle
.bottom
;
1440 void VclExpander::setAllocation(const Size
&rAllocation
)
1442 const FrameStyle
&rFrameStyle
=
1443 GetSettings().GetStyleSettings().GetFrameStyle();
1444 Size
aAllocation(rAllocation
.Width() - rFrameStyle
.left
- rFrameStyle
.right
,
1445 rAllocation
.Height() - rFrameStyle
.top
- rFrameStyle
.bottom
);
1446 Point
aChildPos(rFrameStyle
.left
, rFrameStyle
.top
);
1448 WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1450 //The label widget is the last (of two) children
1451 Window
*pChild
= get_child();
1452 Window
*pLabel
= pChild
!= pWindowImpl
->mpLastChild
? pWindowImpl
->mpLastChild
: NULL
;
1454 Size aButtonSize
= getLayoutRequisition(m_aDisclosureButton
);
1456 Size aExpanderSize
= aButtonSize
;
1457 if (pLabel
&& pLabel
->IsVisible())
1459 aLabelSize
= getLayoutRequisition(*pLabel
);
1460 aExpanderSize
.Height() = std::max(aExpanderSize
.Height(), aLabelSize
.Height());
1461 aExpanderSize
.Width() += aLabelSize
.Width();
1464 aExpanderSize
.Height() = std::min(aExpanderSize
.Height(), aAllocation
.Height());
1465 aExpanderSize
.Width() = std::min(aExpanderSize
.Width(), aAllocation
.Width());
1467 aButtonSize
.Height() = std::min(aButtonSize
.Height(), aExpanderSize
.Height());
1468 aButtonSize
.Width() = std::min(aButtonSize
.Width(), aExpanderSize
.Width());
1470 long nExtraExpanderHeight
= aExpanderSize
.Height() - aButtonSize
.Height();
1471 Point
aButtonPos(aChildPos
.X(), aChildPos
.Y() + nExtraExpanderHeight
/2);
1472 setLayoutAllocation(m_aDisclosureButton
, aButtonPos
, aButtonSize
);
1474 if (pLabel
&& pLabel
->IsVisible())
1476 aLabelSize
.Height() = std::min(aLabelSize
.Height(), aExpanderSize
.Height());
1477 aLabelSize
.Width() = std::min(aLabelSize
.Width(),
1478 aExpanderSize
.Width() - aButtonSize
.Width());
1480 long nExtraLabelHeight
= aExpanderSize
.Height() - aLabelSize
.Height();
1481 Point
aLabelPos(aChildPos
.X() + aButtonSize
.Width(), aChildPos
.Y() + nExtraLabelHeight
/2);
1482 setLayoutAllocation(*pLabel
, aLabelPos
, aLabelSize
);
1485 aAllocation
.Height() -= aExpanderSize
.Height();
1486 aChildPos
.Y() += aExpanderSize
.Height();
1488 if (pChild
&& pChild
->IsVisible())
1490 if (!m_aDisclosureButton
.IsChecked())
1491 aAllocation
= Size();
1492 setLayoutAllocation(*pChild
, aChildPos
, aAllocation
);
1496 bool VclExpander::set_property(const OString
&rKey
, const OString
&rValue
)
1498 if (rKey
== "expanded")
1499 m_aDisclosureButton
.Check(toBool(rValue
));
1500 else if (rKey
== "resize-toplevel")
1501 m_bResizeTopLevel
= toBool(rValue
);
1503 return VclBin::set_property(rKey
, rValue
);
1507 void VclExpander::StateChanged(StateChangedType nType
)
1509 VclBin::StateChanged( nType
);
1511 if (nType
== STATE_CHANGE_INITSHOW
)
1513 Window
*pChild
= get_child();
1515 pChild
->Show(m_aDisclosureButton
.IsChecked());
1519 IMPL_LINK( VclExpander
, ClickHdl
, DisclosureButton
*, pBtn
)
1521 Window
*pChild
= get_child();
1524 pChild
->Show(pBtn
->IsChecked());
1526 Dialog
* pResizeDialog
= m_bResizeTopLevel
? GetParentDialog() : NULL
;
1528 pResizeDialog
->setOptimalLayoutSize();
1533 const Window
*VclScrolledWindow::get_child() const
1535 assert(GetChildCount() == 3);
1536 const WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1537 return pWindowImpl
->mpLastChild
;
1540 Window
*VclScrolledWindow::get_child()
1542 return const_cast<Window
*>(const_cast<const VclScrolledWindow
*>(this)->get_child());
1545 Size
VclScrolledWindow::calculateRequisition() const
1549 const Window
*pChild
= get_child();
1550 if (pChild
&& pChild
->IsVisible())
1551 aRet
= getLayoutRequisition(*pChild
);
1553 if (m_aVScroll
.IsVisible())
1554 aRet
.Width() += getLayoutRequisition(m_aVScroll
).Width();
1556 if (m_aHScroll
.IsVisible())
1557 aRet
.Height() += getLayoutRequisition(m_aHScroll
).Height();
1562 void VclScrolledWindow::setAllocation(const Size
&rAllocation
)
1564 Size
aChildAllocation(rAllocation
);
1567 Window
*pChild
= get_child();
1568 if (pChild
&& pChild
->IsVisible())
1569 aChildReq
= getLayoutRequisition(*pChild
);
1571 if (m_aVScroll
.IsVisible())
1573 long nScrollBarWidth
= getLayoutRequisition(m_aVScroll
).Width();
1574 Point
aScrollPos(rAllocation
.Width() - nScrollBarWidth
, 0);
1575 Size
aScrollSize(nScrollBarWidth
, rAllocation
.Height());
1576 setLayoutAllocation(m_aVScroll
, aScrollPos
, aScrollSize
);
1577 aChildAllocation
.Width() -= nScrollBarWidth
;
1578 aChildAllocation
.Height() = aChildReq
.Height();
1581 if (m_aHScroll
.IsVisible())
1583 long nScrollBarHeight
= getLayoutRequisition(m_aHScroll
).Height();
1584 Point
aScrollPos(0, rAllocation
.Height() - nScrollBarHeight
);
1585 Size
aScrollSize(rAllocation
.Width(), nScrollBarHeight
);
1586 setLayoutAllocation(m_aHScroll
, aScrollPos
, aScrollSize
);
1587 aChildAllocation
.Height() -= nScrollBarHeight
;
1588 aChildAllocation
.Width() = aChildReq
.Width();
1591 if (pChild
&& pChild
->IsVisible())
1593 Point
aChildPos(pChild
->GetPosPixel());
1594 if (!m_aHScroll
.IsVisible())
1596 if (!m_aVScroll
.IsVisible())
1598 setLayoutAllocation(*pChild
, aChildPos
, aChildAllocation
);
1602 Size
VclScrolledWindow::getVisibleChildSize() const
1604 Size
aRet(GetSizePixel());
1605 if (m_aVScroll
.IsVisible())
1606 aRet
.Width() -= m_aVScroll
.GetSizePixel().Width();
1607 if (m_aHScroll
.IsVisible())
1608 aRet
.Height() -= m_aHScroll
.GetSizePixel().Height();
1612 bool VclScrolledWindow::set_property(const OString
&rKey
, const OString
&rValue
)
1614 bool bRet
= VclBin::set_property(rKey
, rValue
);
1615 m_aVScroll
.Show((GetStyle() & WB_VSCROLL
) != 0);
1616 m_aHScroll
.Show((GetStyle() & WB_HSCROLL
) != 0);
1620 const Window
*VclEventBox::get_child() const
1622 const WindowImpl
* pWindowImpl
= ImplGetWindowImpl();
1624 assert(pWindowImpl
->mpFirstChild
== &m_aEventBoxHelper
);
1626 return pWindowImpl
->mpFirstChild
->GetWindow(WINDOW_NEXT
);
1629 Window
*VclEventBox::get_child()
1631 return const_cast<Window
*>(const_cast<const VclEventBox
*>(this)->get_child());
1634 void VclEventBox::setAllocation(const Size
& rAllocation
)
1636 Point
aChildPos(0, 0);
1637 for (Window
*pChild
= GetWindow(WINDOW_FIRSTCHILD
); pChild
; pChild
= pChild
->GetWindow(WINDOW_NEXT
))
1639 if (!pChild
->IsVisible())
1641 setLayoutAllocation(*pChild
, aChildPos
, rAllocation
);
1645 Size
VclEventBox::calculateRequisition() const
1649 for (const Window
* pChild
= get_child(); pChild
;
1650 pChild
= pChild
->GetWindow(WINDOW_NEXT
))
1652 if (!pChild
->IsVisible())
1654 Size aChildSize
= getLayoutRequisition(*pChild
);
1655 aRet
.Width() = std::max(aRet
.Width(), aChildSize
.Width());
1656 aRet
.Height() = std::max(aRet
.Height(), aChildSize
.Height());
1662 void VclEventBox::Command(const CommandEvent
&)
1664 //discard events by default to block them reaching children
1667 void VclSizeGroup::trigger_queue_resize()
1669 //sufficient to trigger one widget to trigger all of them
1670 if (!m_aWindows
.empty())
1672 Window
*pWindow
= *m_aWindows
.begin();
1673 pWindow
->queue_resize();
1677 void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden
)
1679 if (bIgnoreHidden
!= m_bIgnoreHidden
)
1681 m_bIgnoreHidden
= bIgnoreHidden
;
1682 trigger_queue_resize();
1686 void VclSizeGroup::set_mode(VclSizeGroupMode eMode
)
1688 if (eMode
!= m_eMode
)
1691 trigger_queue_resize();
1696 bool VclSizeGroup::set_property(const OString
&rKey
, const OString
&rValue
)
1698 if (rKey
== "ignore-hidden")
1699 set_ignore_hidden(toBool(rValue
));
1700 else if (rKey
== "mode")
1702 VclSizeGroupMode eMode
= VCL_SIZE_GROUP_HORIZONTAL
;
1703 if (rValue
.equals("none"))
1704 eMode
= VCL_SIZE_GROUP_NONE
;
1705 else if (rValue
.equals("horizontal"))
1706 eMode
= VCL_SIZE_GROUP_HORIZONTAL
;
1707 else if (rValue
.equals("vertical"))
1708 eMode
= VCL_SIZE_GROUP_VERTICAL
;
1709 else if (rValue
.equals("both"))
1710 eMode
= VCL_SIZE_GROUP_BOTH
;
1713 SAL_WARN("vcl.layout", "unknown size group mode" << rValue
.getStr());
1719 SAL_INFO("vcl.layout", "unhandled property: " << rKey
.getStr());
1725 MessageDialog::MessageDialog(Window
* pParent
, WinBits nStyle
)
1726 : Dialog(pParent
, nStyle
)
1729 , m_pPrimaryMessage(NULL
)
1730 , m_pSecondaryMessage(NULL
)
1732 SetType(WINDOW_MESSBOX
);
1735 MessageDialog::MessageDialog(Window
* pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
)
1736 : Dialog(pParent
, rID
, rUIXMLDescription
, WINDOW_MESSBOX
)
1739 , m_pPrimaryMessage(NULL
)
1740 , m_pSecondaryMessage(NULL
)
1744 MessageDialog::~MessageDialog()
1746 delete m_pSecondaryMessage
;
1747 delete m_pPrimaryMessage
;
1752 IMPL_LINK(MessageDialog
, ButtonHdl
, Button
*, pButton
)
1754 //for now insist that we have a builder, we can relax that in
1755 //the future if we need it
1756 assert(m_pUIBuilder
);
1757 EndDialog(m_pUIBuilder
->get_response(pButton
));
1761 void MessageDialog::setButtonHandlers()
1763 SAL_WARN_IF(!m_pUIBuilder
, "vcl.layout", "MessageDialog non-ui load button responses not implemented yet");
1766 VclButtonBox
*pButtonBox
= get_action_area();
1768 for (Window
* pChild
= pButtonBox
->GetWindow(WINDOW_FIRSTCHILD
); pChild
;
1769 pChild
= pChild
->GetWindow(WINDOW_NEXT
))
1771 switch (pChild
->GetType())
1773 case WINDOW_PUSHBUTTON
:
1775 PushButton
* pButton
= (PushButton
*)pChild
;
1776 pButton
->SetClickHdl(LINK(this, MessageDialog
, ButtonHdl
));
1779 //for now at least, insist that the response ids match
1780 //the default actions for those widgets, and leave
1781 //their default handlers in place
1782 case WINDOW_OKBUTTON
:
1783 assert(m_pUIBuilder
->get_response(pChild
) == RET_OK
);
1785 case WINDOW_CANCELBUTTON
:
1786 assert(m_pUIBuilder
->get_response(pChild
) == RET_CANCEL
);
1788 case WINDOW_HELPBUTTON
:
1789 assert(m_pUIBuilder
->get_response(pChild
) == RET_HELP
);
1792 SAL_WARN("vcl.layout", "The type of widget " <<
1793 pChild
->GetHelpId() << " is currently not handled");
1796 //The default is to stick the focus into the first widget
1797 //that accepts it, and if that happens and its a button
1798 //then that becomes the new default button, so explicitly
1799 //put the focus into the default button
1800 if (pChild
->GetStyle() & WB_DEFBUTTON
)
1801 pChild
->GrabFocus();
1805 short MessageDialog::Execute()
1807 setDeferredProperties();
1811 VclContainer
*pContainer
= get_content_area();
1814 m_pGrid
= new VclGrid(pContainer
);
1815 m_pGrid
->set_column_spacing(12);
1817 m_pImage
= new FixedImage(m_pGrid
, WB_CENTER
| WB_VCENTER
| WB_3DLOOK
);
1818 m_pImage
->SetImage(WarningBox::GetStandardImage());
1819 m_pImage
->set_grid_left_attach(0);
1820 m_pImage
->set_grid_top_attach(0);
1821 m_pImage
->set_valign(VCL_ALIGN_START
);
1824 WinBits nWinStyle
= WB_LEFT
| WB_VCENTER
| WB_NOLABEL
| WB_NOTABSTOP
;
1826 m_pPrimaryMessage
= new VclMultiLineEdit(m_pGrid
, nWinStyle
);
1827 m_pPrimaryMessage
->SetPaintTransparent(true);
1828 m_pPrimaryMessage
->EnableCursor(false);
1829 Font aFont
= GetSettings().GetStyleSettings().GetLabelFont();
1830 aFont
.SetSize( Size( 0, aFont
.GetSize().Height() * 1.2 ) );
1831 aFont
.SetWeight(WEIGHT_BOLD
);
1832 m_pPrimaryMessage
->SetControlFont(aFont
);
1833 m_pPrimaryMessage
->set_grid_left_attach(1);
1834 m_pPrimaryMessage
->set_grid_top_attach(0);
1835 m_pPrimaryMessage
->set_hexpand(true);
1836 m_pPrimaryMessage
->SetText(m_sPrimaryString
);
1837 m_pPrimaryMessage
->Show(!m_sPrimaryString
.isEmpty());
1838 m_pPrimaryMessage
->SetMaxTextWidth(m_pPrimaryMessage
->approximate_char_width() * 60);
1840 m_pSecondaryMessage
= new VclMultiLineEdit(m_pGrid
, nWinStyle
);
1841 m_pSecondaryMessage
->SetPaintTransparent(true);
1842 m_pSecondaryMessage
->EnableCursor(false);
1843 m_pSecondaryMessage
->set_grid_left_attach(1);
1844 m_pSecondaryMessage
->set_grid_top_attach(1);
1845 m_pSecondaryMessage
->set_hexpand(true);
1846 m_pSecondaryMessage
->SetText(m_sSecondaryString
);
1847 m_pSecondaryMessage
->Show(!m_sSecondaryString
.isEmpty());
1848 m_pSecondaryMessage
->SetMaxTextWidth(m_pSecondaryMessage
->approximate_char_width() * 80);
1852 setButtonHandlers();
1854 VclButtonBox
*pButtonBox
= get_action_area();
1856 pButtonBox
->sort_native_button_order();
1859 return Dialog::Execute();
1862 OUString
MessageDialog::get_primary_text() const
1864 const_cast<MessageDialog
*>(this)->setDeferredProperties();
1866 return m_sPrimaryString
;
1869 OUString
MessageDialog::get_secondary_text() const
1871 const_cast<MessageDialog
*>(this)->setDeferredProperties();
1873 return m_sSecondaryString
;
1876 bool MessageDialog::set_property(const OString
&rKey
, const OString
&rValue
)
1879 set_primary_text(OStringToOUString(rValue
, RTL_TEXTENCODING_UTF8
));
1880 else if (rKey
== "secondary-text")
1881 set_secondary_text(OStringToOUString(rValue
, RTL_TEXTENCODING_UTF8
));
1883 return Dialog::set_property(rKey
, rValue
);
1887 void MessageDialog::set_primary_text(const OUString
&rPrimaryString
)
1889 m_sPrimaryString
= rPrimaryString
;
1890 if (m_pPrimaryMessage
)
1892 m_pPrimaryMessage
->SetText(m_sPrimaryString
);
1893 m_pPrimaryMessage
->Show(!m_sPrimaryString
.isEmpty());
1897 void MessageDialog::set_secondary_text(const OUString
&rSecondaryString
)
1899 m_sSecondaryString
= rSecondaryString
;
1900 if (m_pSecondaryMessage
)
1902 m_pSecondaryMessage
->SetText(OUString("\n") + m_sSecondaryString
);
1903 m_pSecondaryMessage
->Show(!m_sSecondaryString
.isEmpty());
1907 Size
getLegacyBestSizeForChildren(const Window
&rWindow
)
1911 for (const Window
* pChild
= rWindow
.GetWindow(WINDOW_FIRSTCHILD
); pChild
;
1912 pChild
= pChild
->GetWindow(WINDOW_NEXT
))
1914 if (!pChild
->IsVisible())
1917 Rectangle
aChildBounds(pChild
->GetPosPixel(), pChild
->GetSizePixel());
1918 aBounds
.Union(aChildBounds
);
1921 if (aBounds
.IsEmpty())
1922 return rWindow
.GetSizePixel();
1924 Size
aRet(aBounds
.GetSize());
1925 Point
aTopLeft(aBounds
.TopLeft());
1926 aRet
.Width() += aTopLeft
.X()*2;
1927 aRet
.Height() += aTopLeft
.Y()*2;
1932 Window
* getNonLayoutParent(Window
*pWindow
)
1936 pWindow
= pWindow
->GetParent();
1937 if (!pWindow
|| !isContainerWindow(*pWindow
))
1943 Window
* getNonLayoutRealParent(Window
*pWindow
)
1947 pWindow
= pWindow
->ImplGetParent();
1948 if (!pWindow
|| !isContainerWindow(*pWindow
))
1954 bool isVisibleInLayout(const Window
*pWindow
)
1956 bool bVisible
= true;
1959 bVisible
= pWindow
->IsVisible();
1960 pWindow
= pWindow
->GetParent();
1961 if (!pWindow
|| !isContainerWindow(*pWindow
))
1967 bool isEnabledInLayout(const Window
*pWindow
)
1969 bool bEnabled
= true;
1972 bEnabled
= pWindow
->IsEnabled();
1973 pWindow
= pWindow
->GetParent();
1974 if (!pWindow
|| !isContainerWindow(*pWindow
))
1980 bool isLayoutEnabled(const Window
*pWindow
)
1982 //Child is a container => we're layout enabled
1983 const Window
*pChild
= pWindow
? pWindow
->GetWindow(WINDOW_FIRSTCHILD
) : NULL
;
1984 return pChild
&& isContainerWindow(*pChild
) && !pChild
->GetWindow(WINDOW_NEXT
);
1987 bool isInitialLayout(const Window
*pWindow
)
1989 Dialog
*pParentDialog
= pWindow
? pWindow
->GetParentDialog() : NULL
;
1990 return pParentDialog
&& pParentDialog
->isCalculatingInitialLayoutSize();
1993 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */