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 <kglobalsettings.h>
00050 #include <kguiitem.h>
00051 #include <kpushbutton.h>
00052 #include <qptrlist.h>
00053 #include <assert.h>
00054 
00055 #define minButtonWidth 50
00056 
00057 class KButtonBox::Item {
00058 public:
00059   KPushButton *button;
00060   bool noexpand;
00061   unsigned short stretch;
00062   unsigned short actual_size;
00063 };
00064 
00065 template class QPtrList<KButtonBox::Item>;
00066 
00067 class KButtonBoxPrivate {
00068 public:
00069   unsigned short border;
00070   unsigned short autoborder;
00071   unsigned short orientation;
00072   bool activated;
00073   QPtrList<KButtonBox::Item> buttons;
00074 };
00075 
00076 KButtonBox::KButtonBox(QWidget *parent, Orientation _orientation,
00077                int border, int autoborder)
00078   :  QWidget(parent)
00079 {
00080   data = new KButtonBoxPrivate;
00081   assert(data != 0);
00082 
00083   data->orientation = _orientation;
00084   data->border = border;
00085   data->autoborder = autoborder < 0 ? border : autoborder;
00086   data->buttons.setAutoDelete(true);
00087 }
00088 
00089 KButtonBox::~KButtonBox() {
00090   delete data;
00091 }
00092 
00093 QPushButton *KButtonBox::addButton(const QString& text, bool noexpand) {
00094   Item *item = new Item;
00095 
00096   item->button = new KPushButton(text, this);
00097   item->noexpand  = noexpand;
00098   data->buttons.append(item);
00099   item->button->adjustSize();
00100 
00101   this->updateGeometry();
00102 
00103   return item->button;
00104 }
00105 
00106 QPushButton *KButtonBox::addButton(const KGuiItem& guiitem, bool noexpand) {
00107   Item *item = new Item;
00108 
00109   item->button = new KPushButton( guiitem, this);
00110   item->noexpand  = noexpand;
00111   data->buttons.append(item);
00112   item->button->adjustSize();
00113 
00114   this->updateGeometry();
00115 
00116   return item->button;
00117 }
00118 
00119   QPushButton *
00120 KButtonBox::addButton(
00121   const QString & text,
00122   QObject *       receiver,
00123   const char *    slot,
00124   bool            noexpand
00125 )
00126 {
00127   QPushButton * pb = addButton(text, noexpand);
00128 
00129   if ((0 != receiver) && (0 != slot))
00130     QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
00131 
00132   return pb;
00133 }
00134 
00135   QPushButton *
00136 KButtonBox::addButton(
00137   const KGuiItem& guiitem,
00138   QObject *       receiver,
00139   const char *    slot,
00140   bool            noexpand
00141 )
00142 {
00143   QPushButton * pb = addButton(guiitem, noexpand);
00144 
00145   if ((0 != receiver) && (0 != slot))
00146     QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
00147 
00148   return pb;
00149 }
00150 
00151 void KButtonBox::addStretch(int scale) {
00152   if(scale > 0) {
00153     Item *item = new Item;
00154     item->button = 0;
00155     item->noexpand  = false;
00156     item->stretch = scale;
00157     data->buttons.append(item);
00158   }
00159 }
00160 
00161 void KButtonBox::layout() {
00162   // resize all buttons
00163   QSize bs = bestButtonSize();
00164 
00165   for(unsigned int i = 0; i < data->buttons.count(); i++) {
00166     Item *item = data->buttons.at(i);
00167     QPushButton *b = item->button;
00168     if(b != 0) {
00169       if(item->noexpand)
00170     b->setFixedSize(buttonSizeHint(b));
00171       else
00172     b->setFixedSize(bs);
00173     }
00174   }
00175 
00176   setMinimumSize(sizeHint());
00177 }
00178 
00179 void KButtonBox::placeButtons() {
00180   unsigned int i;
00181 
00182   if(data->orientation == Horizontal) {
00183     // calculate free size and stretches
00184     int fs = width() - 2 * data->border;
00185     int stretch = 0;
00186     for(i = 0; i < data->buttons.count(); i++) {
00187       Item *item = data->buttons.at(i);
00188       if(item->button != 0) {
00189     fs -= item->button->width();
00190 
00191     // Last button?
00192     if(i != data->buttons.count() - 1)
00193       fs -= data->autoborder;
00194       } else
00195     stretch +=item->stretch;
00196     }
00197 
00198     // distribute buttons
00199     int x_pos = data->border;
00200     for(i = 0; i < data->buttons.count(); i++) {
00201       Item *item = data->buttons.at(i);
00202       if(item->button != 0) {
00203     QPushButton *b = item->button;
00204     b->move(x_pos, (height() - b->height()) / 2);
00205 
00206     x_pos += b->width() + data->autoborder;
00207       } else
00208     x_pos += (int)((((double)fs) * item->stretch) / stretch);
00209     }
00210   } else { // VERTICAL
00211     // calcualte free size and stretches
00212     int fs = height() - 2 * data->border;
00213     int stretch = 0;
00214     for(i = 0; i < data->buttons.count(); i++) {
00215       Item *item = data->buttons.at(i);
00216       if(item->button != 0)
00217     fs -= item->button->height() + data->autoborder;
00218       else
00219     stretch +=item->stretch;
00220     }
00221 
00222     // distribute buttons
00223     int y_pos = data->border;
00224     for(i = 0; i < data->buttons.count(); i++) {
00225       Item *item = data->buttons.at(i);
00226       if(item->button != 0) {
00227     QPushButton *b = item->button;
00228     b->move((width() - b->width()) / 2, y_pos);
00229 
00230     y_pos += b->height() + data->autoborder;
00231       } else
00232     y_pos += (int)((((double)fs) * item->stretch) / stretch);
00233     }
00234   }
00235 }
00236 
00237 void KButtonBox::resizeEvent(QResizeEvent *) {
00238   placeButtons();
00239 }
00240 
00241 QSize KButtonBox::bestButtonSize() const {
00242   QSize s(0, 0);
00243   unsigned int i;
00244 
00245   // calculate optimal size
00246   for(i = 0; i < data->buttons.count(); i++) {
00247     KButtonBox *that = (KButtonBox*)this; // to remove the const ;(
00248     Item *item = that->data->buttons.at(i);
00249     QPushButton *b = item->button;
00250 
00251     if(b != 0 && !item->noexpand) {
00252       QSize bs = buttonSizeHint(b);
00253 
00254       if(bs.width() > s.width())
00255     s.setWidth(bs.width());
00256       if(bs.height() > s.height())
00257     s.setHeight(bs.height());
00258     }
00259   }
00260 
00261   return s;
00262 }
00263 
00264 QSize KButtonBox::sizeHint() const {
00265   unsigned int i, dw;
00266 
00267   if(data->buttons.count() == 0)
00268     return QSize(0, 0);
00269   else {
00270     dw = 2 * data->border;
00271 
00272     QSize bs = bestButtonSize();
00273     for(i = 0; i < data->buttons.count(); i++) {
00274       KButtonBox *that = (KButtonBox*)this;
00275       Item *item = that->data->buttons.at(i);
00276       QPushButton *b = item->button;
00277       if(b != 0) {
00278     QSize s;
00279     if(item->noexpand)
00280       s = that->buttonSizeHint(b);
00281     else
00282       s = bs;
00283 
00284     if(data->orientation == Horizontal)
00285       dw += s.width();
00286     else
00287       dw += s.height();
00288 
00289     if( i != data->buttons.count() - 1 )
00290       dw += data->autoborder;
00291       }
00292     }
00293 
00294     if(data->orientation == Horizontal)
00295     return QSize(dw, bs.height() + 2 * data->border);
00296     else
00297     return QSize(bs.width() + 2 * data->border, dw);
00298   }
00299 }
00300 
00301 QSizePolicy KButtonBox::sizePolicy() const
00302 {
00303     return data->orientation == Horizontal?
00304         QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) :
00305         QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
00306 }
00307 
00308 /*
00309  * Returns the best size for a button. If a button is less than
00310  * minButtonWidth pixels wide, return minButtonWidth pixels
00311  * as minimum width
00312  */
00313 QSize KButtonBox::buttonSizeHint(QPushButton *b) const {
00314   QSize s = b->sizeHint();
00315   QSize ms = b->minimumSize();
00316   if(s.width() < minButtonWidth)
00317     s.setWidth(minButtonWidth);
00318 
00319   // allows the programmer to override the settings
00320   if(ms.width() > s.width())
00321     s.setWidth(ms.width());
00322   if(ms.height() > s.height())
00323     s.setHeight(ms.height());
00324 
00325   return s;
00326 }
00327 
00328 void KButtonBox::virtual_hook( int, void* )
00329 { /*BASE::virtual_hook( id, data );*/ }
00330 
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 23 17:11:52 2004 by doxygen 1.3.8-20040913 written by Dimitri van Heesch, © 1997-2003