kdeui Library API Documentation

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  * 03/08/2000 Mario Weilguni <mweilguni@kde.org>
00029  * Removed all those long outdated Motif stuff
00030  * Improved and clarified some if conditions (easier to understand)
00031  *
00032  * 11/13/98 Reginald Stadlbauer <reggie@kde.org>
00033  * Now in Qt 1.4x motif default buttons have no extra width/height anymore.
00034  * So the KButtonBox doesn't add this width/height to default buttons anymore
00035  * which makes the buttons look better.
00036  *
00037  * 01/17/98  Mario Weilguni <mweilguni@sime.com>
00038  * Fixed a bug in sizeHint()
00039  * Improved the handling of Motif default buttons
00040  *
00041  * 01/09/98  Mario Weilguni <mweilguni@sime.com>
00042  * The last button was to far right away from the right/bottom border.
00043  * Fixed this. Removed old code. Buttons get now a minimum width.
00044  * Programmer may now override minimum width and height of a button.
00045  *
00046  */
00047 
00048 #include "kbuttonbox.moc"
00049 #include <qpushbutton.h>
00050 #include <qptrlist.h>
00051 #include <assert.h>
00052 
00053 #define minButtonWidth 50
00054 
00055 class KButtonBox::Item {
00056 public:
00057   QPushButton *button;
00058   bool noexpand;
00059   unsigned short stretch;
00060   unsigned short actual_size;
00061 };
00062 
00063 template class QPtrList<KButtonBox::Item>;
00064 
00065 class KButtonBoxPrivate {
00066 public:
00067   unsigned short border;
00068   unsigned short autoborder;
00069   unsigned short orientation;
00070   bool activated;
00071   QPtrList<KButtonBox::Item> buttons;
00072 };
00073 
00074 KButtonBox::KButtonBox(QWidget *parent, Orientation _orientation,
00075                int border, int autoborder)
00076   :  QWidget(parent)
00077 {
00078   data = new KButtonBoxPrivate;
00079   assert(data != 0);
00080 
00081   data->orientation = _orientation;
00082   data->border = border;
00083   data->autoborder = autoborder < 0 ? border : autoborder;
00084   data->buttons.setAutoDelete(TRUE);
00085 }
00086 
00087 KButtonBox::~KButtonBox() {
00088   delete data;
00089 }
00090 
00091 QPushButton *KButtonBox::addButton(const QString& text, bool noexpand) {
00092   Item *item = new Item;
00093 
00094   item->button = new QPushButton(text, this);
00095   item->noexpand  = noexpand;
00096   data->buttons.append(item);
00097   item->button->adjustSize();
00098 
00099   return item->button;
00100 }
00101 
00102   QPushButton *
00103 KButtonBox::addButton(
00104   const QString & text,
00105   QObject *       receiver,
00106   const char *    slot,
00107   bool            noexpand
00108 )
00109 {
00110   QPushButton * pb = addButton(text, noexpand);
00111 
00112   if ((0 != receiver) && (0 != slot))
00113     QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
00114 
00115   return pb;
00116 }
00117 
00118 
00119 void KButtonBox::addStretch(int scale) {
00120   if(scale > 0) {
00121     Item *item = new Item;
00122     item->button = 0;
00123     item->noexpand  = FALSE;
00124     item->stretch = scale;
00125     data->buttons.append(item);
00126   }
00127 }
00128 
00129 void KButtonBox::layout() {
00130   // resize all buttons
00131   QSize bs = bestButtonSize();
00132 
00133   for(unsigned int i = 0; i < data->buttons.count(); i++) {
00134     Item *item = data->buttons.at(i);
00135     QPushButton *b = item->button;
00136     if(b != 0) {
00137       if(item->noexpand)
00138     b->setFixedSize(buttonSizeHint(b));
00139       else
00140     b->setFixedSize(bs);
00141     }
00142   }
00143 
00144   setMinimumSize(sizeHint());
00145 }
00146 
00147 void KButtonBox::placeButtons() {
00148   unsigned int i;
00149 
00150   if(data->orientation == Horizontal) {
00151     // calculate free size and stretches
00152     int fs = width() - 2 * data->border;
00153     int stretch = 0;
00154     for(i = 0; i < data->buttons.count(); i++) {
00155       Item *item = data->buttons.at(i);
00156       if(item->button != 0) {
00157     fs -= item->button->width();
00158 
00159     // Last button?
00160     if(i != data->buttons.count() - 1)
00161       fs -= data->autoborder;
00162       } else
00163     stretch +=item->stretch;
00164     }
00165 
00166     // distribute buttons
00167     int x_pos = data->border;
00168     for(i = 0; i < data->buttons.count(); i++) {
00169       Item *item = data->buttons.at(i);
00170       if(item->button != 0) {
00171     QPushButton *b = item->button;
00172     b->move(x_pos, (height() - b->height()) / 2);
00173 
00174     x_pos += b->width() + data->autoborder;
00175       } else
00176     x_pos += (int)((((double)fs) * item->stretch) / stretch);
00177     }
00178   } else { // VERTICAL
00179     // calcualte free size and stretches
00180     int fs = height() - 2 * data->border;
00181     int stretch = 0;
00182     for(i = 0; i < data->buttons.count(); i++) {
00183       Item *item = data->buttons.at(i);
00184       if(item->button != 0)
00185     fs -= item->button->height() + data->autoborder;
00186       else
00187     stretch +=item->stretch;
00188     }
00189 
00190     // distribute buttons
00191     int y_pos = data->border;
00192     for(i = 0; i < data->buttons.count(); i++) {
00193       Item *item = data->buttons.at(i);
00194       if(item->button != 0) {
00195     QPushButton *b = item->button;
00196     b->move((width() - b->width()) / 2, y_pos);
00197 
00198     y_pos += b->height() + data->autoborder;
00199       } else
00200     y_pos += (int)((((double)fs) * item->stretch) / stretch);
00201     }
00202   }
00203 }
00204 
00205 void KButtonBox::resizeEvent(QResizeEvent *) {
00206   placeButtons();
00207 }
00208 
00209 QSize KButtonBox::bestButtonSize() const {
00210   QSize s(0, 0);
00211   unsigned int i;
00212 
00213   // calculate optimal size
00214   for(i = 0; i < data->buttons.count(); i++) {
00215     KButtonBox *that = (KButtonBox*)this; // to remove the const ;(
00216     Item *item = that->data->buttons.at(i);
00217     QPushButton *b = item->button;
00218 
00219     if(b != 0 && !item->noexpand) {
00220       QSize bs = buttonSizeHint(b);
00221 
00222       if(bs.width() > s.width())
00223     s.setWidth(bs.width());
00224       if(bs.height() > s.height())
00225     s.setHeight(bs.height());
00226     }
00227   }
00228 
00229   return s;
00230 }
00231 
00232 QSize KButtonBox::sizeHint() const {
00233   unsigned int i, dw;
00234 
00235   if(data->buttons.count() == 0)
00236     return QSize(0, 0);
00237   else {
00238     dw = 2 * data->border;
00239 
00240     QSize bs = bestButtonSize();
00241     for(i = 0; i < data->buttons.count(); i++) {
00242       KButtonBox *that = (KButtonBox*)this;
00243       Item *item = that->data->buttons.at(i);
00244       QPushButton *b = item->button;
00245       if(b != 0) {
00246     QSize s;
00247     if(item->noexpand)
00248       s = that->buttonSizeHint(b);
00249     else
00250       s = bs;
00251 
00252     if(data->orientation == Horizontal)
00253       dw += s.width();
00254     else
00255       dw += s.height();
00256 
00257     if( i != data->buttons.count() - 1 )
00258       dw += data->autoborder;
00259       }
00260     }
00261 
00262     if(data->orientation == Horizontal)
00263     return QSize(dw, bs.height() + 2 * data->border);
00264     else
00265     return QSize(bs.width() + 2 * data->border, dw);
00266   }
00267 }
00268 
00269 QSizePolicy KButtonBox::sizePolicy() const
00270 {
00271     return data->orientation == Horizontal?
00272         QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) :
00273         QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
00274 }
00275 
00276 /*
00277  * Returns the best size for a button. If a button is less than
00278  * minButtonWidth pixels wide, return minButtonWidth pixels
00279  * as minimum width
00280  */
00281 QSize KButtonBox::buttonSizeHint(QPushButton *b) const {
00282   QSize s = b->sizeHint();
00283   QSize ms = b->minimumSize();
00284   if(s.width() < minButtonWidth)
00285     s.setWidth(minButtonWidth);
00286 
00287   // allows the programmer to override the settings
00288   if(ms.width() > s.width())
00289     s.setWidth(ms.width());
00290   if(ms.height() > s.height())
00291     s.setHeight(ms.height());
00292 
00293   return s;
00294 }
00295 
00296 void KButtonBox::virtual_hook( int, void* )
00297 { /*BASE::virtual_hook( id, data );*/ }
00298 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:15:02 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001