1*9f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9f62ea84SAndrew Rist * distributed with this work for additional information 6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an 15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 17*9f62ea84SAndrew Rist * specific language governing permissions and limitations 18*9f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9f62ea84SAndrew Rist *************************************************************/ 21*9f62ea84SAndrew Rist 22*9f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "precompiled_vcl.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include "svdata.hxx" 27cdf0e10cSrcweir 28cdf0e10cSrcweir #include "vcl/arrange.hxx" 29cdf0e10cSrcweir #include "vcl/edit.hxx" 30cdf0e10cSrcweir #include "vcl/svapp.hxx" 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include "com/sun/star/beans/PropertyValue.hpp" 33cdf0e10cSrcweir #include "com/sun/star/awt/Rectangle.hpp" 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include "osl/diagnose.h" 36cdf0e10cSrcweir 37cdf0e10cSrcweir using namespace vcl; 38cdf0e10cSrcweir using namespace com::sun::star; 39cdf0e10cSrcweir 40cdf0e10cSrcweir // ---------------------------------------- 41cdf0e10cSrcweir // vcl::WindowArranger 42cdf0e10cSrcweir //----------------------------------------- 43cdf0e10cSrcweir 44cdf0e10cSrcweir long WindowArranger::getDefaultBorder() 45cdf0e10cSrcweir { 46cdf0e10cSrcweir ImplSVData* pSVData = ImplGetSVData(); 47cdf0e10cSrcweir long nResult = pSVData->maAppData.mnDefaultLayoutBorder; 48cdf0e10cSrcweir if( nResult < 0 ) 49cdf0e10cSrcweir { 50cdf0e10cSrcweir OutputDevice* pDefDev = Application::GetDefaultDevice(); 51cdf0e10cSrcweir if( pDefDev ) 52cdf0e10cSrcweir { 53cdf0e10cSrcweir Size aBorder( pDefDev->LogicToPixel( Size( 3, 3 ), MapMode( MAP_APPFONT ) ) ); 54cdf0e10cSrcweir nResult = pSVData->maAppData.mnDefaultLayoutBorder = aBorder.Height(); 55cdf0e10cSrcweir } 56cdf0e10cSrcweir } 57cdf0e10cSrcweir return nResult > 0 ? nResult : 0; 58cdf0e10cSrcweir } 59cdf0e10cSrcweir 60cdf0e10cSrcweir WindowArranger::~WindowArranger() 61cdf0e10cSrcweir {} 62cdf0e10cSrcweir 63cdf0e10cSrcweir void WindowArranger::setParent( WindowArranger* i_pParent ) 64cdf0e10cSrcweir { 65cdf0e10cSrcweir OSL_VERIFY( i_pParent->m_pParentWindow == m_pParentWindow || m_pParentWindow == NULL ); 66cdf0e10cSrcweir 67cdf0e10cSrcweir m_pParentArranger = i_pParent; 68cdf0e10cSrcweir m_pParentWindow = i_pParent->m_pParentWindow; 69cdf0e10cSrcweir setParentWindow( m_pParentWindow ); 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir void WindowArranger::setParentWindow( Window* i_pNewParent ) 73cdf0e10cSrcweir { 74cdf0e10cSrcweir m_pParentWindow = i_pNewParent; 75cdf0e10cSrcweir 76cdf0e10cSrcweir size_t nEle = countElements(); 77cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir Element* pEle = getElement( i ); 80cdf0e10cSrcweir if( pEle ) // sanity check 81cdf0e10cSrcweir { 82cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 83cdf0e10cSrcweir if( pEle->m_pElement ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir OSL_VERIFY( pEle->m_pElement->GetParent() == i_pNewParent ); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir #endif 88cdf0e10cSrcweir if( pEle->m_pChild ) 89cdf0e10cSrcweir pEle->m_pChild->setParentWindow( i_pNewParent ); 90cdf0e10cSrcweir } 91cdf0e10cSrcweir } 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir void WindowArranger::show( bool i_bShow, bool i_bImmediateUpdate ) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir size_t nEle = countElements(); 97cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir Element* pEle = getElement( i ); 100cdf0e10cSrcweir if( pEle ) // sanity check 101cdf0e10cSrcweir { 102cdf0e10cSrcweir pEle->m_bHidden = ! i_bShow; 103cdf0e10cSrcweir if( pEle->m_pElement ) 104cdf0e10cSrcweir pEle->m_pElement->Show( i_bShow ); 105cdf0e10cSrcweir if( pEle->m_pChild.get() ) 106cdf0e10cSrcweir pEle->m_pChild->show( i_bShow, false ); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir } 109cdf0e10cSrcweir if( m_pParentArranger ) 110cdf0e10cSrcweir { 111cdf0e10cSrcweir nEle = m_pParentArranger->countElements(); 112cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir Element* pEle = m_pParentArranger->getElement( i ); 115cdf0e10cSrcweir if( pEle && pEle->m_pChild.get() == this ) 116cdf0e10cSrcweir { 117cdf0e10cSrcweir pEle->m_bHidden = ! i_bShow; 118cdf0e10cSrcweir break; 119cdf0e10cSrcweir } 120cdf0e10cSrcweir } 121cdf0e10cSrcweir } 122cdf0e10cSrcweir if( i_bImmediateUpdate ) 123cdf0e10cSrcweir { 124cdf0e10cSrcweir // find the topmost parent 125cdf0e10cSrcweir WindowArranger* pResize = this; 126cdf0e10cSrcweir while( pResize->m_pParentArranger ) 127cdf0e10cSrcweir pResize = pResize->m_pParentArranger; 128cdf0e10cSrcweir pResize->resize(); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir } 131cdf0e10cSrcweir 132cdf0e10cSrcweir bool WindowArranger::isVisible() const 133cdf0e10cSrcweir { 134cdf0e10cSrcweir size_t nEle = countElements(); 135cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir const Element* pEle = getConstElement( i ); 138cdf0e10cSrcweir if( pEle->isVisible() ) 139cdf0e10cSrcweir return true; 140cdf0e10cSrcweir } 141cdf0e10cSrcweir return false; 142cdf0e10cSrcweir } 143cdf0e10cSrcweir 144cdf0e10cSrcweir bool WindowArranger::Element::isVisible() const 145cdf0e10cSrcweir { 146cdf0e10cSrcweir bool bVisible = false; 147cdf0e10cSrcweir if( ! m_bHidden ) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir if( m_pElement ) 150cdf0e10cSrcweir bVisible = m_pElement->IsVisible(); 151cdf0e10cSrcweir else if( m_pChild ) 152cdf0e10cSrcweir bVisible = m_pChild->isVisible(); 153cdf0e10cSrcweir } 154cdf0e10cSrcweir return bVisible; 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir sal_Int32 WindowArranger::Element::getExpandPriority() const 158cdf0e10cSrcweir { 159cdf0e10cSrcweir sal_Int32 nPrio = m_nExpandPriority; 160cdf0e10cSrcweir if( m_pChild && m_nExpandPriority >= 0 ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir size_t nElements = m_pChild->countElements(); 163cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir sal_Int32 nCPrio = m_pChild->getExpandPriority( i ); 166cdf0e10cSrcweir if( nCPrio > nPrio ) 167cdf0e10cSrcweir nPrio = nCPrio; 168cdf0e10cSrcweir } 169cdf0e10cSrcweir } 170cdf0e10cSrcweir return nPrio; 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir Size WindowArranger::Element::getOptimalSize( WindowSizeType i_eType ) const 174cdf0e10cSrcweir { 175cdf0e10cSrcweir Size aResult; 176cdf0e10cSrcweir if( ! m_bHidden ) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir bool bVisible = false; 179cdf0e10cSrcweir if( m_pElement && m_pElement->IsVisible() ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir aResult = m_pElement->GetOptimalSize( i_eType ); 182cdf0e10cSrcweir bVisible = true; 183cdf0e10cSrcweir } 184cdf0e10cSrcweir else if( m_pChild && m_pChild->isVisible() ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir aResult = m_pChild->getOptimalSize( i_eType ); 187cdf0e10cSrcweir bVisible = true; 188cdf0e10cSrcweir } 189cdf0e10cSrcweir if( bVisible ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir if( aResult.Width() < m_aMinSize.Width() ) 192cdf0e10cSrcweir aResult.Width() = m_aMinSize.Width(); 193cdf0e10cSrcweir if( aResult.Height() < m_aMinSize.Height() ) 194cdf0e10cSrcweir aResult.Height() = m_aMinSize.Height(); 195cdf0e10cSrcweir aResult.Width() += getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder ); 196cdf0e10cSrcweir aResult.Height() += getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder ); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir } 199cdf0e10cSrcweir 200cdf0e10cSrcweir return aResult; 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir void WindowArranger::Element::setPosSize( const Point& i_rPos, const Size& i_rSize ) 204cdf0e10cSrcweir { 205cdf0e10cSrcweir Point aPoint( i_rPos ); 206cdf0e10cSrcweir Size aSize( i_rSize ); 207cdf0e10cSrcweir aPoint.X() += getBorderValue( m_nLeftBorder ); 208cdf0e10cSrcweir aPoint.Y() += getBorderValue( m_nTopBorder ); 209cdf0e10cSrcweir aSize.Width() -= getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder ); 210cdf0e10cSrcweir aSize.Height() -= getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder ); 211cdf0e10cSrcweir if( m_pElement ) 212cdf0e10cSrcweir m_pElement->SetPosSizePixel( aPoint, aSize ); 213cdf0e10cSrcweir else if( m_pChild ) 214cdf0e10cSrcweir m_pChild->setManagedArea( Rectangle( aPoint, aSize ) ); 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > WindowArranger::getProperties() const 218cdf0e10cSrcweir { 219cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aRet( 3 ); 220cdf0e10cSrcweir aRet[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OuterBorder" ) ); 221cdf0e10cSrcweir aRet[0].Value = uno::makeAny( sal_Int32( getBorderValue( m_nOuterBorder ) ) ); 222cdf0e10cSrcweir aRet[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ManagedArea" ) ); 223cdf0e10cSrcweir awt::Rectangle aArea( m_aManagedArea.getX(), m_aManagedArea.getY(), m_aManagedArea.getWidth(), m_aManagedArea.getHeight() ); 224cdf0e10cSrcweir aRet[1].Value = uno::makeAny( aArea ); 225cdf0e10cSrcweir aRet[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ); 226cdf0e10cSrcweir aRet[2].Value = uno::makeAny( sal_Bool( isVisible() ) ); 227cdf0e10cSrcweir return aRet; 228cdf0e10cSrcweir } 229cdf0e10cSrcweir 230cdf0e10cSrcweir void WindowArranger::setProperties( const uno::Sequence< beans::PropertyValue >& i_rProps ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir const beans::PropertyValue* pProps = i_rProps.getConstArray(); 233cdf0e10cSrcweir bool bResize = false; 234cdf0e10cSrcweir for( sal_Int32 i = 0; i < i_rProps.getLength(); i++ ) 235cdf0e10cSrcweir { 236cdf0e10cSrcweir if( pProps[i].Name.equalsAscii( "OuterBorder" ) ) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir sal_Int32 nVal = 0; 239cdf0e10cSrcweir if( pProps[i].Value >>= nVal ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir if( getBorderValue( m_nOuterBorder ) != nVal ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir m_nOuterBorder = nVal; 244cdf0e10cSrcweir bResize = true; 245cdf0e10cSrcweir } 246cdf0e10cSrcweir } 247cdf0e10cSrcweir } 248cdf0e10cSrcweir else if( pProps[i].Name.equalsAscii( "ManagedArea" ) ) 249cdf0e10cSrcweir { 250cdf0e10cSrcweir awt::Rectangle aArea( 0, 0, 0, 0 ); 251cdf0e10cSrcweir if( pProps[i].Value >>= aArea ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir m_aManagedArea.setX( aArea.X ); 254cdf0e10cSrcweir m_aManagedArea.setY( aArea.Y ); 255cdf0e10cSrcweir m_aManagedArea.setWidth( aArea.Width ); 256cdf0e10cSrcweir m_aManagedArea.setHeight( aArea.Height ); 257cdf0e10cSrcweir bResize = true; 258cdf0e10cSrcweir } 259cdf0e10cSrcweir } 260cdf0e10cSrcweir else if( pProps[i].Name.equalsAscii( "Visible" ) ) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir sal_Bool bVal = sal_False; 263cdf0e10cSrcweir if( pProps[i].Value >>= bVal ) 264cdf0e10cSrcweir { 265cdf0e10cSrcweir show( bVal, false ); 266cdf0e10cSrcweir bResize = true; 267cdf0e10cSrcweir } 268cdf0e10cSrcweir } 269cdf0e10cSrcweir } 270cdf0e10cSrcweir if( bResize ) 271cdf0e10cSrcweir resize(); 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir 275cdf0e10cSrcweir // ---------------------------------------- 276cdf0e10cSrcweir // vcl::RowOrColumn 277cdf0e10cSrcweir //----------------------------------------- 278cdf0e10cSrcweir 279cdf0e10cSrcweir RowOrColumn::~RowOrColumn() 280cdf0e10cSrcweir { 281cdf0e10cSrcweir for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin(); 282cdf0e10cSrcweir it != m_aElements.end(); ++it ) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir it->deleteChild(); 285cdf0e10cSrcweir } 286cdf0e10cSrcweir } 287cdf0e10cSrcweir 288cdf0e10cSrcweir Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const 289cdf0e10cSrcweir { 290cdf0e10cSrcweir Size aRet( 0, 0 ); 291cdf0e10cSrcweir long nDistance = getBorderValue( m_nBorderWidth ); 292cdf0e10cSrcweir for( std::vector< WindowArranger::Element >::const_iterator it = m_aElements.begin(); 293cdf0e10cSrcweir it != m_aElements.end(); ++it ) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir if( it->isVisible() ) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir // get the size of type of the managed element 298cdf0e10cSrcweir Size aElementSize( it->getOptimalSize( i_eType ) ); 299cdf0e10cSrcweir if( m_bColumn ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir // add the distance between elements 302cdf0e10cSrcweir aRet.Height() += nDistance; 303cdf0e10cSrcweir // check if the width needs adjustment 304cdf0e10cSrcweir if( aRet.Width() < aElementSize.Width() ) 305cdf0e10cSrcweir aRet.Width() = aElementSize.Width(); 306cdf0e10cSrcweir aRet.Height() += aElementSize.Height(); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir else 309cdf0e10cSrcweir { 310cdf0e10cSrcweir // add the distance between elements 311cdf0e10cSrcweir aRet.Width() += nDistance; 312cdf0e10cSrcweir // check if the height needs adjustment 313cdf0e10cSrcweir if( aRet.Height() < aElementSize.Height() ) 314cdf0e10cSrcweir aRet.Height() = aElementSize.Height(); 315cdf0e10cSrcweir aRet.Width() += aElementSize.Width(); 316cdf0e10cSrcweir } 317cdf0e10cSrcweir } 318cdf0e10cSrcweir } 319cdf0e10cSrcweir 320cdf0e10cSrcweir if( aRet.Width() != 0 || aRet.Height() != 0 ) 321cdf0e10cSrcweir { 322cdf0e10cSrcweir // subtract the border for the first element 323cdf0e10cSrcweir if( m_bColumn ) 324cdf0e10cSrcweir aRet.Height() -= nDistance; 325cdf0e10cSrcweir else 326cdf0e10cSrcweir aRet.Width() -= nDistance; 327cdf0e10cSrcweir 328cdf0e10cSrcweir // add the outer border 329cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 330cdf0e10cSrcweir aRet.Width() += 2*nOuterBorder; 331cdf0e10cSrcweir aRet.Height() += 2*nOuterBorder; 332cdf0e10cSrcweir } 333cdf0e10cSrcweir 334cdf0e10cSrcweir return aRet; 335cdf0e10cSrcweir } 336cdf0e10cSrcweir 337cdf0e10cSrcweir void RowOrColumn::distributeRowWidth( std::vector<Size>& io_rSizes, long /*i_nUsedWidth*/, long i_nExtraWidth ) 338cdf0e10cSrcweir { 339cdf0e10cSrcweir if( ! io_rSizes.empty() && io_rSizes.size() == m_aElements.size() ) 340cdf0e10cSrcweir { 341cdf0e10cSrcweir // find all elements with the highest expand priority 342cdf0e10cSrcweir size_t nElements = m_aElements.size(); 343cdf0e10cSrcweir std::vector< size_t > aIndices; 344cdf0e10cSrcweir sal_Int32 nHighPrio = 0; 345cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir if( m_aElements[ i ].isVisible() ) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir sal_Int32 nCurPrio = m_aElements[ i ].getExpandPriority(); 350cdf0e10cSrcweir if( nCurPrio > nHighPrio ) 351cdf0e10cSrcweir { 352cdf0e10cSrcweir aIndices.clear(); 353cdf0e10cSrcweir nHighPrio = nCurPrio; 354cdf0e10cSrcweir } 355cdf0e10cSrcweir if( nCurPrio == nHighPrio ) 356cdf0e10cSrcweir aIndices.push_back( i ); 357cdf0e10cSrcweir } 358cdf0e10cSrcweir } 359cdf0e10cSrcweir 360cdf0e10cSrcweir // distribute extra space evenly among collected elements 361cdf0e10cSrcweir nElements = aIndices.size(); 362cdf0e10cSrcweir if( nElements > 0 ) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir long nDelta = i_nExtraWidth / nElements; 365cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 366cdf0e10cSrcweir { 367cdf0e10cSrcweir io_rSizes[ aIndices[i] ].Width() += nDelta; 368cdf0e10cSrcweir i_nExtraWidth -= nDelta; 369cdf0e10cSrcweir } 370cdf0e10cSrcweir // add the last pixels to the last row element 371cdf0e10cSrcweir if( i_nExtraWidth > 0 && nElements > 0 ) 372cdf0e10cSrcweir io_rSizes[aIndices.back()].Width() += i_nExtraWidth; 373cdf0e10cSrcweir } 374cdf0e10cSrcweir } 375cdf0e10cSrcweir } 376cdf0e10cSrcweir 377cdf0e10cSrcweir void RowOrColumn::distributeColumnHeight( std::vector<Size>& io_rSizes, long /*i_nUsedHeight*/, long i_nExtraHeight ) 378cdf0e10cSrcweir { 379cdf0e10cSrcweir if( ! io_rSizes.empty() && io_rSizes.size() == m_aElements.size() ) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir // find all elements with the highest expand priority 382cdf0e10cSrcweir size_t nElements = m_aElements.size(); 383cdf0e10cSrcweir std::vector< size_t > aIndices; 384cdf0e10cSrcweir sal_Int32 nHighPrio = 3; 385cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 386cdf0e10cSrcweir { 387cdf0e10cSrcweir if( m_aElements[ i ].isVisible() ) 388cdf0e10cSrcweir { 389cdf0e10cSrcweir sal_Int32 nCurPrio = m_aElements[ i ].getExpandPriority(); 390cdf0e10cSrcweir if( nCurPrio > nHighPrio ) 391cdf0e10cSrcweir { 392cdf0e10cSrcweir aIndices.clear(); 393cdf0e10cSrcweir nHighPrio = nCurPrio; 394cdf0e10cSrcweir } 395cdf0e10cSrcweir if( nCurPrio == nHighPrio ) 396cdf0e10cSrcweir aIndices.push_back( i ); 397cdf0e10cSrcweir } 398cdf0e10cSrcweir } 399cdf0e10cSrcweir 400cdf0e10cSrcweir // distribute extra space evenly among collected elements 401cdf0e10cSrcweir nElements = aIndices.size(); 402cdf0e10cSrcweir if( nElements > 0 ) 403cdf0e10cSrcweir { 404cdf0e10cSrcweir long nDelta = i_nExtraHeight / nElements; 405cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 406cdf0e10cSrcweir { 407cdf0e10cSrcweir io_rSizes[ aIndices[i] ].Height() += nDelta; 408cdf0e10cSrcweir i_nExtraHeight -= nDelta; 409cdf0e10cSrcweir } 410cdf0e10cSrcweir // add the last pixels to the last row element 411cdf0e10cSrcweir if( i_nExtraHeight > 0 && nElements > 0 ) 412cdf0e10cSrcweir io_rSizes[aIndices.back()].Height() += i_nExtraHeight; 413cdf0e10cSrcweir } 414cdf0e10cSrcweir } 415cdf0e10cSrcweir } 416cdf0e10cSrcweir 417cdf0e10cSrcweir void RowOrColumn::resize() 418cdf0e10cSrcweir { 419cdf0e10cSrcweir // check if we can get optimal size, else fallback to minimal size 420cdf0e10cSrcweir Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED ) ); 421cdf0e10cSrcweir WindowSizeType eType = WINDOWSIZE_PREFERRED; 422cdf0e10cSrcweir if( m_bColumn ) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir if( aOptSize.Height() > m_aManagedArea.GetHeight() ) 425cdf0e10cSrcweir eType = WINDOWSIZE_MINIMUM; 426cdf0e10cSrcweir } 427cdf0e10cSrcweir else 428cdf0e10cSrcweir { 429cdf0e10cSrcweir if( aOptSize.Width() > m_aManagedArea.GetWidth() ) 430cdf0e10cSrcweir eType = WINDOWSIZE_MINIMUM; 431cdf0e10cSrcweir } 432cdf0e10cSrcweir 433cdf0e10cSrcweir size_t nElements = m_aElements.size(); 434cdf0e10cSrcweir // get all element sizes for sizing 435cdf0e10cSrcweir std::vector<Size> aElementSizes( nElements ); 436cdf0e10cSrcweir long nDistance = getBorderValue( m_nBorderWidth ); 437cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 438cdf0e10cSrcweir long nUsedWidth = 2*nOuterBorder - (nElements ? nDistance : 0); 439cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir if( m_aElements[i].isVisible() ) 442cdf0e10cSrcweir { 443cdf0e10cSrcweir aElementSizes[i] = m_aElements[i].getOptimalSize( eType ); 444cdf0e10cSrcweir if( m_bColumn ) 445cdf0e10cSrcweir { 446cdf0e10cSrcweir aElementSizes[i].Width() = m_aManagedArea.GetWidth() - 2 * nOuterBorder; 447cdf0e10cSrcweir nUsedWidth += aElementSizes[i].Height() + nDistance; 448cdf0e10cSrcweir } 449cdf0e10cSrcweir else 450cdf0e10cSrcweir { 451cdf0e10cSrcweir aElementSizes[i].Height() = m_aManagedArea.GetHeight() - 2 * nOuterBorder; 452cdf0e10cSrcweir nUsedWidth += aElementSizes[i].Width() + nDistance; 453cdf0e10cSrcweir } 454cdf0e10cSrcweir } 455cdf0e10cSrcweir } 456cdf0e10cSrcweir 457cdf0e10cSrcweir long nExtraWidth = (m_bColumn ? m_aManagedArea.GetHeight() : m_aManagedArea.GetWidth()) - nUsedWidth; 458cdf0e10cSrcweir if( nExtraWidth > 0 ) 459cdf0e10cSrcweir { 460cdf0e10cSrcweir if( m_bColumn ) 461cdf0e10cSrcweir distributeColumnHeight( aElementSizes, nUsedWidth, nExtraWidth ); 462cdf0e10cSrcweir else 463cdf0e10cSrcweir distributeRowWidth( aElementSizes, nUsedWidth, nExtraWidth ); 464cdf0e10cSrcweir } 465cdf0e10cSrcweir 466cdf0e10cSrcweir // get starting position 467cdf0e10cSrcweir Point aElementPos( m_aManagedArea.TopLeft() ); 468cdf0e10cSrcweir // outer border 469cdf0e10cSrcweir aElementPos.X() += nOuterBorder; 470cdf0e10cSrcweir aElementPos.Y() += nOuterBorder; 471cdf0e10cSrcweir 472cdf0e10cSrcweir // position managed windows 473cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir // get the size of type of the managed element 476cdf0e10cSrcweir if( m_aElements[i].isVisible() ) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir m_aElements[i].setPosSize( aElementPos, aElementSizes[i] ); 479cdf0e10cSrcweir if( m_bColumn ) 480cdf0e10cSrcweir aElementPos.Y() += nDistance + aElementSizes[i].Height(); 481cdf0e10cSrcweir else 482cdf0e10cSrcweir aElementPos.X() += nDistance + aElementSizes[i].Width(); 483cdf0e10cSrcweir } 484cdf0e10cSrcweir } 485cdf0e10cSrcweir } 486cdf0e10cSrcweir 487cdf0e10cSrcweir size_t RowOrColumn::addWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio, const Size& i_rMinSize, size_t i_nIndex ) 488cdf0e10cSrcweir { 489cdf0e10cSrcweir size_t nIndex = i_nIndex; 490cdf0e10cSrcweir if( i_nIndex >= m_aElements.size() ) 491cdf0e10cSrcweir { 492cdf0e10cSrcweir nIndex = m_aElements.size(); 493cdf0e10cSrcweir m_aElements.push_back( WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) ); 494cdf0e10cSrcweir } 495cdf0e10cSrcweir else 496cdf0e10cSrcweir { 497cdf0e10cSrcweir std::vector< WindowArranger::Element >::iterator it = m_aElements.begin(); 498cdf0e10cSrcweir while( i_nIndex-- ) 499cdf0e10cSrcweir ++it; 500cdf0e10cSrcweir m_aElements.insert( it, WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) ); 501cdf0e10cSrcweir } 502cdf0e10cSrcweir return nIndex; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir 505cdf0e10cSrcweir size_t RowOrColumn::addChild( boost::shared_ptr<WindowArranger> const & i_pChild, sal_Int32 i_nExpandPrio, size_t i_nIndex ) 506cdf0e10cSrcweir { 507cdf0e10cSrcweir size_t nIndex = i_nIndex; 508cdf0e10cSrcweir if( i_nIndex >= m_aElements.size() ) 509cdf0e10cSrcweir { 510cdf0e10cSrcweir nIndex = m_aElements.size(); 511cdf0e10cSrcweir m_aElements.push_back( WindowArranger::Element( NULL, i_pChild, i_nExpandPrio ) ); 512cdf0e10cSrcweir } 513cdf0e10cSrcweir else 514cdf0e10cSrcweir { 515cdf0e10cSrcweir std::vector< WindowArranger::Element >::iterator it = m_aElements.begin(); 516cdf0e10cSrcweir while( i_nIndex-- ) 517cdf0e10cSrcweir ++it; 518cdf0e10cSrcweir m_aElements.insert( it, WindowArranger::Element( NULL, i_pChild, i_nExpandPrio ) ); 519cdf0e10cSrcweir } 520cdf0e10cSrcweir return nIndex; 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir void RowOrColumn::remove( Window* i_pWindow ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir if( i_pWindow ) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin(); 528cdf0e10cSrcweir it != m_aElements.end(); ++it ) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir if( it->m_pElement == i_pWindow ) 531cdf0e10cSrcweir { 532cdf0e10cSrcweir m_aElements.erase( it ); 533cdf0e10cSrcweir return; 534cdf0e10cSrcweir } 535cdf0e10cSrcweir } 536cdf0e10cSrcweir } 537cdf0e10cSrcweir } 538cdf0e10cSrcweir 539cdf0e10cSrcweir void RowOrColumn::remove( boost::shared_ptr<WindowArranger> const & i_pChild ) 540cdf0e10cSrcweir { 541cdf0e10cSrcweir if( i_pChild ) 542cdf0e10cSrcweir { 543cdf0e10cSrcweir for( std::vector< WindowArranger::Element >::iterator it = m_aElements.begin(); 544cdf0e10cSrcweir it != m_aElements.end(); ++it ) 545cdf0e10cSrcweir { 546cdf0e10cSrcweir if( it->m_pChild == i_pChild ) 547cdf0e10cSrcweir { 548cdf0e10cSrcweir m_aElements.erase( it ); 549cdf0e10cSrcweir return; 550cdf0e10cSrcweir } 551cdf0e10cSrcweir } 552cdf0e10cSrcweir } 553cdf0e10cSrcweir } 554cdf0e10cSrcweir 555cdf0e10cSrcweir // ---------------------------------------- 556cdf0e10cSrcweir // vcl::LabeledElement 557cdf0e10cSrcweir //----------------------------------------- 558cdf0e10cSrcweir 559cdf0e10cSrcweir LabeledElement::~LabeledElement() 560cdf0e10cSrcweir { 561cdf0e10cSrcweir m_aLabel.deleteChild(); 562cdf0e10cSrcweir m_aElement.deleteChild(); 563cdf0e10cSrcweir } 564cdf0e10cSrcweir 565cdf0e10cSrcweir Size LabeledElement::getOptimalSize( WindowSizeType i_eType ) const 566cdf0e10cSrcweir { 567cdf0e10cSrcweir Size aRet( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) ); 568cdf0e10cSrcweir if( aRet.Width() != 0 ) 569cdf0e10cSrcweir { 570cdf0e10cSrcweir if( m_nLabelColumnWidth != 0 ) 571cdf0e10cSrcweir aRet.Width() = m_nLabelColumnWidth; 572cdf0e10cSrcweir else 573cdf0e10cSrcweir aRet.Width() += getBorderValue( m_nDistance ); 574cdf0e10cSrcweir } 575cdf0e10cSrcweir Size aElementSize( m_aElement.getOptimalSize( i_eType ) ); 576cdf0e10cSrcweir aRet.Width() += aElementSize.Width(); 577cdf0e10cSrcweir if( aElementSize.Height() > aRet.Height() ) 578cdf0e10cSrcweir aRet.Height() = aElementSize.Height(); 579cdf0e10cSrcweir if( aRet.Height() != 0 ) 580cdf0e10cSrcweir aRet.Height() += 2 * getBorderValue( m_nOuterBorder ); 581cdf0e10cSrcweir 582cdf0e10cSrcweir return aRet; 583cdf0e10cSrcweir } 584cdf0e10cSrcweir 585cdf0e10cSrcweir void LabeledElement::resize() 586cdf0e10cSrcweir { 587cdf0e10cSrcweir Size aLabelSize( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) ); 588cdf0e10cSrcweir Size aElementSize( m_aElement.getOptimalSize( WINDOWSIZE_PREFERRED ) ); 589cdf0e10cSrcweir long nDistance = getBorderValue( m_nDistance ); 590cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 591cdf0e10cSrcweir if( nDistance + aLabelSize.Width() + aElementSize.Width() > m_aManagedArea.GetWidth() ) 592cdf0e10cSrcweir aElementSize = m_aElement.getOptimalSize( WINDOWSIZE_MINIMUM ); 593cdf0e10cSrcweir 594cdf0e10cSrcweir // align label and element vertically in LabeledElement 595cdf0e10cSrcweir long nYOff = (m_aManagedArea.GetHeight() - 2*nOuterBorder - aLabelSize.Height()) / 2; 596cdf0e10cSrcweir Point aPos( m_aManagedArea.Left(), 597cdf0e10cSrcweir m_aManagedArea.Top() + nOuterBorder + nYOff ); 598cdf0e10cSrcweir Size aSize( aLabelSize ); 599cdf0e10cSrcweir if( m_nLabelColumnWidth != 0 ) 600cdf0e10cSrcweir aSize.Width() = m_nLabelColumnWidth; 601cdf0e10cSrcweir m_aLabel.setPosSize( aPos, aSize ); 602cdf0e10cSrcweir 603cdf0e10cSrcweir aPos.X() += aSize.Width() + nDistance; 604cdf0e10cSrcweir nYOff = (m_aManagedArea.GetHeight() - 2*nOuterBorder - aElementSize.Height()) / 2; 605cdf0e10cSrcweir aPos.Y() = m_aManagedArea.Top() + nOuterBorder + nYOff; 606cdf0e10cSrcweir aSize.Width() = aElementSize.Width(); 607cdf0e10cSrcweir aSize.Height() = m_aManagedArea.GetHeight() - 2*nOuterBorder; 608cdf0e10cSrcweir 609cdf0e10cSrcweir // label style 610cdf0e10cSrcweir // 0: position left and right 611cdf0e10cSrcweir // 1: keep the element close to label and grow it 612cdf0e10cSrcweir // 2: keep the element close and don't grow it 613cdf0e10cSrcweir if( m_nLabelStyle == 0) 614cdf0e10cSrcweir { 615cdf0e10cSrcweir if( aPos.X() + aSize.Width() < m_aManagedArea.Right() ) 616cdf0e10cSrcweir aPos.X() = m_aManagedArea.Right() - aSize.Width(); 617cdf0e10cSrcweir } 618cdf0e10cSrcweir else if( m_nLabelStyle == 1 ) 619cdf0e10cSrcweir { 620cdf0e10cSrcweir if( aPos.X() + aSize.Width() < m_aManagedArea.Right() ) 621cdf0e10cSrcweir aSize.Width() = m_aManagedArea.Right() - aPos.X(); 622cdf0e10cSrcweir } 623cdf0e10cSrcweir m_aElement.setPosSize( aPos, aSize ); 624cdf0e10cSrcweir } 625cdf0e10cSrcweir 626cdf0e10cSrcweir void LabeledElement::setLabel( Window* i_pLabel ) 627cdf0e10cSrcweir { 628cdf0e10cSrcweir m_aLabel.m_pElement = i_pLabel; 629cdf0e10cSrcweir m_aLabel.m_pChild.reset(); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir 632cdf0e10cSrcweir void LabeledElement::setLabel( boost::shared_ptr<WindowArranger> const & i_pLabel ) 633cdf0e10cSrcweir { 634cdf0e10cSrcweir m_aLabel.m_pElement = NULL; 635cdf0e10cSrcweir m_aLabel.m_pChild = i_pLabel; 636cdf0e10cSrcweir } 637cdf0e10cSrcweir 638cdf0e10cSrcweir void LabeledElement::setElement( Window* i_pElement ) 639cdf0e10cSrcweir { 640cdf0e10cSrcweir m_aElement.m_pElement = i_pElement; 641cdf0e10cSrcweir m_aElement.m_pChild.reset(); 642cdf0e10cSrcweir } 643cdf0e10cSrcweir 644cdf0e10cSrcweir void LabeledElement::setElement( boost::shared_ptr<WindowArranger> const & i_pElement ) 645cdf0e10cSrcweir { 646cdf0e10cSrcweir m_aElement.m_pElement = NULL; 647cdf0e10cSrcweir m_aElement.m_pChild = i_pElement; 648cdf0e10cSrcweir } 649cdf0e10cSrcweir 650cdf0e10cSrcweir // ---------------------------------------- 651cdf0e10cSrcweir // vcl::LabelColumn 652cdf0e10cSrcweir //----------------------------------------- 653cdf0e10cSrcweir LabelColumn::~LabelColumn() 654cdf0e10cSrcweir { 655cdf0e10cSrcweir } 656cdf0e10cSrcweir 657cdf0e10cSrcweir long LabelColumn::getLabelWidth() const 658cdf0e10cSrcweir { 659cdf0e10cSrcweir long nWidth = 0; 660cdf0e10cSrcweir 661cdf0e10cSrcweir size_t nEle = countElements(); 662cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 663cdf0e10cSrcweir { 664cdf0e10cSrcweir const Element* pEle = getConstElement( i ); 665cdf0e10cSrcweir if( pEle && pEle->m_pChild.get() ) 666cdf0e10cSrcweir { 667cdf0e10cSrcweir const LabeledElement* pLabel = dynamic_cast< const LabeledElement* >(pEle->m_pChild.get()); 668cdf0e10cSrcweir if( pLabel ) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir Window* pLW = pLabel->getWindow( 0 ); 671cdf0e10cSrcweir if( pLW ) 672cdf0e10cSrcweir { 673cdf0e10cSrcweir Size aLabSize( pLW->GetOptimalSize( WINDOWSIZE_MINIMUM ) ); 674cdf0e10cSrcweir long nLB = 0; 675cdf0e10cSrcweir pLabel->getBorders(0, &nLB); 676cdf0e10cSrcweir aLabSize.Width() += getBorderValue( nLB ); 677cdf0e10cSrcweir if( aLabSize.Width() > nWidth ) 678cdf0e10cSrcweir nWidth = aLabSize.Width(); 679cdf0e10cSrcweir } 680cdf0e10cSrcweir } 681cdf0e10cSrcweir } 682cdf0e10cSrcweir } 683cdf0e10cSrcweir return nWidth + getBorderValue( getBorderWidth() ); 684cdf0e10cSrcweir } 685cdf0e10cSrcweir 686cdf0e10cSrcweir Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const 687cdf0e10cSrcweir { 688cdf0e10cSrcweir long nWidth = getLabelWidth(); 689cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 690cdf0e10cSrcweir Size aColumnSize; 691cdf0e10cSrcweir 692cdf0e10cSrcweir // every child is a LabeledElement 693cdf0e10cSrcweir size_t nEle = countElements(); 694cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 695cdf0e10cSrcweir { 696cdf0e10cSrcweir Size aElementSize; 697cdf0e10cSrcweir const Element* pEle = getConstElement( i ); 698cdf0e10cSrcweir if( pEle && pEle->m_pChild.get() ) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir const LabeledElement* pLabel = dynamic_cast< const LabeledElement* >(pEle->m_pChild.get()); 701cdf0e10cSrcweir if( pLabel ) // we have a label 702cdf0e10cSrcweir { 703cdf0e10cSrcweir aElementSize = pLabel->getLabelSize( WINDOWSIZE_MINIMUM ); 704cdf0e10cSrcweir if( aElementSize.Width() ) 705cdf0e10cSrcweir aElementSize.Width() = nWidth; 706cdf0e10cSrcweir Size aSize( pLabel->getElementSize( i_eType ) ); 707cdf0e10cSrcweir aElementSize.Width() += aSize.Width(); 708cdf0e10cSrcweir if( aSize.Height() > aElementSize.Height() ) 709cdf0e10cSrcweir aElementSize.Height() = aSize.Height(); 710cdf0e10cSrcweir } 711cdf0e10cSrcweir else // a non label, just treat it as a row 712cdf0e10cSrcweir { 713cdf0e10cSrcweir aElementSize = pEle->getOptimalSize( i_eType ); 714cdf0e10cSrcweir } 715cdf0e10cSrcweir } 716cdf0e10cSrcweir else if( pEle && pEle->m_pElement ) // a general window, treat is as a row 717cdf0e10cSrcweir { 718cdf0e10cSrcweir aElementSize = pEle->getOptimalSize( i_eType ); 719cdf0e10cSrcweir } 720cdf0e10cSrcweir if( aElementSize.Width() ) 721cdf0e10cSrcweir { 722cdf0e10cSrcweir aElementSize.Width() += 2*nOuterBorder; 723cdf0e10cSrcweir if( aElementSize.Width() > aColumnSize.Width() ) 724cdf0e10cSrcweir aColumnSize.Width() = aElementSize.Width(); 725cdf0e10cSrcweir } 726cdf0e10cSrcweir if( aElementSize.Height() ) 727cdf0e10cSrcweir { 728cdf0e10cSrcweir aColumnSize.Height() += getBorderValue( getBorderWidth() ) + aElementSize.Height(); 729cdf0e10cSrcweir } 730cdf0e10cSrcweir } 731cdf0e10cSrcweir if( nEle > 0 && aColumnSize.Height() ) 732cdf0e10cSrcweir { 733cdf0e10cSrcweir aColumnSize.Height() -= getBorderValue( getBorderWidth() ); // for the first element 734cdf0e10cSrcweir aColumnSize.Height() += 2*nOuterBorder; 735cdf0e10cSrcweir } 736cdf0e10cSrcweir return aColumnSize; 737cdf0e10cSrcweir } 738cdf0e10cSrcweir 739cdf0e10cSrcweir void LabelColumn::resize() 740cdf0e10cSrcweir { 741cdf0e10cSrcweir long nWidth = getLabelWidth(); 742cdf0e10cSrcweir size_t nEle = countElements(); 743cdf0e10cSrcweir for( size_t i = 0; i < nEle; i++ ) 744cdf0e10cSrcweir { 745cdf0e10cSrcweir Element* pEle = getElement( i ); 746cdf0e10cSrcweir if( pEle && pEle->m_pChild.get() ) 747cdf0e10cSrcweir { 748cdf0e10cSrcweir LabeledElement* pLabel = dynamic_cast< LabeledElement* >(pEle->m_pChild.get()); 749cdf0e10cSrcweir if( pLabel ) 750cdf0e10cSrcweir pLabel->setLabelColumnWidth( nWidth ); 751cdf0e10cSrcweir } 752cdf0e10cSrcweir } 753cdf0e10cSrcweir RowOrColumn::resize(); 754cdf0e10cSrcweir } 755cdf0e10cSrcweir 756cdf0e10cSrcweir size_t LabelColumn::addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> const& i_rElement, long i_nIndent ) 757cdf0e10cSrcweir { 758cdf0e10cSrcweir boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) ); 759cdf0e10cSrcweir xLabel->setLabel( i_pLabel ); 760cdf0e10cSrcweir xLabel->setBorders( 0, i_nIndent, 0, 0, 0 ); 761cdf0e10cSrcweir xLabel->setElement( i_rElement ); 762cdf0e10cSrcweir size_t nIndex = addChild( xLabel ); 763cdf0e10cSrcweir resize(); 764cdf0e10cSrcweir return nIndex; 765cdf0e10cSrcweir } 766cdf0e10cSrcweir 767cdf0e10cSrcweir size_t LabelColumn::addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent, const Size& i_rElementMinSize ) 768cdf0e10cSrcweir { 769cdf0e10cSrcweir boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) ); 770cdf0e10cSrcweir xLabel->setLabel( i_pLabel ); 771cdf0e10cSrcweir xLabel->setBorders( 0, i_nIndent, 0, 0, 0 ); 772cdf0e10cSrcweir xLabel->setElement( i_pElement ); 773cdf0e10cSrcweir xLabel->setMinimumSize( 1, i_rElementMinSize ); 774cdf0e10cSrcweir size_t nIndex = addChild( xLabel ); 775cdf0e10cSrcweir resize(); 776cdf0e10cSrcweir return nIndex; 777cdf0e10cSrcweir } 778cdf0e10cSrcweir 779cdf0e10cSrcweir // ---------------------------------------- 780cdf0e10cSrcweir // vcl::Indenter 781cdf0e10cSrcweir //----------------------------------------- 782cdf0e10cSrcweir 783cdf0e10cSrcweir Indenter::~Indenter() 784cdf0e10cSrcweir { 785cdf0e10cSrcweir m_aElement.deleteChild(); 786cdf0e10cSrcweir } 787cdf0e10cSrcweir 788cdf0e10cSrcweir Size Indenter::getOptimalSize( WindowSizeType i_eType ) const 789cdf0e10cSrcweir { 790cdf0e10cSrcweir Size aSize( m_aElement.getOptimalSize( i_eType ) ); 791cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 792cdf0e10cSrcweir long nIndent = getBorderValue( m_nIndent ); 793cdf0e10cSrcweir aSize.Width() += 2*nOuterBorder + nIndent; 794cdf0e10cSrcweir aSize.Height() += 2*nOuterBorder; 795cdf0e10cSrcweir return aSize; 796cdf0e10cSrcweir } 797cdf0e10cSrcweir 798cdf0e10cSrcweir void Indenter::resize() 799cdf0e10cSrcweir { 800cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 801cdf0e10cSrcweir long nIndent = getBorderValue( m_nIndent ); 802cdf0e10cSrcweir Point aPt( m_aManagedArea.TopLeft() ); 803cdf0e10cSrcweir aPt.X() += nOuterBorder + nIndent; 804cdf0e10cSrcweir aPt.Y() += nOuterBorder; 805cdf0e10cSrcweir Size aSz( m_aManagedArea.GetSize() ); 806cdf0e10cSrcweir aSz.Width() -= 2*nOuterBorder + nIndent; 807cdf0e10cSrcweir aSz.Height() -= 2*nOuterBorder; 808cdf0e10cSrcweir m_aElement.setPosSize( aPt, aSz ); 809cdf0e10cSrcweir } 810cdf0e10cSrcweir 811cdf0e10cSrcweir void Indenter::setWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio ) 812cdf0e10cSrcweir { 813cdf0e10cSrcweir OSL_VERIFY( (m_aElement.m_pElement == 0 && m_aElement.m_pChild == 0) || i_pWindow == 0 ); 814cdf0e10cSrcweir OSL_VERIFY( i_pWindow == 0 || i_pWindow->GetParent() == m_pParentWindow ); 815cdf0e10cSrcweir m_aElement.m_pElement = i_pWindow; 816cdf0e10cSrcweir m_aElement.m_nExpandPriority = i_nExpandPrio; 817cdf0e10cSrcweir } 818cdf0e10cSrcweir 819cdf0e10cSrcweir void Indenter::setChild( boost::shared_ptr<WindowArranger> const & i_pChild, sal_Int32 i_nExpandPrio ) 820cdf0e10cSrcweir { 821cdf0e10cSrcweir OSL_VERIFY( (m_aElement.m_pElement == 0 && m_aElement.m_pChild == 0 ) || i_pChild == 0 ); 822cdf0e10cSrcweir m_aElement.m_pChild = i_pChild; 823cdf0e10cSrcweir m_aElement.m_nExpandPriority = i_nExpandPrio; 824cdf0e10cSrcweir } 825cdf0e10cSrcweir 826cdf0e10cSrcweir // ---------------------------------------- 827cdf0e10cSrcweir // vcl::MatrixArranger 828cdf0e10cSrcweir //----------------------------------------- 829cdf0e10cSrcweir MatrixArranger::~MatrixArranger() 830cdf0e10cSrcweir { 831cdf0e10cSrcweir } 832cdf0e10cSrcweir 833cdf0e10cSrcweir Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, 834cdf0e10cSrcweir std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights, 835cdf0e10cSrcweir std::vector<sal_Int32>& o_rColumnPrio, std::vector<sal_Int32>& o_rRowPrio 836cdf0e10cSrcweir ) const 837cdf0e10cSrcweir { 838cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 839cdf0e10cSrcweir Size aMatrixSize( 2*nOuterBorder, 2*nOuterBorder ); 840cdf0e10cSrcweir 841cdf0e10cSrcweir // first find out the current number of rows and columns 842cdf0e10cSrcweir sal_uInt32 nRows = 0, nColumns = 0; 843cdf0e10cSrcweir for( std::vector< MatrixElement >::const_iterator it = m_aElements.begin(); 844cdf0e10cSrcweir it != m_aElements.end(); ++it ) 845cdf0e10cSrcweir { 846cdf0e10cSrcweir if( it->m_nX >= nColumns ) 847cdf0e10cSrcweir nColumns = it->m_nX+1; 848cdf0e10cSrcweir if( it->m_nY >= nRows ) 849cdf0e10cSrcweir nRows = it->m_nY+1; 850cdf0e10cSrcweir } 851cdf0e10cSrcweir 852cdf0e10cSrcweir // now allocate row and column depth vectors 853cdf0e10cSrcweir o_rColumnWidths = std::vector< long >( nColumns, 0 ); 854cdf0e10cSrcweir o_rRowHeights = std::vector< long >( nRows, 0 ); 855cdf0e10cSrcweir o_rColumnPrio = std::vector< sal_Int32 >( nColumns, 0 ); 856cdf0e10cSrcweir o_rRowPrio = std::vector< sal_Int32 >( nRows, 0 ); 857cdf0e10cSrcweir 858cdf0e10cSrcweir // get sizes an allocate them into rows/columns 859cdf0e10cSrcweir for( std::vector< MatrixElement >::const_iterator it = m_aElements.begin(); 860cdf0e10cSrcweir it != m_aElements.end(); ++it ) 861cdf0e10cSrcweir { 862cdf0e10cSrcweir Size aSize( it->getOptimalSize( i_eType ) ); 863cdf0e10cSrcweir if( aSize.Width() > o_rColumnWidths[ it->m_nX ] ) 864cdf0e10cSrcweir o_rColumnWidths[ it->m_nX ] = aSize.Width(); 865cdf0e10cSrcweir if( aSize.Height() > o_rRowHeights[ it->m_nY ] ) 866cdf0e10cSrcweir o_rRowHeights[ it->m_nY ] = aSize.Height(); 867cdf0e10cSrcweir if( it->m_nExpandPriority > o_rColumnPrio[ it->m_nX ] ) 868cdf0e10cSrcweir o_rColumnPrio[ it->m_nX ] = it->m_nExpandPriority; 869cdf0e10cSrcweir if( it->m_nExpandPriority > o_rRowPrio[ it->m_nY ] ) 870cdf0e10cSrcweir o_rRowPrio[ it->m_nY ] = it->m_nExpandPriority; 871cdf0e10cSrcweir } 872cdf0e10cSrcweir 873cdf0e10cSrcweir // add up sizes 874cdf0e10cSrcweir long nDistanceX = getBorderValue( m_nBorderX ); 875cdf0e10cSrcweir long nDistanceY = getBorderValue( m_nBorderY ); 876cdf0e10cSrcweir for( sal_uInt32 i = 0; i < nColumns; i++ ) 877cdf0e10cSrcweir aMatrixSize.Width() += o_rColumnWidths[i] + nDistanceX; 878cdf0e10cSrcweir if( nColumns > 0 ) 879cdf0e10cSrcweir aMatrixSize.Width() -= nDistanceX; 880cdf0e10cSrcweir 881cdf0e10cSrcweir for( sal_uInt32 i = 0; i < nRows; i++ ) 882cdf0e10cSrcweir aMatrixSize.Height() += o_rRowHeights[i] + nDistanceY; 883cdf0e10cSrcweir if( nRows > 0 ) 884cdf0e10cSrcweir aMatrixSize.Height() -= nDistanceY; 885cdf0e10cSrcweir 886cdf0e10cSrcweir return aMatrixSize; 887cdf0e10cSrcweir } 888cdf0e10cSrcweir 889cdf0e10cSrcweir Size MatrixArranger::getOptimalSize( WindowSizeType i_eType ) const 890cdf0e10cSrcweir { 891cdf0e10cSrcweir std::vector<long> aColumnWidths, aRowHeights; 892cdf0e10cSrcweir std::vector<sal_Int32> aColumnPrio, aRowPrio; 893cdf0e10cSrcweir return getOptimalSize( i_eType, aColumnWidths, aRowHeights, aColumnPrio, aRowPrio ); 894cdf0e10cSrcweir } 895cdf0e10cSrcweir 896cdf0e10cSrcweir void MatrixArranger::distributeExtraSize( std::vector<long>& io_rSizes, const std::vector<sal_Int32>& i_rPrios, long i_nExtraWidth ) 897cdf0e10cSrcweir { 898cdf0e10cSrcweir if( ! io_rSizes.empty() && io_rSizes.size() == i_rPrios.size() ) // sanity check 899cdf0e10cSrcweir { 900cdf0e10cSrcweir // find all elements with the highest expand priority 901cdf0e10cSrcweir size_t nElements = io_rSizes.size(); 902cdf0e10cSrcweir std::vector< size_t > aIndices; 903cdf0e10cSrcweir sal_Int32 nHighPrio = 0; 904cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 905cdf0e10cSrcweir { 906cdf0e10cSrcweir sal_Int32 nCurPrio = i_rPrios[ i ]; 907cdf0e10cSrcweir if( nCurPrio > nHighPrio ) 908cdf0e10cSrcweir { 909cdf0e10cSrcweir aIndices.clear(); 910cdf0e10cSrcweir nHighPrio = nCurPrio; 911cdf0e10cSrcweir } 912cdf0e10cSrcweir if( nCurPrio == nHighPrio ) 913cdf0e10cSrcweir aIndices.push_back( i ); 914cdf0e10cSrcweir } 915cdf0e10cSrcweir 916cdf0e10cSrcweir // distribute extra space evenly among collected elements 917cdf0e10cSrcweir nElements = aIndices.size(); 918cdf0e10cSrcweir if( nElements > 0 ) 919cdf0e10cSrcweir { 920cdf0e10cSrcweir long nDelta = i_nExtraWidth / nElements; 921cdf0e10cSrcweir for( size_t i = 0; i < nElements; i++ ) 922cdf0e10cSrcweir { 923cdf0e10cSrcweir io_rSizes[ aIndices[i] ] += nDelta; 924cdf0e10cSrcweir i_nExtraWidth -= nDelta; 925cdf0e10cSrcweir } 926cdf0e10cSrcweir // add the last pixels to the last row element 927cdf0e10cSrcweir if( i_nExtraWidth > 0 && nElements > 0 ) 928cdf0e10cSrcweir io_rSizes[aIndices.back()] += i_nExtraWidth; 929cdf0e10cSrcweir } 930cdf0e10cSrcweir } 931cdf0e10cSrcweir } 932cdf0e10cSrcweir 933cdf0e10cSrcweir 934cdf0e10cSrcweir void MatrixArranger::resize() 935cdf0e10cSrcweir { 936cdf0e10cSrcweir // assure that we have at least one row and column 937cdf0e10cSrcweir if( m_aElements.empty() ) 938cdf0e10cSrcweir return; 939cdf0e10cSrcweir 940cdf0e10cSrcweir // check if we can get optimal size, else fallback to minimal size 941cdf0e10cSrcweir std::vector<long> aColumnWidths, aRowHeights; 942cdf0e10cSrcweir std::vector<sal_Int32> aColumnPrio, aRowPrio; 943cdf0e10cSrcweir Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED, aColumnWidths, aRowHeights, aColumnPrio, aRowPrio ) ); 944cdf0e10cSrcweir if( aOptSize.Height() > m_aManagedArea.GetHeight() || 945cdf0e10cSrcweir aOptSize.Width() > m_aManagedArea.GetWidth() ) 946cdf0e10cSrcweir { 947cdf0e10cSrcweir std::vector<long> aMinColumnWidths, aMinRowHeights; 948cdf0e10cSrcweir getOptimalSize( WINDOWSIZE_MINIMUM, aMinColumnWidths, aMinRowHeights, aColumnPrio, aRowPrio ); 949cdf0e10cSrcweir if( aOptSize.Height() > m_aManagedArea.GetHeight() ) 950cdf0e10cSrcweir aRowHeights = aMinRowHeights; 951cdf0e10cSrcweir if( aOptSize.Width() > m_aManagedArea.GetWidth() ) 952cdf0e10cSrcweir aColumnWidths = aMinColumnWidths; 953cdf0e10cSrcweir } 954cdf0e10cSrcweir 955cdf0e10cSrcweir // distribute extra space available 956cdf0e10cSrcweir long nExtraSize = m_aManagedArea.GetWidth(); 957cdf0e10cSrcweir for( size_t i = 0; i < aColumnWidths.size(); ++i ) 958cdf0e10cSrcweir nExtraSize -= aColumnWidths[i] + m_nBorderX; 959cdf0e10cSrcweir if( nExtraSize > 0 ) 960cdf0e10cSrcweir distributeExtraSize( aColumnWidths, aColumnPrio, nExtraSize ); 961cdf0e10cSrcweir nExtraSize = m_aManagedArea.GetHeight(); 962cdf0e10cSrcweir for( size_t i = 0; i < aRowHeights.size(); ++i ) 963cdf0e10cSrcweir nExtraSize -= aRowHeights[i] + m_nBorderY; 964cdf0e10cSrcweir if( nExtraSize > 0 ) 965cdf0e10cSrcweir distributeExtraSize( aRowHeights, aRowPrio, nExtraSize ); 966cdf0e10cSrcweir 967cdf0e10cSrcweir // prepare offsets 968cdf0e10cSrcweir long nDistanceX = getBorderValue( m_nBorderX ); 969cdf0e10cSrcweir long nDistanceY = getBorderValue( m_nBorderY ); 970cdf0e10cSrcweir long nOuterBorder = getBorderValue( m_nOuterBorder ); 971cdf0e10cSrcweir std::vector<long> aColumnX( aColumnWidths.size() ); 972cdf0e10cSrcweir aColumnX[0] = m_aManagedArea.Left() + nOuterBorder; 973cdf0e10cSrcweir for( size_t i = 1; i < aColumnX.size(); i++ ) 974cdf0e10cSrcweir aColumnX[i] = aColumnX[i-1] + aColumnWidths[i-1] + nDistanceX; 975cdf0e10cSrcweir 976cdf0e10cSrcweir std::vector<long> aRowY( aRowHeights.size() ); 977cdf0e10cSrcweir aRowY[0] = m_aManagedArea.Top() + nOuterBorder; 978cdf0e10cSrcweir for( size_t i = 1; i < aRowY.size(); i++ ) 979cdf0e10cSrcweir aRowY[i] = aRowY[i-1] + aRowHeights[i-1] + nDistanceY; 980cdf0e10cSrcweir 981cdf0e10cSrcweir // now iterate over the elements and assign their positions 982cdf0e10cSrcweir for( std::vector< MatrixElement >::iterator it = m_aElements.begin(); 983cdf0e10cSrcweir it != m_aElements.end(); ++it ) 984cdf0e10cSrcweir { 985cdf0e10cSrcweir Point aCellPos( aColumnX[it->m_nX], aRowY[it->m_nY] ); 986cdf0e10cSrcweir Size aCellSize( aColumnWidths[it->m_nX], aRowHeights[it->m_nY] ); 987cdf0e10cSrcweir it->setPosSize( aCellPos, aCellSize ); 988cdf0e10cSrcweir } 989cdf0e10cSrcweir } 990cdf0e10cSrcweir 991cdf0e10cSrcweir size_t MatrixArranger::addWindow( Window* i_pWindow, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio, const Size& i_rMinSize ) 992cdf0e10cSrcweir { 993cdf0e10cSrcweir sal_uInt64 nMapValue = getMap( i_nX, i_nY ); 994cdf0e10cSrcweir std::map< sal_uInt64, size_t >::const_iterator it = m_aMatrixMap.find( nMapValue ); 995cdf0e10cSrcweir size_t nIndex = 0; 996cdf0e10cSrcweir if( it == m_aMatrixMap.end() ) 997cdf0e10cSrcweir { 998cdf0e10cSrcweir m_aMatrixMap[ nMapValue ] = nIndex = m_aElements.size(); 999cdf0e10cSrcweir m_aElements.push_back( MatrixElement( i_pWindow, i_nX, i_nY, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) ); 1000cdf0e10cSrcweir } 1001cdf0e10cSrcweir else 1002cdf0e10cSrcweir { 1003cdf0e10cSrcweir MatrixElement& rEle( m_aElements[ it->second ] ); 1004cdf0e10cSrcweir rEle.m_pElement = i_pWindow; 1005cdf0e10cSrcweir rEle.m_pChild.reset(); 1006cdf0e10cSrcweir rEle.m_nExpandPriority = i_nExpandPrio; 1007cdf0e10cSrcweir rEle.m_aMinSize = i_rMinSize; 1008cdf0e10cSrcweir rEle.m_nX = i_nX; 1009cdf0e10cSrcweir rEle.m_nY = i_nY; 1010cdf0e10cSrcweir nIndex = it->second; 1011cdf0e10cSrcweir } 1012cdf0e10cSrcweir return nIndex; 1013cdf0e10cSrcweir } 1014cdf0e10cSrcweir 1015cdf0e10cSrcweir void MatrixArranger::remove( Window* i_pWindow ) 1016cdf0e10cSrcweir { 1017cdf0e10cSrcweir if( i_pWindow ) 1018cdf0e10cSrcweir { 1019cdf0e10cSrcweir for( std::vector< MatrixElement >::iterator it = m_aElements.begin(); 1020cdf0e10cSrcweir it != m_aElements.end(); ++it ) 1021cdf0e10cSrcweir { 1022cdf0e10cSrcweir if( it->m_pElement == i_pWindow ) 1023cdf0e10cSrcweir { 1024cdf0e10cSrcweir m_aMatrixMap.erase( getMap( it->m_nX, it->m_nY ) ); 1025cdf0e10cSrcweir m_aElements.erase( it ); 1026cdf0e10cSrcweir return; 1027cdf0e10cSrcweir } 1028cdf0e10cSrcweir } 1029cdf0e10cSrcweir } 1030cdf0e10cSrcweir } 1031cdf0e10cSrcweir 1032cdf0e10cSrcweir size_t MatrixArranger::addChild( boost::shared_ptr<WindowArranger> const &i_pChild, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio ) 1033cdf0e10cSrcweir { 1034cdf0e10cSrcweir sal_uInt64 nMapValue = getMap( i_nX, i_nY ); 1035cdf0e10cSrcweir std::map< sal_uInt64, size_t >::const_iterator it = m_aMatrixMap.find( nMapValue ); 1036cdf0e10cSrcweir size_t nIndex = 0; 1037cdf0e10cSrcweir if( it == m_aMatrixMap.end() ) 1038cdf0e10cSrcweir { 1039cdf0e10cSrcweir m_aMatrixMap[ nMapValue ] = nIndex = m_aElements.size(); 1040cdf0e10cSrcweir m_aElements.push_back( MatrixElement( NULL, i_nX, i_nY, i_pChild, i_nExpandPrio ) ); 1041cdf0e10cSrcweir } 1042cdf0e10cSrcweir else 1043cdf0e10cSrcweir { 1044cdf0e10cSrcweir MatrixElement& rEle( m_aElements[ it->second ] ); 1045cdf0e10cSrcweir rEle.m_pElement = 0; 1046cdf0e10cSrcweir rEle.m_pChild = i_pChild; 1047cdf0e10cSrcweir rEle.m_nExpandPriority = i_nExpandPrio; 1048cdf0e10cSrcweir rEle.m_nX = i_nX; 1049cdf0e10cSrcweir rEle.m_nY = i_nY; 1050cdf0e10cSrcweir nIndex = it->second; 1051cdf0e10cSrcweir } 1052cdf0e10cSrcweir return nIndex; 1053cdf0e10cSrcweir } 1054cdf0e10cSrcweir 1055cdf0e10cSrcweir void MatrixArranger::remove( boost::shared_ptr<WindowArranger> const &i_pChild ) 1056cdf0e10cSrcweir { 1057cdf0e10cSrcweir if( i_pChild ) 1058cdf0e10cSrcweir { 1059cdf0e10cSrcweir for( std::vector< MatrixElement >::iterator it = m_aElements.begin(); 1060cdf0e10cSrcweir it != m_aElements.end(); ++it ) 1061cdf0e10cSrcweir { 1062cdf0e10cSrcweir if( it->m_pChild == i_pChild ) 1063cdf0e10cSrcweir { 1064cdf0e10cSrcweir m_aMatrixMap.erase( getMap( it->m_nX, it->m_nY ) ); 1065cdf0e10cSrcweir m_aElements.erase( it ); 1066cdf0e10cSrcweir return; 1067cdf0e10cSrcweir } 1068cdf0e10cSrcweir } 1069cdf0e10cSrcweir } 1070cdf0e10cSrcweir } 1071cdf0e10cSrcweir 1072