KDE3Support
k3buttonbox.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 * K3ButtonBox 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 K3ButtonBox 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 "k3buttonbox.moc" 00053 #include <kglobalsettings.h> 00054 #include <kguiitem.h> 00055 #include <kpushbutton.h> 00056 #include <QList> 00057 #include <assert.h> 00058 00059 #define minButtonWidth 50 00060 00061 class K3ButtonBox::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 QList<K3ButtonBox::Item *>; 00072 00073 class K3ButtonBoxPrivate { 00074 public: 00075 unsigned short border; 00076 unsigned short autoborder; 00077 unsigned short orientation; 00078 bool activated; 00079 QList<K3ButtonBox::Item *> buttons; 00080 }; 00081 00082 K3ButtonBox::K3ButtonBox(QWidget *parent, Qt::Orientation _orientation, 00083 int border, int autoborder) 00084 : QWidget(parent), data(new K3ButtonBoxPrivate) 00085 { 00086 assert(data); 00087 00088 data->orientation = _orientation; 00089 data->border = border; 00090 data->autoborder = autoborder < 0 ? border : autoborder; 00091 } 00092 00093 K3ButtonBox::~K3ButtonBox() { 00094 while(!data->buttons.isEmpty()) 00095 delete data->buttons.takeFirst(); 00096 00097 delete data; 00098 } 00099 00100 QPushButton *K3ButtonBox::addButton(const QString& text, bool noexpand) { 00101 Item* const item = new Item(new KPushButton(text, this)); 00102 00103 item->noexpand = noexpand; 00104 data->buttons.append(item); 00105 item->button->adjustSize(); 00106 00107 updateGeometry(); 00108 00109 return item->button; 00110 } 00111 00112 QPushButton *K3ButtonBox::addButton(const KGuiItem& guiitem, bool noexpand) { 00113 Item* const item = new Item(new KPushButton(guiitem, this)); 00114 00115 item->noexpand = noexpand; 00116 data->buttons.append(item); 00117 item->button->adjustSize(); 00118 00119 updateGeometry(); 00120 00121 return item->button; 00122 } 00123 00124 QPushButton * 00125 K3ButtonBox::addButton( 00126 const QString & text, 00127 QObject * receiver, 00128 const char * slot, 00129 bool noexpand 00130 ) 00131 { 00132 QPushButton * pb = addButton(text, noexpand); 00133 00134 if ((0 != receiver) && (0 != slot)) 00135 QObject::connect(pb, SIGNAL(clicked()), receiver, slot); 00136 00137 return pb; 00138 } 00139 00140 QPushButton * 00141 K3ButtonBox::addButton( 00142 const KGuiItem& guiitem, 00143 QObject * receiver, 00144 const char * slot, 00145 bool noexpand 00146 ) 00147 { 00148 QPushButton * pb = addButton(guiitem, noexpand); 00149 00150 if ((0 != receiver) && (0 != slot)) 00151 QObject::connect(pb, SIGNAL(clicked()), receiver, slot); 00152 00153 return pb; 00154 } 00155 00156 void K3ButtonBox::addStretch(int scale) { 00157 if(scale > 0) { 00158 Item* const item = new Item(0); 00159 item->noexpand = false; 00160 item->stretch = scale; 00161 data->buttons.append(item); 00162 } 00163 } 00164 00165 void K3ButtonBox::layout() { 00166 // resize all buttons 00167 const QSize bs = bestButtonSize(); 00168 00169 foreach(Item *item, data->buttons) { 00170 QPushButton* const b = item->button; 00171 if(b) { 00172 if(item->noexpand) 00173 b->setFixedSize(buttonSizeHint(b)); 00174 else 00175 b->setFixedSize(bs); 00176 } 00177 } 00178 00179 setMinimumSize(sizeHint()); 00180 } 00181 00182 void K3ButtonBox::placeButtons() { 00183 00184 if(data->orientation == Qt::Horizontal) { 00185 // calculate free size and stretches 00186 int fs = width() - 2 * data->border; 00187 int stretch = 0; 00188 { 00189 foreach(Item *item, data->buttons) { 00190 QPushButton* const b = item->button; 00191 if(b) { 00192 fs -= b->width(); 00193 00194 // Last button? 00195 if(!(item == data->buttons.last())) 00196 fs -= data->autoborder; 00197 } else { 00198 stretch +=item->stretch; 00199 } 00200 00201 } 00202 } 00203 00204 // distribute buttons 00205 int x_pos = data->border; 00206 { 00207 foreach(Item *item, data->buttons) { 00208 00209 QPushButton* const b = item->button; 00210 if(b) { 00211 b->move(x_pos, (height() - b->height()) / 2); 00212 00213 x_pos += b->width() + data->autoborder; 00214 } else { 00215 x_pos += (int)((((double)fs) * item->stretch) / stretch); 00216 } 00217 00218 } 00219 } 00220 00221 } else { // VERTICAL 00222 // calcualte free size and stretches 00223 int fs = height() - 2 * data->border; 00224 int stretch = 0; 00225 { 00226 foreach(Item *item, data->buttons) { 00227 00228 QPushButton* const b = item->button; 00229 if(b) 00230 fs -= b->height() + data->autoborder; 00231 else 00232 stretch +=item->stretch; 00233 00234 } 00235 00236 } 00237 00238 // distribute buttons 00239 int y_pos = data->border; 00240 { 00241 foreach(Item *item, data->buttons) { 00242 00243 QPushButton* const b = item->button; 00244 if(b) { 00245 b->move((width() - b->width()) / 2, y_pos); 00246 00247 y_pos += b->height() + data->autoborder; 00248 } else { 00249 y_pos += (int)((((double)fs) * item->stretch) / stretch); 00250 } 00251 00252 } 00253 } 00254 } 00255 } 00256 00257 void K3ButtonBox::resizeEvent(QResizeEvent *) { 00258 placeButtons(); 00259 } 00260 00261 QSize K3ButtonBox::bestButtonSize() const { 00262 QSize s(0, 0); 00263 00264 // calculate optimal size 00265 foreach(Item *item, data->buttons) { 00266 00267 QPushButton* const b = item->button; 00268 00269 if(b && !item->noexpand) { 00270 const QSize bs = buttonSizeHint(b); 00271 00272 const int bsWidth = bs.width(); 00273 const int bsHeight = bs.height(); 00274 00275 if(bsWidth > s.width()) 00276 s.setWidth(bsWidth); 00277 if(bsHeight > s.height()) 00278 s.setHeight(bsHeight); 00279 } 00280 } 00281 00282 return s; 00283 } 00284 00285 QSize K3ButtonBox::sizeHint() const { 00286 unsigned int dw; 00287 00288 if(data->buttons.isEmpty()) 00289 return QSize(0, 0); 00290 else { 00291 dw = 2 * data->border; 00292 00293 const QSize bs = bestButtonSize(); 00294 00295 foreach(Item *item, data->buttons) { 00296 00297 QPushButton* const b = item->button; 00298 00299 if(b) { 00300 QSize s; 00301 if(item->noexpand) 00302 s = buttonSizeHint(b); 00303 else 00304 s = bs; 00305 00306 if(data->orientation == Qt::Horizontal) 00307 dw += s.width(); 00308 else 00309 dw += s.height(); 00310 00311 if( !(item == data->buttons.last()) ) 00312 dw += data->autoborder; 00313 } 00314 00315 } 00316 00317 if(data->orientation == Qt::Horizontal) 00318 return QSize(dw, bs.height() + 2 * data->border); 00319 else 00320 return QSize(bs.width() + 2 * data->border, dw); 00321 } 00322 } 00323 00324 QSizePolicy K3ButtonBox::sizePolicy() const 00325 { 00326 return data->orientation == Qt::Horizontal? 00327 QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) : 00328 QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ); 00329 } 00330 00331 /* 00332 * Returns the best size for a button. If a button is less than 00333 * minButtonWidth pixels wide, return minButtonWidth pixels 00334 * as minimum width 00335 */ 00336 QSize K3ButtonBox::buttonSizeHint(QPushButton *b) const { 00337 QSize s = b->sizeHint(); 00338 const QSize ms = b->minimumSize(); 00339 if(s.width() < minButtonWidth) 00340 s.setWidth(minButtonWidth); 00341 00342 // allows the programmer to override the settings 00343 const int msWidth = ms.width(); 00344 const int msHeight = ms.height(); 00345 00346 if(msWidth > s.width()) 00347 s.setWidth(msWidth); 00348 if(msHeight > s.height()) 00349 s.setHeight(msHeight); 00350 00351 return s; 00352 }
KDE 4.6 API Reference