Developer Documentation
QtFlapBox.cc
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40\*===========================================================================*/
41
42
43
44
45
46//=============================================================================
47//
48// CLASS QtFlapBox - IMPLEMENTATION
49//
50//=============================================================================
51
52//== INCLUDES =================================================================
53
54#include "QtFlapBox.hh"
55
56#include <QScrollBar>
57
58//== NAMESPACES ===============================================================
59
60namespace ACG {
61namespace QtWidgets {
62
63//== IMPLEMENTATION ==========================================================
64
65
66QtFlapBox::QtFlapBox( QWidget * _parent, Qt::WindowFlags /* _f */ )
67 : QScrollArea( _parent )
68{
69 setBackgroundRole(QPalette::Dark);
70 // setSizePolicy( QSizePolicy::Minimum, QSizePolicy::MinimumExpanding );
71 QSizePolicy sp = sizePolicy();
72 sp.setHorizontalPolicy( QSizePolicy::MinimumExpanding );
73 sp.setVerticalPolicy( QSizePolicy::Preferred );
74 sp.setHorizontalStretch( 1 );
75 sp.setVerticalStretch( 0 );
76 setSizePolicy( sp );
77
78 // create a container that holds all the flaps
79 container = new QWidget;
80 container->setBackgroundRole( QPalette::Button );
81
82
83 // flaps are ordered vertically
84 boxlayout = new QVBoxLayout( container );
85 boxlayout->setContentsMargins(0,0,0,0);
86 boxlayout->setSpacing(0);
87
88 // the container will be scrollable
89 setWidget( container );
90
91 relayout();
92}
93
94
95//-----------------------------------------------------------------------------
96
97
98QtFlapBox::~QtFlapBox()
99{
100}
101
102
103//-----------------------------------------------------------------------------
104
105
106int
107QtFlapBox::addItem( QWidget * _widget,
108 const QIcon & _icon,
109 const QString & _text )
110{
111 return insertItem( -1, _widget, _icon, _text );
112}
113
114
115//-----------------------------------------------------------------------------
116
117
118int
119QtFlapBox::addItem( QWidget * _widget, const QString & _text )
120{
121 return insertItem( -1, _widget, QIcon(), _text);
122}
123
124
125//-----------------------------------------------------------------------------
126
127
128int
129QtFlapBox::count() const
130{
131 return flapList.count();
132}
133
134
135//-----------------------------------------------------------------------------
136
137
138int
139QtFlapBox::indexOf( QWidget * _widget ) const
140{
141 Flap * f = flap( _widget );
142 return ( f ? flapList.indexOf( *f ) : -1 );
143}
144
145
146//-----------------------------------------------------------------------------
147
148
149int
150QtFlapBox::insertItem( int _index,
151 QWidget * _widget,
152 const QIcon & _icon,
153 const QString & _text )
154{
155 if ( ! _widget )
156 return -1;
157
158 connect( _widget, SIGNAL( destroyed( QObject * ) ),
159 this, SLOT( widgetDestroyed( QObject * ) ) );
160
161 Flap f;
162 f.button = new QPushButton;//( container );
163 // f.button->setMinimumSize( 200, 20 );
164 connect( f.button, SIGNAL( clicked() ),
165 this, SLOT( buttonClicked() ) );
166
167 f.widget = _widget;
168 f.widget->setParent( container );
169 f.widget->hide();
170
171 f.setText( _text );
172 f.setIcon( _icon );
173
174 if ( _index < 0 || _index >= flapList.count() )
175 {
176 _index = flapList.count();
177 flapList.append( f );
178 boxlayout->addWidget( f.button );
179 boxlayout->addWidget( f.widget );
180 relayout();
181 }
182 else
183 {
184 flapList.insert( _index, f );
185 relayout();
186 }
187
188 f.button->show();
189
190// d->updateTabs();
191// itemInserted(index);
192
193 return _index;
194
195}
196
197
198//-----------------------------------------------------------------------------
199
200
201
202int
203QtFlapBox::insertItem( int _index,
204 QWidget * _widget,
205 const QString & _text )
206{
207 return insertItem( _index, _widget, QIcon(), _text );
208}
209
210
211//-----------------------------------------------------------------------------
212
213
214bool
215QtFlapBox::isItemEnabled( int _index ) const
216{
217 const Flap * f = flap( _index );
218 return f && f->button->isEnabled();
219}
220
221
222//-----------------------------------------------------------------------------
223
224
225QIcon
226QtFlapBox::itemIcon( int _index ) const
227{
228 const Flap * f = flap( _index );
229 return ( f ? f->icon() : QIcon() );
230}
231
232//-----------------------------------------------------------------------------
233
234
235QString
236QtFlapBox::itemText( int _index ) const
237{
238 const Flap * f = flap( _index );
239 return ( f ? f->text() : QString() );
240}
241
242
243//-----------------------------------------------------------------------------
244
245
246QString
247QtFlapBox::itemToolTip( int _index ) const
248{
249 const Flap * f = flap( _index );
250 return ( f ? f->toolTip() : QString() );
251}
252
253
254//-----------------------------------------------------------------------------
255
256
257void
258QtFlapBox::removeItem( int _index )
259{
260 if ( QWidget * w = widget( _index ) )
261 {
262 disconnect( w, SIGNAL( destroyed( QObject * ) ),
263 this, SLOT( widgetDestroyed( QObject * ) ) );
264 w->setParent( this );
265 // destroy internal data
266 widgetDestroyed( w );
267 // itemRemoved( _index );
268 }
269}
270
271
272//-----------------------------------------------------------------------------
273
274
275void
276QtFlapBox::setItemEnabled( int _index, bool _enabled )
277{
278 Flap * f = flap( _index );
279 if ( ! f )
280 return;
281
282 f->button->setEnabled( _enabled );
283}
284
285
286//-----------------------------------------------------------------------------
287
288
289void
290QtFlapBox::setItemIcon( int _index, const QIcon & _icon )
291{
292 Flap * f = flap( _index );
293 if ( f )
294 f->setIcon( _icon );
295}
296
297
298//-----------------------------------------------------------------------------
299
300
301void
302QtFlapBox::setItemText( int _index, const QString & _text )
303{
304 Flap * f = flap( _index );
305 if ( f )
306 f->setText( _text );
307}
308
309
310//-----------------------------------------------------------------------------
311
312
313void
314QtFlapBox::setItemToolTip( int _index, const QString & _tip )
315{
316 Flap * f = flap( _index );
317 if ( f )
318 f->setToolTip( _tip );
319}
320
321
322//-----------------------------------------------------------------------------
323
324
325QWidget *
326QtFlapBox::widget( int _index ) const
327{
328 if ( _index < 0 || _index >= (int) flapList.size() )
329 return 0;
330
331 return flapList.at( _index ).widget;
332}
333
334
335//-----------------------------------------------------------------------------
336
337
338bool
339QtFlapBox::isItemHidden( int _index ) const
340{
341 const Flap * f = flap( _index );
342
343 if ( ! f )
344 return false;
345
346 return f->widget->isHidden();
347}
348
349
350//-----------------------------------------------------------------------------
351
352
353void
354QtFlapBox::setItemHidden( int _index, bool _hidden )
355{
356 Flap * f = flap( _index );
357 if ( ! f )
358 return;
359
360 f->widget->setHidden( _hidden );
361}
362
363
364//-----------------------------------------------------------------------------
365
366
367QSize
368QtFlapBox::sizeHint() const
369{
370 int width_hint = 0;
371 int height_hint = 0;
372
373 for ( FlapList::ConstIterator i = flapList.constBegin();
374 i != flapList.constEnd(); ++i)
375 {
376 QWidget * w = i->widget;
377 QSize ws = w->sizeHint();
378
379 QPushButton * b = i->button;
380 QSize bs = b->sizeHint();
381
382 if ( bs.width() > width_hint )
383 width_hint = bs.width();
384
385 if ( ! w->isHidden() )
386 {
387 height_hint += ws.height();
388 if ( ws.width() > width_hint )
389 width_hint = ws.width();
390 }
391
392 height_hint += bs.height();
393 }
394
395
396 QSize sz( width_hint + verticalScrollBar()->sizeHint().width()
397 + 2 * frameWidth(),
398 height_hint );
399
400 return sz;
401}
402
403
404//-----------------------------------------------------------------------------
405
406
407QtFlapBox::Flap *
408QtFlapBox::flap( QWidget * _widget ) const
409{
410 if ( ! _widget )
411 return 0;
412
413 for ( FlapList::ConstIterator i = flapList.constBegin();
414 i != flapList.constEnd(); ++i )
415 if ( (*i).widget == _widget )
416 return (Flap*) &(*i);
417
418 return 0;
419}
420
421
422//-----------------------------------------------------------------------------
423
424
425const QtFlapBox::Flap *
426QtFlapBox::flap( int _index ) const
427{
428 if ( _index >= 0 && _index < flapList.size() )
429 return &flapList.at( _index );
430 return 0;
431}
432
433
434//-----------------------------------------------------------------------------
435
436
437QtFlapBox::Flap *
438QtFlapBox::flap( int _index )
439{
440 if ( _index >= 0 && _index < flapList.size() )
441 return &flapList[ _index ];
442 return 0;
443}
444
445
446
447//-----------------------------------------------------------------------------
448
449
450void updateFlaps()
451{
452// QToolBoxButton *lastButton = currentPage ? currentPage->button : 0;
453// bool after = false;
454// for (PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i) {
455// QToolBoxButton *tB = (*i).button;
456// QWidget *tW = (*i).widget;
457// if (after) {
458// QPalette p = tB->palette();
459// p.setColor(tB->backgroundRole(), tW->palette().color(tW->backgroundRole()));
460// tB->setPalette(p);
461// tB->update();
462// } else if (tB->backgroundRole() != QPalette::Background) {
463// tB->setBackgroundRole(QPalette::Background);
464// tB->update();
465// }
466// after = (*i).button == lastButton;
467// }
468
469}
470
471
472//-----------------------------------------------------------------------------
473
474
475void
476QtFlapBox::relayout()
477{
478 delete boxlayout;
479 boxlayout = new QVBoxLayout;
480 boxlayout->setContentsMargins(0,0,0,0);
481 boxlayout->setSpacing(0);
482
483 for ( FlapList::ConstIterator i = flapList.constBegin();
484 i != flapList.constEnd(); ++i )
485 {
486 boxlayout->addWidget( (*i).button );
487 boxlayout->addWidget( (*i).widget );
488 }
489
490 container->setLayout( boxlayout );
491
492 QSize area_size = size();
493 QSize cont_size = container->sizeHint();
494 QSize s;
495 s.setWidth( area_size.width() );
496 s.setHeight( cont_size.height() );
497
498 container->resize( s );
499 // resize( sizeHint() );
500
501 updateGeometry();
502}
503
504
505//-----------------------------------------------------------------------------
506
507
508void
509QtFlapBox::buttonClicked()
510{
511 QPushButton * b = ::qobject_cast< QPushButton * >( sender() );
512
513 for ( FlapList::ConstIterator i = flapList.constBegin();
514 i != flapList.constEnd(); ++i)
515 if ( i->button == b )
516 {
517 QWidget * w = i->widget;
518
519 if ( w->isHidden() )
520 w->show();
521 else
522 w->hide();
523
524 relayout();
525 break;
526 }
527
528}
529
530
531//-----------------------------------------------------------------------------
532
533
534void
535QtFlapBox::widgetDestroyed( QObject * _object )
536{
537 // no verification - vtbl corrupted already
538 QWidget * p = ( QWidget * ) _object;
539
540 Flap * f = flap( p );
541
542 if ( !p || !f )
543 return;
544
545 boxlayout->removeWidget( f->widget );
546 boxlayout->removeWidget( f->button );
547 delete f->button;
548
549 flapList.removeAll( *f );
550}
551
552
553//-----------------------------------------------------------------------------
554
555
556void
557QtFlapBox::resizeEvent( QResizeEvent * _event )
558{
559 QSize container_size = container->size();
560
561 container_size.setWidth( _event->size().width() );
562
563 container->resize( container_size );
564
565 QScrollArea::resizeEvent( _event );
566}
567
568
569//-----------------------------------------------------------------------------
570
571
572
573//=============================================================================
574} // namespace QtWidgets
575} // namespace ACG
576//=============================================================================
Namespace providing different geometric functions concerning angles.