# kdeui Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kbuttonbox.cpp

    00001 /* This file is part of the KDE libraries
    00002     Copyright (C) 1997 Mario Weilguni (mweilguni@sime.com)
    00003
    00004     This library is free software; you can redistribute it and/or
    00005     modify it under the terms of the GNU Library General Public
    00006     License as published by the Free Software Foundation; either
    00007     version 2 of the License, or (at your option) any later version.
    00008
    00009     This library is distributed in the hope that it will be useful,
    00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012     Library General Public License for more details.
    00013
    00014     You should have received a copy of the GNU Library General Public License
    00015     along with this library; see the file COPYING.LIB.  If not, write to
    00016     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017     Boston, MA 02111-1307, USA.
    00018 */
    00019
    00020 /*
    00021  * KButtonBox class
    00022  *
    00023  * A container widget for buttons. Uses Qt layout control to place the
    00024  * buttons, can handle both vertical and horizontal button placement.
    00025 *
    00026  * HISTORY
    00027  *
    00028  * 05/11/2004 Andrew Coles <andrew_coles@yahoo.co.uk>
    00029  * Now uses QPtrListIterators instead of indexing through data->buttons
    00030  * Item.button and data are now const pointers, set in the relevant constructors
    00031  *
    00032  * 03/08/2000 Mario Weilguni <mweilguni@kde.org>
    00033  * Removed all those long outdated Motif stuff
    00034  * Improved and clarified some if conditions (easier to understand)
    00035  *
    00036  * 11/13/98 Reginald Stadlbauer <reggie@kde.org>
    00037  * Now in Qt 1.4x motif default buttons have no extra width/height anymore.
    00038  * So the KButtonBox doesn't add this width/height to default buttons anymore
    00039  * which makes the buttons look better.
    00040  *
    00041  * 01/17/98  Mario Weilguni <mweilguni@sime.com>
    00042  * Fixed a bug in sizeHint()
    00043  * Improved the handling of Motif default buttons
    00044  *
    00045  * 01/09/98  Mario Weilguni <mweilguni@sime.com>
    00046  * The last button was to far right away from the right/bottom border.
    00047  * Fixed this. Removed old code. Buttons get now a minimum width.
    00048  * Programmer may now override minimum width and height of a button.
    00049  *
    00050  */
    00051
    00052 #include "kbuttonbox.moc"
    00053 #include <kglobalsettings.h>
    00054 #include <kguiitem.h>
    00055 #include <kpushbutton.h>
    00056 #include <qptrlist.h>
    00057 #include <assert.h>
    00058
    00059 #define minButtonWidth 50
    00060
    00061 class KButtonBox::Item {
    00062 public:
    00063   KPushButton* const button;
    00064   bool noexpand;
    00065   unsigned short stretch;
    00066   unsigned short actual_size;
    00067
    00068   Item(KPushButton* const _button) : button(_button) {};
    00069 };
    00070
    00071 template class QPtrList<KButtonBox::Item>;
    00072
    00073 class KButtonBoxPrivate {
    00074 public:
    00075   unsigned short border;
    00076   unsigned short autoborder;
    00077   unsigned short orientation;
    00078   bool activated;
    00079   QPtrList<KButtonBox::Item> buttons;
    00080 };
    00081
    00082 KButtonBox::KButtonBox(QWidget *parent, Orientation _orientation,
    00083                int border, int autoborder)
    00084   :  QWidget(parent), data(new KButtonBoxPrivate)
    00085 {
    00086   assert(data);
    00087
    00088   data->orientation = _orientation;
    00089   data->border = border;
    00090   data->autoborder = autoborder < 0 ? border : autoborder;
    00091   data->buttons.setAutoDelete(true);
    00092 }
    00093
    00094 KButtonBox::~KButtonBox() {
    00095   delete data;
    00096 }
    00097
    00098 QPushButton *KButtonBox::addButton(const QString& text, bool noexpand) {
    00099   Item* const item = new Item(new KPushButton(text, this));
    00100
    00101   item->noexpand  = noexpand;
    00102   data->buttons.append(item);
    00103   item->button->adjustSize();
    00104
    00105   this->updateGeometry();
    00106
    00107   return item->button;
    00108 }
    00109
    00110 QPushButton *KButtonBox::addButton(const KGuiItem& guiitem, bool noexpand) {
    00111   Item* const item = new Item(new KPushButton(guiitem, this));
    00112
    00113   item->noexpand  = noexpand;
    00114   data->buttons.append(item);
    00115   item->button->adjustSize();
    00116
    00117   this->updateGeometry();
    00118
    00119   return item->button;
    00120 }
    00121
    00122   QPushButton *
    00123 KButtonBox::addButton(
    00124   const QString & text,
    00125   QObject *       receiver,
    00126   const char *    slot,
    00127   bool            noexpand
    00128 )
    00129 {
    00130   QPushButton * pb = addButton(text, noexpand);
    00131
    00132   if ((0 != receiver) && (0 != slot))
    00133     QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
    00134
    00135   return pb;
    00136 }
    00137
    00138   QPushButton *
    00139 KButtonBox::addButton(
    00140   const KGuiItem& guiitem,
    00141   QObject *       receiver,
    00142   const char *    slot,
    00143   bool            noexpand
    00144 )
    00145 {
    00146   QPushButton * pb = addButton(guiitem, noexpand);
    00147
    00148   if ((0 != receiver) && (0 != slot))
    00149     QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
    00150
    00151   return pb;
    00152 }
    00153
    00154 void KButtonBox::addStretch(int scale) {
    00155   if(scale > 0) {
    00156     Item* const item = new Item(0);
    00157     item->noexpand  = false;
    00158     item->stretch = scale;
    00159     data->buttons.append(item);
    00160   }
    00161 }
    00162
    00163 void KButtonBox::layout() {
    00164   // resize all buttons
    00165   const QSize bs = bestButtonSize();
    00166
    00167   QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00168   Item* item;
    00169
    00170   while ( (item = itr.current()) != 0 ) {
    00171     QPushButton* const b = item->button;
    00172     if(b) {
    00173       if(item->noexpand)
    00174     b->setFixedSize(buttonSizeHint(b));
    00175       else
    00176     b->setFixedSize(bs);
    00177     }
    00178     ++itr;
    00179   }
    00180
    00181   setMinimumSize(sizeHint());
    00182 }
    00183
    00184 void KButtonBox::placeButtons() {
    00185
    00186   if(data->orientation == Horizontal) {
    00187     // calculate free size and stretches
    00188     int fs = width() - 2 * data->border;
    00189     int stretch = 0;
    00190     {
    00191       QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00192       Item *item;
    00193
    00194       while ( (item = itr.current()) != 0 ) {
    00195         QPushButton* const b = item->button;
    00196         if(b) {
    00197           fs -= b->width();
    00198
    00199           // Last button?
    00200           if(!itr.atLast())
    00201             fs -= data->autoborder;
    00202         } else {
    00203           stretch +=item->stretch;
    00204         }
    00205
    00206         ++itr;
    00207       }
    00208     }
    00209
    00210     // distribute buttons
    00211     int x_pos = data->border;
    00212     {
    00213       QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00214       Item *item;
    00215
    00216       while ( (item = itr.current()) != 0 ) {
    00217         QPushButton* const b = item->button;
    00218         if(b) {
    00219           b->move(x_pos, (height() - b->height()) / 2);
    00220
    00221           x_pos += b->width() + data->autoborder;
    00222         } else {
    00223           x_pos += (int)((((double)fs) * item->stretch) / stretch);
    00224         }
    00225
    00226         ++itr;
    00227       }
    00228     }
    00229
    00230   } else { // VERTICAL
    00231     // calcualte free size and stretches
    00232     int fs = height() - 2 * data->border;
    00233     int stretch = 0;
    00234     {
    00235       QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00236       Item *item;
    00237
    00238       while ( (item = itr.current()) != 0 ) {
    00239         QPushButton* const b = item->button;
    00240         if(b)
    00241           fs -= b->height() + data->autoborder;
    00242         else
    00243           stretch +=item->stretch;
    00244
    00245     ++itr;
    00246       }
    00247
    00248     }
    00249
    00250     // distribute buttons
    00251     int y_pos = data->border;
    00252     {
    00253       QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00254       Item *item;
    00255
    00256       while ( (item = itr.current()) != 0 ) {
    00257         QPushButton* const b = item->button;
    00258         if(b) {
    00259           b->move((width() - b->width()) / 2, y_pos);
    00260
    00261           y_pos += b->height() + data->autoborder;
    00262         } else {
    00263           y_pos += (int)((((double)fs) * item->stretch) / stretch);
    00264         }
    00265
    00266         ++itr;
    00267       }
    00268     }
    00269   }
    00270 }
    00271
    00272 void KButtonBox::resizeEvent(QResizeEvent *) {
    00273   placeButtons();
    00274 }
    00275
    00276 QSize KButtonBox::bestButtonSize() const {
    00277   QSize s(0, 0);
    00278
    00279   // calculate optimal size
    00280   QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00281   Item *item;
    00282
    00283   while ( (item = itr.current()) != 0 ) {
    00284     QPushButton* const b = item->button;
    00285
    00286     if(b && !item->noexpand) {
    00287       const QSize bs = buttonSizeHint(b);
    00288
    00289       const int bsWidth = bs.width();
    00290       const int bsHeight = bs.height();
    00291
    00292       if(bsWidth > s.width())
    00293     s.setWidth(bsWidth);
    00294       if(bsHeight > s.height())
    00295     s.setHeight(bsHeight);
    00296     }
    00297     ++itr;
    00298   }
    00299
    00300   return s;
    00301 }
    00302
    00303 QSize KButtonBox::sizeHint() const {
    00304   unsigned int dw;
    00305
    00306   if(data->buttons.isEmpty())
    00307     return QSize(0, 0);
    00308   else {
    00309     dw = 2 * data->border;
    00310
    00311     const QSize bs = bestButtonSize();
    00312
    00313     QPtrListIterator<KButtonBox::Item> itr(data->buttons);
    00314     Item *item;
    00315
    00316     while ( (item = itr.current()) != 0 ) {
    00317       QPushButton* const b = item->button;
    00318
    00319       if(b) {
    00320     QSize s;
    00321     if(item->noexpand)
    00322       s = buttonSizeHint(b);
    00323     else
    00324       s = bs;
    00325
    00326     if(data->orientation == Horizontal)
    00327       dw += s.width();
    00328     else
    00329       dw += s.height();
    00330
    00331     if( !itr.atLast() )
    00332       dw += data->autoborder;
    00333       }
    00334
    00335       ++itr;
    00336     }
    00337
    00338     if(data->orientation == Horizontal)
    00339     return QSize(dw, bs.height() + 2 * data->border);
    00340     else
    00341     return QSize(bs.width() + 2 * data->border, dw);
    00342   }
    00343 }
    00344
    00345 QSizePolicy KButtonBox::sizePolicy() const
    00346 {
    00347     return data->orientation == Horizontal?
    00348         QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) :
    00349         QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
    00350 }
    00351
    00352 /*
    00353  * Returns the best size for a button. If a button is less than
    00354  * minButtonWidth pixels wide, return minButtonWidth pixels
    00355  * as minimum width
    00356  */
    00357 QSize KButtonBox::buttonSizeHint(QPushButton *b) const {
    00358   QSize s = b->sizeHint();
    00359   const QSize ms = b->minimumSize();
    00360   if(s.width() < minButtonWidth)
    00361     s.setWidth(minButtonWidth);
    00362
    00363   // allows the programmer to override the settings
    00364   const int msWidth = ms.width();
    00365   const int msHeight = ms.height();
    00366
    00367   if(msWidth > s.width())
    00368     s.setWidth(msWidth);
    00369   if(msHeight > s.height())
    00370     s.setHeight(msHeight);
    00371
    00372   return s;
    00373 }
    00374
    00375 void KButtonBox::virtual_hook( int, void* )
    00376 { /*BASE::virtual_hook( id, data );*/ }
    00377

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:13 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003