lib Library API Documentation

tktoolbarbutton.cpp

00001 /*
00002  * Kivio - Visual Modelling and Flowcharting
00003  * Copyright (C) 2000 theKompany.com
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 // Delay in ms before delayed popup pops up
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>
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 13:19:28 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2003