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
getDefaultBorder()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
~WindowArranger()60cdf0e10cSrcweir WindowArranger::~WindowArranger()
61cdf0e10cSrcweir {}
62cdf0e10cSrcweir
setParent(WindowArranger * i_pParent)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
setParentWindow(Window * i_pNewParent)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
show(bool i_bShow,bool i_bImmediateUpdate)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
isVisible() const132cdf0e10cSrcweir 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
isVisible() const144cdf0e10cSrcweir 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
getExpandPriority() const157cdf0e10cSrcweir 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
getOptimalSize(WindowSizeType i_eType) const173cdf0e10cSrcweir 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
setPosSize(const Point & i_rPos,const Size & i_rSize)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
getProperties() const217cdf0e10cSrcweir 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
setProperties(const uno::Sequence<beans::PropertyValue> & i_rProps)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
~RowOrColumn()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
getOptimalSize(WindowSizeType i_eType) const288cdf0e10cSrcweir 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
distributeRowWidth(std::vector<Size> & io_rSizes,long,long i_nExtraWidth)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
distributeColumnHeight(std::vector<Size> & io_rSizes,long,long i_nExtraHeight)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
resize()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
addWindow(Window * i_pWindow,sal_Int32 i_nExpandPrio,const Size & i_rMinSize,size_t i_nIndex)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
addChild(boost::shared_ptr<WindowArranger> const & i_pChild,sal_Int32 i_nExpandPrio,size_t i_nIndex)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
remove(Window * i_pWindow)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
remove(boost::shared_ptr<WindowArranger> const & i_pChild)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
~LabeledElement()559cdf0e10cSrcweir LabeledElement::~LabeledElement()
560cdf0e10cSrcweir {
561cdf0e10cSrcweir m_aLabel.deleteChild();
562cdf0e10cSrcweir m_aElement.deleteChild();
563cdf0e10cSrcweir }
564cdf0e10cSrcweir
getOptimalSize(WindowSizeType i_eType) const565cdf0e10cSrcweir 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
resize()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
setLabel(Window * i_pLabel)626cdf0e10cSrcweir void LabeledElement::setLabel( Window* i_pLabel )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir m_aLabel.m_pElement = i_pLabel;
629cdf0e10cSrcweir m_aLabel.m_pChild.reset();
630cdf0e10cSrcweir }
631cdf0e10cSrcweir
setLabel(boost::shared_ptr<WindowArranger> const & i_pLabel)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
setElement(Window * i_pElement)638cdf0e10cSrcweir void LabeledElement::setElement( Window* i_pElement )
639cdf0e10cSrcweir {
640cdf0e10cSrcweir m_aElement.m_pElement = i_pElement;
641cdf0e10cSrcweir m_aElement.m_pChild.reset();
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
setElement(boost::shared_ptr<WindowArranger> const & i_pElement)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 //-----------------------------------------
~LabelColumn()653cdf0e10cSrcweir LabelColumn::~LabelColumn()
654cdf0e10cSrcweir {
655cdf0e10cSrcweir }
656cdf0e10cSrcweir
getLabelWidth() const657cdf0e10cSrcweir 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
getOptimalSize(WindowSizeType i_eType) const686cdf0e10cSrcweir 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
resize()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
addRow(Window * i_pLabel,boost::shared_ptr<WindowArranger> const & i_rElement,long i_nIndent)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
addRow(Window * i_pLabel,Window * i_pElement,long i_nIndent,const Size & i_rElementMinSize)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
~Indenter()783cdf0e10cSrcweir Indenter::~Indenter()
784cdf0e10cSrcweir {
785cdf0e10cSrcweir m_aElement.deleteChild();
786cdf0e10cSrcweir }
787cdf0e10cSrcweir
getOptimalSize(WindowSizeType i_eType) const788cdf0e10cSrcweir 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
resize()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
setWindow(Window * i_pWindow,sal_Int32 i_nExpandPrio)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
setChild(boost::shared_ptr<WindowArranger> const & i_pChild,sal_Int32 i_nExpandPrio)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 //-----------------------------------------
~MatrixArranger()829cdf0e10cSrcweir MatrixArranger::~MatrixArranger()
830cdf0e10cSrcweir {
831cdf0e10cSrcweir }
832cdf0e10cSrcweir
getOptimalSize(WindowSizeType i_eType,std::vector<long> & o_rColumnWidths,std::vector<long> & o_rRowHeights,std::vector<sal_Int32> & o_rColumnPrio,std::vector<sal_Int32> & o_rRowPrio) const833cdf0e10cSrcweir 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
getOptimalSize(WindowSizeType i_eType) const889cdf0e10cSrcweir 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
distributeExtraSize(std::vector<long> & io_rSizes,const std::vector<sal_Int32> & i_rPrios,long i_nExtraWidth)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
resize()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
addWindow(Window * i_pWindow,sal_uInt32 i_nX,sal_uInt32 i_nY,sal_Int32 i_nExpandPrio,const Size & i_rMinSize)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
remove(Window * i_pWindow)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
addChild(boost::shared_ptr<WindowArranger> const & i_pChild,sal_uInt32 i_nX,sal_uInt32 i_nY,sal_Int32 i_nExpandPrio)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
remove(boost::shared_ptr<WindowArranger> const & i_pChild)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 }
1071