00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include <tktoolbarbutton.h>
00020
00021
#include <qtimer.h>
00022
#include <qtooltip.h>
00023
#include <qpopupmenu.h>
00024
#include <qcursor.h>
00025
#include <qpainter.h>
00026
#include <qdrawutil.h>
00027
#include <qstyle.h>
00028
00029
#include <kdeversion.h>
00030
#include <kapplication.h>
00031
#include <kiconeffect.h>
00032
#include <kiconloader.h>
00033
#include <kglobalsettings.h>
00034
00035
00036
#define POPUP_DELAY 500
00037
00038
class TKToolBarButton::TKToolBarButtonPrivate
00039 {
00040
public:
00041 TKToolBarButtonPrivate()
00042 {
00043 m_iconMode = TK::IconOnly;
00044 m_isPopup =
false;
00045 m_isToggle =
false;
00046 m_isOn =
false;
00047 m_isRaised =
false;
00048 m_autoRaised =
true;
00049 ignoreNextMousePress =
false;
00050
00051 m_text = QString::null;
00052 m_iconName = QString::null;
00053 m_arrowPressed =
false;
00054 m_delayTimer = 0L;
00055 m_popup = 0L;
00056
00057 m_disabledIconName = QString::null;
00058 m_defaultIconName = QString::null;
00059
00060 m_instance = KGlobal::instance();
00061 }
00062
00063 ~TKToolBarButtonPrivate()
00064 {
00065
delete m_delayTimer;
00066 m_delayTimer = 0;
00067 }
00068
00069
bool m_isPopup;
00070
bool m_isToggle;
00071
bool m_isOn;
00072
bool m_isRaised;
00073
bool m_autoRaised;
00074
bool m_arrowPressed;
00075
bool ignoreNextMousePress;
00076
00077
QString m_text;
00078
QString m_iconName;
00079
QString m_disabledIconName;
00080
QString m_defaultIconName;
00081
00082 TK::IconMode m_iconMode;
00083
00084
QTimer *m_delayTimer;
00085
QPopupMenu *m_popup;
00086
00087 KInstance *m_instance;
00088 };
00089
00090 TKToolBarButton::TKToolBarButton(
const QString& icon,
const QString& txt,
00091
QWidget* parent,
const char* name,
00092 KInstance *instance )
00093 :
QToolButton(parent,name)
00094 {
00095 d =
new TKToolBarButtonPrivate;
00096 d->m_text = txt;
00097 d->m_instance = instance;
00098
00099 setFocusPolicy( NoFocus );
00100
00101 connect(
this, SIGNAL(clicked()), SLOT(slotClicked()) );
00102 connect(
this, SIGNAL(pressed()), SLOT(slotPressed()) );
00103 connect(
this, SIGNAL(released()), SLOT(slotReleased()) );
00104
00105 installEventFilter(
this);
00106
00107 setIcon(icon);
00108 modeChange();
00109 }
00110
00111 TKToolBarButton::TKToolBarButton(
const QPixmap& pixmap,
const QString& txt,
QWidget* parent,
const char* name )
00112 :
QToolButton(parent,name )
00113 {
00114 d =
new TKToolBarButtonPrivate;
00115 d->m_text = txt;
00116
00117 setFocusPolicy( NoFocus );
00118
00119 connect(
this, SIGNAL(clicked()), SLOT(slotClicked()) );
00120 connect(
this, SIGNAL(pressed()), SLOT(slotPressed()) );
00121 connect(
this, SIGNAL(released()), SLOT(slotReleased()) );
00122
00123 installEventFilter(
this);
00124
00125 setPixmap(pixmap);
00126 modeChange();
00127 }
00128
00129 TKToolBarButton::~TKToolBarButton()
00130 {
00131
delete d;
00132 }
00133
00134
QString TKToolBarButton::text()
00135 {
00136
return d->m_text;
00137 }
00138
00139
void TKToolBarButton::modeChange()
00140 {
00141 QToolTip::add(
this,d->m_text);
00142
00143
int border = 3;
00144
int w = 2*border;
00145
int h = 2*border;
00146
00147
if (pixmap()) {
00148 w += pixmap()->width();
00149 h = QMAX(h,pixmap()->height()+2*border);
00150
if (d->m_iconMode == TK::IconAndText && !d->m_text.isEmpty())
00151 w += border;
00152 }
00153
00154
if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty())
00155 {
00156
QFont tmp_font = KGlobalSettings::toolBarFont();
00157
QFontMetrics fm(tmp_font);
00158
00159 h = QMAX(h,fm.lineSpacing()+2*border);
00160 w += fm.width(d->m_text);
00161 }
00162
00163
if (d->m_popup && !d->m_isToggle)
00164 w += 11;
00165
00166
QSize size(w,h);
00167 setMinimumSize(size);
00168
00169 updateGeometry();
00170 }
00171
00172
void TKToolBarButton::setEnabled(
bool enabled )
00173 {
00174
if (isEnabled()==enabled)
00175
return;
00176
00177 QToolButton::setPixmap( (enabled ? defaultPixmap : disabledPixmap) );
00178 QToolButton::setEnabled( enabled );
00179 }
00180
00181
void TKToolBarButton::setText(
const QString& text)
00182 {
00183 d->m_text = text;
00184 repaint(
false);
00185 }
00186
00187
void TKToolBarButton::setIcon(
const QString& icon )
00188 {
00189 d->m_iconName = icon;
00190
int iconSize = 16;
00191
00192 setPixmap( BarIcon(icon, iconSize, KIcon::ActiveState, d->m_instance),
false );
00193 setDisabledPixmap( BarIcon(icon, iconSize, KIcon::DisabledState, d->m_instance) );
00194 setDefaultPixmap( BarIcon(icon, iconSize, KIcon::DefaultState, d->m_instance) );
00195 }
00196
00197
void TKToolBarButton::setDisabledIcon(
const QString &icon )
00198 {
00199 d->m_disabledIconName = icon;
00200
int iconSize = 16;
00201 setDisabledPixmap( BarIcon(icon, iconSize, KIcon::DisabledState, d->m_instance) );
00202 }
00203
00204
void TKToolBarButton::setDefaultIcon(
const QString &icon )
00205 {
00206 d->m_defaultIconName = icon;
00207
int iconSize = 16;
00208 setDefaultPixmap( BarIcon(icon, iconSize, KIcon::DefaultState, d->m_instance) );
00209 }
00210
00211
QPixmap TKToolBarButton::getActivePixmap()
const
00212
{
00213
return activePixmap;
00214 }
00215
00216
void TKToolBarButton::setPixmap(
const QPixmap &pixmap )
00217 {
00218 setPixmap( pixmap,
true );
00219 }
00220
00221
void TKToolBarButton::setPixmap(
const QPixmap &pixmap,
bool generate )
00222 {
00223 activePixmap = pixmap;
00224
00225
if ( generate )
00226 {
00227 makeDefaultPixmap();
00228 makeDisabledPixmap();
00229 }
00230
else
00231 {
00232
if (defaultPixmap.isNull())
00233 defaultPixmap = activePixmap;
00234
if (disabledPixmap.isNull())
00235 disabledPixmap = activePixmap;
00236 }
00237
00238 QToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
00239 }
00240
00241
void TKToolBarButton::setDefaultPixmap(
const QPixmap &pixmap )
00242 {
00243 defaultPixmap = pixmap;
00244 QToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
00245 }
00246
00247
void TKToolBarButton::setDisabledPixmap(
const QPixmap &pixmap )
00248 {
00249 disabledPixmap = pixmap;
00250 QToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
00251 }
00252
00253
void TKToolBarButton::setPopup(
QPopupMenu *p)
00254 {
00255 d->m_popup = p;
00256 d->m_popup->setFont(KGlobalSettings::toolBarFont());
00257 p->installEventFilter(
this);
00258
00259 modeChange();
00260 }
00261
00262
QPopupMenu *TKToolBarButton::popup()
00263 {
00264
return d->m_popup;
00265 }
00266
00267
void TKToolBarButton::setDelayedPopup (
QPopupMenu *p,
bool toggle )
00268 {
00269 d->m_isPopup =
true;
00270 setToggle(toggle);
00271
00272
if (!d->m_delayTimer) {
00273 d->m_delayTimer =
new QTimer(
this);
00274 connect(d->m_delayTimer, SIGNAL(timeout()),
this, SLOT(slotDelayTimeout()));
00275 }
00276
00277 setPopup(p);
00278 }
00279
00280
void TKToolBarButton::setRaised(
bool f)
00281 {
00282 d->m_isRaised = f;
00283 repaint(
false);
00284 }
00285
00286
void TKToolBarButton::setAutoRaised(
bool f)
00287 {
00288 d->m_autoRaised = f;
00289 }
00290
00291
void TKToolBarButton::leaveEvent(
QEvent *)
00292 {
00293
if (!d->m_isToggle && !(d->m_popup && d->m_popup->isVisible()) ) {
00294 QToolButton::setPixmap(isEnabled() ? defaultPixmap : disabledPixmap);
00295
if (d->m_autoRaised)
00296 setRaised(
false);
00297 }
00298 }
00299
00300
void TKToolBarButton::enterEvent(
QEvent *)
00301 {
00302
if (!d->m_isToggle) {
00303
if (isEnabled()) {
00304 QToolButton::setPixmap(activePixmap);
00305
if (d->m_autoRaised)
00306 setRaised(
true);
00307 }
else {
00308 QToolButton::setPixmap(disabledPixmap);
00309 }
00310 repaint(
false);
00311 }
00312 }
00313
00314
bool TKToolBarButton::eventFilter(
QObject *o,
QEvent *ev)
00315 {
00316
if ( o ==
this )
00317
if (ev->type() == QEvent::MouseButtonPress && d->m_popup && d->m_isPopup ) {
00318
if (!d->m_isToggle) {
00319 d->m_arrowPressed = arrowPressed( mapFromGlobal(QCursor::pos()) );
00320 }
else {
00321 d->m_delayTimer->start(POPUP_DELAY);
00322 }
00323 }
00324
00325
if ( o == d->m_popup) {
00326
switch (ev->type())
00327 {
00328
case QEvent::Show:
00329 on(
true);
00330
return false;
00331
case QEvent::Hide:
00332 on(
false);
00333 setDown(
false);
00334
if ( !geometry().contains(parentWidget()->mapFromGlobal(QCursor::pos())) )
00335 leaveEvent(0L);
00336
return false;
00337
break;
00338
case QEvent::MouseButtonPress: {
00339 d->m_arrowPressed = arrowPressed( mapFromGlobal(QCursor::pos()) );
00340 d->ignoreNextMousePress = d->m_arrowPressed;
00341
break;
00342 }
00343
default:
00344
break;
00345 }
00346 }
00347
return false;
00348 }
00349
00350
void TKToolBarButton::drawButton(
QPainter* p )
00351 {
00352
#define DRAW_PIXMAP_AND_TEXT \
00353
int x = 3;\
00354
if (pixmap()) {\
00355
style().drawItem( p, QRect( x, 0, pixmap()->width(), height() ), AlignCenter, colorGroup(), isEnabled(), pixmap(), QString::null );\
00356
if (d->m_iconMode==TK::IconAndText && !d->m_text.isEmpty()) {\
00357
x += pixmap()->width() + 3;\
00358
}\
00359
}\
00360
if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty()) {\
00361
QFontMetrics fm(KGlobalSettings::toolBarFont());\
00362
style().drawItem( p, QRect( x, 0, fm.width(d->m_text), height() ), AlignCenter, colorGroup(), isEnabled(), 0, d->m_text );\
00363
}
00364
00365
const char* arrow[] = {
00366
"7 4 2 1",
00367
"# c Black",
00368
". c None",
00369
"#######",
00370
".#####.",
00371
"..###..",
00372
"...#..."};
00373
QPixmap arrow_pix(arrow);
00374
bool f = d->m_isOn || isDown();
00375
00376
if (d->m_popup && !d->m_isToggle)
00377 {
00378
if (d->m_isPopup)
00379 {
00380 QStyle::SFlags flags = QStyle::Style_Default;
00381
if (isEnabled()) flags |= QStyle::Style_Enabled;
00382
if (isOn()) flags |= QStyle::Style_On;
00383
if (d->m_isRaised) flags |= QStyle::Style_Raised;
00384
if (hasFocus()) flags |= QStyle::Style_HasFocus;
00385
00386 style().drawComplexControl( QStyle::CC_ToolButton, p,
this,
QRect( 0, 0, width()-12, height() ), colorGroup(), flags, QStyle::SC_ToolButton );
00387 style().drawComplexControl( QStyle::CC_ToolButton, p,
this,
QRect( width()-13, 0, 13, height() ), colorGroup(), flags, QStyle::SC_ToolButton );
00388 style().drawItem( p,
QRect( width()-13, 0, 13, height() ), AlignCenter, colorGroup(), isEnabled(), &arrow_pix, QString::null );
00389
if ( d->m_isRaised )
00390 qDrawShadeLine( p, width()-12, 0, width()-12, height(), colorGroup(),
true );
00391 DRAW_PIXMAP_AND_TEXT
00392 }
else {
00393 style().drawControl( QStyle::CE_PushButton, p,
this,
QRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f );
00394 DRAW_PIXMAP_AND_TEXT
00395
int z = f ? 1:0;
00396 p->drawPixmap(width()-11+z,(height()-4)/2+z ,arrow_pix);
00397 }
00398 }
else {
00399 style().drawControl( QStyle::CE_PushButton, p,
this,
QRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f );
00400 DRAW_PIXMAP_AND_TEXT
00401 }
00402 }
00403
00404
void TKToolBarButton::paletteChange(
const QPalette &)
00405 {
00406 makeDisabledPixmap();
00407
if ( !isEnabled() )
00408 QToolButton::setPixmap( disabledPixmap );
00409
else
00410 QToolButton::setPixmap( defaultPixmap );
00411 repaint(
false);
00412 }
00413
00414
void TKToolBarButton::makeDefaultPixmap()
00415 {
00416
if (activePixmap.isNull())
00417
return;
00418
00419 KIconEffect effect;
00420 defaultPixmap = effect.apply(activePixmap, KIcon::Toolbar, KIcon::DefaultState);
00421 }
00422
00423
void TKToolBarButton::makeDisabledPixmap()
00424 {
00425
if (activePixmap.isNull())
00426
return;
00427
00428 KIconEffect effect;
00429 disabledPixmap = effect.apply(activePixmap, KIcon::Toolbar, KIcon::DisabledState);
00430 }
00431
00432
QSize TKToolBarButton::sizeHint()
const
00433
{
00434
return minimumSize();
00435 }
00436
00437
QSize TKToolBarButton::minimumSizeHint()
const
00438
{
00439
return minimumSize();
00440 }
00441
00442
void TKToolBarButton::showMenu()
00443 {
00444
QPoint p ( mapToGlobal(
QPoint( 0, 0 ) ) );
00445
#if KDE_IS_VERSION(3,1,90)
00446
const int deskHeight = KGlobalSettings::desktopGeometry(
this).height();
00447
#else
00448
const int deskHeight = QApplication::desktop()->height();
00449
#endif
00450
if ( p.y() + height() + d->m_popup->height() > deskHeight )
00451 p.setY( p.y() - d->m_popup->height() );
00452
else
00453 p.setY( p.y() + height( ));
00454
00455 d->m_popup->popup(p);
00456 }
00457
00458
void TKToolBarButton::slotDelayTimeout()
00459 {
00460 d->m_delayTimer->stop();
00461 showMenu();
00462 }
00463
00464
void TKToolBarButton::slotClicked()
00465 {
00466
if ( d->ignoreNextMousePress ) {
00467 d->ignoreNextMousePress=
false;
00468
return;
00469 }
00470
00471
if (d->m_popup && !d->m_isPopup)
00472 showMenu();
00473
else
00474 emit buttonClicked();
00475 }
00476
00477
void TKToolBarButton::slotPressed()
00478 {
00479
if ( d->ignoreNextMousePress )
00480
return;
00481
00482
if (d->m_popup) {
00483
if (!d->m_isPopup || d->m_isPopup && d->m_arrowPressed)
00484 showMenu();
00485 }
00486
else
00487 emit buttonPressed();
00488
00489 d->ignoreNextMousePress =
false;
00490 }
00491
00492
void TKToolBarButton::slotReleased()
00493 {
00494
if (d->m_popup && d->m_isPopup)
00495 d->m_delayTimer->stop();
00496
00497 emit buttonReleased();
00498 }
00499
00500
void TKToolBarButton::slotToggled()
00501 {
00502 emit buttonToggled();
00503 }
00504
00505
void TKToolBarButton::on(
bool flag)
00506 {
00507 d->m_isOn = flag;
00508 repaint();
00509 }
00510
00511
void TKToolBarButton::toggle()
00512 {
00513 on(!d->m_isOn);
00514 }
00515
00516
void TKToolBarButton::setToggle(
bool flag)
00517 {
00518 d->m_isToggle = flag;
00519
if (flag ==
true)
00520 connect(
this, SIGNAL(toggled(
bool)),
this, SLOT(slotToggled()));
00521
else
00522 disconnect(
this, SIGNAL(toggled(
bool)),
this, SLOT(slotToggled()));
00523
00524 modeChange();
00525 repaint();
00526 }
00527
00528
void TKToolBarButton::setIconMode( TK::IconMode m )
00529 {
00530 d->m_iconMode = m;
00531 modeChange();
00532 repaint();
00533 }
00534
00535
#include <tktoolbarbutton.moc>