Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef _VCL_ARRANGE_HXX
30 : : #define _VCL_ARRANGE_HXX
31 : :
32 : : #include "vcl/window.hxx"
33 : :
34 : : #include <vector>
35 : : #include <map>
36 : : #include <boost/shared_ptr.hpp>
37 : :
38 : : namespace vcl
39 : : {
40 : : /* some helper classes for simple window layouting
41 : : guidelines:
42 : : - a WindowArranger is not a Window
43 : : - a WindowArranger hierarchy manages exactly one level of child windows inside a common parent
44 : : this is to keep the vcl Window hierarchy flat, as some code like accelerators depend on such behavior
45 : : - a WindowArranger never becomes owner of a Window, windows need to be destroyed separately
46 : : - a WindowArranger however always is owner of its child WindowArrangers, that is the
47 : : WindowArranger hierarchy will keep track of its objects and delete them
48 : : - a managed element of a WindowArranger can either be a Window (a leaf in the hierarchy)
49 : : or a child WindowArranger (a node in the hierarchy), but never both
50 : : */
51 : :
52 : : class VCL_DLLPUBLIC WindowArranger
53 : : {
54 : : protected:
55 : 0 : struct Element
56 : : {
57 : : Window* m_pElement;
58 : : boost::shared_ptr<WindowArranger> m_pChild;
59 : : sal_Int32 m_nExpandPriority;
60 : : Size m_aMinSize;
61 : : bool m_bHidden;
62 : : long m_nLeftBorder;
63 : : long m_nTopBorder;
64 : : long m_nRightBorder;
65 : : long m_nBottomBorder;
66 : :
67 : 0 : Element()
68 : : : m_pElement( NULL )
69 : : , m_pChild()
70 : : , m_nExpandPriority( 0 )
71 : : , m_bHidden( false )
72 : : , m_nLeftBorder( 0 )
73 : : , m_nTopBorder( 0 )
74 : : , m_nRightBorder( 0 )
75 : 0 : , m_nBottomBorder( 0 )
76 : 0 : {}
77 : :
78 : 0 : Element( Window* i_pWin,
79 : : boost::shared_ptr<WindowArranger> const & i_pChild = boost::shared_ptr<WindowArranger>(),
80 : : sal_Int32 i_nExpandPriority = 0,
81 : : const Size& i_rMinSize = Size()
82 : : )
83 : : : m_pElement( i_pWin )
84 : : , m_pChild( i_pChild )
85 : : , m_nExpandPriority( i_nExpandPriority )
86 : : , m_aMinSize( i_rMinSize )
87 : : , m_bHidden( false )
88 : : , m_nLeftBorder( 0 )
89 : : , m_nTopBorder( 0 )
90 : : , m_nRightBorder( 0 )
91 : 0 : , m_nBottomBorder( 0 )
92 : 0 : {}
93 : :
94 : 0 : void deleteChild() { m_pChild.reset(); }
95 : :
96 : : sal_Int32 getExpandPriority() const;
97 : : Size getOptimalSize( WindowSizeType ) const;
98 : : bool isVisible() const;
99 : : void setPosSize( const Point&, const Size& );
100 : : };
101 : :
102 : : Window* m_pParentWindow;
103 : : WindowArranger* m_pParentArranger;
104 : : Rectangle m_aManagedArea;
105 : : long m_nOuterBorder;
106 : :
107 : : rtl::OUString m_aIdentifier;
108 : :
109 : : virtual Element* getElement( size_t i_nIndex ) = 0;
110 : 0 : const Element* getConstElement( size_t i_nIndex ) const
111 : 0 : { return const_cast<WindowArranger*>(this)->getElement( i_nIndex ); }
112 : :
113 : :
114 : : public:
115 : : static long getDefaultBorder();
116 : :
117 : 0 : static long getBorderValue( long nBorder )
118 [ # # ]: 0 : { return nBorder >= 0 ? nBorder : -nBorder * getDefaultBorder(); }
119 : :
120 : 0 : WindowArranger( WindowArranger* i_pParent = NULL )
121 : : : m_pParentWindow( i_pParent ? i_pParent->m_pParentWindow : NULL )
122 : : , m_pParentArranger( i_pParent )
123 [ # # ]: 0 : , m_nOuterBorder( 0 )
124 : 0 : {}
125 : : virtual ~WindowArranger();
126 : :
127 : : // ask what would be the optimal size
128 : : virtual Size getOptimalSize( WindowSizeType ) const = 0;
129 : : // call Resize to trigger layouting inside the managed area
130 : : // without function while parent window is unset
131 : : virtual void resize() = 0;
132 : : // avoid this if possible, using the constructor instead
133 : : // there can be only one parent window and all managed windows MUST
134 : : // be direct children of that window
135 : : // violating that condition will result in undefined behavior
136 : : virtual void setParentWindow( Window* );
137 : :
138 : : virtual void setParent( WindowArranger* );
139 : :
140 : : virtual size_t countElements() const = 0;
141 : : boost::shared_ptr<WindowArranger> getChild( size_t i_nIndex ) const
142 : : {
143 : : const Element* pEle = getConstElement( i_nIndex );
144 : : return pEle ? pEle->m_pChild : boost::shared_ptr<WindowArranger>();
145 : : }
146 : 0 : Window* getWindow( size_t i_nIndex ) const
147 : : {
148 : 0 : const Element* pEle = getConstElement( i_nIndex );
149 [ # # ]: 0 : return pEle ? pEle->m_pElement : NULL;
150 : : }
151 : :
152 : : virtual bool isVisible() const; // true if any element is visible
153 : :
154 : : virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getProperties() const;
155 : : virtual void setProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& );
156 : :
157 : 0 : sal_Int32 getExpandPriority( size_t i_nIndex ) const
158 : : {
159 : 0 : const Element* pEle = getConstElement( i_nIndex );
160 [ # # ]: 0 : return pEle ? pEle->getExpandPriority() : 0;
161 : : }
162 : :
163 : : Size getMinimumSize( size_t i_nIndex ) const
164 : : {
165 : : const Element* pEle = getConstElement( i_nIndex );
166 : : return pEle ? pEle->m_aMinSize : Size();
167 : : }
168 : :
169 : 0 : bool setMinimumSize( size_t i_nIndex, const Size& i_rMinSize )
170 : : {
171 : 0 : Element* pEle = getElement( i_nIndex );
172 [ # # ]: 0 : if( pEle )
173 : 0 : pEle->m_aMinSize = i_rMinSize;
174 : 0 : return pEle != NULL;
175 : : }
176 : :
177 : 0 : void setBorders( size_t i_nIndex, long i_nLeft, long i_nTop, long i_nRight, long i_nBottom )
178 : : {
179 : 0 : Element* pEle = getElement( i_nIndex );
180 [ # # ]: 0 : if( pEle )
181 : : {
182 : 0 : pEle->m_nLeftBorder = i_nLeft;
183 : 0 : pEle->m_nRightBorder = i_nRight;
184 : 0 : pEle->m_nTopBorder = i_nTop;
185 : 0 : pEle->m_nBottomBorder = i_nBottom;
186 : : }
187 : 0 : }
188 : :
189 : 0 : void getBorders( size_t i_nIndex, long* i_pLeft = NULL, long* i_pTop = NULL, long* i_pRight = NULL, long* i_pBottom = NULL ) const
190 : : {
191 : 0 : const Element* pEle = getConstElement( i_nIndex );
192 [ # # ]: 0 : if( pEle )
193 : : {
194 [ # # ]: 0 : if( i_pLeft ) *i_pLeft = pEle->m_nLeftBorder;
195 [ # # ]: 0 : if( i_pTop ) *i_pTop = pEle->m_nTopBorder;
196 [ # # ]: 0 : if( i_pRight ) *i_pRight = pEle->m_nRightBorder;
197 [ # # ]: 0 : if( i_pBottom ) *i_pBottom = pEle->m_nBottomBorder;
198 : : }
199 : 0 : }
200 : :
201 : :
202 : : void show( bool i_bShow = true, bool i_bImmediateUpdate = true );
203 : :
204 : 0 : void setManagedArea( const Rectangle& i_rArea )
205 : : {
206 : 0 : m_aManagedArea = i_rArea;
207 : 0 : resize();
208 : 0 : }
209 : : const Rectangle& getManagedArea() const { return m_aManagedArea; }
210 : :
211 : 0 : void setOuterBorder( long i_nBorder )
212 : : {
213 : 0 : m_nOuterBorder = i_nBorder;
214 : 0 : resize();
215 : 0 : }
216 : :
217 : : const rtl::OUString getIdentifier() const
218 : : { return m_aIdentifier; }
219 : :
220 : : void setIdentifier( const rtl::OUString& i_rId )
221 : : { m_aIdentifier = i_rId; }
222 : : };
223 : :
224 : : class VCL_DLLPUBLIC RowOrColumn : public WindowArranger
225 : : {
226 : : long m_nBorderWidth;
227 : : bool m_bColumn;
228 : :
229 : : std::vector< WindowArranger::Element > m_aElements;
230 : :
231 : : void distributeRowWidth( std::vector< Size >& io_rSizes, long i_nUsedWidth, long i_nExtraWidth );
232 : : void distributeColumnHeight( std::vector< Size >& io_rSizes, long i_nUsedHeight, long i_nExtraHeight );
233 : : protected:
234 : 0 : virtual Element* getElement( size_t i_nIndex )
235 [ # # ]: 0 : { return i_nIndex < m_aElements.size() ? &m_aElements[ i_nIndex ] : 0; }
236 : :
237 : : public:
238 : 0 : RowOrColumn( WindowArranger* i_pParent = NULL,
239 : : bool bColumn = true, long i_nBorderWidth = -1 )
240 : : : WindowArranger( i_pParent )
241 : : , m_nBorderWidth( i_nBorderWidth )
242 [ # # ]: 0 : , m_bColumn( bColumn )
243 : 0 : {}
244 : :
245 : : virtual ~RowOrColumn();
246 : :
247 : : virtual Size getOptimalSize( WindowSizeType ) const;
248 : : virtual void resize();
249 : 0 : virtual size_t countElements() const { return m_aElements.size(); }
250 : :
251 : : // add a managed window at the given index
252 : : // an index smaller than zero means add the window at the end
253 : : size_t addWindow( Window*, sal_Int32 i_nExpandPrio = 0, const Size& i_rMinSize = Size(), size_t i_nIndex = ~0 );
254 : :
255 : : size_t addChild( boost::shared_ptr<WindowArranger> const &, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 );
256 : : // convenience: use for addChild( new WindowArranger( ... ) ) constructs
257 : 0 : size_t addChild( WindowArranger* i_pNewChild, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 )
258 [ # # ]: 0 : { return addChild( boost::shared_ptr<WindowArranger>( i_pNewChild ), i_nExpandPrio, i_nIndex ); }
259 : :
260 : 0 : long getBorderWidth() const { return m_nBorderWidth; }
261 : : };
262 : :
263 : : class VCL_DLLPUBLIC LabeledElement : public WindowArranger
264 : : {
265 : : WindowArranger::Element m_aLabel;
266 : : WindowArranger::Element m_aElement;
267 : : long m_nDistance;
268 : : long m_nLabelColumnWidth;
269 : : int m_nLabelStyle;
270 : : protected:
271 : 0 : virtual Element* getElement( size_t i_nIndex )
272 : : {
273 [ # # ]: 0 : if( i_nIndex == 0 )
274 : 0 : return &m_aLabel;
275 [ # # ]: 0 : else if( i_nIndex == 1 )
276 : 0 : return &m_aElement;
277 : 0 : return 0;
278 : : }
279 : :
280 : : public:
281 : 0 : LabeledElement( WindowArranger* i_pParent = NULL, int i_nLabelStyle = 0, long i_nDistance = -1 )
282 : : : WindowArranger( i_pParent )
283 : : , m_nDistance( i_nDistance )
284 : : , m_nLabelColumnWidth( 0 )
285 [ # # ][ # # ]: 0 : , m_nLabelStyle( i_nLabelStyle )
286 : 0 : {}
287 : :
288 : : virtual ~LabeledElement();
289 : :
290 : : virtual Size getOptimalSize( WindowSizeType ) const;
291 : : virtual void resize();
292 : 0 : virtual size_t countElements() const { return 2; }
293 : :
294 : : void setLabel( Window* );
295 : : void setElement( Window* );
296 : : void setElement( boost::shared_ptr<WindowArranger> const & );
297 : 0 : void setLabelColumnWidth( long i_nWidth )
298 : 0 : { m_nLabelColumnWidth = i_nWidth; }
299 : :
300 : 0 : Size getLabelSize( WindowSizeType i_eType ) const
301 : 0 : { return m_aLabel.getOptimalSize( i_eType ); }
302 : 0 : Size getElementSize( WindowSizeType i_eType ) const
303 : 0 : { return m_aElement.getOptimalSize( i_eType ); }
304 : : };
305 : :
306 : : class VCL_DLLPUBLIC LabelColumn : public RowOrColumn
307 : : {
308 : : long getLabelWidth() const;
309 : : public:
310 : 0 : LabelColumn( WindowArranger* i_pParent = NULL, long i_nBorderWidth = -1 )
311 : 0 : : RowOrColumn( i_pParent, true, i_nBorderWidth )
312 : 0 : {}
313 : : virtual ~LabelColumn();
314 : :
315 : : virtual Size getOptimalSize( WindowSizeType ) const;
316 : : virtual void resize();
317 : :
318 : : // returns the index of the added label
319 : : size_t addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> const& i_rElement, long i_nIndent = 0 );
320 : : size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0, const Size& i_rElementMinSize = Size() );
321 : : };
322 : :
323 : : class VCL_DLLPUBLIC Indenter : public WindowArranger
324 : : {
325 : : long m_nIndent;
326 : : WindowArranger::Element m_aElement;
327 : :
328 : : protected:
329 : 0 : virtual Element* getElement( size_t i_nIndex )
330 [ # # ]: 0 : { return i_nIndex == 0 ? &m_aElement : NULL; }
331 : :
332 : : public:
333 : 0 : Indenter( WindowArranger* i_pParent = NULL, long i_nIndent = 3*getDefaultBorder() )
334 : : : WindowArranger( i_pParent )
335 [ # # ]: 0 : , m_nIndent( i_nIndent )
336 : 0 : {}
337 : :
338 : : virtual ~Indenter();
339 : :
340 : : virtual Size getOptimalSize( WindowSizeType ) const;
341 : : virtual void resize();
342 [ # # ][ # # ]: 0 : virtual size_t countElements() const { return (m_aElement.m_pElement != 0 || m_aElement.m_pChild != 0) ? 1 : 0; }
343 : :
344 : : void setIndent( long i_nIndent )
345 : : {
346 : : m_nIndent = i_nIndent;
347 : : resize();
348 : : }
349 : :
350 : : void setWindow( Window*, sal_Int32 i_nExpandPrio = 0 );
351 : : void setChild( boost::shared_ptr<WindowArranger> const &, sal_Int32 i_nExpandPrio = 0 );
352 : : // convenience: use for setChild( new WindowArranger( ... ) ) constructs
353 : : void setChild( WindowArranger* i_pChild, sal_Int32 i_nExpandPrio = 0 )
354 : : { setChild( boost::shared_ptr<WindowArranger>( i_pChild ), i_nExpandPrio ); }
355 : : };
356 : :
357 : : class VCL_DLLPUBLIC Spacer : public WindowArranger
358 : : {
359 : : WindowArranger::Element m_aElement;
360 : : Size m_aSize;
361 : :
362 : : protected:
363 : 0 : virtual Element* getElement( size_t i_nIndex )
364 [ # # ]: 0 : { return i_nIndex == 0 ? &m_aElement : NULL; }
365 : :
366 : : public:
367 : 0 : Spacer( WindowArranger* i_pParent = NULL, sal_Int32 i_nPrio = 20, const Size& i_rSize = Size( 0, 0 ) )
368 : : : WindowArranger( i_pParent )
369 : : , m_aElement( NULL, boost::shared_ptr<WindowArranger>(), i_nPrio )
370 [ # # ][ # # ]: 0 : , m_aSize( i_rSize )
[ # # ]
371 : 0 : {}
372 : :
373 [ # # ][ # # ]: 0 : virtual ~Spacer() {}
374 : :
375 : 0 : virtual Size getOptimalSize( WindowSizeType ) const
376 : 0 : { return m_aSize; }
377 : 0 : virtual void resize() {}
378 : 0 : virtual void setParentWindow( Window* ) {}
379 : 0 : virtual size_t countElements() const { return 1; }
380 : 0 : virtual bool isVisible() const { return true; }
381 : : };
382 : :
383 : : }
384 : :
385 : : #endif
386 : :
387 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|