Salome HOME
c2f04236a8716078b59646c2f834e7a1c68a868c
[modules/gui.git] / src / Qtx / QtxGridBox.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:      QtxGridBox.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxGridBox.h"
26
27 #include <QGridLayout>
28 #include <QChildEvent>
29
30 /*!
31   \class QtxGridBox::Space
32   \internal
33   \brief Represents a space in the grid box.
34 */
35
36 class QtxGridBox::Space : public QWidget
37 {
38 public:
39   Space( const int, QtxGridBox* );
40   virtual ~Space();
41
42   virtual QSize sizeHint() const;
43   virtual QSize minimumSizeHint() const;
44
45 private:
46   int           mySize;
47   QtxGridBox*   myGrid;
48 };
49
50 /*!
51   \brief Constructor.
52   \param sz size
53   \param gb parent grid box
54 */
55 QtxGridBox::Space::Space( const int sz, QtxGridBox* gb )
56 : QWidget( gb ),
57   mySize( sz ),
58   myGrid( gb )
59 {
60   setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
61 }
62
63 /*!
64   \brief Destructor.
65 */
66 QtxGridBox::Space::~Space()
67 {
68 }
69
70 /*!
71   \brief Get recommended size for the widget.
72   \return recommended size for the widget
73 */
74 QSize QtxGridBox::Space::sizeHint() const
75 {
76   return minimumSizeHint();
77 }
78
79 /*!
80   \brief Get recommended minimum size for the widget.
81   \return recommended minimum size for the widget
82 */
83 QSize QtxGridBox::Space::minimumSizeHint() const
84 {
85   QSize sz( 0, 0 );
86   if ( myGrid && myGrid->orientation() == Qt::Horizontal )
87     sz.setWidth( mySize );
88   else
89     sz.setHeight( mySize );
90   return sz;
91 }
92
93 /*!
94   \class QtxGridBox
95   \brief A container widget with possibility to automatically layout
96          child widgets.
97 */
98
99 /*!
100   \brief Constructor.
101   \param parent parent widget
102   \param m grid box margin
103   \param s grid box spacing
104 */
105 QtxGridBox::QtxGridBox( QWidget* parent, const int m, const int s )
106 : QWidget( parent ),
107   myCols( 1 ),
108   mySkip( false ),
109   myOrient( Qt::Vertical ),
110   myCol( 0 ),
111   myRow( 0 )
112 {
113   myLayout = new QGridLayout( this );
114   myLayout->setMargin( m );
115   myLayout->setSpacing( s );
116 }
117
118 /*!
119   \brief Constructor.
120   \param cols number of grid box columns or rows (depending on the orientation)
121   \param o grid box orientation
122   \param parent parent widget
123   \param m grid box margin
124   \param s grid box spacing
125 */
126 QtxGridBox::QtxGridBox( const int cols, Qt::Orientation o, QWidget* parent, const int m, const int s )
127 : QWidget( parent ),
128   myCols( cols ),
129   mySkip( false ),
130   myOrient( o ),
131   myLayout( 0 ),
132   myCol( 0 ),
133   myRow( 0 )
134 {
135   myLayout = new QGridLayout( this );
136   myLayout->setMargin( m );
137   myLayout->setSpacing( s );
138 }
139
140 /*!
141   \brief Destructor.
142 */
143 QtxGridBox::~QtxGridBox()
144 {
145 }
146
147 /*!
148   \brief Get number of grid box columns/rows (depending on the orientation).
149   \return number of columns (rows)
150 */
151 int QtxGridBox::columns() const
152 {
153   return myCols;
154 }
155
156 /*!
157   \brief Get the grid box orientation.
158   \return orientation
159 */
160 Qt::Orientation QtxGridBox::orientation() const
161 {
162   return myOrient;
163 }
164
165 /*!
166   \brief Set number of grid box columns/rows (depending on the orientation).
167   \param cols number of columns (rows)
168 */
169 void QtxGridBox::setColumns( const int cols )
170 {
171   setLayout( cols, orientation() );
172 }
173
174 /*!
175   \brief Set the grid box orientation.
176   \param o orientation
177 */
178 void QtxGridBox::setOrientation( Qt::Orientation o )
179 {
180   setLayout( columns(), o );
181 }
182
183 /*!
184   \brief Initialize internal layout.
185   \param cols number of columns (rows)
186   \param o orientation
187 */
188 void QtxGridBox::setLayout( const int cols, Qt::Orientation o )
189 {
190   if ( myCols == cols && myOrient == o )
191     return;
192
193   myCols = cols;
194   myOrient = o;
195
196   arrangeWidgets();
197 }
198
199 /*!
200   \brief Get "skip invisible widgets" flags.
201   \return current flag state
202 */
203 bool QtxGridBox::skipInvisible() const
204 {
205   return mySkip;
206 }
207
208 /*!
209   \brief Set "skip invisible widgets" flags.
210
211   If this flag is set to \c false, invisible widgets
212   are not taken into account when layouting widgets.
213
214   \param on new flag state
215 */
216 void QtxGridBox::setSkipInvisible( const bool on )
217 {
218   if ( mySkip == on )
219     return;
220
221   mySkip = on;
222   arrangeWidgets();
223 }
224
225 /*!
226   \brief Add space (empty cell) to the grid box.
227   \param sp requied space size
228 */
229 void QtxGridBox::addSpace( const int sp )
230 {
231   new Space( sp, this );
232 }
233
234 /*!
235   \brief Get grid box's inside margin size.
236   \return inside margin size
237 */
238 int QtxGridBox::insideMargin() const
239 {
240   return myLayout->margin();
241 }
242
243 /*!
244   \brief Get grid box's inside spacing size.
245   \return inside spacing size
246 */
247 int QtxGridBox::insideSpacing() const
248 {
249   return myLayout->spacing();
250 }
251
252 /*!
253   \brief Set grid box's inside margin size.
254   \param m new inside margin size
255 */
256 void QtxGridBox::setInsideMargin( const int m )
257 {
258   myLayout->setMargin( m );
259 }
260
261 /*!
262   \brief Set grid box's inside spacing size.
263   \param s new inside spacing size
264 */
265 void QtxGridBox::setInsideSpacing( const int s )
266 {
267   myLayout->setSpacing( s );
268 }
269
270 /*!
271   \brief Custom event filter.
272   \param o event receiver object.
273   \param e event
274   \return \c true if the event processing should be stopped
275 */
276 bool QtxGridBox::eventFilter( QObject* o, QEvent* e )
277 {
278   if ( skipInvisible() && ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
279                             e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) )
280     arrangeWidgets();
281
282   return QWidget::eventFilter( o, e );
283 }
284
285 /*!
286   \brief Customize child event.
287   \param e child event
288 */
289 void QtxGridBox::childEvent( QChildEvent* e )
290 {
291   if ( e->child()->isWidgetType() )
292   {
293     QWidget* wid = (QWidget*)e->child();
294     if ( e->type() == QEvent::ChildAdded )
295     {
296       placeWidget( wid );
297       wid->installEventFilter( this );
298     }
299     else if ( e->type() == QEvent::ChildRemoved )
300       wid->removeEventFilter( this );
301   }
302   QWidget::childEvent( e );
303 }
304
305 /*!
306   \brief Increment the grid box current cell.
307 */
308 void QtxGridBox::skip()
309 {
310   if ( orientation() == Qt::Horizontal )
311   {
312     myCol++;
313     if ( myCol >= columns() )
314     {
315       myRow++;
316       myCol = 0;
317     }
318   }
319   else
320   {
321     myRow++;
322     if ( myRow >= columns() )
323     {
324       myCol++;
325       myRow = 0;
326     }
327   }
328 }
329
330 /*!
331   \brief Arrange child widgets.
332 */
333 void QtxGridBox::arrangeWidgets()
334 {
335   myRow = myCol = 0;
336   int m = myLayout ? myLayout->margin() : 0;
337   int s = myLayout ? myLayout->spacing() : 0;
338   delete myLayout;
339   myLayout = new QGridLayout( this );
340   myLayout->setMargin( m );
341   myLayout->setSpacing( s );
342
343   QObjectList list = children();
344   for ( QObjectList::iterator it = list.begin(); it != list.end(); ++it )
345   {
346     if ( !(*it)->isWidgetType() )
347       continue;
348
349     QWidget* wid = (QWidget*)(*it);
350     if ( !skipInvisible() || wid->isVisibleTo( this ) )
351       placeWidget( wid );
352   }
353   updateGeometry();
354 }
355
356 /*!
357   \brief Place new widget to the current grid box cell.
358   \param wid widget being inserted
359 */
360 void QtxGridBox::placeWidget( QWidget* wid )
361 {
362   myLayout->addWidget( wid, myRow, myCol );
363
364   skip();
365 }