LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/window - layout.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 15 792 1.9 %
Date: 2012-12-27 Functions: 4 60 6.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <vcl/dialog.hxx>
      11             : #include <vcl/layout.hxx>
      12             : #include "window.h"
      13             : 
      14           0 : VclContainer::VclContainer(Window *pParent, WinBits nStyle)
      15             :     : Window(WINDOW_CONTAINER)
      16           0 :     , m_bLayoutDirty(true)
      17             : {
      18           0 :     ImplInit(pParent, nStyle, NULL);
      19           0 :     EnableChildTransparentMode();
      20           0 :     SetPaintTransparent(sal_True);
      21           0 :     SetBackground();
      22           0 : }
      23             : 
      24           0 : Size VclContainer::GetOptimalSize(WindowSizeType eType) const
      25             : {
      26           0 :     if (eType == WINDOWSIZE_MAXIMUM)
      27           0 :         return Window::GetOptimalSize(eType);
      28           0 :     return calculateRequisition();
      29             : }
      30             : 
      31           0 : void VclContainer::setLayoutPosSize(Window &rWindow, const Point &rPos, const Size &rSize)
      32             : {
      33           0 :     sal_Int32 nBorderWidth = rWindow.get_border_width();
      34           0 :     sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
      35           0 :     sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
      36           0 :     sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
      37           0 :     sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
      38           0 :     Point aPos(rPos.X() + nLeft, rPos.Y() + nTop);
      39           0 :     Size aSize(rSize.Width() - nLeft - nRight, rSize.Height() - nTop - nBottom);
      40           0 :     rWindow.SetPosSizePixel(aPos, aSize);
      41           0 : }
      42             : 
      43           0 : void VclContainer::setLayoutAllocation(Window &rChild, const Point &rAllocPos, const Size &rChildAlloc)
      44             : {
      45           0 :     VclAlign eHalign = rChild.get_halign();
      46           0 :     VclAlign eValign = rChild.get_valign();
      47             : 
      48             :     //typical case
      49           0 :     if (eHalign == VCL_ALIGN_FILL && eValign == VCL_ALIGN_FILL)
      50             :     {
      51           0 :         setLayoutPosSize(rChild, rAllocPos, rChildAlloc);
      52           0 :         return;
      53             :     }
      54             : 
      55           0 :     Point aChildPos(rAllocPos);
      56           0 :     Size aChildSize(rChildAlloc);
      57           0 :     Size aChildPreferredSize(getLayoutRequisition(rChild));
      58             : 
      59           0 :     switch (eHalign)
      60             :     {
      61             :         case VCL_ALIGN_FILL:
      62           0 :             break;
      63             :         case VCL_ALIGN_START:
      64           0 :             if (aChildPreferredSize.Width() < rChildAlloc.Width())
      65           0 :                 aChildSize.Width() = aChildPreferredSize.Width();
      66           0 :             break;
      67             :         case VCL_ALIGN_END:
      68           0 :             if (aChildPreferredSize.Width() < rChildAlloc.Width())
      69           0 :                 aChildSize.Width() = aChildPreferredSize.Width();
      70           0 :             aChildPos.X() += rChildAlloc.Width();
      71           0 :             aChildPos.X() -= aChildSize.Width();
      72           0 :             break;
      73             :         case VCL_ALIGN_CENTER:
      74           0 :             if (aChildPreferredSize.Width() < aChildSize.Width())
      75           0 :                 aChildSize.Width() = aChildPreferredSize.Width();
      76           0 :             aChildPos.X() += (rChildAlloc.Width() - aChildSize.Width()) / 2;
      77           0 :             break;
      78             :     }
      79             : 
      80           0 :     switch (eValign)
      81             :     {
      82             :         case VCL_ALIGN_FILL:
      83           0 :             break;
      84             :         case VCL_ALIGN_START:
      85           0 :             if (aChildPreferredSize.Height() < rChildAlloc.Height())
      86           0 :                 aChildSize.Height() = aChildPreferredSize.Height();
      87           0 :             break;
      88             :         case VCL_ALIGN_END:
      89           0 :             if (aChildPreferredSize.Height() < rChildAlloc.Height())
      90           0 :                 aChildSize.Height() = aChildPreferredSize.Height();
      91           0 :             aChildPos.Y() += rChildAlloc.Height();
      92           0 :             aChildPos.Y() -= aChildSize.Height();
      93           0 :             break;
      94             :         case VCL_ALIGN_CENTER:
      95           0 :             if (aChildPreferredSize.Height() < aChildSize.Height())
      96           0 :                 aChildSize.Height() = aChildPreferredSize.Height();
      97           0 :             aChildPos.Y() += (rChildAlloc.Height() - aChildSize.Height()) / 2;
      98           0 :             break;
      99             :     }
     100             : 
     101           0 :     setLayoutPosSize(rChild, aChildPos, aChildSize);
     102             : }
     103             : 
     104           0 : Size VclContainer::getLayoutRequisition(const Window &rWindow)
     105             : {
     106           0 :     sal_Int32 nBorderWidth = rWindow.get_border_width();
     107           0 :     sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
     108           0 :     sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
     109           0 :     sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
     110           0 :     sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
     111           0 :     Size aSize(rWindow.get_preferred_size());
     112           0 :     return Size(aSize.Width() + nLeft + nRight, aSize.Height() + nTop + nBottom);
     113             : }
     114             : 
     115           0 : void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
     116             : {
     117           0 :     bool bSizeChanged = rAllocation != GetOutputSizePixel();
     118           0 :     Window::SetPosSizePixel(rAllocPos, rAllocation);
     119           0 :     if (m_bLayoutDirty || bSizeChanged)
     120             :     {
     121           0 :         m_bLayoutDirty = false;
     122           0 :         setAllocation(rAllocation);
     123             :     }
     124           0 : }
     125             : 
     126           0 : void VclContainer::SetPosPixel(const Point& rAllocPos)
     127             : {
     128           0 :     Point aAllocPos = rAllocPos;
     129           0 :     sal_Int32 nBorderWidth = get_border_width();
     130           0 :     aAllocPos.X() += nBorderWidth + get_margin_left();
     131           0 :     aAllocPos.Y() += nBorderWidth + get_margin_top();
     132             : 
     133           0 :     if (aAllocPos != GetPosPixel())
     134           0 :         Window::SetPosPixel(aAllocPos);
     135           0 : }
     136             : 
     137           0 : void VclContainer::SetSizePixel(const Size& rAllocation)
     138             : {
     139           0 :     Size aAllocation = rAllocation;
     140           0 :     sal_Int32 nBorderWidth = get_border_width();
     141           0 :     aAllocation.Width() -= nBorderWidth*2 + get_margin_left() + get_margin_right();
     142           0 :     aAllocation.Height() -= nBorderWidth*2 + get_margin_top() + get_margin_bottom();
     143           0 :     bool bSizeChanged = aAllocation != GetSizePixel();
     144           0 :     if (bSizeChanged)
     145           0 :         Window::SetSizePixel(aAllocation);
     146           0 :     if (m_bLayoutDirty || bSizeChanged)
     147             :     {
     148           0 :         m_bLayoutDirty = false;
     149           0 :         setAllocation(aAllocation);
     150             :     }
     151           0 : }
     152             : 
     153           0 : void VclBox::accumulateMaxes(const Size &rChildSize, Size &rSize) const
     154             : {
     155           0 :     long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
     156           0 :     long nSecondaryBoxDimension = getSecondaryDimension(rSize);
     157           0 :     setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
     158             : 
     159           0 :     long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
     160           0 :     long nPrimaryBoxDimension = getPrimaryDimension(rSize);
     161           0 :     if (m_bHomogeneous)
     162           0 :         setPrimaryDimension(rSize, std::max(nPrimaryBoxDimension, nPrimaryChildDimension));
     163             :     else
     164           0 :         setPrimaryDimension(rSize, nPrimaryBoxDimension + nPrimaryChildDimension);
     165           0 : }
     166             : 
     167           0 : Size VclBox::calculateRequisition() const
     168             : {
     169           0 :     sal_uInt16 nVisibleChildren = 0;
     170             : 
     171           0 :     Size aSize;
     172           0 :     for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     173             :     {
     174           0 :         if (!pChild->IsVisible())
     175           0 :             continue;
     176           0 :         ++nVisibleChildren;
     177           0 :         Size aChildSize = getLayoutRequisition(*pChild);
     178             : 
     179           0 :         long nPrimaryDimension = getPrimaryDimension(aChildSize);
     180           0 :         nPrimaryDimension += pChild->get_padding() * 2;
     181           0 :         setPrimaryDimension(aChildSize, nPrimaryDimension);
     182             : 
     183           0 :         accumulateMaxes(aChildSize, aSize);
     184             :     }
     185             : 
     186           0 :     return finalizeMaxes(aSize, nVisibleChildren);
     187             : }
     188             : 
     189           0 : void VclBox::setAllocation(const Size &rAllocation)
     190             : {
     191           0 :     sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;
     192           0 :     for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     193             :     {
     194           0 :         if (!pChild->IsVisible())
     195           0 :             continue;
     196           0 :         ++nVisibleChildren;
     197           0 :         bool bExpand = getPrimaryDimensionChildExpand(*pChild);
     198           0 :         if (bExpand)
     199           0 :             ++nExpandChildren;
     200             :     }
     201             : 
     202           0 :     if (!nVisibleChildren)
     203           0 :         return;
     204             : 
     205           0 :     long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
     206             : 
     207           0 :     long nHomogeneousDimension = 0, nExtraSpace = 0;
     208           0 :     if (m_bHomogeneous)
     209             :     {
     210             :         nHomogeneousDimension = ((nAllocPrimaryDimension -
     211           0 :             (nVisibleChildren - 1) * m_nSpacing)) / nVisibleChildren;
     212             :     }
     213           0 :     else if (nExpandChildren)
     214             :     {
     215           0 :         Size aRequisition = calculateRequisition();
     216           0 :         nExtraSpace = (getPrimaryDimension(rAllocation) - getPrimaryDimension(aRequisition)) / nExpandChildren;
     217             :     }
     218             : 
     219           0 :     for (sal_Int32 ePackType = VCL_PACK_START; ePackType <= VCL_PACK_END; ++ePackType)
     220             :     {
     221           0 :         Point aPos(0, 0);
     222           0 :         if (ePackType == VCL_PACK_END)
     223             :         {
     224           0 :             long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
     225           0 :             setPrimaryCoordinate(aPos, nPrimaryCoordinate + nAllocPrimaryDimension);
     226             :         }
     227             : 
     228           0 :         for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     229             :         {
     230           0 :             if (!pChild->IsVisible())
     231           0 :                 continue;
     232             : 
     233           0 :             sal_Int32 ePacking = pChild->get_pack_type();
     234             : 
     235           0 :             if (ePacking != ePackType)
     236           0 :                 continue;
     237             : 
     238           0 :             long nPadding = pChild->get_padding();
     239             : 
     240           0 :             Size aBoxSize;
     241           0 :             if (m_bHomogeneous)
     242           0 :                 setPrimaryDimension(aBoxSize, nHomogeneousDimension);
     243             :             else
     244             :             {
     245           0 :                 aBoxSize = getLayoutRequisition(*pChild);
     246           0 :                 long nPrimaryDimension = getPrimaryDimension(aBoxSize);
     247           0 :                 nPrimaryDimension += nPadding * 2;
     248           0 :                 if (getPrimaryDimensionChildExpand(*pChild))
     249           0 :                     nPrimaryDimension += nExtraSpace;
     250           0 :                 setPrimaryDimension(aBoxSize, nPrimaryDimension);
     251             :             }
     252           0 :             setSecondaryDimension(aBoxSize, getSecondaryDimension(rAllocation));
     253             : 
     254           0 :             Point aChildPos(aPos);
     255           0 :             Size aChildSize(aBoxSize);
     256           0 :             long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
     257             : 
     258           0 :             bool bFill = pChild->get_fill();
     259           0 :             if (bFill)
     260             :             {
     261             :                 setPrimaryDimension(aChildSize, std::max(static_cast<long>(1),
     262           0 :                     getPrimaryDimension(aBoxSize) - nPadding * 2));
     263             : 
     264           0 :                 setPrimaryCoordinate(aChildPos, nPrimaryCoordinate + nPadding);
     265             :             }
     266             :             else
     267             :             {
     268             :                 setPrimaryDimension(aChildSize,
     269           0 :                     getPrimaryDimension(getLayoutRequisition(*pChild)));
     270             : 
     271             :                 setPrimaryCoordinate(aChildPos, nPrimaryCoordinate +
     272           0 :                     (getPrimaryDimension(aBoxSize) - getPrimaryDimension(aChildSize)) / 2);
     273             :             }
     274             : 
     275           0 :             long nDiff = getPrimaryDimension(aBoxSize) + m_nSpacing;
     276           0 :             if (ePackType == VCL_PACK_START)
     277           0 :                 setPrimaryCoordinate(aPos, nPrimaryCoordinate + nDiff);
     278             :             else
     279             :             {
     280           0 :                 setPrimaryCoordinate(aPos, nPrimaryCoordinate - nDiff);
     281           0 :                 setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) -
     282           0 :                     getPrimaryDimension(aBoxSize));
     283             :             }
     284             : 
     285           0 :             setLayoutAllocation(*pChild, aChildPos, aChildSize);
     286             :         }
     287             :     }
     288             : }
     289             : 
     290           0 : bool VclBox::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
     291             : {
     292           0 :     if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("spacing")))
     293           0 :         set_spacing(rValue.toInt32());
     294           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("homogeneous")))
     295           0 :         set_homogeneous(toBool(rValue));
     296             :     else
     297           0 :         return VclContainer::set_property(rKey, rValue);
     298           0 :     return true;
     299             : }
     300             : 
     301             : #define DEFAULT_CHILD_MIN_WIDTH 85
     302             : #define DEFAULT_CHILD_MIN_HEIGHT 27
     303             : 
     304           0 : Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
     305             : {
     306           0 :     Size aRet;
     307             : 
     308           0 :     if (nVisibleChildren)
     309             :     {
     310           0 :         long nPrimaryDimension = getPrimaryDimension(rSize);
     311           0 :         if (m_bHomogeneous)
     312           0 :             nPrimaryDimension *= nVisibleChildren;
     313           0 :         setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
     314           0 :         setSecondaryDimension(aRet, getSecondaryDimension(rSize));
     315             :     }
     316             : 
     317           0 :     return aRet;
     318             : }
     319             : 
     320           0 : Size VclButtonBox::addReqGroups(const VclButtonBox::Requisition &rReq) const
     321             : {
     322           0 :     Size aRet;
     323             : 
     324           0 :     long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
     325           0 :     long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
     326             : 
     327             :     assert(m_bHomogeneous);
     328             : 
     329           0 :     if (m_bHomogeneousGroups)
     330           0 :         setPrimaryDimension(aRet, std::max(nMainGroupDimension, nSubGroupDimension));
     331             :     else
     332             :     {
     333             :         setPrimaryDimension(aRet,
     334             :             (rReq.m_nMainGroupChildren * nMainGroupDimension
     335             :             + rReq.m_nSubGroupChildren * nSubGroupDimension) /
     336           0 :             (rReq.m_nMainGroupChildren + rReq.m_nSubGroupChildren));
     337             :     }
     338             : 
     339             :     setSecondaryDimension(aRet,
     340           0 :         std::max(getSecondaryDimension(rReq.m_aMainGroupSize),
     341           0 :         getSecondaryDimension(rReq.m_aSubGroupSize)));
     342             : 
     343           0 :     return aRet;
     344             : }
     345             : 
     346           0 : VclButtonBox::Requisition VclButtonBox::calculatePrimarySecondaryRequisitions() const
     347             : {
     348           0 :     Requisition aReq;
     349             : 
     350           0 :     Size aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
     351           0 :     Size aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
     352             : 
     353           0 :     for (const Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     354             :     {
     355           0 :         if (!pChild->IsVisible())
     356           0 :             continue;
     357           0 :         Size aChildSize = getLayoutRequisition(*pChild);
     358           0 :         if (!pChild->get_secondary())
     359             :         {
     360           0 :             ++aReq.m_nMainGroupChildren;
     361           0 :             accumulateMaxes(aChildSize, aMainGroupSize);
     362             :         }
     363             :         else
     364             :         {
     365           0 :             ++aReq.m_nSubGroupChildren;
     366           0 :             accumulateMaxes(aChildSize, aSubGroupSize);
     367             :         }
     368             :     }
     369             : 
     370           0 :     if (aReq.m_nMainGroupChildren)
     371           0 :         aReq.m_aMainGroupSize = aMainGroupSize;
     372           0 :     if (aReq.m_nSubGroupChildren)
     373           0 :         aReq.m_aSubGroupSize = aSubGroupSize;
     374             : 
     375           0 :     return aReq;
     376             : }
     377             : 
     378           0 : Size VclButtonBox::calculateRequisition() const
     379             : {
     380           0 :     Requisition aReq(calculatePrimarySecondaryRequisitions());
     381           0 :     sal_uInt16 nVisibleChildren = aReq.m_nMainGroupChildren + aReq.m_nSubGroupChildren;
     382           0 :     return finalizeMaxes(addReqGroups(aReq), nVisibleChildren);
     383             : }
     384             : 
     385           0 : bool VclButtonBox::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
     386             : {
     387           0 :     if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("layout-style")))
     388             :     {
     389           0 :         VclButtonBoxStyle eStyle = VCL_BUTTONBOX_DEFAULT_STYLE;
     390           0 :         if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("start")))
     391           0 :             eStyle = VCL_BUTTONBOX_START;
     392           0 :         else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("spread")))
     393           0 :             eStyle = VCL_BUTTONBOX_SPREAD;
     394           0 :         else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("edge")))
     395           0 :             eStyle = VCL_BUTTONBOX_EDGE;
     396           0 :         else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("start")))
     397           0 :             eStyle = VCL_BUTTONBOX_START;
     398           0 :         else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("end")))
     399           0 :             eStyle = VCL_BUTTONBOX_END;
     400           0 :         else if (rValue.equalsL(RTL_CONSTASCII_STRINGPARAM("center")))
     401           0 :             eStyle = VCL_BUTTONBOX_CENTER;
     402             :         else
     403             :         {
     404             :             SAL_WARN("vcl.layout", "unknown layout style " << rValue.getStr());
     405             :         }
     406           0 :         set_layout(eStyle);
     407             :     }
     408           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("homogeneous")))
     409           0 :         m_bHomogeneousGroups = toBool(rValue);
     410             :     else
     411           0 :         return VclBox::set_property(rKey, rValue);
     412           0 :     return true;
     413             : }
     414             : 
     415           0 : void VclButtonBox::setAllocation(const Size &rAllocation)
     416             : {
     417           0 :     Requisition aReq(calculatePrimarySecondaryRequisitions());
     418             : 
     419           0 :     sal_uInt16 nVisibleChildren = aReq.m_nMainGroupChildren + aReq.m_nSubGroupChildren;
     420           0 :     if (!nVisibleChildren)
     421           0 :         return;
     422             : 
     423           0 :     long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
     424             : 
     425           0 :     long nMainGroupPrimaryDimension = getPrimaryDimension(aReq.m_aMainGroupSize);
     426           0 :     long nSubGroupPrimaryDimension = getPrimaryDimension(aReq.m_aSubGroupSize);
     427           0 :     if (m_bHomogeneousGroups)
     428           0 :         nSubGroupPrimaryDimension = nMainGroupPrimaryDimension = std::max(nSubGroupPrimaryDimension, nMainGroupPrimaryDimension);
     429             : 
     430           0 :     Point aMainGroupPos, aOtherGroupPos;
     431             : 
     432             :     //To-Do, other layout styles
     433           0 :     switch (m_eLayoutStyle)
     434             :     {
     435             :         case VCL_BUTTONBOX_START:
     436           0 :             if (aReq.m_nSubGroupChildren)
     437             :             {
     438             :                 long nOtherPrimaryDimension = getPrimaryDimension(
     439           0 :                     finalizeMaxes(aReq.m_aSubGroupSize, aReq.m_nSubGroupChildren));
     440             :                 setPrimaryCoordinate(aOtherGroupPos,
     441           0 :                     nAllocPrimaryDimension - nOtherPrimaryDimension);
     442             :             }
     443           0 :             break;
     444             :         default:
     445             :             SAL_WARN("vcl.layout", "todo unimplemented layout style");
     446             :         case VCL_BUTTONBOX_DEFAULT_STYLE:
     447             :         case VCL_BUTTONBOX_END:
     448           0 :             if (aReq.m_nMainGroupChildren)
     449             :             {
     450             :                 long nMainPrimaryDimension = getPrimaryDimension(
     451           0 :                     finalizeMaxes(aReq.m_aMainGroupSize, aReq.m_nMainGroupChildren));
     452             :                 setPrimaryCoordinate(aMainGroupPos,
     453           0 :                     nAllocPrimaryDimension - nMainPrimaryDimension);
     454             :             }
     455           0 :             break;
     456             :     }
     457             : 
     458           0 :     Size aChildSize;
     459           0 :     setSecondaryDimension(aChildSize, getSecondaryDimension(rAllocation));
     460             : 
     461           0 :     for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     462             :     {
     463           0 :         if (!pChild->IsVisible())
     464           0 :             continue;
     465             : 
     466           0 :         if (pChild->get_secondary())
     467             :         {
     468           0 :             setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
     469           0 :             setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
     470           0 :             long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
     471           0 :             setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + m_nSpacing);
     472             :         }
     473             :         else
     474             :         {
     475           0 :             setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
     476           0 :             setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
     477           0 :             long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
     478           0 :             setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + m_nSpacing);
     479             :         }
     480             :     }
     481             : }
     482             : 
     483           0 : VclGrid::array_type VclGrid::assembleGrid() const
     484             : {
     485           0 :     ext_array_type A;
     486             : 
     487           0 :     for (Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild;
     488             :         pChild = pChild->GetWindow(WINDOW_NEXT))
     489             :     {
     490           0 :         sal_Int32 nLeftAttach = pChild->get_grid_left_attach();
     491           0 :         sal_Int32 nWidth = pChild->get_grid_width();
     492           0 :         sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
     493             : 
     494           0 :         sal_Int32 nTopAttach = pChild->get_grid_top_attach();
     495           0 :         sal_Int32 nHeight = pChild->get_grid_height();
     496           0 :         sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
     497             : 
     498           0 :         sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
     499           0 :         sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
     500           0 :         if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
     501             :         {
     502           0 :             nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
     503           0 :             nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
     504           0 :             A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
     505             :         }
     506             : 
     507           0 :         ExtendedGridEntry &rEntry = A[nLeftAttach][nTopAttach];
     508           0 :         rEntry.pChild = pChild;
     509           0 :         rEntry.nSpanWidth = nWidth;
     510           0 :         rEntry.nSpanHeight = nHeight;
     511           0 :         rEntry.x = nLeftAttach;
     512           0 :         rEntry.y = nTopAttach;
     513             : 
     514           0 :         for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     515             :         {
     516           0 :             for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     517             :             {
     518           0 :                 ExtendedGridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
     519           0 :                 rSpan.x = nLeftAttach;
     520           0 :                 rSpan.y = nTopAttach;
     521             :             }
     522             :         }
     523             :     }
     524             : 
     525             :     //see if we have any empty rows/cols
     526           0 :     sal_Int32 nMaxX = A.shape()[0];
     527           0 :     sal_Int32 nMaxY = A.shape()[1];
     528             : 
     529           0 :     std::vector<bool> aNonEmptyCols(nMaxX);
     530           0 :     std::vector<bool> aNonEmptyRows(nMaxY);
     531             : 
     532           0 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     533             :     {
     534           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     535             :         {
     536           0 :             const GridEntry &rEntry = A[x][y];
     537           0 :             const Window *pChild = rEntry.pChild;
     538           0 :             if (pChild && pChild->IsVisible())
     539             :             {
     540           0 :                 aNonEmptyCols[x] = true;
     541           0 :                 aNonEmptyRows[y] = true;
     542             :             }
     543             :         }
     544             :     }
     545             : 
     546             :     //reduce the spans of elements that span empty rows or columns
     547           0 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     548             :     {
     549           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     550             :         {
     551           0 :             ExtendedGridEntry &rSpan = A[x][y];
     552             :             //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
     553             :             //just points back to itself if there's no cell spanning
     554           0 :             if ((rSpan.x == -1) || (rSpan.y == -1))
     555             :             {
     556             :                 //there is no entry for this cell, i.e. this is a cell
     557             :                 //with no widget in it, or spanned by any other widget
     558           0 :                 continue;
     559             :             }
     560           0 :             ExtendedGridEntry &rEntry = A[rSpan.x][rSpan.y];
     561           0 :             if (aNonEmptyCols[x] == false)
     562           0 :                 --rEntry.nSpanWidth;
     563           0 :             if (aNonEmptyRows[y] == false)
     564           0 :                 --rEntry.nSpanHeight;
     565             :         }
     566             :     }
     567             : 
     568           0 :     sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
     569           0 :     sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
     570             : 
     571             :     //make new grid without empty rows and columns
     572           0 :     array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
     573           0 :     for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
     574             :     {
     575           0 :         if (aNonEmptyCols[x] == false)
     576           0 :             continue;
     577           0 :         for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
     578             :         {
     579           0 :             if (aNonEmptyRows[y] == false)
     580           0 :                 continue;
     581           0 :             GridEntry &rEntry = A[x][y];
     582           0 :             B[x2][y2++] = rEntry;
     583             :         }
     584           0 :         ++x2;
     585             :     }
     586             : 
     587           0 :     return B;
     588             : }
     589             : 
     590           0 : bool VclGrid::isNullGrid(const array_type &A) const
     591             : {
     592           0 :     sal_Int32 nMaxX = A.shape()[0];
     593           0 :     sal_Int32 nMaxY = A.shape()[1];
     594             : 
     595           0 :     if (!nMaxX || !nMaxY)
     596           0 :         return true;
     597           0 :     return false;
     598             : }
     599             : 
     600           0 : void VclGrid::calcMaxs(const array_type &A, std::vector<Value> &rWidths, std::vector<Value> &rHeights) const
     601             : {
     602           0 :     sal_Int32 nMaxX = A.shape()[0];
     603           0 :     sal_Int32 nMaxY = A.shape()[1];
     604             : 
     605           0 :     rWidths.resize(nMaxX);
     606           0 :     rHeights.resize(nMaxY);
     607             : 
     608             :     //first use the non spanning entries to set default width/heights
     609           0 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     610             :     {
     611           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     612             :         {
     613           0 :             const GridEntry &rEntry = A[x][y];
     614           0 :             const Window *pChild = rEntry.pChild;
     615           0 :             if (!pChild)
     616           0 :                 continue;
     617             : 
     618           0 :             sal_Int32 nWidth = rEntry.nSpanWidth;
     619           0 :             sal_Int32 nHeight = rEntry.nSpanHeight;
     620             : 
     621           0 :             for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     622           0 :                 rWidths[x+nSpanX].m_bExpand = rWidths[x+nSpanX].m_bExpand | pChild->get_hexpand();
     623             : 
     624           0 :             for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     625           0 :                 rHeights[y+nSpanY].m_bExpand = rHeights[y+nSpanY].m_bExpand | pChild->get_vexpand();
     626             : 
     627           0 :             if (nWidth == 1 || nHeight == 1)
     628             :             {
     629           0 :                 Size aChildSize = getLayoutRequisition(*pChild);
     630           0 :                 if (nWidth == 1)
     631           0 :                     rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
     632           0 :                 if (nHeight == 1)
     633           0 :                     rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
     634             :             }
     635             :         }
     636             :     }
     637             : 
     638             :     //now use the spanning entries and split any extra sizes across expanding rows/cols
     639             :     //where possible
     640           0 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     641             :     {
     642           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     643             :         {
     644           0 :             const GridEntry &rEntry = A[x][y];
     645           0 :             const Window *pChild = rEntry.pChild;
     646           0 :             if (!pChild)
     647           0 :                 continue;
     648             : 
     649           0 :             sal_Int32 nWidth = rEntry.nSpanWidth;
     650           0 :             sal_Int32 nHeight = rEntry.nSpanHeight;
     651             : 
     652           0 :             if (nWidth == 1 && nHeight == 1)
     653           0 :                 continue;
     654             : 
     655           0 :             Size aChildSize = getLayoutRequisition(*pChild);
     656             : 
     657           0 :             if (nWidth > 1)
     658             :             {
     659           0 :                 sal_Int32 nExistingWidth = 0;
     660           0 :                 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     661           0 :                     nExistingWidth += rWidths[x+nSpanX].m_nValue;
     662             : 
     663           0 :                 sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
     664             : 
     665           0 :                 if (nExtraWidth > 0)
     666             :                 {
     667           0 :                     bool bForceExpandAll = false;
     668           0 :                     sal_Int32 nExpandables = 0;
     669           0 :                     for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     670           0 :                         if (rWidths[x+nSpanX].m_bExpand)
     671           0 :                             ++nExpandables;
     672           0 :                     if (nExpandables == 0)
     673             :                     {
     674           0 :                         nExpandables = nWidth;
     675           0 :                         bForceExpandAll = true;
     676             :                     }
     677             : 
     678           0 :                     for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     679             :                     {
     680           0 :                         if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
     681           0 :                             rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
     682             :                     }
     683             :                 }
     684             :             }
     685             : 
     686           0 :             if (nHeight > 1)
     687             :             {
     688           0 :                 sal_Int32 nExistingHeight = 0;
     689           0 :                 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     690           0 :                     nExistingHeight += rHeights[y+nSpanY].m_nValue;
     691             : 
     692           0 :                 sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
     693             : 
     694           0 :                 if (nExtraHeight > 0)
     695             :                 {
     696           0 :                     bool bForceExpandAll = false;
     697           0 :                     sal_Int32 nExpandables = 0;
     698           0 :                     for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     699           0 :                         if (rHeights[y+nSpanY].m_bExpand)
     700           0 :                             ++nExpandables;
     701           0 :                     if (nExpandables == 0)
     702             :                     {
     703           0 :                         nExpandables = nHeight;
     704           0 :                         bForceExpandAll = true;
     705             :                     }
     706             : 
     707           0 :                     for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     708             :                     {
     709           0 :                         if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
     710           0 :                             rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
     711             :                     }
     712             :                 }
     713             :             }
     714             :         }
     715             :     }
     716           0 : }
     717             : 
     718           0 : bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
     719             : {
     720           0 :     return i.m_nValue < j.m_nValue;
     721             : }
     722             : 
     723           0 : VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
     724             : {
     725           0 :     VclGrid::Value aRet;
     726           0 :     aRet.m_nValue = i.m_nValue + j.m_nValue;
     727           0 :     aRet.m_bExpand = i.m_bExpand | j.m_bExpand;
     728           0 :     return aRet;
     729             : }
     730             : 
     731           0 : Size VclGrid::calculateRequisition() const
     732             : {
     733           0 :     array_type A = assembleGrid();
     734             : 
     735           0 :     if (isNullGrid(A))
     736           0 :         return Size();
     737             : 
     738           0 :     std::vector<Value> aWidths;
     739           0 :     std::vector<Value> aHeights;
     740           0 :     calcMaxs(A, aWidths, aHeights);
     741             : 
     742           0 :     long nTotalWidth = 0;
     743           0 :     if (get_column_homogeneous())
     744             :     {
     745           0 :         nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
     746           0 :         nTotalWidth *= aWidths.size();
     747             :     }
     748             :     else
     749             :     {
     750           0 :         nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
     751             :     }
     752             : 
     753           0 :     nTotalWidth += get_column_spacing() * (aWidths.size()-1);
     754             : 
     755           0 :     long nTotalHeight = 0;
     756           0 :     if (get_row_homogeneous())
     757             :     {
     758           0 :         nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
     759           0 :         nTotalHeight *= aHeights.size();
     760             :     }
     761             :     else
     762             :     {
     763           0 :         nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
     764             :     }
     765             : 
     766           0 :     nTotalHeight += get_row_spacing() * (aHeights.size()-1);
     767             : 
     768           0 :     return Size(nTotalWidth, nTotalHeight);
     769             : }
     770             : 
     771           0 : void VclGrid::setAllocation(const Size& rAllocation)
     772             : {
     773           0 :     array_type A = assembleGrid();
     774             : 
     775           0 :     if (isNullGrid(A))
     776           0 :         return;
     777             : 
     778           0 :     sal_Int32 nMaxX = A.shape()[0];
     779           0 :     sal_Int32 nMaxY = A.shape()[1];
     780             : 
     781           0 :     Size aRequisition;
     782           0 :     std::vector<Value> aWidths(nMaxX);
     783           0 :     std::vector<Value> aHeights(nMaxY);
     784           0 :     if (!get_column_homogeneous() || !get_row_homogeneous())
     785             :     {
     786           0 :         aRequisition = calculateRequisition();
     787           0 :         calcMaxs(A, aWidths, aHeights);
     788             :     }
     789             : 
     790           0 :     long nAvailableWidth = rAllocation.Width() - (get_column_spacing() * nMaxX);
     791           0 :     if (get_column_homogeneous())
     792             :     {
     793           0 :         for (sal_Int32 x = 0; x < nMaxX; ++x)
     794           0 :             aWidths[x].m_nValue = nAvailableWidth/nMaxX;
     795             :     }
     796           0 :     else if (rAllocation.Width() != aRequisition.Width())
     797             :     {
     798           0 :         sal_Int32 nExpandables = 0;
     799           0 :         for (sal_Int32 x = 0; x < nMaxX; ++x)
     800           0 :             if (aWidths[x].m_bExpand)
     801           0 :                 ++nExpandables;
     802           0 :         long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
     803             : 
     804           0 :         if (rAllocation.Width() < aRequisition.Width())
     805             :         {
     806           0 :             long nExtraWidth = (rAllocation.Width() - aRequisition.Width() - nExtraWidthForExpanders * nExpandables) / nMaxX;
     807             : 
     808           0 :             for (sal_Int32 x = 0; x < nMaxX; ++x)
     809           0 :                 aWidths[x].m_nValue += nExtraWidth;
     810             :         }
     811             : 
     812           0 :         if (nExtraWidthForExpanders)
     813             :         {
     814           0 :             for (sal_Int32 x = 0; x < nMaxX; ++x)
     815           0 :                 if (aWidths[x].m_bExpand)
     816           0 :                     aWidths[x].m_nValue += nExtraWidthForExpanders;
     817             :         }
     818             :     }
     819             : 
     820           0 :     long nAvailableHeight = rAllocation.Height() - (get_row_spacing() * nMaxY);
     821           0 :     if (get_row_homogeneous())
     822             :     {
     823           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     824           0 :             aHeights[y].m_nValue = nAvailableHeight/nMaxY;
     825             :     }
     826           0 :     else if (rAllocation.Height() != aRequisition.Height())
     827             :     {
     828           0 :         sal_Int32 nExpandables = 0;
     829           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     830           0 :             if (aHeights[y].m_bExpand)
     831           0 :                 ++nExpandables;
     832           0 :         long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
     833             : 
     834           0 :         if (rAllocation.Height() < aRequisition.Height())
     835             :         {
     836           0 :             long nExtraHeight = (rAllocation.Height() - aRequisition.Height() - nExtraHeightForExpanders * nExpandables) / nMaxY;
     837             : 
     838           0 :             for (sal_Int32 y = 0; y < nMaxY; ++y)
     839           0 :                 aHeights[y].m_nValue += nExtraHeight;
     840             :         }
     841             : 
     842           0 :         if (nExtraHeightForExpanders)
     843             :         {
     844           0 :             for (sal_Int32 y = 0; y < nMaxY; ++y)
     845           0 :                 if (aHeights[y].m_bExpand)
     846           0 :                     aHeights[y].m_nValue += nExtraHeightForExpanders;
     847             :         }
     848             :     }
     849             : 
     850           0 :     Point aAllocPos(0, 0);
     851           0 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     852             :     {
     853           0 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     854             :         {
     855           0 :             GridEntry &rEntry = A[x][y];
     856           0 :             Window *pChild = rEntry.pChild;
     857           0 :             if (pChild)
     858             :             {
     859           0 :                 Size aChildAlloc(0, 0);
     860             : 
     861           0 :                 sal_Int32 nWidth = rEntry.nSpanWidth;
     862           0 :                 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     863           0 :                     aChildAlloc.Width() += aWidths[x+nSpanX].m_nValue;
     864           0 :                 aChildAlloc.Width() += get_column_spacing()*(nWidth-1);
     865             : 
     866           0 :                 sal_Int32 nHeight = rEntry.nSpanHeight;
     867           0 :                 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     868           0 :                     aChildAlloc.Height() += aHeights[y+nSpanY].m_nValue;
     869           0 :                 aChildAlloc.Height() += get_row_spacing()*(nHeight-1);
     870             : 
     871           0 :                 setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
     872             :             }
     873           0 :             aAllocPos.Y() += aHeights[y].m_nValue + get_row_spacing();
     874             :         }
     875           0 :         aAllocPos.X() += aWidths[x].m_nValue + get_column_spacing();
     876           0 :         aAllocPos.Y() = 0;
     877           0 :     }
     878             : }
     879             : 
     880           0 : bool toBool(const rtl::OString &rValue)
     881             : {
     882           0 :     return (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1');
     883             : }
     884             : 
     885           0 : bool VclGrid::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
     886             : {
     887           0 :     if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("row-spacing")))
     888           0 :         set_row_spacing(rValue.toInt32());
     889           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("column-spacing")))
     890           0 :         set_column_spacing(rValue.toInt32());
     891           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("row-homogeneous")))
     892           0 :         set_row_homogeneous(toBool(rValue));
     893           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("column-homogeneous")))
     894           0 :         set_column_homogeneous(toBool(rValue));
     895           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("n-rows")))
     896             :         /*nothing to do*/;
     897             :     else
     898           0 :         return VclContainer::set_property(rKey, rValue);
     899           0 :     return true;
     900             : }
     901             : 
     902           0 : void setGridAttach(Window &rWidget, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nWidth, sal_Int32 nHeight)
     903             : {
     904           0 :     rWidget.set_grid_left_attach(nLeft);
     905           0 :     rWidget.set_grid_top_attach(nTop);
     906           0 :     rWidget.set_grid_width(nWidth);
     907           0 :     rWidget.set_grid_height(nHeight);
     908           0 : }
     909             : 
     910           0 : const Window *VclBin::get_child() const
     911             : {
     912           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
     913             : 
     914           0 :     return pWindowImpl->mpFirstChild;
     915             : }
     916             : 
     917           0 : Window *VclBin::get_child()
     918             : {
     919           0 :     return const_cast<Window*>(const_cast<const VclBin*>(this)->get_child());
     920             : }
     921             : 
     922           0 : Size VclBin::calculateRequisition() const
     923             : {
     924           0 :     const Window *pChild = get_child();
     925           0 :     if (pChild && pChild->IsVisible())
     926           0 :         return getLayoutRequisition(*pChild);
     927           0 :     return Size(0, 0);
     928             : }
     929             : 
     930           0 : void VclBin::setAllocation(const Size &rAllocation)
     931             : {
     932           0 :     Window *pChild = get_child();
     933           0 :     if (pChild && pChild->IsVisible())
     934           0 :         setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
     935           0 : }
     936             : 
     937             : //To-Do, hook a DecorationView into VclFrame ?
     938             : 
     939           0 : Size VclFrame::calculateRequisition() const
     940             : {
     941           0 :     Size aRet(0, 0);
     942             : 
     943           0 :     WindowImpl* pWindowImpl = ImplGetWindowImpl();
     944             : 
     945           0 :     const Window *pChild = get_child();
     946           0 :     const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
     947             : 
     948           0 :     if (pChild && pChild->IsVisible())
     949           0 :         aRet = getLayoutRequisition(*pChild);
     950             : 
     951           0 :     if (pLabel && pLabel->IsVisible())
     952             :     {
     953           0 :         Size aLabelSize = getLayoutRequisition(*pLabel);
     954           0 :         aRet.Height() += aLabelSize.Height();
     955           0 :         aRet.Width() = std::max(aLabelSize.Width(), aRet.Width());
     956             :     }
     957             : 
     958             :     const FrameStyle &rFrameStyle =
     959           0 :         GetSettings().GetStyleSettings().GetFrameStyle();
     960           0 :     aRet.Width() += rFrameStyle.left + rFrameStyle.right;
     961           0 :     aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
     962             : 
     963           0 :     return aRet;
     964             : }
     965             : 
     966           0 : void VclFrame::setAllocation(const Size &rAllocation)
     967             : {
     968             :     //SetBackground( Color(0xFF, 0x00, 0xFF) );
     969             : 
     970             :     const FrameStyle &rFrameStyle =
     971           0 :         GetSettings().GetStyleSettings().GetFrameStyle();
     972           0 :     Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
     973           0 :         rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
     974           0 :     Point aChildPos(rFrameStyle.left, rFrameStyle.top);
     975             : 
     976           0 :     WindowImpl* pWindowImpl = ImplGetWindowImpl();
     977             : 
     978             :     //The label widget is the last (of two) children
     979           0 :     Window *pChild = get_child();
     980           0 :     Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
     981             : 
     982           0 :     if (pLabel && pLabel->IsVisible())
     983             :     {
     984           0 :         Size aLabelSize = getLayoutRequisition(*pLabel);
     985           0 :         aLabelSize.Height() = std::min(aLabelSize.Height(), aAllocation.Height());
     986           0 :         aLabelSize.Width() = std::min(aLabelSize.Width(), aAllocation.Width());
     987           0 :         setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
     988           0 :         aAllocation.Height() -= aLabelSize.Height();
     989           0 :         aChildPos.Y() += aLabelSize.Height();
     990             :     }
     991             : 
     992           0 :     if (pChild && pChild->IsVisible())
     993           0 :         setLayoutAllocation(*pChild, aChildPos, aAllocation);
     994           0 : }
     995             : 
     996           0 : const Window *VclFrame::get_label_widget() const
     997             : {
     998             :     //The label widget is the last (of two) children
     999           0 :     const Window *pChild = get_child();
    1000           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1001           0 :     return pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
    1002             : }
    1003             : 
    1004           0 : Window *VclFrame::get_label_widget()
    1005             : {
    1006           0 :     return const_cast<Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
    1007             : }
    1008             : 
    1009           0 : void VclFrame::set_label(const rtl::OUString &rLabel)
    1010             : {
    1011             :     //The label widget is the last (of two) children
    1012           0 :     Window *pLabel = get_label_widget();
    1013             :     assert(pLabel);
    1014           0 :     pLabel->SetText(rLabel);
    1015           0 : }
    1016             : 
    1017           0 : Size VclAlignment::calculateRequisition() const
    1018             : {
    1019             :     Size aRet(m_nLeftPadding + m_nRightPadding,
    1020           0 :         m_nTopPadding + m_nBottomPadding);
    1021             : 
    1022           0 :     const Window *pChild = get_child();
    1023           0 :     if (pChild && pChild->IsVisible())
    1024             :     {
    1025           0 :         Size aChildSize = getLayoutRequisition(*pChild);
    1026           0 :         aRet.Width() += aChildSize.Width();
    1027           0 :         aRet.Height() += aChildSize.Height();
    1028             :     }
    1029             : 
    1030           0 :     return aRet;
    1031             : }
    1032             : 
    1033           0 : void VclAlignment::setAllocation(const Size &rAllocation)
    1034             : {
    1035           0 :     Window *pChild = get_child();
    1036           0 :     if (!pChild || !pChild->IsVisible())
    1037           0 :         return;
    1038             : 
    1039           0 :     Point aChildPos(m_nLeftPadding, m_nTopPadding);
    1040             : 
    1041           0 :     Size aAllocation;
    1042           0 :     aAllocation.Width() = rAllocation.Width() - (m_nLeftPadding + m_nRightPadding);
    1043           0 :     aAllocation.Height() = rAllocation.Height() - (m_nTopPadding + m_nBottomPadding);
    1044             : 
    1045           0 :     setLayoutAllocation(*pChild, aChildPos, aAllocation);
    1046             : }
    1047             : 
    1048           0 : bool VclAlignment::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
    1049             : {
    1050           0 :     if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("bottom-padding")))
    1051           0 :         m_nBottomPadding = rValue.toInt32();
    1052           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("left-padding")))
    1053           0 :         m_nLeftPadding = rValue.toInt32();
    1054           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("right-padding")))
    1055           0 :         m_nRightPadding = rValue.toInt32();
    1056           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("top-padding")))
    1057           0 :         m_nTopPadding = rValue.toInt32();
    1058           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("xalign")))
    1059           0 :         m_fXAlign = rValue.toFloat();
    1060           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("xscale")))
    1061           0 :         m_fXScale = rValue.toFloat();
    1062           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("yalign")))
    1063           0 :         m_fYAlign = rValue.toFloat();
    1064           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("yscale")))
    1065           0 :         m_fYScale = rValue.toFloat();
    1066             :     else
    1067           0 :         return VclBin::set_property(rKey, rValue);
    1068           0 :     return true;
    1069             : }
    1070             : 
    1071           0 : const Window *VclExpander::get_child() const
    1072             : {
    1073           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1074             : 
    1075             :     assert(pWindowImpl->mpFirstChild == &m_aDisclosureButton);
    1076             : 
    1077           0 :     return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
    1078             : }
    1079             : 
    1080           0 : Window *VclExpander::get_child()
    1081             : {
    1082           0 :     return const_cast<Window*>(const_cast<const VclExpander*>(this)->get_child());
    1083             : }
    1084             : 
    1085           0 : Size VclExpander::calculateRequisition() const
    1086             : {
    1087           0 :     Size aRet(0, 0);
    1088             : 
    1089           0 :     WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1090             : 
    1091           0 :     const Window *pChild = get_child();
    1092           0 :     const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
    1093             : 
    1094           0 :     if (pChild && pChild->IsVisible() && m_aDisclosureButton.IsChecked())
    1095           0 :         aRet = getLayoutRequisition(*pChild);
    1096             : 
    1097           0 :     Size aExpanderSize = getLayoutRequisition(m_aDisclosureButton);
    1098             : 
    1099           0 :     if (pLabel && pLabel->IsVisible())
    1100             :     {
    1101           0 :         Size aLabelSize = getLayoutRequisition(*pLabel);
    1102           0 :         aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
    1103           0 :         aExpanderSize.Width() += aLabelSize.Width();
    1104             :     }
    1105             : 
    1106           0 :     aRet.Height() += aExpanderSize.Height();
    1107           0 :     aRet.Width() = std::max(aExpanderSize.Width(), aRet.Width());
    1108             : 
    1109             :     const FrameStyle &rFrameStyle =
    1110           0 :         GetSettings().GetStyleSettings().GetFrameStyle();
    1111           0 :     aRet.Width() += rFrameStyle.left + rFrameStyle.right;
    1112           0 :     aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
    1113             : 
    1114           0 :     return aRet;
    1115             : }
    1116             : 
    1117           0 : void VclExpander::setAllocation(const Size &rAllocation)
    1118             : {
    1119             :     const FrameStyle &rFrameStyle =
    1120           0 :         GetSettings().GetStyleSettings().GetFrameStyle();
    1121           0 :     Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
    1122           0 :         rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
    1123           0 :     Point aChildPos(rFrameStyle.left, rFrameStyle.top);
    1124             : 
    1125           0 :     WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1126             : 
    1127             :     //The label widget is the last (of two) children
    1128           0 :     Window *pChild = get_child();
    1129           0 :     Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
    1130             : 
    1131           0 :     Size aButtonSize = getLayoutRequisition(m_aDisclosureButton);
    1132           0 :     Size aLabelSize;
    1133           0 :     Size aExpanderSize = aButtonSize;
    1134           0 :     if (pLabel && pLabel->IsVisible())
    1135             :     {
    1136           0 :         aLabelSize = getLayoutRequisition(*pLabel);
    1137           0 :         aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
    1138           0 :         aExpanderSize.Width() += aLabelSize.Width();
    1139             :     }
    1140             : 
    1141           0 :     aExpanderSize.Height() = std::min(aExpanderSize.Height(), aAllocation.Height());
    1142           0 :     aExpanderSize.Width() = std::min(aExpanderSize.Width(), aAllocation.Width());
    1143             : 
    1144           0 :     aButtonSize.Height() = std::min(aButtonSize.Height(), aExpanderSize.Height());
    1145           0 :     aButtonSize.Width() = std::min(aButtonSize.Width(), aExpanderSize.Width());
    1146             : 
    1147           0 :     long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
    1148           0 :     Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
    1149           0 :     setLayoutAllocation(m_aDisclosureButton, aButtonPos, aButtonSize);
    1150             : 
    1151           0 :     if (pLabel && pLabel->IsVisible())
    1152             :     {
    1153           0 :         aLabelSize.Height() = std::min(aLabelSize.Height(), aExpanderSize.Height());
    1154           0 :         aLabelSize.Width() = std::min(aLabelSize.Width(),
    1155           0 :             aExpanderSize.Width() - aButtonSize.Width());
    1156             : 
    1157           0 :         long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
    1158           0 :         Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
    1159           0 :         setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
    1160             :     }
    1161             : 
    1162           0 :     aAllocation.Height() -= aExpanderSize.Height();
    1163           0 :     aChildPos.Y() += aExpanderSize.Height();
    1164             : 
    1165           0 :     if (pChild && pChild->IsVisible())
    1166             :     {
    1167           0 :         if (!m_aDisclosureButton.IsChecked())
    1168           0 :             aAllocation = Size();
    1169           0 :         setLayoutAllocation(*pChild, aChildPos, aAllocation);
    1170             :     }
    1171           0 : }
    1172             : 
    1173           0 : bool VclExpander::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
    1174             : {
    1175           0 :     if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("expanded")))
    1176           0 :         m_aDisclosureButton.Check(toBool(rValue));
    1177           0 :     else if (rKey.equalsL(RTL_CONSTASCII_STRINGPARAM("resize-toplevel")))
    1178           0 :         m_bResizeTopLevel = toBool(rValue);
    1179             :     else
    1180           0 :         return VclBin::set_property(rKey, rValue);
    1181           0 :     return true;
    1182             : }
    1183             : 
    1184           0 : IMPL_LINK( VclExpander, ClickHdl, DisclosureButton*, pBtn )
    1185             : {
    1186           0 :     Window *pChild = get_child();
    1187           0 :     if (pChild)
    1188             :     {
    1189           0 :         pChild->Show(pBtn->IsChecked());
    1190           0 :         queue_resize();
    1191           0 :         Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : NULL;
    1192           0 :         if (pResizeDialog)
    1193           0 :             pResizeDialog->setInitialLayoutSize();
    1194             :     }
    1195           0 :     return 0;
    1196             : }
    1197             : 
    1198           0 : const Window *VclScrolledWindow::get_child() const
    1199             : {
    1200             :     assert(GetChildCount() == 3);
    1201           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1202           0 :     return pWindowImpl->mpLastChild;
    1203             : }
    1204             : 
    1205           0 : Window *VclScrolledWindow::get_child()
    1206             : {
    1207           0 :     return const_cast<Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
    1208             : }
    1209             : 
    1210           0 : Size VclScrolledWindow::calculateRequisition() const
    1211             : {
    1212           0 :     Size aRet(0, 0);
    1213             : 
    1214           0 :     const Window *pChild = get_child();
    1215           0 :     if (pChild && pChild->IsVisible())
    1216           0 :         aRet = getLayoutRequisition(*pChild);
    1217             : 
    1218           0 :     if (m_aVScroll.IsVisible())
    1219           0 :         aRet.Width() += getLayoutRequisition(m_aVScroll).Width();
    1220             : 
    1221           0 :     if (m_aHScroll.IsVisible())
    1222           0 :         aRet.Height() += getLayoutRequisition(m_aVScroll).Height();
    1223             : 
    1224           0 :     return aRet;
    1225             : }
    1226             : 
    1227           0 : void VclScrolledWindow::setAllocation(const Size &rAllocation)
    1228             : {
    1229           0 :     Size aChildAllocation(rAllocation);
    1230           0 :     Size aChildReq;
    1231             : 
    1232           0 :     Window *pChild = get_child();
    1233           0 :     if (pChild && pChild->IsVisible())
    1234           0 :         aChildReq = getLayoutRequisition(*pChild);
    1235             : 
    1236           0 :     if (m_aVScroll.IsVisible())
    1237             :     {
    1238           0 :         long nScrollBarWidth = getLayoutRequisition(m_aVScroll).Width();
    1239           0 :         Point aScrollPos(rAllocation.Width() - nScrollBarWidth, 0);
    1240           0 :         Size aScrollSize(nScrollBarWidth, rAllocation.Height());
    1241           0 :         setLayoutAllocation(m_aVScroll, aScrollPos, aScrollSize);
    1242           0 :         aChildAllocation.Width() -= nScrollBarWidth;
    1243           0 :         aChildAllocation.Height() = aChildReq.Height();
    1244             :     }
    1245             : 
    1246           0 :     if (m_aHScroll.IsVisible())
    1247             :     {
    1248           0 :         long nScrollBarHeight = getLayoutRequisition(m_aHScroll).Height();
    1249           0 :         Point aScrollPos(0, rAllocation.Height() - nScrollBarHeight);
    1250           0 :         Size aScrollSize(rAllocation.Width(), nScrollBarHeight);
    1251           0 :         setLayoutAllocation(m_aHScroll, aScrollPos, aScrollSize);
    1252           0 :         aChildAllocation.Height() -= nScrollBarHeight;
    1253           0 :         aChildAllocation.Width() = aChildReq.Width();
    1254             :     }
    1255             : 
    1256           0 :     if (pChild && pChild->IsVisible())
    1257             :     {
    1258           0 :         Point aChildPos(pChild->GetPosPixel());
    1259           0 :         if (!m_aHScroll.IsVisible())
    1260           0 :             aChildPos.X() = 0;
    1261           0 :         if (!m_aVScroll.IsVisible())
    1262           0 :             aChildPos.Y() = 0;
    1263           0 :         setLayoutAllocation(*pChild, aChildPos, aChildAllocation);
    1264             :     }
    1265           0 : }
    1266             : 
    1267           0 : Size VclScrolledWindow::getVisibleChildSize() const
    1268             : {
    1269           0 :     Size aRet(GetSizePixel());
    1270           0 :     if (m_aVScroll.IsVisible())
    1271           0 :         aRet.Width() -= m_aVScroll.GetSizePixel().Width();
    1272           0 :     if (m_aHScroll.IsVisible())
    1273           0 :         aRet.Height() -= m_aHScroll.GetSizePixel().Height();
    1274           0 :     return aRet;
    1275             : }
    1276             : 
    1277           0 : bool VclScrolledWindow::set_property(const rtl::OString &rKey, const rtl::OString &rValue)
    1278             : {
    1279           0 :     bool bRet = VclBin::set_property(rKey, rValue);
    1280           0 :     m_aVScroll.Show(GetStyle() & WB_VERT);
    1281           0 :     m_aHScroll.Show(GetStyle() & WB_HORZ);
    1282           0 :     return bRet;
    1283             : }
    1284             : 
    1285           0 : Size getLegacyBestSizeForChildren(const Window &rWindow)
    1286             : {
    1287           0 :     Rectangle aBounds;
    1288             : 
    1289           0 :     for (const Window* pChild = rWindow.GetWindow(WINDOW_FIRSTCHILD); pChild;
    1290             :         pChild = pChild->GetWindow(WINDOW_NEXT))
    1291             :     {
    1292           0 :         if (!pChild->IsVisible())
    1293           0 :             continue;
    1294             : 
    1295           0 :         Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
    1296           0 :         aBounds.Union(aChildBounds);
    1297             :     }
    1298             : 
    1299           0 :     if (aBounds.IsEmpty())
    1300           0 :         return rWindow.GetSizePixel();
    1301             : 
    1302           0 :     Size aRet(aBounds.GetSize());
    1303           0 :     Point aTopLeft(aBounds.TopLeft());
    1304           0 :     aRet.Width() += aTopLeft.X()*2;
    1305           0 :     aRet.Height() += aTopLeft.Y()*2;
    1306             : 
    1307           0 :     return aRet;
    1308             : }
    1309             : 
    1310         680 : Window* getNonLayoutParent(Window *pWindow)
    1311             : {
    1312        1360 :     while (pWindow)
    1313             :     {
    1314         680 :         pWindow = pWindow->GetParent();
    1315         680 :         if (!pWindow || !isContainerWindow(*pWindow))
    1316         680 :             break;
    1317             :     }
    1318         680 :     return pWindow;
    1319             : }
    1320             : 
    1321           0 : Window* getNonLayoutRealParent(Window *pWindow)
    1322             : {
    1323           0 :     while (pWindow)
    1324             :     {
    1325           0 :         pWindow = pWindow->ImplGetParent();
    1326           0 :         if (!pWindow || !isContainerWindow(*pWindow))
    1327           0 :             break;
    1328             :     }
    1329           0 :     return pWindow;
    1330             : }
    1331             : 
    1332         408 : bool isVisibleInLayout(const Window *pWindow)
    1333             : {
    1334         408 :     bool bVisible = true;
    1335         816 :     while (bVisible)
    1336             :     {
    1337         408 :         bVisible = pWindow->IsVisible();
    1338         408 :         pWindow = pWindow->GetParent();
    1339         408 :         if (!pWindow || !isContainerWindow(*pWindow))
    1340         408 :             break;
    1341             :     }
    1342         408 :     return bVisible;
    1343             : }
    1344             : 
    1345           0 : bool isEnabledInLayout(const Window *pWindow)
    1346             : {
    1347           0 :     bool bEnabled = true;
    1348           0 :     while (bEnabled)
    1349             :     {
    1350           0 :         bEnabled = pWindow->IsEnabled();
    1351           0 :         pWindow = pWindow->GetParent();
    1352           0 :         if (!pWindow || !isContainerWindow(*pWindow))
    1353           0 :             break;
    1354             :     }
    1355           0 :     return bEnabled;
    1356         108 : }
    1357             : 
    1358             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10