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