diff options
Diffstat (limited to 'plugins/gui-quickbar/buttonflowlayout.cpp')
-rw-r--r-- | plugins/gui-quickbar/buttonflowlayout.cpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/plugins/gui-quickbar/buttonflowlayout.cpp b/plugins/gui-quickbar/buttonflowlayout.cpp new file mode 100644 index 0000000..45c19d5 --- /dev/null +++ b/plugins/gui-quickbar/buttonflowlayout.cpp @@ -0,0 +1,268 @@ +/**************************************************************************** +** $Id: buttonflowtqlayout.cpp 272 2005-05-18 08:12:51Z emw $ +** +** Implementing your own layout: flow example +** +** Copyright (C) 1996 by Trolltech AS. All rights reserved. +** +** This file is part of an example program for TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ +/** + Modified 2002 by Klas Kalass (klas.kalass@gmx.de) for tderadio + */ + +#include <kdebug.h> + +#include "buttonflowlayout.h" + +/*********************************************/ +/* Iterator */ +class ButtonFlowLayoutIterator :public TQGLayoutIterator +{ +public: + ButtonFlowLayoutIterator( TQPtrList<TQLayoutItem> *l ) :idx(0), list(l) {} + uint count() const; + TQLayoutItem *current(); + TQLayoutItem *next(); + TQLayoutItem *takeCurrent(); + +private: + int idx; + TQPtrList<TQLayoutItem> *list; + +}; + +uint ButtonFlowLayoutIterator::count() const +{ + return list->count(); +} + +TQLayoutItem *ButtonFlowLayoutIterator::current() +{ + return idx < int(count()) ? list->at(idx) : 0; +} + +TQLayoutItem *ButtonFlowLayoutIterator::next() +{ + idx++; return current(); +} + +TQLayoutItem *ButtonFlowLayoutIterator::takeCurrent() +{ + return idx < int(count()) ? list->take( idx ) : 0; +} + +/**************************************************************/ + +ButtonFlowLayout::ButtonFlowLayout( TQWidget *parent, int margin, int spacing, + const char *name ) + : TQLayout( parent, margin, spacing, name ), + cached_width(0) +{ +} + +ButtonFlowLayout::ButtonFlowLayout( TQLayout* parentLayout, int spacing, const char *name ) + : TQLayout( parentLayout, spacing, name ), + cached_width(0) +{ +} + +ButtonFlowLayout::ButtonFlowLayout( int spacing, const char *name ) + : TQLayout( spacing, name ), + cached_width(0) +{ +} + +ButtonFlowLayout::~ButtonFlowLayout() +{ + deleteAllItems(); +} + + +int ButtonFlowLayout::heightForWidth( int w ) const +{ + if ( cached_width != w ) { + //Not all C++ compilers support "mutable" yet: + ButtonFlowLayout * mthis = (ButtonFlowLayout*)this; + int h = mthis->doLayout( TQRect(0,0,w,0), TRUE ); + mthis->cached_hfw = h; + mthis->cached_width = w; + return h; + } + return cached_hfw; +} + +void ButtonFlowLayout::addItem( TQLayoutItem *item) +{ + list.append( TQT_TQLAYOUTITEM(item) ); +} + +bool ButtonFlowLayout::hasHeightForWidth() const +{ + return TRUE; +} + +TQSize ButtonFlowLayout::sizeHint() const +{ + return minimumSize(); +} + +TQSizePolicy::ExpandData ButtonFlowLayout::expanding() const +{ + return TQ_SPNoDirection; +} + +TQLayoutIterator ButtonFlowLayout::iterator() +{ + // [FIXME] +#ifdef USE_QT4 + #warning [FIXME] ContainerAreaLayout iterators may not function correctly under Qt4 + return TQLayoutIterator( this ); // [FIXME] +#else // USE_QT4 + return TQLayoutIterator( new ButtonFlowLayoutIterator( &list ) ); +#endif // USE_QT4 +} + +void ButtonFlowLayout::setGeometry( const TQRect &r ) +{ + TQLayout::setGeometry( r ); + doLayout( r ); +} + +int ButtonFlowLayout::doLayout( const TQRect &r, bool testonly ) +{ +/* kdDebug() << "buttonflowlayout::doLayout (" + << r.x() << "," << r.y() << "," + << r.width() << "," << r.height() << ", " << testonly << ")\n"; +*/ + float x = r.x(); + float y = r.y(); + int h = 0; //height of this line so far. + float buttonWidth = 0; + int buttonHeight = 0; + int linecount = 0; + int totalWidth = r.width(); + int totalHeight = r.height(); + + TQPtrListIterator<TQLayoutItem> it(list); + TQLayoutItem *o; + + // get the width of the biggest Button + + it.toFirst(); + while ( (o=it.current()) != 0 ) { + ++it; + buttonWidth = TQMAX( buttonWidth, o->sizeHint().width() ); + buttonHeight = TQMAX( buttonHeight, o->sizeHint().height() ); + } + + // calculate the optimal width + unsigned int columns = (totalWidth + spacing()) / + ((int)buttonWidth + spacing()); + if (columns > it.count() ) columns = it.count(); + if (columns == 0) columns = 1; // avoid division by zero + + + int rows = (it.count() - 1) / columns + 1; + float deltaH = (float)(totalHeight - rows * buttonHeight - (rows - 1) * spacing()) + / (float)(rows + 1) ; + if (deltaH < 0) deltaH = 0; + + y += deltaH; + + buttonWidth = (float)(totalWidth - spacing()*(columns-1)) / (float)columns; + +/* fprintf (stderr, "cols = %i col-width = %f\n" + "rows = %i row-height = %i\n" + "w = %i h = %i\n", + columns, buttonWidth, + rows, buttonHeight, + totalWidth, totalHeight + ); +*/ + // calculate the positions and sizes + it.toFirst(); + while ( (o = it.current()) != 0 ) { + +// fprintf (stderr, "x = %i y = %i\n", x, (int)y); + ++it; + int btnRight = (int)rint(x + buttonWidth) - 1, + btnLeft = (int)rint(x); + + if ( btnRight > r.right() && h > 0 ) { + x = r.x(); + btnRight = (int)rint(x + buttonWidth) - 1; + btnLeft = (int)rint(x); + + y += h + spacing() + deltaH; + h = 0; + linecount++; + } + if (!testonly) + o->setGeometry( TQRect( TQPoint( btnLeft, (int)rint(y) ), + TQSize( btnRight - btnLeft + 1, + buttonHeight) ) + ); + + x += buttonWidth + spacing(); + h = TQMAX( h, buttonHeight ); + } + + int ret = (int)rint(y + h + deltaH) - r.y(); + +// kdDebug() << "ButtonFlowLayout::doLayout() = " << ret << endl; + return ret; +} + + +TQSize ButtonFlowLayout::minimumSize() const +{ + return minimumSize(geometry().size()); +} + + +TQSize ButtonFlowLayout::minimumSize(const TQSize &r) const +{ + TQSize s(0, 0); + + for (TQPtrListIterator<TQLayoutItem> it(list); it.current(); ++it) { + TQLayoutItem *o = it.current(); + s = s.expandedTo( o->sizeHint()); //minimumSize() ); + } + + s.setHeight(heightForWidth(r.width())); + + return s; +} + +#ifdef USE_QT4 +/*! + \reimp +*/ +int ButtonFlowLayout::count() const { + return list.count(); +} + +/*! + \reimp +*/ +TQLayoutItem* ButtonFlowLayout::itemAt(int index) const { + return index >= 0 && index < list.count() ? (const_cast<TQPtrList<TQLayoutItem>&>(list).at(index)) : 0; +} + +/*! + \reimp +*/ +TQLayoutItem* ButtonFlowLayout::takeAt(int index) { + if (index < 0 || index >= list.count()) + return 0; + TQLayoutItem *item = list.at(index); + list.remove(list.at(index)); + delete item; + + invalidate(); + return item; +} +#endif // USE_QT4 |