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