• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

kbuttonbox.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, 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 

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal