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 
60 namespace ACG {
61 namespace QtWidgets {
62 
63 //== IMPLEMENTATION ==========================================================
64 
65 
66 QtFlapBox::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->setMargin(0);
86  boxlayout->setSpacing(0);
87 
88  // the container will be scrollable
89  setWidget( container );
90 
91  relayout();
92 }
93 
94 
95 //-----------------------------------------------------------------------------
96 
97 
98 QtFlapBox::~QtFlapBox()
99 {
100 }
101 
102 
103 //-----------------------------------------------------------------------------
104 
105 
106 int
107 QtFlapBox::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 
118 int
119 QtFlapBox::addItem( QWidget * _widget, const QString & _text )
120 {
121  return insertItem( -1, _widget, QIcon(), _text);
122 }
123 
124 
125 //-----------------------------------------------------------------------------
126 
127 
128 int
129 QtFlapBox::count() const
130 {
131  return flapList.count();
132 }
133 
134 
135 //-----------------------------------------------------------------------------
136 
137 
138 int
139 QtFlapBox::indexOf( QWidget * _widget ) const
140 {
141  Flap * f = flap( _widget );
142  return ( f ? flapList.indexOf( *f ) : -1 );
143 }
144 
145 
146 //-----------------------------------------------------------------------------
147 
148 
149 int
150 QtFlapBox::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 
202 int
203 QtFlapBox::insertItem( int _index,
204  QWidget * _widget,
205  const QString & _text )
206 {
207  return insertItem( _index, _widget, QIcon(), _text );
208 }
209 
210 
211 //-----------------------------------------------------------------------------
212 
213 
214 bool
215 QtFlapBox::isItemEnabled( int _index ) const
216 {
217  const Flap * f = flap( _index );
218  return f && f->button->isEnabled();
219 }
220 
221 
222 //-----------------------------------------------------------------------------
223 
224 
225 QIcon
226 QtFlapBox::itemIcon( int _index ) const
227 {
228  const Flap * f = flap( _index );
229  return ( f ? f->icon() : QIcon() );
230 }
231 
232 //-----------------------------------------------------------------------------
233 
234 
235 QString
236 QtFlapBox::itemText( int _index ) const
237 {
238  const Flap * f = flap( _index );
239  return ( f ? f->text() : QString() );
240 }
241 
242 
243 //-----------------------------------------------------------------------------
244 
245 
246 QString
247 QtFlapBox::itemToolTip( int _index ) const
248 {
249  const Flap * f = flap( _index );
250  return ( f ? f->toolTip() : QString() );
251 }
252 
253 
254 //-----------------------------------------------------------------------------
255 
256 
257 void
258 QtFlapBox::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 
275 void
276 QtFlapBox::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 
289 void
290 QtFlapBox::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 
301 void
302 QtFlapBox::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 
313 void
314 QtFlapBox::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 
325 QWidget *
326 QtFlapBox::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 
338 bool
339 QtFlapBox::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 
353 void
354 QtFlapBox::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 
367 QSize
368 QtFlapBox::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 
407 QtFlapBox::Flap *
408 QtFlapBox::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 
425 const QtFlapBox::Flap *
426 QtFlapBox::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 
437 QtFlapBox::Flap *
438 QtFlapBox::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 
450 void 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 
475 void
476 QtFlapBox::relayout()
477 {
478  delete boxlayout;
479  boxlayout = new QVBoxLayout;
480  boxlayout->setMargin(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 
508 void
509 QtFlapBox::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 
534 void
535 QtFlapBox::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 
556 void
557 QtFlapBox::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.