Diffstat (limited to 'microkde/kdeui/kbuttonbox.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | microkde/kdeui/kbuttonbox.cpp | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/microkde/kdeui/kbuttonbox.cpp b/microkde/kdeui/kbuttonbox.cpp new file mode 100644 index 0000000..16206e8 --- a/dev/null +++ b/microkde/kdeui/kbuttonbox.cpp | |||
@@ -0,0 +1,300 @@ | |||
1 | /* This file is part of the KDE libraries | ||
2 | Copyright (C) 1997 Mario Weilguni (mweilguni@sime.com) | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Library General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 2 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Library General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this library; see the file COPYING.LIB. If not, write to | ||
16 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
17 | Boston, MA 02111-1307, USA. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * KButtonBox class | ||
22 | * | ||
23 | * A container widget for buttons. Uses Qt layout control to place the | ||
24 | * buttons, can handle both vertical and horizontal button placement. | ||
25 | * | ||
26 | * HISTORY | ||
27 | * | ||
28 | * 03/08/2000 Mario Weilguni <mweilguni@kde.org> | ||
29 | * Removed all those long outdated Motif stuff | ||
30 | * Improved and clarified some if conditions (easier to understand) | ||
31 | * | ||
32 | * 11/13/98 Reginald Stadlbauer <reggie@kde.org> | ||
33 | * Now in Qt 1.4x motif default buttons have no extra width/height anymore. | ||
34 | * So the KButtonBox doesn't add this width/height to default buttons anymore | ||
35 | * which makes the buttons look better. | ||
36 | * | ||
37 | * 01/17/98 Mario Weilguni <mweilguni@sime.com> | ||
38 | * Fixed a bug in sizeHint() | ||
39 | * Improved the handling of Motif default buttons | ||
40 | * | ||
41 | * 01/09/98 Mario Weilguni <mweilguni@sime.com> | ||
42 | * The last button was to far right away from the right/bottom border. | ||
43 | * Fixed this. Removed old code. Buttons get now a minimum width. | ||
44 | * Programmer may now override minimum width and height of a button. | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | //US #include "kbuttonbox.moc" | ||
49 | |||
50 | #include <kbuttonbox.h> | ||
51 | #include <qpushbutton.h> | ||
52 | #include <qptrlist.h> | ||
53 | #include <assert.h> | ||
54 | |||
55 | #define minButtonWidth 50 | ||
56 | |||
57 | class KButtonBox::Item { | ||
58 | public: | ||
59 | QPushButton *button; | ||
60 | bool noexpand; | ||
61 | unsigned short stretch; | ||
62 | unsigned short actual_size; | ||
63 | }; | ||
64 | |||
65 | template class QPtrList<KButtonBox::Item>; | ||
66 | |||
67 | class KButtonBoxPrivate { | ||
68 | public: | ||
69 | unsigned short border; | ||
70 | unsigned short autoborder; | ||
71 | unsigned short orientation; | ||
72 | bool activated; | ||
73 | QPtrList<KButtonBox::Item> buttons; | ||
74 | }; | ||
75 | |||
76 | KButtonBox::KButtonBox(QWidget *parent, Orientation _orientation, | ||
77 | int border, int autoborder) | ||
78 | : QWidget(parent) | ||
79 | { | ||
80 | data = new KButtonBoxPrivate; | ||
81 | assert(data != 0); | ||
82 | |||
83 | data->orientation = _orientation; | ||
84 | data->border = border; | ||
85 | data->autoborder = autoborder < 0 ? border : autoborder; | ||
86 | data->buttons.setAutoDelete(TRUE); | ||
87 | } | ||
88 | |||
89 | KButtonBox::~KButtonBox() { | ||
90 | delete data; | ||
91 | } | ||
92 | |||
93 | QPushButton *KButtonBox::addButton(const QString& text, bool noexpand) { | ||
94 | Item *item = new Item; | ||
95 | |||
96 | item->button = new QPushButton(text, this); | ||
97 | item->noexpand = noexpand; | ||
98 | data->buttons.append(item); | ||
99 | item->button->adjustSize(); | ||
100 | |||
101 | return item->button; | ||
102 | } | ||
103 | |||
104 | QPushButton * | ||
105 | KButtonBox::addButton( | ||
106 | const QString & text, | ||
107 | QObject * receiver, | ||
108 | const char * slot, | ||
109 | bool noexpand | ||
110 | ) | ||
111 | { | ||
112 | QPushButton * pb = addButton(text, noexpand); | ||
113 | |||
114 | if ((0 != receiver) && (0 != slot)) | ||
115 | QObject::connect(pb, SIGNAL(clicked()), receiver, slot); | ||
116 | |||
117 | return pb; | ||
118 | } | ||
119 | |||
120 | |||
121 | void KButtonBox::addStretch(int scale) { | ||
122 | if(scale > 0) { | ||
123 | Item *item = new Item; | ||
124 | item->button = 0; | ||
125 | item->noexpand = FALSE; | ||
126 | item->stretch = scale; | ||
127 | data->buttons.append(item); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | void KButtonBox::layout() { | ||
132 | // resize all buttons | ||
133 | QSize bs = bestButtonSize(); | ||
134 | |||
135 | for(unsigned int i = 0; i < data->buttons.count(); i++) { | ||
136 | Item *item = data->buttons.at(i); | ||
137 | QPushButton *b = item->button; | ||
138 | if(b != 0) { | ||
139 | if(item->noexpand) | ||
140 | b->setFixedSize(buttonSizeHint(b)); | ||
141 | else | ||
142 | b->setFixedSize(bs); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | setMinimumSize(sizeHint()); | ||
147 | } | ||
148 | |||
149 | void KButtonBox::placeButtons() { | ||
150 | unsigned int i; | ||
151 | |||
152 | if(data->orientation == Horizontal) { | ||
153 | // calculate free size and stretches | ||
154 | int fs = width() - 2 * data->border; | ||
155 | int stretch = 0; | ||
156 | for(i = 0; i < data->buttons.count(); i++) { | ||
157 | Item *item = data->buttons.at(i); | ||
158 | if(item->button != 0) { | ||
159 | fs -= item->button->width(); | ||
160 | |||
161 | // Last button? | ||
162 | if(i != data->buttons.count() - 1) | ||
163 | fs -= data->autoborder; | ||
164 | } else | ||
165 | stretch +=item->stretch; | ||
166 | } | ||
167 | |||
168 | // distribute buttons | ||
169 | int x_pos = data->border; | ||
170 | for(i = 0; i < data->buttons.count(); i++) { | ||
171 | Item *item = data->buttons.at(i); | ||
172 | if(item->button != 0) { | ||
173 | QPushButton *b = item->button; | ||
174 | b->move(x_pos, (height() - b->height()) / 2); | ||
175 | |||
176 | x_pos += b->width() + data->autoborder; | ||
177 | } else | ||
178 | x_pos += (int)((((double)fs) * item->stretch) / stretch); | ||
179 | } | ||
180 | } else { // VERTICAL | ||
181 | // calcualte free size and stretches | ||
182 | int fs = height() - 2 * data->border; | ||
183 | int stretch = 0; | ||
184 | for(i = 0; i < data->buttons.count(); i++) { | ||
185 | Item *item = data->buttons.at(i); | ||
186 | if(item->button != 0) | ||
187 | fs -= item->button->height() + data->autoborder; | ||
188 | else | ||
189 | stretch +=item->stretch; | ||
190 | } | ||
191 | |||
192 | // distribute buttons | ||
193 | int y_pos = data->border; | ||
194 | for(i = 0; i < data->buttons.count(); i++) { | ||
195 | Item *item = data->buttons.at(i); | ||
196 | if(item->button != 0) { | ||
197 | QPushButton *b = item->button; | ||
198 | b->move((width() - b->width()) / 2, y_pos); | ||
199 | |||
200 | y_pos += b->height() + data->autoborder; | ||
201 | } else | ||
202 | y_pos += (int)((((double)fs) * item->stretch) / stretch); | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | |||
207 | void KButtonBox::resizeEvent(QResizeEvent *) { | ||
208 | placeButtons(); | ||
209 | } | ||
210 | |||
211 | QSize KButtonBox::bestButtonSize() const { | ||
212 | QSize s(0, 0); | ||
213 | unsigned int i; | ||
214 | |||
215 | // calculate optimal size | ||
216 | for(i = 0; i < data->buttons.count(); i++) { | ||
217 | KButtonBox *that = (KButtonBox*)this; // to remove the const ;( | ||
218 | Item *item = that->data->buttons.at(i); | ||
219 | QPushButton *b = item->button; | ||
220 | |||
221 | if(b != 0 && !item->noexpand) { | ||
222 | QSize bs = buttonSizeHint(b); | ||
223 | |||
224 | if(bs.width() > s.width()) | ||
225 | s.setWidth(bs.width()); | ||
226 | if(bs.height() > s.height()) | ||
227 | s.setHeight(bs.height()); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | return s; | ||
232 | } | ||
233 | |||
234 | QSize KButtonBox::sizeHint() const { | ||
235 | unsigned int i, dw; | ||
236 | |||
237 | if(data->buttons.count() == 0) | ||
238 | return QSize(0, 0); | ||
239 | else { | ||
240 | dw = 2 * data->border; | ||
241 | |||
242 | QSize bs = bestButtonSize(); | ||
243 | for(i = 0; i < data->buttons.count(); i++) { | ||
244 | KButtonBox *that = (KButtonBox*)this; | ||
245 | Item *item = that->data->buttons.at(i); | ||
246 | QPushButton *b = item->button; | ||
247 | if(b != 0) { | ||
248 | QSize s; | ||
249 | if(item->noexpand) | ||
250 | s = that->buttonSizeHint(b); | ||
251 | else | ||
252 | s = bs; | ||
253 | |||
254 | if(data->orientation == Horizontal) | ||
255 | dw += s.width(); | ||
256 | else | ||
257 | dw += s.height(); | ||
258 | |||
259 | if( i != data->buttons.count() - 1 ) | ||
260 | dw += data->autoborder; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | if(data->orientation == Horizontal) | ||
265 | return QSize(dw, bs.height() + 2 * data->border); | ||
266 | else | ||
267 | return QSize(bs.width() + 2 * data->border, dw); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | QSizePolicy KButtonBox::sizePolicy() const | ||
272 | { | ||
273 | return data->orientation == Horizontal? | ||
274 | QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) : | ||
275 | QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ); | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * Returns the best size for a button. If a button is less than | ||
280 | * minButtonWidth pixels wide, return minButtonWidth pixels | ||
281 | * as minimum width | ||
282 | */ | ||
283 | QSize KButtonBox::buttonSizeHint(QPushButton *b) const { | ||
284 | QSize s = b->sizeHint(); | ||
285 | QSize ms = b->minimumSize(); | ||
286 | if(s.width() < minButtonWidth) | ||
287 | s.setWidth(minButtonWidth); | ||
288 | |||
289 | // allows the programmer to override the settings | ||
290 | if(ms.width() > s.width()) | ||
291 | s.setWidth(ms.width()); | ||
292 | if(ms.height() > s.height()) | ||
293 | s.setHeight(ms.height()); | ||
294 | |||
295 | return s; | ||
296 | } | ||
297 | |||
298 | void KButtonBox::virtual_hook( int, void* ) | ||
299 | { /*BASE::virtual_hook( id, data );*/ } | ||
300 | |||