lib

ttdetoolbarbutton.cpp
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000 theKompany.com
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20#include <ttdetoolbarbutton.h>
21
22#include <tqtimer.h>
23#include <tqtooltip.h>
24#include <tqpopupmenu.h>
25#include <tqcursor.h>
26#include <tqpainter.h>
27#include <tqdrawutil.h>
28#include <tqstyle.h>
29
30#include <tdeapplication.h>
31#include <kiconeffect.h>
32#include <kiconloader.h>
33#include <tdeglobalsettings.h>
34
35// Delay in ms before delayed popup pops up
36#define POPUP_DELAY 500
37
38class TTDEToolBarButton::TTDEToolBarButtonPrivate
39{
40public:
41 TTDEToolBarButtonPrivate()
42 {
43 m_iconMode = TK::IconOnly;
44 m_isPopup = false;
45 m_isToggle = false;
46 m_isOn = false;
47 m_isRaised = false;
48 m_autoRaised = true;
49 ignoreNextMousePress = false;
50
51 m_text = TQString();
52 m_iconName = TQString();
53 m_arrowPressed = false;
54 m_delayTimer = 0L;
55 m_popup = 0L;
56
57 m_disabledIconName = TQString();
58 m_defaultIconName = TQString();
59
60 m_instance = TDEGlobal::instance();
61 }
62
63 ~TTDEToolBarButtonPrivate()
64 {
65 delete m_delayTimer;
66 m_delayTimer = 0;
67 }
68
69 bool m_isPopup;
70 bool m_isToggle;
71 bool m_isOn;
72 bool m_isRaised;
73 bool m_autoRaised;
74 bool m_arrowPressed;
75 bool ignoreNextMousePress;
76
77 TQString m_text;
78 TQString m_iconName;
79 TQString m_disabledIconName;
80 TQString m_defaultIconName;
81
82 TK::IconMode m_iconMode;
83
84 TQTimer *m_delayTimer;
85 TQPopupMenu *m_popup;
86
87 TDEInstance *m_instance;
88};
89
90TTDEToolBarButton::TTDEToolBarButton( const TQString& icon, const TQString& txt,
91 TQWidget* parent, const char* name,
92 TDEInstance *instance )
93: TQToolButton(parent,name)
94{
95 d = new TTDEToolBarButtonPrivate;
96 d->m_text = txt;
97 d->m_instance = instance;
98
99 setFocusPolicy( TQWidget::NoFocus );
100
101 connect(this, TQ_SIGNAL(clicked()), TQ_SLOT(slotClicked()) );
102 connect(this, TQ_SIGNAL(pressed()), TQ_SLOT(slotPressed()) );
103 connect(this, TQ_SIGNAL(released()), TQ_SLOT(slotReleased()) );
104
105 installEventFilter(this);
106
107 setIcon(icon);
108 modeChange();
109}
110
111TTDEToolBarButton::TTDEToolBarButton( const TQPixmap& pixmap, const TQString& txt, TQWidget* parent, const char* name )
112: TQToolButton(parent,name )
113{
114 d = new TTDEToolBarButtonPrivate;
115 d->m_text = txt;
116
117 setFocusPolicy( TQWidget::NoFocus );
118
119 connect(this, TQ_SIGNAL(clicked()), TQ_SLOT(slotClicked()) );
120 connect(this, TQ_SIGNAL(pressed()), TQ_SLOT(slotPressed()) );
121 connect(this, TQ_SIGNAL(released()), TQ_SLOT(slotReleased()) );
122
123 installEventFilter(this);
124
125 setPixmap(pixmap);
126 modeChange();
127}
128
129TTDEToolBarButton::~TTDEToolBarButton()
130{
131 delete d;
132}
133
134TQString TTDEToolBarButton::text()
135{
136 return d->m_text;
137}
138
139void TTDEToolBarButton::modeChange()
140{
141 TQToolTip::add(this,d->m_text);
142
143 int border = 3;
144 int w = 2*border;
145 int h = 2*border;
146
147 if (pixmap()) {
148 w += pixmap()->width();
149 h = TQMAX(h,pixmap()->height()+2*border);
150 if (d->m_iconMode == TK::IconAndText && !d->m_text.isEmpty())
151 w += border;
152 }
153
154 if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty())
155 {
156 TQFont tmp_font = TDEGlobalSettings::toolBarFont();
157 TQFontMetrics fm(tmp_font);
158
159 h = TQMAX(h,fm.lineSpacing()+2*border);
160 w += fm.width(d->m_text);
161 }
162
163 if (d->m_popup && !d->m_isToggle)
164 w += 11;
165
166 TQSize size(w,h);
167 setMinimumSize(size);
168
169 updateGeometry();
170}
171
172void TTDEToolBarButton::setEnabled( bool enabled )
173{
174 if (isEnabled()==enabled)
175 return;
176
177 TQToolButton::setPixmap( (enabled ? defaultPixmap : disabledPixmap) );
178 TQToolButton::setEnabled( enabled );
179}
180
181void TTDEToolBarButton::setText( const TQString& text)
182{
183 d->m_text = text;
184 repaint(false);
185}
186
187void TTDEToolBarButton::setIcon( const TQString& icon )
188{
189 d->m_iconName = icon;
190 int iconSize = 16;
191
192 setPixmap( BarIcon(icon, iconSize, TDEIcon::ActiveState, d->m_instance), false );
193 setDisabledPixmap( BarIcon(icon, iconSize, TDEIcon::DisabledState, d->m_instance) );
194 setDefaultPixmap( BarIcon(icon, iconSize, TDEIcon::DefaultState, d->m_instance) );
195}
196
197void TTDEToolBarButton::setDisabledIcon( const TQString &icon )
198{
199 d->m_disabledIconName = icon;
200 int iconSize = 16;
201 setDisabledPixmap( BarIcon(icon, iconSize, TDEIcon::DisabledState, d->m_instance) );
202}
203
204void TTDEToolBarButton::setDefaultIcon( const TQString &icon )
205{
206 d->m_defaultIconName = icon;
207 int iconSize = 16;
208 setDefaultPixmap( BarIcon(icon, iconSize, TDEIcon::DefaultState, d->m_instance) );
209}
210
211TQPixmap TTDEToolBarButton::getActivePixmap() const
212{
213 return activePixmap;
214}
215
216void TTDEToolBarButton::setPixmap( const TQPixmap &pixmap )
217{
218 setPixmap( pixmap, true );
219}
220
221void TTDEToolBarButton::setPixmap( const TQPixmap &pixmap, bool generate )
222{
223 activePixmap = pixmap;
224
225 if ( generate )
226 {
227 makeDefaultPixmap();
228 makeDisabledPixmap();
229 }
230 else
231 {
232 if (defaultPixmap.isNull())
233 defaultPixmap = activePixmap;
234 if (disabledPixmap.isNull())
235 disabledPixmap = activePixmap;
236 }
237
238 TQToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
239}
240
241void TTDEToolBarButton::setDefaultPixmap( const TQPixmap &pixmap )
242{
243 defaultPixmap = pixmap;
244 TQToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
245}
246
247void TTDEToolBarButton::setDisabledPixmap( const TQPixmap &pixmap )
248{
249 disabledPixmap = pixmap;
250 TQToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
251}
252
253void TTDEToolBarButton::setPopup(TQPopupMenu *p)
254{
255 d->m_popup = p;
256 d->m_popup->setFont(TDEGlobalSettings::toolBarFont());
257 p->installEventFilter(this);
258
259 modeChange();
260}
261
262TQPopupMenu *TTDEToolBarButton::popup()
263{
264 return d->m_popup;
265}
266
267void TTDEToolBarButton::setDelayedPopup (TQPopupMenu *p, bool toggle )
268{
269 d->m_isPopup = true;
270 setToggle(toggle);
271
272 if (!d->m_delayTimer) {
273 d->m_delayTimer = new TQTimer(this);
274 connect(d->m_delayTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotDelayTimeout()));
275 }
276
277 setPopup(p);
278}
279
280void TTDEToolBarButton::setRaised(bool f)
281{
282 d->m_isRaised = f;
283 repaint(false);
284}
285
286void TTDEToolBarButton::setAutoRaised(bool f)
287{
288 d->m_autoRaised = f;
289}
290
291void TTDEToolBarButton::leaveEvent(TQEvent *)
292{
293 if (!d->m_isToggle && !(d->m_popup && d->m_popup->isVisible()) ) {
294 TQToolButton::setPixmap(isEnabled() ? defaultPixmap : disabledPixmap);
295 if (d->m_autoRaised)
296 setRaised(false);
297 }
298}
299
300void TTDEToolBarButton::enterEvent(TQEvent *)
301{
302 if (!d->m_isToggle) {
303 if (isEnabled()) {
304 TQToolButton::setPixmap(activePixmap);
305 if (d->m_autoRaised)
306 setRaised(true);
307 } else {
308 TQToolButton::setPixmap(disabledPixmap);
309 }
310 repaint(false);
311 }
312}
313
314bool TTDEToolBarButton::eventFilter(TQObject *o, TQEvent *ev)
315{
316 if ( o == this )
317 if (ev->type() == TQEvent::MouseButtonPress && d->m_popup && d->m_isPopup ) {
318 if (!d->m_isToggle) {
319 d->m_arrowPressed = arrowPressed( mapFromGlobal(TQCursor::pos()) );
320 } else {
321 d->m_delayTimer->start(POPUP_DELAY);
322 }
323 }
324
325 if ( o == d->m_popup) {
326 switch (ev->type())
327 {
328 case TQEvent::Show:
329 on(true);
330 return false;
331 case TQEvent::Hide:
332 on(false);
333 setDown(false);
334 if ( !geometry().contains(parentWidget()->mapFromGlobal(TQCursor::pos())) )
335 leaveEvent(0L);
336 return false;
337 break;
338 case TQEvent::MouseButtonPress: {
339 d->m_arrowPressed = arrowPressed( mapFromGlobal(TQCursor::pos()) );
340 d->ignoreNextMousePress = d->m_arrowPressed;
341 break;
342 }
343 default:
344 break;
345 }
346 }
347 return false;
348}
349
350void TTDEToolBarButton::drawButton( TQPainter* p )
351{
352#define DRAW_PIXMAP_AND_TEXT \
353 int x = 3;\
354 if (pixmap()) {\
355 style().drawItem( p, TQRect( x, 0, pixmap()->width(), height() ), AlignCenter, colorGroup(), isEnabled(), pixmap(), TQString() );\
356 if (d->m_iconMode==TK::IconAndText && !d->m_text.isEmpty()) {\
357 x += pixmap()->width() + 3;\
358 }\
359 }\
360 if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty()) {\
361 TQFontMetrics fm(TDEGlobalSettings::toolBarFont());\
362 style().drawItem( p, TQRect( x, 0, fm.width(d->m_text), height() ), AlignCenter, colorGroup(), isEnabled(), 0, d->m_text );\
363 }
364
365 const char* arrow[] = {
366 "7 4 2 1",
367 "# c Black",
368 ". c None",
369 "#######",
370 ".#####.",
371 "..###..",
372 "...#..."};
373 TQPixmap arrow_pix(arrow);
374 bool f = d->m_isOn || isDown();
375
376 if (d->m_popup && !d->m_isToggle)
377 {
378 if (d->m_isPopup)
379 {
380 TQStyle::SFlags flags = TQStyle::Style_Default;
381 if (isEnabled()) flags |= TQStyle::Style_Enabled;
382 if (isOn()) flags |= TQStyle::Style_On;
383 if (d->m_isRaised) flags |= TQStyle::Style_Raised;
384 if (hasFocus()) flags |= TQStyle::Style_HasFocus;
385
386 style().drawComplexControl( TQStyle::CC_ToolButton, p, this, TQRect( 0, 0, width()-12, height() ), colorGroup(), flags, TQStyle::SC_ToolButton );
387 style().drawComplexControl( TQStyle::CC_ToolButton, p, this, TQRect( width()-13, 0, 13, height() ), colorGroup(), flags, TQStyle::SC_ToolButton );
388 style().drawItem( p, TQRect( width()-13, 0, 13, height() ), AlignCenter, colorGroup(), isEnabled(), &arrow_pix, TQString() );
389 if ( d->m_isRaised )
390 qDrawShadeLine( p, width()-12, 0, width()-12, height(), colorGroup(), true );
391 DRAW_PIXMAP_AND_TEXT
392 } else {
393 style().drawControl( TQStyle::CE_PushButton, p, this, TQRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f );
394 DRAW_PIXMAP_AND_TEXT
395 int z = f ? 1:0;
396 p->drawPixmap(width()-11+z,(height()-4)/2+z ,arrow_pix);
397 }
398 } else {
399 style().drawControl( TQStyle::CE_PushButton, p, this, TQRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f );
400 DRAW_PIXMAP_AND_TEXT
401 }
402}
403
404void TTDEToolBarButton::paletteChange(const TQPalette &)
405{
406 makeDisabledPixmap();
407 if ( !isEnabled() )
408 TQToolButton::setPixmap( disabledPixmap );
409 else
410 TQToolButton::setPixmap( defaultPixmap );
411 repaint(false);
412}
413
414void TTDEToolBarButton::makeDefaultPixmap()
415{
416 if (activePixmap.isNull())
417 return;
418
419 TDEIconEffect effect;
420 defaultPixmap = effect.apply(activePixmap, TDEIcon::Toolbar, TDEIcon::DefaultState);
421}
422
423void TTDEToolBarButton::makeDisabledPixmap()
424{
425 if (activePixmap.isNull())
426 return;
427
428 TDEIconEffect effect;
429 disabledPixmap = effect.apply(activePixmap, TDEIcon::Toolbar, TDEIcon::DisabledState);
430}
431
432TQSize TTDEToolBarButton::sizeHint() const
433{
434 return minimumSize();
435}
436
437TQSize TTDEToolBarButton::minimumSizeHint() const
438{
439 return minimumSize();
440}
441
442void TTDEToolBarButton::showMenu()
443{
444 TQPoint p ( mapToGlobal( TQPoint( 0, 0 ) ) );
445 const int deskHeight = TDEGlobalSettings::desktopGeometry(this).height();
446 if ( p.y() + height() + d->m_popup->height() > deskHeight )
447 p.setY( p.y() - d->m_popup->height() );
448 else
449 p.setY( p.y() + height( ));
450
451 d->m_popup->popup(p);
452}
453
454void TTDEToolBarButton::slotDelayTimeout()
455{
456 d->m_delayTimer->stop();
457 showMenu();
458}
459
460void TTDEToolBarButton::slotClicked()
461{
462 if ( d->ignoreNextMousePress ) {
463 d->ignoreNextMousePress=false;
464 return;
465 }
466
467 if (d->m_popup && !d->m_isPopup)
468 showMenu();
469 else
470 emit buttonClicked();
471}
472
473void TTDEToolBarButton::slotPressed()
474{
475 if ( d->ignoreNextMousePress )
476 return;
477
478 if (d->m_popup) {
479 if (!d->m_isPopup || d->m_isPopup && d->m_arrowPressed)
480 showMenu();
481 }
482 else
483 emit buttonPressed();
484
485 d->ignoreNextMousePress = false;
486}
487
488void TTDEToolBarButton::slotReleased()
489{
490 if (d->m_popup && d->m_isPopup)
491 d->m_delayTimer->stop();
492
493 emit buttonReleased();
494}
495
496void TTDEToolBarButton::slotToggled()
497{
498 emit buttonToggled();
499}
500
501void TTDEToolBarButton::on(bool flag)
502{
503 d->m_isOn = flag;
504 repaint();
505}
506
507void TTDEToolBarButton::toggle()
508{
509 on(!d->m_isOn);
510}
511
512void TTDEToolBarButton::setToggle(bool flag)
513{
514 d->m_isToggle = flag;
515 if (flag == true)
516 connect(this, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotToggled()));
517 else
518 disconnect(this, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(slotToggled()));
519
520 modeChange();
521 repaint();
522}
523
524void TTDEToolBarButton::setIconMode( TK::IconMode m )
525{
526 d->m_iconMode = m;
527 modeChange();
528 repaint();
529}
530
531#include <ttdetoolbarbutton.moc>
const char * name(StdAction id)