2011-11-09 22:58:42 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
2012-09-27 09:38:41 +01:00
|
|
|
* This file is part of the LibreOffice project.
|
2011-11-09 22:58:42 +00:00
|
|
|
*
|
2012-09-27 09:38:41 +01:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2011-11-09 22:58:42 +00:00
|
|
|
*/
|
|
|
|
|
2012-08-23 11:54:40 +01:00
|
|
|
#include <vcl/dialog.hxx>
|
2011-11-09 22:58:42 +00:00
|
|
|
#include <vcl/layout.hxx>
|
2012-04-11 11:41:54 +01:00
|
|
|
#include "window.h"
|
|
|
|
|
2012-12-04 15:28:48 +00:00
|
|
|
VclContainer::VclContainer(Window *pParent, WinBits nStyle)
|
2012-06-16 20:23:31 +01:00
|
|
|
: Window(WINDOW_CONTAINER)
|
2012-08-23 15:18:14 +01:00
|
|
|
, m_bLayoutDirty(true)
|
2012-06-16 20:23:31 +01:00
|
|
|
{
|
2012-12-04 15:28:48 +00:00
|
|
|
ImplInit(pParent, nStyle, NULL);
|
2012-11-25 18:29:37 +04:00
|
|
|
EnableChildTransparentMode();
|
2012-11-24 17:46:50 +04:00
|
|
|
SetPaintTransparent(sal_True);
|
2012-11-20 16:37:44 +04:00
|
|
|
SetBackground();
|
2012-06-16 20:23:31 +01:00
|
|
|
}
|
|
|
|
|
2012-04-11 11:41:54 +01:00
|
|
|
Size VclContainer::GetOptimalSize(WindowSizeType eType) const
|
|
|
|
{
|
|
|
|
if (eType == WINDOWSIZE_MAXIMUM)
|
|
|
|
return Window::GetOptimalSize(eType);
|
2012-08-24 13:40:42 +01:00
|
|
|
return calculateRequisition();
|
2012-04-11 11:41:54 +01:00
|
|
|
}
|
|
|
|
|
2012-11-15 20:04:42 +00:00
|
|
|
void VclContainer::setLayoutPosSize(Window &rWindow, const Point &rPos, const Size &rSize)
|
2012-04-11 11:41:54 +01:00
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
sal_Int32 nBorderWidth = rWindow.get_border_width();
|
|
|
|
sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
|
|
|
|
sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
|
|
|
|
sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
|
|
|
|
sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
|
|
|
|
Point aPos(rPos.X() + nLeft, rPos.Y() + nTop);
|
|
|
|
Size aSize(rSize.Width() - nLeft - nRight, rSize.Height() - nTop - nBottom);
|
|
|
|
rWindow.SetPosSizePixel(aPos, aSize);
|
|
|
|
}
|
2012-05-18 13:48:13 +01:00
|
|
|
|
2012-11-15 20:04:42 +00:00
|
|
|
void VclContainer::setLayoutAllocation(Window &rChild, const Point &rAllocPos, const Size &rChildAlloc)
|
|
|
|
{
|
|
|
|
VclAlign eHalign = rChild.get_halign();
|
|
|
|
VclAlign eValign = rChild.get_valign();
|
|
|
|
|
|
|
|
//typical case
|
|
|
|
if (eHalign == VCL_ALIGN_FILL && eValign == VCL_ALIGN_FILL)
|
|
|
|
{
|
|
|
|
setLayoutPosSize(rChild, rAllocPos, rChildAlloc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Point aChildPos(rAllocPos);
|
|
|
|
Size aChildSize(rChildAlloc);
|
|
|
|
Size aChildPreferredSize(getLayoutRequisition(rChild));
|
|
|
|
|
|
|
|
switch (eHalign)
|
|
|
|
{
|
|
|
|
case VCL_ALIGN_FILL:
|
|
|
|
break;
|
|
|
|
case VCL_ALIGN_START:
|
|
|
|
if (aChildPreferredSize.Width() < rChildAlloc.Width())
|
|
|
|
aChildSize.Width() = aChildPreferredSize.Width();
|
|
|
|
break;
|
|
|
|
case VCL_ALIGN_END:
|
|
|
|
if (aChildPreferredSize.Width() < rChildAlloc.Width())
|
|
|
|
aChildSize.Width() = aChildPreferredSize.Width();
|
|
|
|
aChildPos.X() += rChildAlloc.Width();
|
|
|
|
aChildPos.X() -= aChildSize.Width();
|
|
|
|
break;
|
|
|
|
case VCL_ALIGN_CENTER:
|
|
|
|
if (aChildPreferredSize.Width() < aChildSize.Width())
|
|
|
|
aChildSize.Width() = aChildPreferredSize.Width();
|
|
|
|
aChildPos.X() += (rChildAlloc.Width() - aChildSize.Width()) / 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (eValign)
|
|
|
|
{
|
|
|
|
case VCL_ALIGN_FILL:
|
|
|
|
break;
|
|
|
|
case VCL_ALIGN_START:
|
|
|
|
if (aChildPreferredSize.Height() < rChildAlloc.Height())
|
|
|
|
aChildSize.Height() = aChildPreferredSize.Height();
|
|
|
|
break;
|
|
|
|
case VCL_ALIGN_END:
|
|
|
|
if (aChildPreferredSize.Height() < rChildAlloc.Height())
|
|
|
|
aChildSize.Height() = aChildPreferredSize.Height();
|
|
|
|
aChildPos.Y() += rChildAlloc.Height();
|
|
|
|
aChildPos.Y() -= aChildSize.Height();
|
|
|
|
break;
|
|
|
|
case VCL_ALIGN_CENTER:
|
|
|
|
if (aChildPreferredSize.Height() < aChildSize.Height())
|
|
|
|
aChildSize.Height() = aChildPreferredSize.Height();
|
|
|
|
aChildPos.Y() += (rChildAlloc.Height() - aChildSize.Height()) / 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
setLayoutPosSize(rChild, aChildPos, aChildSize);
|
|
|
|
}
|
|
|
|
|
2012-08-24 13:40:42 +01:00
|
|
|
Size VclContainer::getLayoutRequisition(const Window &rWindow)
|
|
|
|
{
|
|
|
|
sal_Int32 nBorderWidth = rWindow.get_border_width();
|
|
|
|
sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
|
|
|
|
sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
|
|
|
|
sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
|
|
|
|
sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
|
|
|
|
Size aSize(rWindow.get_preferred_size());
|
|
|
|
return Size(aSize.Width() + nLeft + nRight, aSize.Height() + nTop + nBottom);
|
|
|
|
}
|
2012-06-16 13:29:15 +01:00
|
|
|
|
2012-08-24 13:40:42 +01:00
|
|
|
void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
|
|
|
|
{
|
|
|
|
bool bSizeChanged = rAllocation != GetOutputSizePixel();
|
|
|
|
Window::SetPosSizePixel(rAllocPos, rAllocation);
|
2012-08-23 15:18:14 +01:00
|
|
|
if (m_bLayoutDirty || bSizeChanged)
|
|
|
|
{
|
|
|
|
m_bLayoutDirty = false;
|
2012-10-08 15:40:49 +01:00
|
|
|
setAllocation(rAllocation);
|
2012-08-23 15:18:14 +01:00
|
|
|
}
|
2012-06-16 13:29:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void VclContainer::SetPosPixel(const Point& rAllocPos)
|
|
|
|
{
|
|
|
|
Point aAllocPos = rAllocPos;
|
2012-08-23 16:43:09 +01:00
|
|
|
sal_Int32 nBorderWidth = get_border_width();
|
|
|
|
aAllocPos.X() += nBorderWidth + get_margin_left();
|
|
|
|
aAllocPos.Y() += nBorderWidth + get_margin_top();
|
2012-06-16 13:29:15 +01:00
|
|
|
|
|
|
|
if (aAllocPos != GetPosPixel())
|
|
|
|
Window::SetPosPixel(aAllocPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VclContainer::SetSizePixel(const Size& rAllocation)
|
|
|
|
{
|
|
|
|
Size aAllocation = rAllocation;
|
2012-08-23 16:43:09 +01:00
|
|
|
sal_Int32 nBorderWidth = get_border_width();
|
|
|
|
aAllocation.Width() -= nBorderWidth*2 + get_margin_left() + get_margin_right();
|
|
|
|
aAllocation.Height() -= nBorderWidth*2 + get_margin_top() + get_margin_bottom();
|
2012-08-23 15:18:14 +01:00
|
|
|
bool bSizeChanged = aAllocation != GetSizePixel();
|
|
|
|
if (bSizeChanged)
|
2012-06-16 13:29:15 +01:00
|
|
|
Window::SetSizePixel(aAllocation);
|
2012-08-23 15:18:14 +01:00
|
|
|
if (m_bLayoutDirty || bSizeChanged)
|
|
|
|
{
|
|
|
|
m_bLayoutDirty = false;
|
2012-10-08 15:40:49 +01:00
|
|
|
setAllocation(aAllocation);
|
2012-06-16 13:29:15 +01:00
|
|
|
}
|
2012-05-18 13:48:13 +01:00
|
|
|
}
|
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
void VclBox::accumulateMaxes(const Size &rChildSize, Size &rSize) const
|
|
|
|
{
|
|
|
|
long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
|
|
|
|
long nSecondaryBoxDimension = getSecondaryDimension(rSize);
|
|
|
|
setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
|
|
|
|
|
|
|
|
long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
|
|
|
|
long nPrimaryBoxDimension = getPrimaryDimension(rSize);
|
|
|
|
if (m_bHomogeneous)
|
|
|
|
setPrimaryDimension(rSize, std::max(nPrimaryBoxDimension, nPrimaryChildDimension));
|
|
|
|
else
|
|
|
|
setPrimaryDimension(rSize, nPrimaryBoxDimension + nPrimaryChildDimension);
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
Size VclBox::calculateRequisition() const
|
2011-11-09 22:58:42 +00:00
|
|
|
{
|
|
|
|
sal_uInt16 nVisibleChildren = 0;
|
|
|
|
|
|
|
|
Size aSize;
|
2012-04-16 15:14:42 +01:00
|
|
|
for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
|
2011-11-09 22:58:42 +00:00
|
|
|
{
|
|
|
|
if (!pChild->IsVisible())
|
|
|
|
continue;
|
|
|
|
++nVisibleChildren;
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aChildSize = getLayoutRequisition(*pChild);
|
2012-10-24 16:28:17 +01:00
|
|
|
|
|
|
|
long nPrimaryDimension = getPrimaryDimension(aChildSize);
|
|
|
|
nPrimaryDimension += pChild->get_padding() * 2;
|
|
|
|
setPrimaryDimension(aChildSize, nPrimaryDimension);
|
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
accumulateMaxes(aChildSize, aSize);
|
2011-11-09 22:58:42 +00:00
|
|
|
}
|
|
|
|
|
2012-10-24 10:10:56 +01:00
|
|
|
return finalizeMaxes(aSize, nVisibleChildren);
|
2011-11-09 22:58:42 +00:00
|
|
|
}
|
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
void VclBox::setAllocation(const Size &rAllocation)
|
2011-11-09 22:58:42 +00:00
|
|
|
{
|
2011-11-15 16:38:47 +00:00
|
|
|
sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;
|
2012-04-16 15:14:42 +01:00
|
|
|
for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
|
2011-11-09 22:58:42 +00:00
|
|
|
{
|
|
|
|
if (!pChild->IsVisible())
|
|
|
|
continue;
|
|
|
|
++nVisibleChildren;
|
2012-11-15 14:49:37 +00:00
|
|
|
bool bExpand = getPrimaryDimensionChildExpand(*pChild);
|
2011-11-14 16:56:25 +00:00
|
|
|
if (bExpand)
|
2011-11-09 22:58:42 +00:00
|
|
|
++nExpandChildren;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nVisibleChildren)
|
|
|
|
return;
|
|
|
|
|
2012-05-18 13:48:13 +01:00
|
|
|
long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
|
2011-11-15 09:50:11 +00:00
|
|
|
|
2012-05-18 13:48:13 +01:00
|
|
|
long nHomogeneousDimension = 0, nExtraSpace = 0;
|
2011-11-09 22:58:42 +00:00
|
|
|
if (m_bHomogeneous)
|
|
|
|
{
|
2011-11-15 16:38:47 +00:00
|
|
|
nHomogeneousDimension = ((nAllocPrimaryDimension -
|
|
|
|
(nVisibleChildren - 1) * m_nSpacing)) / nVisibleChildren;
|
2011-11-09 22:58:42 +00:00
|
|
|
}
|
|
|
|
else if (nExpandChildren)
|
|
|
|
{
|
|
|
|
Size aRequisition = calculateRequisition();
|
2012-05-18 13:48:13 +01:00
|
|
|
nExtraSpace = (getPrimaryDimension(rAllocation) - getPrimaryDimension(aRequisition)) / nExpandChildren;
|
2011-11-09 22:58:42 +00:00
|
|
|
}
|
|
|
|
|
2011-11-15 09:50:11 +00:00
|
|
|
for (sal_Int32 ePackType = VCL_PACK_START; ePackType <= VCL_PACK_END; ++ePackType)
|
|
|
|
{
|
2012-05-18 13:48:13 +01:00
|
|
|
Point aPos(0, 0);
|
2011-11-15 09:50:11 +00:00
|
|
|
if (ePackType == VCL_PACK_END)
|
2011-11-09 22:58:42 +00:00
|
|
|
{
|
2011-11-15 09:50:11 +00:00
|
|
|
long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
|
|
|
|
setPrimaryCoordinate(aPos, nPrimaryCoordinate + nAllocPrimaryDimension);
|
2011-11-09 22:58:42 +00:00
|
|
|
}
|
|
|
|
|
2012-04-16 15:14:42 +01:00
|
|
|
for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
|
2011-11-09 22:58:42 +00:00
|
|
|
{
|
2011-11-15 09:50:11 +00:00
|
|
|
if (!pChild->IsVisible())
|
|
|
|
continue;
|
|
|
|
|
2012-08-15 11:19:06 +01:00
|
|
|
sal_Int32 ePacking = pChild->get_pack_type();
|
2011-11-15 09:50:11 +00:00
|
|
|
|
|
|
|
if (ePacking != ePackType)
|
|
|
|
continue;
|
|
|
|
|
2012-08-15 11:19:06 +01:00
|
|
|
long nPadding = pChild->get_padding();
|
2011-11-15 09:50:11 +00:00
|
|
|
|
|
|
|
Size aBoxSize;
|
|
|
|
if (m_bHomogeneous)
|
|
|
|
setPrimaryDimension(aBoxSize, nHomogeneousDimension);
|
|
|
|
else
|
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
aBoxSize = getLayoutRequisition(*pChild);
|
2011-11-15 09:50:11 +00:00
|
|
|
long nPrimaryDimension = getPrimaryDimension(aBoxSize);
|
2012-10-24 16:28:17 +01:00
|
|
|
nPrimaryDimension += nPadding * 2;
|
2012-11-15 14:49:37 +00:00
|
|
|
if (getPrimaryDimensionChildExpand(*pChild))
|
2012-10-24 16:28:17 +01:00
|
|
|
nPrimaryDimension += nExtraSpace;
|
|
|
|
setPrimaryDimension(aBoxSize, nPrimaryDimension);
|
2011-11-15 09:50:11 +00:00
|
|
|
}
|
2012-05-18 13:48:13 +01:00
|
|
|
setSecondaryDimension(aBoxSize, getSecondaryDimension(rAllocation));
|
2011-11-15 09:50:11 +00:00
|
|
|
|
|
|
|
Point aChildPos(aPos);
|
|
|
|
Size aChildSize(aBoxSize);
|
|
|
|
long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
|
|
|
|
|
2012-08-15 11:19:06 +01:00
|
|
|
bool bFill = pChild->get_fill();
|
2011-11-15 09:50:11 +00:00
|
|
|
if (bFill)
|
|
|
|
{
|
|
|
|
setPrimaryDimension(aChildSize, std::max(static_cast<long>(1),
|
|
|
|
getPrimaryDimension(aBoxSize) - nPadding * 2));
|
|
|
|
|
|
|
|
setPrimaryCoordinate(aChildPos, nPrimaryCoordinate + nPadding);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setPrimaryDimension(aChildSize,
|
2012-08-24 13:40:42 +01:00
|
|
|
getPrimaryDimension(getLayoutRequisition(*pChild)));
|
2011-11-15 09:50:11 +00:00
|
|
|
|
|
|
|
setPrimaryCoordinate(aChildPos, nPrimaryCoordinate +
|
|
|
|
(getPrimaryDimension(aBoxSize) - getPrimaryDimension(aChildSize)) / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
long nDiff = getPrimaryDimension(aBoxSize) + m_nSpacing;
|
|
|
|
if (ePackType == VCL_PACK_START)
|
|
|
|
setPrimaryCoordinate(aPos, nPrimaryCoordinate + nDiff);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setPrimaryCoordinate(aPos, nPrimaryCoordinate - nDiff);
|
|
|
|
setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) -
|
2012-03-29 10:27:27 +01:00
|
|
|
getPrimaryDimension(aBoxSize));
|
2011-11-15 09:50:11 +00:00
|
|
|
}
|
|
|
|
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pChild, aChildPos, aChildSize);
|
2011-11-09 22:58:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-16 11:05:57 +01:00
|
|
|
bool VclBox::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("spacing")))
|
|
|
|
set_spacing(rValue.toInt32());
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("homogeneous")))
|
|
|
|
set_homogeneous(toBool(rValue));
|
|
|
|
else
|
2012-05-18 13:48:13 +01:00
|
|
|
return VclContainer::set_property(rKey, rValue);
|
2012-04-16 11:05:57 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-11-17 21:24:33 +00:00
|
|
|
#define DEFAULT_CHILD_MIN_WIDTH 85
|
|
|
|
#define DEFAULT_CHILD_MIN_HEIGHT 27
|
2011-11-17 11:46:16 +00:00
|
|
|
|
2012-10-24 10:10:56 +01:00
|
|
|
Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
|
|
|
|
{
|
|
|
|
Size aRet;
|
|
|
|
|
|
|
|
if (nVisibleChildren)
|
|
|
|
{
|
|
|
|
long nPrimaryDimension = getPrimaryDimension(rSize);
|
|
|
|
if (m_bHomogeneous)
|
|
|
|
nPrimaryDimension *= nVisibleChildren;
|
|
|
|
setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
|
|
|
|
setSecondaryDimension(aRet, getSecondaryDimension(rSize));
|
|
|
|
}
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
Size VclButtonBox::addReqGroups(const VclButtonBox::Requisition &rReq) const
|
|
|
|
{
|
|
|
|
Size aRet;
|
|
|
|
|
|
|
|
long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
|
|
|
|
long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
|
|
|
|
|
|
|
|
assert(m_bHomogeneous);
|
|
|
|
|
|
|
|
if (m_bHomogeneousGroups)
|
|
|
|
setPrimaryDimension(aRet, std::max(nMainGroupDimension, nSubGroupDimension));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setPrimaryDimension(aRet,
|
|
|
|
(rReq.m_nMainGroupChildren * nMainGroupDimension
|
|
|
|
+ rReq.m_nSubGroupChildren * nSubGroupDimension) /
|
|
|
|
(rReq.m_nMainGroupChildren + rReq.m_nSubGroupChildren));
|
|
|
|
}
|
|
|
|
|
|
|
|
setSecondaryDimension(aRet,
|
|
|
|
std::max(getSecondaryDimension(rReq.m_aMainGroupSize),
|
|
|
|
getSecondaryDimension(rReq.m_aSubGroupSize)));
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2012-10-22 10:27:50 +01:00
|
|
|
VclButtonBox::Requisition VclButtonBox::calculatePrimarySecondaryRequisitions() const
|
2011-11-17 11:46:16 +00:00
|
|
|
{
|
2012-10-22 10:27:50 +01:00
|
|
|
Requisition aReq;
|
2011-11-17 11:46:16 +00:00
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
Size aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
|
|
|
|
Size aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
|
2011-11-17 11:46:16 +00:00
|
|
|
|
2013-01-01 15:13:42 +00:00
|
|
|
bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VCL_BUTTONBOX_SPREAD || m_eLayoutStyle == VCL_BUTTONBOX_CENTER);
|
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
for (const Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
|
2011-11-17 11:46:16 +00:00
|
|
|
{
|
|
|
|
if (!pChild->IsVisible())
|
|
|
|
continue;
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aChildSize = getLayoutRequisition(*pChild);
|
2013-01-01 15:13:42 +00:00
|
|
|
if (bIgnoreSecondaryPacking || !pChild->get_secondary())
|
2012-10-24 10:30:28 +01:00
|
|
|
{
|
|
|
|
++aReq.m_nMainGroupChildren;
|
|
|
|
accumulateMaxes(aChildSize, aMainGroupSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++aReq.m_nSubGroupChildren;
|
|
|
|
accumulateMaxes(aChildSize, aSubGroupSize);
|
|
|
|
}
|
2011-11-17 11:46:16 +00:00
|
|
|
}
|
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
if (aReq.m_nMainGroupChildren)
|
|
|
|
aReq.m_aMainGroupSize = aMainGroupSize;
|
|
|
|
if (aReq.m_nSubGroupChildren)
|
|
|
|
aReq.m_aSubGroupSize = aSubGroupSize;
|
2012-06-01 10:26:18 +01:00
|
|
|
|
2012-10-22 10:27:50 +01:00
|
|
|
return aReq;
|
|
|
|
}
|
|
|
|
|
|
|
|
Size VclButtonBox::calculateRequisition() const
|
|
|
|
{
|
2012-10-24 10:30:28 +01:00
|
|
|
Requisition aReq(calculatePrimarySecondaryRequisitions());
|
|
|
|
sal_uInt16 nVisibleChildren = aReq.m_nMainGroupChildren + aReq.m_nSubGroupChildren;
|
|
|
|
return finalizeMaxes(addReqGroups(aReq), nVisibleChildren);
|
2011-11-17 11:46:16 +00:00
|
|
|
}
|
|
|
|
|
2012-06-06 10:46:49 +01:00
|
|
|
bool VclButtonBox::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("layout-style")))
|
|
|
|
{
|
|
|
|
VclButtonBoxStyle eStyle = VCL_BUTTONBOX_DEFAULT_STYLE;
|
|
|
|
if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("start")))
|
|
|
|
eStyle = VCL_BUTTONBOX_START;
|
|
|
|
else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("spread")))
|
|
|
|
eStyle = VCL_BUTTONBOX_SPREAD;
|
|
|
|
else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("edge")))
|
|
|
|
eStyle = VCL_BUTTONBOX_EDGE;
|
|
|
|
else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("start")))
|
|
|
|
eStyle = VCL_BUTTONBOX_START;
|
|
|
|
else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("end")))
|
|
|
|
eStyle = VCL_BUTTONBOX_END;
|
|
|
|
else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("center")))
|
|
|
|
eStyle = VCL_BUTTONBOX_CENTER;
|
|
|
|
else
|
2012-09-25 12:45:16 +01:00
|
|
|
{
|
|
|
|
SAL_WARN("vcl.layout", "unknown layout style " << rValue.getStr());
|
|
|
|
}
|
2012-06-06 10:46:49 +01:00
|
|
|
set_layout(eStyle);
|
|
|
|
}
|
2012-10-24 10:30:28 +01:00
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("homogeneous")))
|
|
|
|
m_bHomogeneousGroups = toBool(rValue);
|
2012-06-06 10:46:49 +01:00
|
|
|
else
|
|
|
|
return VclBox::set_property(rKey, rValue);
|
|
|
|
return true;
|
|
|
|
}
|
2011-11-17 11:46:16 +00:00
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
void VclButtonBox::setAllocation(const Size &rAllocation)
|
2011-11-15 16:38:47 +00:00
|
|
|
{
|
2012-10-22 10:27:50 +01:00
|
|
|
Requisition aReq(calculatePrimarySecondaryRequisitions());
|
2011-11-15 16:38:47 +00:00
|
|
|
|
2012-10-24 10:30:28 +01:00
|
|
|
sal_uInt16 nVisibleChildren = aReq.m_nMainGroupChildren + aReq.m_nSubGroupChildren;
|
2011-11-15 16:38:47 +00:00
|
|
|
if (!nVisibleChildren)
|
|
|
|
return;
|
|
|
|
|
|
|
|
long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
|
2012-10-24 10:30:28 +01:00
|
|
|
|
|
|
|
long nMainGroupPrimaryDimension = getPrimaryDimension(aReq.m_aMainGroupSize);
|
|
|
|
long nSubGroupPrimaryDimension = getPrimaryDimension(aReq.m_aSubGroupSize);
|
|
|
|
if (m_bHomogeneousGroups)
|
|
|
|
nSubGroupPrimaryDimension = nMainGroupPrimaryDimension = std::max(nSubGroupPrimaryDimension, nMainGroupPrimaryDimension);
|
2011-11-15 16:38:47 +00:00
|
|
|
|
2012-10-22 10:27:50 +01:00
|
|
|
Point aMainGroupPos, aOtherGroupPos;
|
2013-01-01 15:13:42 +00:00
|
|
|
int nSpacing = m_nSpacing;
|
2012-06-06 10:46:49 +01:00
|
|
|
|
|
|
|
//To-Do, other layout styles
|
|
|
|
switch (m_eLayoutStyle)
|
|
|
|
{
|
|
|
|
case VCL_BUTTONBOX_START:
|
2012-10-24 10:30:28 +01:00
|
|
|
if (aReq.m_nSubGroupChildren)
|
2012-10-22 10:27:50 +01:00
|
|
|
{
|
2012-10-24 10:30:28 +01:00
|
|
|
long nOtherPrimaryDimension = getPrimaryDimension(
|
|
|
|
finalizeMaxes(aReq.m_aSubGroupSize, aReq.m_nSubGroupChildren));
|
2012-10-22 10:27:50 +01:00
|
|
|
setPrimaryCoordinate(aOtherGroupPos,
|
|
|
|
nAllocPrimaryDimension - nOtherPrimaryDimension);
|
|
|
|
}
|
2012-06-06 10:46:49 +01:00
|
|
|
break;
|
2013-01-01 15:13:42 +00:00
|
|
|
case VCL_BUTTONBOX_SPREAD:
|
|
|
|
if (aReq.m_nMainGroupChildren)
|
|
|
|
{
|
|
|
|
long nMainPrimaryDimension = getPrimaryDimension(
|
|
|
|
finalizeMaxes(aReq.m_aMainGroupSize, aReq.m_nMainGroupChildren));
|
|
|
|
long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
|
|
|
|
nExtraSpace += (aReq.m_nMainGroupChildren-1) * nSpacing;
|
|
|
|
nSpacing = nExtraSpace/(aReq.m_nMainGroupChildren+1);
|
|
|
|
setPrimaryCoordinate(aMainGroupPos, nSpacing);
|
|
|
|
}
|
|
|
|
break;
|
2012-06-06 10:46:49 +01:00
|
|
|
default:
|
2012-09-25 12:45:16 +01:00
|
|
|
SAL_WARN("vcl.layout", "todo unimplemented layout style");
|
2012-06-06 10:46:49 +01:00
|
|
|
case VCL_BUTTONBOX_DEFAULT_STYLE:
|
|
|
|
case VCL_BUTTONBOX_END:
|
2012-10-24 10:30:28 +01:00
|
|
|
if (aReq.m_nMainGroupChildren)
|
2012-10-22 10:27:50 +01:00
|
|
|
{
|
2012-10-24 10:30:28 +01:00
|
|
|
long nMainPrimaryDimension = getPrimaryDimension(
|
|
|
|
finalizeMaxes(aReq.m_aMainGroupSize, aReq.m_nMainGroupChildren));
|
2012-10-22 10:27:50 +01:00
|
|
|
setPrimaryCoordinate(aMainGroupPos,
|
|
|
|
nAllocPrimaryDimension - nMainPrimaryDimension);
|
|
|
|
}
|
2012-06-06 10:46:49 +01:00
|
|
|
break;
|
|
|
|
}
|
2011-11-15 16:38:47 +00:00
|
|
|
|
2012-10-22 10:27:50 +01:00
|
|
|
Size aChildSize;
|
2012-10-24 10:30:28 +01:00
|
|
|
setSecondaryDimension(aChildSize, getSecondaryDimension(rAllocation));
|
2012-10-22 10:27:50 +01:00
|
|
|
|
2013-01-01 15:13:42 +00:00
|
|
|
bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VCL_BUTTONBOX_SPREAD || m_eLayoutStyle == VCL_BUTTONBOX_CENTER);
|
2012-04-16 15:14:42 +01:00
|
|
|
for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
|
2011-11-15 16:38:47 +00:00
|
|
|
{
|
|
|
|
if (!pChild->IsVisible())
|
|
|
|
continue;
|
|
|
|
|
2013-01-01 15:13:42 +00:00
|
|
|
if (bIgnoreSecondaryPacking || !pChild->get_secondary())
|
2012-10-22 10:27:50 +01:00
|
|
|
{
|
2012-10-24 10:30:28 +01:00
|
|
|
setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
|
2012-10-22 10:27:50 +01:00
|
|
|
setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
|
|
|
|
long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
|
2013-01-01 15:13:42 +00:00
|
|
|
setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + nSpacing);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
|
|
|
|
setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
|
|
|
|
long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
|
|
|
|
setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + nSpacing);
|
2012-10-22 10:27:50 +01:00
|
|
|
}
|
2011-11-15 16:38:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
VclGrid::array_type VclGrid::assembleGrid() const
|
2012-02-01 10:12:42 +00:00
|
|
|
{
|
2012-08-31 09:16:39 +01:00
|
|
|
ext_array_type A;
|
2012-02-01 10:12:42 +00:00
|
|
|
|
|
|
|
for (Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild;
|
|
|
|
pChild = pChild->GetWindow(WINDOW_NEXT))
|
|
|
|
{
|
2012-08-15 11:19:06 +01:00
|
|
|
sal_Int32 nLeftAttach = pChild->get_grid_left_attach();
|
|
|
|
sal_Int32 nWidth = pChild->get_grid_width();
|
2012-02-01 10:12:42 +00:00
|
|
|
sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
|
|
|
|
|
2012-08-15 11:19:06 +01:00
|
|
|
sal_Int32 nTopAttach = pChild->get_grid_top_attach();
|
|
|
|
sal_Int32 nHeight = pChild->get_grid_height();
|
2012-02-01 10:12:42 +00:00
|
|
|
sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
|
|
|
|
|
|
|
|
sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
|
|
|
|
sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
|
|
|
|
if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
|
|
|
|
{
|
|
|
|
nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
|
|
|
|
nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
|
|
|
|
A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
|
|
|
|
}
|
|
|
|
|
2012-08-31 09:16:39 +01:00
|
|
|
ExtendedGridEntry &rEntry = A[nLeftAttach][nTopAttach];
|
|
|
|
rEntry.pChild = pChild;
|
|
|
|
rEntry.nSpanWidth = nWidth;
|
|
|
|
rEntry.nSpanHeight = nHeight;
|
|
|
|
rEntry.x = nLeftAttach;
|
|
|
|
rEntry.y = nTopAttach;
|
2012-02-01 10:12:42 +00:00
|
|
|
|
2012-08-31 09:16:39 +01:00
|
|
|
for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
|
|
|
|
{
|
|
|
|
for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
|
|
|
|
{
|
|
|
|
ExtendedGridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
|
|
|
|
rSpan.x = nLeftAttach;
|
|
|
|
rSpan.y = nTopAttach;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-15 10:19:41 +01:00
|
|
|
|
|
|
|
//see if we have any empty rows/cols
|
|
|
|
sal_Int32 nMaxX = A.shape()[0];
|
|
|
|
sal_Int32 nMaxY = A.shape()[1];
|
|
|
|
|
|
|
|
std::vector<bool> aNonEmptyCols(nMaxX);
|
|
|
|
std::vector<bool> aNonEmptyRows(nMaxY);
|
|
|
|
|
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
{
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
{
|
2012-08-31 09:16:39 +01:00
|
|
|
const GridEntry &rEntry = A[x][y];
|
|
|
|
const Window *pChild = rEntry.pChild;
|
|
|
|
if (pChild && pChild->IsVisible())
|
2012-06-15 10:19:41 +01:00
|
|
|
{
|
2012-08-31 09:16:39 +01:00
|
|
|
aNonEmptyCols[x] = true;
|
|
|
|
aNonEmptyRows[y] = true;
|
2012-06-15 10:19:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-29 16:58:31 +00:00
|
|
|
//reduce the spans of elements that span empty columns
|
2012-08-31 09:16:39 +01:00
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
{
|
2012-12-29 16:58:31 +00:00
|
|
|
std::set<ExtendedGridEntry*> candidates;
|
2012-08-31 09:16:39 +01:00
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
{
|
2012-12-29 16:58:31 +00:00
|
|
|
if (aNonEmptyCols[x])
|
|
|
|
continue;
|
2012-08-31 09:16:39 +01:00
|
|
|
ExtendedGridEntry &rSpan = A[x][y];
|
2012-10-12 12:50:56 +01:00
|
|
|
//cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
|
|
|
|
//just points back to itself if there's no cell spanning
|
|
|
|
if ((rSpan.x == -1) || (rSpan.y == -1))
|
|
|
|
{
|
|
|
|
//there is no entry for this cell, i.e. this is a cell
|
|
|
|
//with no widget in it, or spanned by any other widget
|
|
|
|
continue;
|
|
|
|
}
|
2012-08-31 09:16:39 +01:00
|
|
|
ExtendedGridEntry &rEntry = A[rSpan.x][rSpan.y];
|
2012-12-29 16:58:31 +00:00
|
|
|
candidates.insert(&rEntry);
|
|
|
|
}
|
|
|
|
for (std::set<ExtendedGridEntry*>::iterator aI = candidates.begin(), aEnd = candidates.end();
|
|
|
|
aI != aEnd; ++aI)
|
|
|
|
{
|
|
|
|
ExtendedGridEntry *pEntry = *aI;
|
|
|
|
--pEntry->nSpanWidth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//reduce the spans of elements that span empty rows
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
{
|
|
|
|
std::set<ExtendedGridEntry*> candidates;
|
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
{
|
|
|
|
if (aNonEmptyRows[y])
|
|
|
|
continue;
|
|
|
|
ExtendedGridEntry &rSpan = A[x][y];
|
|
|
|
//cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
|
|
|
|
//just points back to itself if there's no cell spanning
|
|
|
|
if ((rSpan.x == -1) || (rSpan.y == -1))
|
|
|
|
{
|
|
|
|
//there is no entry for this cell, i.e. this is a cell
|
|
|
|
//with no widget in it, or spanned by any other widget
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ExtendedGridEntry &rEntry = A[rSpan.x][rSpan.y];
|
|
|
|
candidates.insert(&rEntry);
|
|
|
|
}
|
|
|
|
for (std::set<ExtendedGridEntry*>::iterator aI = candidates.begin(), aEnd = candidates.end();
|
|
|
|
aI != aEnd; ++aI)
|
|
|
|
{
|
|
|
|
ExtendedGridEntry *pEntry = *aI;
|
|
|
|
--pEntry->nSpanHeight;
|
2012-08-31 09:16:39 +01:00
|
|
|
}
|
|
|
|
}
|
2012-06-15 10:19:41 +01:00
|
|
|
|
2012-09-07 10:42:06 +01:00
|
|
|
sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
|
|
|
|
sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
|
|
|
|
|
2012-06-15 10:19:41 +01:00
|
|
|
//make new grid without empty rows and columns
|
|
|
|
array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
|
|
|
|
for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
|
|
|
|
{
|
|
|
|
if (aNonEmptyCols[x] == false)
|
|
|
|
continue;
|
|
|
|
for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
|
|
|
|
{
|
|
|
|
if (aNonEmptyRows[y] == false)
|
|
|
|
continue;
|
2012-08-31 09:16:39 +01:00
|
|
|
GridEntry &rEntry = A[x][y];
|
|
|
|
B[x2][y2++] = rEntry;
|
2012-06-15 10:19:41 +01:00
|
|
|
}
|
|
|
|
++x2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return B;
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
bool VclGrid::isNullGrid(const array_type &A) const
|
2012-02-01 10:12:42 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nMaxX = A.shape()[0];
|
|
|
|
sal_Int32 nMaxY = A.shape()[1];
|
|
|
|
|
|
|
|
if (!nMaxX || !nMaxY)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
void VclGrid::calcMaxs(const array_type &A, std::vector<Value> &rWidths, std::vector<Value> &rHeights) const
|
2012-02-01 10:12:42 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nMaxX = A.shape()[0];
|
|
|
|
sal_Int32 nMaxY = A.shape()[1];
|
|
|
|
|
|
|
|
rWidths.resize(nMaxX);
|
|
|
|
rHeights.resize(nMaxY);
|
|
|
|
|
2012-10-03 11:04:55 +01:00
|
|
|
//first use the non spanning entries to set default width/heights
|
2012-02-01 10:12:42 +00:00
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
{
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
{
|
2012-08-31 09:16:39 +01:00
|
|
|
const GridEntry &rEntry = A[x][y];
|
|
|
|
const Window *pChild = rEntry.pChild;
|
2012-12-29 16:58:31 +00:00
|
|
|
if (!pChild || !pChild->IsVisible())
|
2012-02-01 10:12:42 +00:00
|
|
|
continue;
|
2012-02-01 10:49:43 +00:00
|
|
|
|
2012-08-31 09:16:39 +01:00
|
|
|
sal_Int32 nWidth = rEntry.nSpanWidth;
|
2012-10-03 11:04:55 +01:00
|
|
|
sal_Int32 nHeight = rEntry.nSpanHeight;
|
|
|
|
|
2012-02-01 10:49:43 +00:00
|
|
|
for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
|
2012-08-16 17:19:22 +01:00
|
|
|
rWidths[x+nSpanX].m_bExpand = rWidths[x+nSpanX].m_bExpand | pChild->get_hexpand();
|
2012-10-03 11:04:55 +01:00
|
|
|
|
|
|
|
for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
|
|
|
|
rHeights[y+nSpanY].m_bExpand = rHeights[y+nSpanY].m_bExpand | pChild->get_vexpand();
|
|
|
|
|
|
|
|
if (nWidth == 1 || nHeight == 1)
|
|
|
|
{
|
|
|
|
Size aChildSize = getLayoutRequisition(*pChild);
|
|
|
|
if (nWidth == 1)
|
|
|
|
rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
|
|
|
|
if (nHeight == 1)
|
|
|
|
rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
|
2012-08-16 17:19:22 +01:00
|
|
|
}
|
2012-10-03 11:04:55 +01:00
|
|
|
}
|
|
|
|
}
|
2012-02-01 10:49:43 +00:00
|
|
|
|
2012-10-03 11:04:55 +01:00
|
|
|
//now use the spanning entries and split any extra sizes across expanding rows/cols
|
|
|
|
//where possible
|
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
{
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
{
|
|
|
|
const GridEntry &rEntry = A[x][y];
|
|
|
|
const Window *pChild = rEntry.pChild;
|
2012-12-29 16:58:31 +00:00
|
|
|
if (!pChild || !pChild->IsVisible())
|
2012-10-03 11:04:55 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
sal_Int32 nWidth = rEntry.nSpanWidth;
|
2012-08-31 09:16:39 +01:00
|
|
|
sal_Int32 nHeight = rEntry.nSpanHeight;
|
2012-10-03 11:04:55 +01:00
|
|
|
|
|
|
|
if (nWidth == 1 && nHeight == 1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Size aChildSize = getLayoutRequisition(*pChild);
|
|
|
|
|
|
|
|
if (nWidth > 1)
|
2012-08-16 17:19:22 +01:00
|
|
|
{
|
2012-10-03 11:04:55 +01:00
|
|
|
sal_Int32 nExistingWidth = 0;
|
|
|
|
for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
|
|
|
|
nExistingWidth += rWidths[x+nSpanX].m_nValue;
|
|
|
|
|
|
|
|
sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
|
|
|
|
|
|
|
|
if (nExtraWidth > 0)
|
|
|
|
{
|
|
|
|
bool bForceExpandAll = false;
|
|
|
|
sal_Int32 nExpandables = 0;
|
|
|
|
for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
|
|
|
|
if (rWidths[x+nSpanX].m_bExpand)
|
|
|
|
++nExpandables;
|
|
|
|
if (nExpandables == 0)
|
|
|
|
{
|
|
|
|
nExpandables = nWidth;
|
|
|
|
bForceExpandAll = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
|
|
|
|
{
|
|
|
|
if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
|
|
|
|
rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nHeight > 1)
|
|
|
|
{
|
|
|
|
sal_Int32 nExistingHeight = 0;
|
|
|
|
for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
|
|
|
|
nExistingHeight += rHeights[y+nSpanY].m_nValue;
|
|
|
|
|
|
|
|
sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
|
|
|
|
|
|
|
|
if (nExtraHeight > 0)
|
|
|
|
{
|
|
|
|
bool bForceExpandAll = false;
|
|
|
|
sal_Int32 nExpandables = 0;
|
|
|
|
for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
|
2012-11-22 11:33:51 +00:00
|
|
|
if (rHeights[y+nSpanY].m_bExpand)
|
2012-10-03 11:04:55 +01:00
|
|
|
++nExpandables;
|
|
|
|
if (nExpandables == 0)
|
|
|
|
{
|
|
|
|
nExpandables = nHeight;
|
|
|
|
bForceExpandAll = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
|
|
|
|
{
|
|
|
|
if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
|
|
|
|
rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
|
|
|
|
}
|
|
|
|
}
|
2012-08-16 17:19:22 +01:00
|
|
|
}
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
|
|
|
|
{
|
|
|
|
return i.m_nValue < j.m_nValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
|
|
|
|
{
|
|
|
|
VclGrid::Value aRet;
|
|
|
|
aRet.m_nValue = i.m_nValue + j.m_nValue;
|
|
|
|
aRet.m_bExpand = i.m_bExpand | j.m_bExpand;
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
Size VclGrid::calculateRequisition() const
|
2012-02-01 10:12:42 +00:00
|
|
|
{
|
|
|
|
array_type A = assembleGrid();
|
|
|
|
|
|
|
|
if (isNullGrid(A))
|
|
|
|
return Size();
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
std::vector<Value> aWidths;
|
|
|
|
std::vector<Value> aHeights;
|
2012-02-01 10:12:42 +00:00
|
|
|
calcMaxs(A, aWidths, aHeights);
|
|
|
|
|
|
|
|
long nTotalWidth = 0;
|
|
|
|
if (get_column_homogeneous())
|
|
|
|
{
|
2012-08-16 17:19:22 +01:00
|
|
|
nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
|
2012-02-01 10:12:42 +00:00
|
|
|
nTotalWidth *= aWidths.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-08-16 17:19:22 +01:00
|
|
|
nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nTotalWidth += get_column_spacing() * (aWidths.size()-1);
|
|
|
|
|
|
|
|
long nTotalHeight = 0;
|
|
|
|
if (get_row_homogeneous())
|
|
|
|
{
|
2012-08-16 17:19:22 +01:00
|
|
|
nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
|
2012-02-01 10:12:42 +00:00
|
|
|
nTotalHeight *= aHeights.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-08-16 17:19:22 +01:00
|
|
|
nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nTotalHeight += get_row_spacing() * (aHeights.size()-1);
|
|
|
|
|
|
|
|
return Size(nTotalWidth, nTotalHeight);
|
|
|
|
}
|
|
|
|
|
2012-03-21 11:26:30 +00:00
|
|
|
void VclGrid::setAllocation(const Size& rAllocation)
|
2012-02-01 10:12:42 +00:00
|
|
|
{
|
|
|
|
array_type A = assembleGrid();
|
|
|
|
|
|
|
|
if (isNullGrid(A))
|
|
|
|
return;
|
|
|
|
|
|
|
|
sal_Int32 nMaxX = A.shape()[0];
|
|
|
|
sal_Int32 nMaxY = A.shape()[1];
|
|
|
|
|
|
|
|
Size aRequisition;
|
2012-08-16 17:19:22 +01:00
|
|
|
std::vector<Value> aWidths(nMaxX);
|
|
|
|
std::vector<Value> aHeights(nMaxY);
|
2012-02-01 10:12:42 +00:00
|
|
|
if (!get_column_homogeneous() || !get_row_homogeneous())
|
|
|
|
{
|
|
|
|
aRequisition = calculateRequisition();
|
|
|
|
calcMaxs(A, aWidths, aHeights);
|
|
|
|
}
|
|
|
|
|
|
|
|
long nAvailableWidth = rAllocation.Width() - (get_column_spacing() * nMaxX);
|
|
|
|
if (get_column_homogeneous())
|
|
|
|
{
|
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
2012-08-16 17:19:22 +01:00
|
|
|
aWidths[x].m_nValue = nAvailableWidth/nMaxX;
|
|
|
|
}
|
2012-11-13 09:44:35 +00:00
|
|
|
else if (rAllocation.Width() != aRequisition.Width())
|
2012-08-16 17:19:22 +01:00
|
|
|
{
|
2012-11-13 09:44:35 +00:00
|
|
|
sal_Int32 nExpandables = 0;
|
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
if (aWidths[x].m_bExpand)
|
|
|
|
++nExpandables;
|
|
|
|
long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
if (rAllocation.Width() < aRequisition.Width())
|
|
|
|
{
|
2012-11-13 09:44:35 +00:00
|
|
|
long nExtraWidth = (rAllocation.Width() - aRequisition.Width() - nExtraWidthForExpanders * nExpandables) / nMaxX;
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
2012-11-13 09:44:35 +00:00
|
|
|
aWidths[x].m_nValue += nExtraWidth;
|
2012-08-16 17:19:22 +01:00
|
|
|
}
|
2012-11-13 09:44:35 +00:00
|
|
|
|
|
|
|
if (nExtraWidthForExpanders)
|
2012-08-16 17:19:22 +01:00
|
|
|
{
|
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
if (aWidths[x].m_bExpand)
|
2012-11-13 09:44:35 +00:00
|
|
|
aWidths[x].m_nValue += nExtraWidthForExpanders;
|
2012-08-16 17:19:22 +01:00
|
|
|
}
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
long nAvailableHeight = rAllocation.Height() - (get_row_spacing() * nMaxY);
|
|
|
|
if (get_row_homogeneous())
|
|
|
|
{
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
2012-08-16 17:19:22 +01:00
|
|
|
aHeights[y].m_nValue = nAvailableHeight/nMaxY;
|
|
|
|
}
|
2012-11-13 09:44:35 +00:00
|
|
|
else if (rAllocation.Height() != aRequisition.Height())
|
2012-08-16 17:19:22 +01:00
|
|
|
{
|
2012-11-13 09:44:35 +00:00
|
|
|
sal_Int32 nExpandables = 0;
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
if (aHeights[y].m_bExpand)
|
|
|
|
++nExpandables;
|
|
|
|
long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
if (rAllocation.Height() < aRequisition.Height())
|
|
|
|
{
|
2012-11-13 09:44:35 +00:00
|
|
|
long nExtraHeight = (rAllocation.Height() - aRequisition.Height() - nExtraHeightForExpanders * nExpandables) / nMaxY;
|
|
|
|
|
2012-08-16 17:19:22 +01:00
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
2012-11-13 09:44:35 +00:00
|
|
|
aHeights[y].m_nValue += nExtraHeight;
|
2012-08-16 17:19:22 +01:00
|
|
|
}
|
2012-11-13 09:44:35 +00:00
|
|
|
|
|
|
|
if (nExtraHeightForExpanders)
|
2012-08-16 17:19:22 +01:00
|
|
|
{
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
if (aHeights[y].m_bExpand)
|
2012-11-13 09:44:35 +00:00
|
|
|
aHeights[y].m_nValue += nExtraHeightForExpanders;
|
2012-08-16 17:19:22 +01:00
|
|
|
}
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
2012-02-01 10:49:43 +00:00
|
|
|
|
2012-06-11 12:48:24 +01:00
|
|
|
Point aAllocPos(0, 0);
|
2012-02-01 10:12:42 +00:00
|
|
|
for (sal_Int32 x = 0; x < nMaxX; ++x)
|
|
|
|
{
|
|
|
|
for (sal_Int32 y = 0; y < nMaxY; ++y)
|
|
|
|
{
|
2012-08-31 09:16:39 +01:00
|
|
|
GridEntry &rEntry = A[x][y];
|
|
|
|
Window *pChild = rEntry.pChild;
|
2012-02-01 10:12:42 +00:00
|
|
|
if (pChild)
|
2012-02-01 10:49:43 +00:00
|
|
|
{
|
2012-06-11 12:48:24 +01:00
|
|
|
Size aChildAlloc(0, 0);
|
2012-06-07 16:54:09 +01:00
|
|
|
|
2012-08-31 09:16:39 +01:00
|
|
|
sal_Int32 nWidth = rEntry.nSpanWidth;
|
2012-06-07 16:54:09 +01:00
|
|
|
for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
|
2012-08-16 17:19:22 +01:00
|
|
|
aChildAlloc.Width() += aWidths[x+nSpanX].m_nValue;
|
2012-06-11 12:48:24 +01:00
|
|
|
aChildAlloc.Width() += get_column_spacing()*(nWidth-1);
|
2012-06-07 16:54:09 +01:00
|
|
|
|
2012-08-31 09:16:39 +01:00
|
|
|
sal_Int32 nHeight = rEntry.nSpanHeight;
|
2012-06-07 16:54:09 +01:00
|
|
|
for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
|
2012-08-16 17:19:22 +01:00
|
|
|
aChildAlloc.Height() += aHeights[y+nSpanY].m_nValue;
|
2012-06-11 12:48:24 +01:00
|
|
|
aChildAlloc.Height() += get_row_spacing()*(nHeight-1);
|
|
|
|
|
2012-11-15 20:04:42 +00:00
|
|
|
setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
|
2012-02-01 10:49:43 +00:00
|
|
|
}
|
2012-08-16 17:19:22 +01:00
|
|
|
aAllocPos.Y() += aHeights[y].m_nValue + get_row_spacing();
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
2012-08-16 17:19:22 +01:00
|
|
|
aAllocPos.X() += aWidths[x].m_nValue + get_column_spacing();
|
2012-06-11 12:48:24 +01:00
|
|
|
aAllocPos.Y() = 0;
|
2012-02-01 10:12:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-16 11:05:57 +01:00
|
|
|
bool toBool(const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
return (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1');
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VclGrid::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("row-spacing")))
|
|
|
|
set_row_spacing(rValue.toInt32());
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("column-spacing")))
|
2012-06-07 15:51:23 +01:00
|
|
|
set_column_spacing(rValue.toInt32());
|
2012-04-16 11:05:57 +01:00
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("row-homogeneous")))
|
|
|
|
set_row_homogeneous(toBool(rValue));
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("column-homogeneous")))
|
|
|
|
set_column_homogeneous(toBool(rValue));
|
2012-04-30 09:53:09 +01:00
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("n-rows")))
|
|
|
|
/*nothing to do*/;
|
2012-04-16 11:05:57 +01:00
|
|
|
else
|
2012-06-06 10:46:49 +01:00
|
|
|
return VclContainer::set_property(rKey, rValue);
|
2012-04-16 11:05:57 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-02-06 19:30:22 +00:00
|
|
|
void setGridAttach(Window &rWidget, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nWidth, sal_Int32 nHeight)
|
|
|
|
{
|
2012-08-15 11:19:06 +01:00
|
|
|
rWidget.set_grid_left_attach(nLeft);
|
|
|
|
rWidget.set_grid_top_attach(nTop);
|
|
|
|
rWidget.set_grid_width(nWidth);
|
|
|
|
rWidget.set_grid_height(nHeight);
|
2012-02-06 19:30:22 +00:00
|
|
|
}
|
|
|
|
|
2012-04-16 10:12:57 +01:00
|
|
|
const Window *VclBin::get_child() const
|
|
|
|
{
|
|
|
|
const WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
|
2012-05-18 15:54:03 +01:00
|
|
|
return pWindowImpl->mpFirstChild;
|
2012-04-16 10:12:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Window *VclBin::get_child()
|
|
|
|
{
|
|
|
|
return const_cast<Window*>(const_cast<const VclBin*>(this)->get_child());
|
|
|
|
}
|
|
|
|
|
2012-06-07 15:11:02 +01:00
|
|
|
Size VclBin::calculateRequisition() const
|
|
|
|
{
|
|
|
|
const Window *pChild = get_child();
|
|
|
|
if (pChild && pChild->IsVisible())
|
2012-08-24 13:40:42 +01:00
|
|
|
return getLayoutRequisition(*pChild);
|
2012-06-07 15:11:02 +01:00
|
|
|
return Size(0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VclBin::setAllocation(const Size &rAllocation)
|
|
|
|
{
|
|
|
|
Window *pChild = get_child();
|
|
|
|
if (pChild && pChild->IsVisible())
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
|
2012-06-07 15:11:02 +01:00
|
|
|
}
|
|
|
|
|
2012-04-11 11:41:54 +01:00
|
|
|
//To-Do, hook a DecorationView into VclFrame ?
|
|
|
|
|
|
|
|
Size VclFrame::calculateRequisition() const
|
|
|
|
{
|
|
|
|
Size aRet(0, 0);
|
|
|
|
|
|
|
|
WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
|
2012-04-16 10:12:57 +01:00
|
|
|
const Window *pChild = get_child();
|
2012-05-18 15:54:03 +01:00
|
|
|
const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
|
2012-04-11 11:41:54 +01:00
|
|
|
|
|
|
|
if (pChild && pChild->IsVisible())
|
2012-08-24 13:40:42 +01:00
|
|
|
aRet = getLayoutRequisition(*pChild);
|
2012-04-11 11:41:54 +01:00
|
|
|
|
|
|
|
if (pLabel && pLabel->IsVisible())
|
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aLabelSize = getLayoutRequisition(*pLabel);
|
2012-04-11 11:41:54 +01:00
|
|
|
aRet.Height() += aLabelSize.Height();
|
|
|
|
aRet.Width() = std::max(aLabelSize.Width(), aRet.Width());
|
|
|
|
}
|
|
|
|
|
2012-05-18 13:48:13 +01:00
|
|
|
const FrameStyle &rFrameStyle =
|
|
|
|
GetSettings().GetStyleSettings().GetFrameStyle();
|
|
|
|
aRet.Width() += rFrameStyle.left + rFrameStyle.right;
|
|
|
|
aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
|
|
|
|
|
2012-04-11 11:41:54 +01:00
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VclFrame::setAllocation(const Size &rAllocation)
|
|
|
|
{
|
2012-06-15 13:35:15 +01:00
|
|
|
//SetBackground( Color(0xFF, 0x00, 0xFF) );
|
|
|
|
|
2012-05-18 13:48:13 +01:00
|
|
|
const FrameStyle &rFrameStyle =
|
|
|
|
GetSettings().GetStyleSettings().GetFrameStyle();
|
|
|
|
Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
|
|
|
|
rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
|
|
|
|
Point aChildPos(rFrameStyle.left, rFrameStyle.top);
|
2012-04-11 11:41:54 +01:00
|
|
|
|
|
|
|
WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
|
|
|
|
//The label widget is the last (of two) children
|
2012-04-16 10:12:57 +01:00
|
|
|
Window *pChild = get_child();
|
2012-05-18 15:54:03 +01:00
|
|
|
Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
|
2012-04-11 11:41:54 +01:00
|
|
|
|
|
|
|
if (pLabel && pLabel->IsVisible())
|
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aLabelSize = getLayoutRequisition(*pLabel);
|
2012-04-11 11:41:54 +01:00
|
|
|
aLabelSize.Height() = std::min(aLabelSize.Height(), aAllocation.Height());
|
|
|
|
aLabelSize.Width() = std::min(aLabelSize.Width(), aAllocation.Width());
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
|
2012-04-11 11:41:54 +01:00
|
|
|
aAllocation.Height() -= aLabelSize.Height();
|
|
|
|
aChildPos.Y() += aLabelSize.Height();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pChild && pChild->IsVisible())
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pChild, aChildPos, aAllocation);
|
2012-04-11 11:41:54 +01:00
|
|
|
}
|
|
|
|
|
2012-10-11 17:31:07 +01:00
|
|
|
const Window *VclFrame::get_label_widget() const
|
|
|
|
{
|
|
|
|
//The label widget is the last (of two) children
|
|
|
|
const Window *pChild = get_child();
|
|
|
|
const WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
return pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Window *VclFrame::get_label_widget()
|
|
|
|
{
|
|
|
|
return const_cast<Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
|
|
|
|
}
|
|
|
|
|
2012-09-10 16:59:55 +01:00
|
|
|
void VclFrame::set_label(const rtl::OUString &rLabel)
|
|
|
|
{
|
|
|
|
//The label widget is the last (of two) children
|
2012-10-11 17:31:07 +01:00
|
|
|
Window *pLabel = get_label_widget();
|
2012-09-10 16:59:55 +01:00
|
|
|
assert(pLabel);
|
|
|
|
pLabel->SetText(rLabel);
|
|
|
|
}
|
|
|
|
|
2012-04-16 10:12:57 +01:00
|
|
|
Size VclAlignment::calculateRequisition() const
|
|
|
|
{
|
|
|
|
Size aRet(m_nLeftPadding + m_nRightPadding,
|
|
|
|
m_nTopPadding + m_nBottomPadding);
|
|
|
|
|
|
|
|
const Window *pChild = get_child();
|
|
|
|
if (pChild && pChild->IsVisible())
|
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aChildSize = getLayoutRequisition(*pChild);
|
2012-04-16 10:12:57 +01:00
|
|
|
aRet.Width() += aChildSize.Width();
|
|
|
|
aRet.Height() += aChildSize.Height();
|
|
|
|
}
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VclAlignment::setAllocation(const Size &rAllocation)
|
|
|
|
{
|
|
|
|
Window *pChild = get_child();
|
|
|
|
if (!pChild || !pChild->IsVisible())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Point aChildPos(m_nLeftPadding, m_nTopPadding);
|
|
|
|
|
|
|
|
Size aAllocation;
|
|
|
|
aAllocation.Width() = rAllocation.Width() - (m_nLeftPadding + m_nRightPadding);
|
|
|
|
aAllocation.Height() = rAllocation.Height() - (m_nTopPadding + m_nBottomPadding);
|
|
|
|
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pChild, aChildPos, aAllocation);
|
2012-04-16 10:12:57 +01:00
|
|
|
}
|
|
|
|
|
2012-04-16 10:50:23 +01:00
|
|
|
bool VclAlignment::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("bottom-padding")))
|
|
|
|
m_nBottomPadding = rValue.toInt32();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("left-padding")))
|
|
|
|
m_nLeftPadding = rValue.toInt32();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("right-padding")))
|
|
|
|
m_nRightPadding = rValue.toInt32();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("top-padding")))
|
|
|
|
m_nTopPadding = rValue.toInt32();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("xalign")))
|
|
|
|
m_fXAlign = rValue.toFloat();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("xscale")))
|
|
|
|
m_fXScale = rValue.toFloat();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("yalign")))
|
|
|
|
m_fYAlign = rValue.toFloat();
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("yscale")))
|
|
|
|
m_fYScale = rValue.toFloat();
|
|
|
|
else
|
2012-06-06 10:46:49 +01:00
|
|
|
return VclBin::set_property(rKey, rValue);
|
2012-04-16 10:50:23 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-08-23 11:54:40 +01:00
|
|
|
const Window *VclExpander::get_child() const
|
|
|
|
{
|
|
|
|
const WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
|
|
|
|
assert(pWindowImpl->mpFirstChild == &m_aDisclosureButton);
|
|
|
|
|
|
|
|
return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
|
|
|
|
}
|
|
|
|
|
|
|
|
Window *VclExpander::get_child()
|
|
|
|
{
|
|
|
|
return const_cast<Window*>(const_cast<const VclExpander*>(this)->get_child());
|
|
|
|
}
|
|
|
|
|
|
|
|
Size VclExpander::calculateRequisition() const
|
|
|
|
{
|
|
|
|
Size aRet(0, 0);
|
|
|
|
|
|
|
|
WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
|
|
|
|
const Window *pChild = get_child();
|
|
|
|
const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
|
|
|
|
|
|
|
|
if (pChild && pChild->IsVisible() && m_aDisclosureButton.IsChecked())
|
2012-08-24 13:40:42 +01:00
|
|
|
aRet = getLayoutRequisition(*pChild);
|
2012-08-23 11:54:40 +01:00
|
|
|
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aExpanderSize = getLayoutRequisition(m_aDisclosureButton);
|
2012-08-23 11:54:40 +01:00
|
|
|
|
|
|
|
if (pLabel && pLabel->IsVisible())
|
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aLabelSize = getLayoutRequisition(*pLabel);
|
2012-08-23 11:54:40 +01:00
|
|
|
aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
|
|
|
|
aExpanderSize.Width() += aLabelSize.Width();
|
|
|
|
}
|
|
|
|
|
|
|
|
aRet.Height() += aExpanderSize.Height();
|
|
|
|
aRet.Width() = std::max(aExpanderSize.Width(), aRet.Width());
|
|
|
|
|
|
|
|
const FrameStyle &rFrameStyle =
|
|
|
|
GetSettings().GetStyleSettings().GetFrameStyle();
|
|
|
|
aRet.Width() += rFrameStyle.left + rFrameStyle.right;
|
|
|
|
aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VclExpander::setAllocation(const Size &rAllocation)
|
|
|
|
{
|
|
|
|
const FrameStyle &rFrameStyle =
|
|
|
|
GetSettings().GetStyleSettings().GetFrameStyle();
|
|
|
|
Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
|
|
|
|
rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
|
|
|
|
Point aChildPos(rFrameStyle.left, rFrameStyle.top);
|
|
|
|
|
|
|
|
WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
|
|
|
|
//The label widget is the last (of two) children
|
|
|
|
Window *pChild = get_child();
|
|
|
|
Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
|
|
|
|
|
2012-08-24 13:40:42 +01:00
|
|
|
Size aButtonSize = getLayoutRequisition(m_aDisclosureButton);
|
2012-08-23 11:54:40 +01:00
|
|
|
Size aLabelSize;
|
|
|
|
Size aExpanderSize = aButtonSize;
|
|
|
|
if (pLabel && pLabel->IsVisible())
|
|
|
|
{
|
2012-08-24 13:40:42 +01:00
|
|
|
aLabelSize = getLayoutRequisition(*pLabel);
|
2012-08-23 11:54:40 +01:00
|
|
|
aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
|
|
|
|
aExpanderSize.Width() += aLabelSize.Width();
|
|
|
|
}
|
|
|
|
|
|
|
|
aExpanderSize.Height() = std::min(aExpanderSize.Height(), aAllocation.Height());
|
|
|
|
aExpanderSize.Width() = std::min(aExpanderSize.Width(), aAllocation.Width());
|
|
|
|
|
|
|
|
aButtonSize.Height() = std::min(aButtonSize.Height(), aExpanderSize.Height());
|
|
|
|
aButtonSize.Width() = std::min(aButtonSize.Width(), aExpanderSize.Width());
|
|
|
|
|
|
|
|
long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
|
|
|
|
Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(m_aDisclosureButton, aButtonPos, aButtonSize);
|
2012-08-23 11:54:40 +01:00
|
|
|
|
|
|
|
if (pLabel && pLabel->IsVisible())
|
|
|
|
{
|
|
|
|
aLabelSize.Height() = std::min(aLabelSize.Height(), aExpanderSize.Height());
|
|
|
|
aLabelSize.Width() = std::min(aLabelSize.Width(),
|
|
|
|
aExpanderSize.Width() - aButtonSize.Width());
|
|
|
|
|
|
|
|
long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
|
|
|
|
Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
|
2012-08-23 11:54:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
aAllocation.Height() -= aExpanderSize.Height();
|
|
|
|
aChildPos.Y() += aExpanderSize.Height();
|
|
|
|
|
|
|
|
if (pChild && pChild->IsVisible())
|
|
|
|
{
|
|
|
|
if (!m_aDisclosureButton.IsChecked())
|
|
|
|
aAllocation = Size();
|
2012-08-24 13:40:42 +01:00
|
|
|
setLayoutAllocation(*pChild, aChildPos, aAllocation);
|
2012-08-23 11:54:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VclExpander::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("expanded")))
|
|
|
|
m_aDisclosureButton.Check(toBool(rValue));
|
|
|
|
else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("resize-toplevel")))
|
|
|
|
m_bResizeTopLevel = toBool(rValue);
|
|
|
|
else
|
|
|
|
return VclBin::set_property(rKey, rValue);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK( VclExpander, ClickHdl, DisclosureButton*, pBtn )
|
|
|
|
{
|
|
|
|
Window *pChild = get_child();
|
|
|
|
if (pChild)
|
|
|
|
{
|
|
|
|
pChild->Show(pBtn->IsChecked());
|
2012-08-23 15:18:14 +01:00
|
|
|
queue_resize();
|
2012-08-23 11:54:40 +01:00
|
|
|
Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : NULL;
|
|
|
|
if (pResizeDialog)
|
|
|
|
pResizeDialog->setInitialLayoutSize();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-04 15:28:48 +00:00
|
|
|
const Window *VclScrolledWindow::get_child() const
|
|
|
|
{
|
|
|
|
assert(GetChildCount() == 3);
|
|
|
|
const WindowImpl* pWindowImpl = ImplGetWindowImpl();
|
|
|
|
return pWindowImpl->mpLastChild;
|
|
|
|
}
|
|
|
|
|
|
|
|
Window *VclScrolledWindow::get_child()
|
|
|
|
{
|
|
|
|
return const_cast<Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
|
|
|
|
}
|
|
|
|
|
|
|
|
Size VclScrolledWindow::calculateRequisition() const
|
|
|
|
{
|
|
|
|
Size aRet(0, 0);
|
|
|
|
|
|
|
|
const Window *pChild = get_child();
|
|
|
|
if (pChild && pChild->IsVisible())
|
|
|
|
aRet = getLayoutRequisition(*pChild);
|
|
|
|
|
|
|
|
if (m_aVScroll.IsVisible())
|
|
|
|
aRet.Width() += getLayoutRequisition(m_aVScroll).Width();
|
|
|
|
|
|
|
|
if (m_aHScroll.IsVisible())
|
|
|
|
aRet.Height() += getLayoutRequisition(m_aVScroll).Height();
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VclScrolledWindow::setAllocation(const Size &rAllocation)
|
|
|
|
{
|
|
|
|
Size aChildAllocation(rAllocation);
|
|
|
|
Size aChildReq;
|
|
|
|
|
|
|
|
Window *pChild = get_child();
|
|
|
|
if (pChild && pChild->IsVisible())
|
|
|
|
aChildReq = getLayoutRequisition(*pChild);
|
|
|
|
|
|
|
|
if (m_aVScroll.IsVisible())
|
|
|
|
{
|
|
|
|
long nScrollBarWidth = getLayoutRequisition(m_aVScroll).Width();
|
|
|
|
Point aScrollPos(rAllocation.Width() - nScrollBarWidth, 0);
|
|
|
|
Size aScrollSize(nScrollBarWidth, rAllocation.Height());
|
|
|
|
setLayoutAllocation(m_aVScroll, aScrollPos, aScrollSize);
|
|
|
|
aChildAllocation.Width() -= nScrollBarWidth;
|
|
|
|
aChildAllocation.Height() = aChildReq.Height();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_aHScroll.IsVisible())
|
|
|
|
{
|
|
|
|
long nScrollBarHeight = getLayoutRequisition(m_aHScroll).Height();
|
|
|
|
Point aScrollPos(0, rAllocation.Height() - nScrollBarHeight);
|
|
|
|
Size aScrollSize(rAllocation.Width(), nScrollBarHeight);
|
|
|
|
setLayoutAllocation(m_aHScroll, aScrollPos, aScrollSize);
|
|
|
|
aChildAllocation.Height() -= nScrollBarHeight;
|
|
|
|
aChildAllocation.Width() = aChildReq.Width();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pChild && pChild->IsVisible())
|
|
|
|
{
|
|
|
|
Point aChildPos(pChild->GetPosPixel());
|
|
|
|
if (!m_aHScroll.IsVisible())
|
|
|
|
aChildPos.X() = 0;
|
|
|
|
if (!m_aVScroll.IsVisible())
|
|
|
|
aChildPos.Y() = 0;
|
|
|
|
setLayoutAllocation(*pChild, aChildPos, aChildAllocation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Size VclScrolledWindow::getVisibleChildSize() const
|
|
|
|
{
|
|
|
|
Size aRet(GetSizePixel());
|
|
|
|
if (m_aVScroll.IsVisible())
|
|
|
|
aRet.Width() -= m_aVScroll.GetSizePixel().Width();
|
|
|
|
if (m_aHScroll.IsVisible())
|
|
|
|
aRet.Height() -= m_aHScroll.GetSizePixel().Height();
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VclScrolledWindow::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
|
|
|
|
{
|
|
|
|
bool bRet = VclBin::set_property(rKey, rValue);
|
|
|
|
m_aVScroll.Show(GetStyle() & WB_VERT);
|
|
|
|
m_aHScroll.Show(GetStyle() & WB_HORZ);
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
2011-12-01 11:49:36 +00:00
|
|
|
Size getLegacyBestSizeForChildren(const Window &rWindow)
|
|
|
|
{
|
|
|
|
Rectangle aBounds;
|
|
|
|
|
2012-04-16 10:12:57 +01:00
|
|
|
for (const Window* pChild = rWindow.GetWindow(WINDOW_FIRSTCHILD); pChild;
|
2011-12-01 11:49:36 +00:00
|
|
|
pChild = pChild->GetWindow(WINDOW_NEXT))
|
|
|
|
{
|
|
|
|
if (!pChild->IsVisible())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
|
|
|
|
aBounds.Union(aChildBounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aBounds.IsEmpty())
|
|
|
|
return rWindow.GetSizePixel();
|
|
|
|
|
|
|
|
Size aRet(aBounds.GetSize());
|
|
|
|
Point aTopLeft(aBounds.TopLeft());
|
|
|
|
aRet.Width() += aTopLeft.X()*2;
|
|
|
|
aRet.Height() += aTopLeft.Y()*2;
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
2011-11-15 16:38:47 +00:00
|
|
|
|
2012-09-25 20:37:53 +01:00
|
|
|
Window* getNonLayoutParent(Window *pWindow)
|
2012-03-21 11:26:30 +00:00
|
|
|
{
|
2012-09-26 00:11:12 +01:00
|
|
|
while (pWindow)
|
|
|
|
{
|
2012-09-25 20:37:53 +01:00
|
|
|
pWindow = pWindow->GetParent();
|
2012-12-04 15:28:48 +00:00
|
|
|
if (!pWindow || !isContainerWindow(*pWindow))
|
2012-09-26 00:11:12 +01:00
|
|
|
break;
|
|
|
|
}
|
2012-09-25 20:37:53 +01:00
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
Window* getNonLayoutRealParent(Window *pWindow)
|
|
|
|
{
|
2012-09-26 00:11:12 +01:00
|
|
|
while (pWindow)
|
|
|
|
{
|
2012-09-25 20:37:53 +01:00
|
|
|
pWindow = pWindow->ImplGetParent();
|
2012-12-04 15:28:48 +00:00
|
|
|
if (!pWindow || !isContainerWindow(*pWindow))
|
2012-09-26 00:11:12 +01:00
|
|
|
break;
|
|
|
|
}
|
2012-09-25 20:37:53 +01:00
|
|
|
return pWindow;
|
2012-03-21 11:26:30 +00:00
|
|
|
}
|
|
|
|
|
2012-09-26 21:35:55 +01:00
|
|
|
bool isVisibleInLayout(const Window *pWindow)
|
|
|
|
{
|
|
|
|
bool bVisible = true;
|
|
|
|
while (bVisible)
|
|
|
|
{
|
|
|
|
bVisible = pWindow->IsVisible();
|
|
|
|
pWindow = pWindow->GetParent();
|
2012-12-04 15:28:48 +00:00
|
|
|
if (!pWindow || !isContainerWindow(*pWindow))
|
2012-09-26 21:35:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return bVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isEnabledInLayout(const Window *pWindow)
|
|
|
|
{
|
|
|
|
bool bEnabled = true;
|
|
|
|
while (bEnabled)
|
|
|
|
{
|
|
|
|
bEnabled = pWindow->IsEnabled();
|
|
|
|
pWindow = pWindow->GetParent();
|
2012-12-04 15:28:48 +00:00
|
|
|
if (!pWindow || !isContainerWindow(*pWindow))
|
2012-09-26 21:35:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return bEnabled;
|
|
|
|
}
|
|
|
|
|
2011-11-09 22:58:42 +00:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|