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   this->updateGeometry();
00100   
00101   return item->button;
00102 }
00103 
00104   QPushButton *
00105 KButtonBox::addButton(
00106   const QString & text,
00107   QObject *       receiver,
00108   const char *    slot,
00109   bool            noexpand
00110 )
00111 {
00112   QPushButton * pb = addButton(text, noexpand);
00113 
00114   if ((0 != receiver) && (0 != slot))
00115     QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
00116 
00117   return pb;
00118 }
00119 
00120 
00121 void KButtonBox::addStretch(int scale) {
00122   if(scale > 0) {
00123     Item *item = new Item;
00124     item->button = 0;
00125     item->noexpand  = false;
00126     item->stretch = scale;
00127     data->buttons.append(item);
00128   }
00129 }
00130 
00131 void KButtonBox::layout() {
00132   // resize all buttons
00133   QSize bs = bestButtonSize();
00134 
00135   for(unsigned int i = 0; i < data->buttons.count(); i++) {
00136     Item *item = data->buttons.at(i);
00137     QPushButton *b = item->button;
00138     if(b != 0) {
00139       if(item->noexpand)
00140     b->setFixedSize(buttonSizeHint(b));
00141       else
00142     b->setFixedSize(bs);
00143     }
00144   }
00145 
00146   setMinimumSize(sizeHint());
00147 }
00148 
00149 void KButtonBox::placeButtons() {
00150   unsigned int i;
00151 
00152   if(data->orientation == Horizontal) {
00153     // calculate free size and stretches
00154     int fs = width() - 2 * data->border;
00155     int stretch = 0;
00156     for(i = 0; i < data->buttons.count(); i++) {
00157       Item *item = data->buttons.at(i);
00158       if(item->button != 0) {
00159     fs -= item->button->width();
00160 
00161     // Last button?
00162     if(i != data->buttons.count() - 1)
00163       fs -= data->autoborder;
00164       } else
00165     stretch +=item->stretch;
00166     }
00167 
00168     // distribute buttons
00169     int x_pos = data->border;
00170     for(i = 0; i < data->buttons.count(); i++) {
00171       Item *item = data->buttons.at(i);
00172       if(item->button != 0) {
00173     QPushButton *b = item->button;
00174     b->move(x_pos, (height() - b->height()) / 2);
00175 
00176     x_pos += b->width() + data->autoborder;
00177       } else
00178     x_pos += (int)((((double)fs) * item->stretch) / stretch);
00179     }
00180   } else { // VERTICAL
00181     // calcualte free size and stretches
00182     int fs = height() - 2 * data->border;
00183     int stretch = 0;
00184     for(i = 0; i < data->buttons.count(); i++) {
00185       Item *item = data->buttons.at(i);
00186       if(item->button != 0)
00187     fs -= item->button->height() + data->autoborder;
00188       else
00189     stretch +=item->stretch;
00190     }
00191 
00192     // distribute buttons
00193     int y_pos = data->border;
00194     for(i = 0; i < data->buttons.count(); i++) {
00195       Item *item = data->buttons.at(i);
00196       if(item->button != 0) {
00197     QPushButton *b = item->button;
00198     b->move((width() - b->width()) / 2, y_pos);
00199 
00200     y_pos += b->height() + data->autoborder;
00201       } else
00202     y_pos += (int)((((double)fs) * item->stretch) / stretch);
00203     }
00204   }
00205 }
00206 
00207 void KButtonBox::resizeEvent(QResizeEvent *) {
00208   placeButtons();
00209 }
00210 
00211 QSize KButtonBox::bestButtonSize() const {
00212   QSize s(0, 0);
00213   unsigned int i;
00214 
00215   // calculate optimal size
00216   for(i = 0; i < data->buttons.count(); i++) {
00217     KButtonBox *that = (KButtonBox*)this; // to remove the const ;(
00218     Item *item = that->data->buttons.at(i);
00219     QPushButton *b = item->button;
00220 
00221     if(b != 0 && !item->noexpand) {
00222       QSize bs = buttonSizeHint(b);
00223 
00224       if(bs.width() > s.width())
00225     s.setWidth(bs.width());
00226       if(bs.height() > s.height())
00227     s.setHeight(bs.height());
00228     }
00229   }
00230 
00231   return s;
00232 }
00233 
00234 QSize KButtonBox::sizeHint() const {
00235   unsigned int i, dw;
00236 
00237   if(data->buttons.count() == 0)
00238     return QSize(0, 0);
00239   else {
00240     dw = 2 * data->border;
00241 
00242     QSize bs = bestButtonSize();
00243     for(i = 0; i < data->buttons.count(); i++) {
00244       KButtonBox *that = (KButtonBox*)this;
00245       Item *item = that->data->buttons.at(i);
00246       QPushButton *b = item->button;
00247       if(b != 0) {
00248     QSize s;
00249     if(item->noexpand)
00250       s = that->buttonSizeHint(b);
00251     else
00252       s = bs;
00253 
00254     if(data->orientation == Horizontal)
00255       dw += s.width();
00256     else
00257       dw += s.height();
00258 
00259     if( i != data->buttons.count() - 1 )
00260       dw += data->autoborder;
00261       }
00262     }
00263 
00264     if(data->orientation == Horizontal)
00265     return QSize(dw, bs.height() + 2 * data->border);
00266     else
00267     return QSize(bs.width() + 2 * data->border, dw);
00268   }
00269 }
00270 
00271 QSizePolicy KButtonBox::sizePolicy() const
00272 {
00273     return data->orientation == Horizontal?
00274         QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) :
00275         QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
00276 }
00277 
00278 /*
00279  * Returns the best size for a button. If a button is less than
00280  * minButtonWidth pixels wide, return minButtonWidth pixels
00281  * as minimum width
00282  */
00283 QSize KButtonBox::buttonSizeHint(QPushButton *b) const {
00284   QSize s = b->sizeHint();
00285   QSize ms = b->minimumSize();
00286   if(s.width() < minButtonWidth)
00287     s.setWidth(minButtonWidth);
00288 
00289   // allows the programmer to override the settings
00290   if(ms.width() > s.width())
00291     s.setWidth(ms.width());
00292   if(ms.height() > s.height())
00293     s.setHeight(ms.height());
00294 
00295   return s;
00296 }
00297 
00298 void KButtonBox::virtual_hook( int, void* )
00299 { /*BASE::virtual_hook( id, data );*/ }
00300 
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 30 05:16:47 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003