/* * Kivio - Visual Modelling and Flowcharting * Copyright (C) 2000 theKompany.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include // Delay in ms before delayed popup pops up #define POPUP_DELAY 500 class TKToolBarButton::TKToolBarButtonPrivate { public: TKToolBarButtonPrivate() { m_iconMode = TK::IconOnly; m_isPopup = false; m_isToggle = false; m_isOn = false; m_isRaised = false; m_autoRaised = true; ignoreNextMousePress = false; m_text = TQString(); m_iconName = TQString(); m_arrowPressed = false; m_delayTimer = 0L; m_popup = 0L; m_disabledIconName = TQString(); m_defaultIconName = TQString(); m_instance = KGlobal::instance(); } ~TKToolBarButtonPrivate() { delete m_delayTimer; m_delayTimer = 0; } bool m_isPopup; bool m_isToggle; bool m_isOn; bool m_isRaised; bool m_autoRaised; bool m_arrowPressed; bool ignoreNextMousePress; TQString m_text; TQString m_iconName; TQString m_disabledIconName; TQString m_defaultIconName; TK::IconMode m_iconMode; TQTimer *m_delayTimer; TQPopupMenu *m_popup; TDEInstance *m_instance; }; TKToolBarButton::TKToolBarButton( const TQString& icon, const TQString& txt, TQWidget* parent, const char* name, TDEInstance *instance ) : TQToolButton(parent,name) { d = new TKToolBarButtonPrivate; d->m_text = txt; d->m_instance = instance; setFocusPolicy( TQ_NoFocus ); connect(this, TQT_SIGNAL(clicked()), TQT_SLOT(slotClicked()) ); connect(this, TQT_SIGNAL(pressed()), TQT_SLOT(slotPressed()) ); connect(this, TQT_SIGNAL(released()), TQT_SLOT(slotReleased()) ); installEventFilter(this); setIcon(icon); modeChange(); } TKToolBarButton::TKToolBarButton( const TQPixmap& pixmap, const TQString& txt, TQWidget* parent, const char* name ) : TQToolButton(parent,name ) { d = new TKToolBarButtonPrivate; d->m_text = txt; setFocusPolicy( TQ_NoFocus ); connect(this, TQT_SIGNAL(clicked()), TQT_SLOT(slotClicked()) ); connect(this, TQT_SIGNAL(pressed()), TQT_SLOT(slotPressed()) ); connect(this, TQT_SIGNAL(released()), TQT_SLOT(slotReleased()) ); installEventFilter(this); setPixmap(pixmap); modeChange(); } TKToolBarButton::~TKToolBarButton() { delete d; } TQString TKToolBarButton::text() { return d->m_text; } void TKToolBarButton::modeChange() { TQToolTip::add(this,d->m_text); int border = 3; int w = 2*border; int h = 2*border; if (pixmap()) { w += pixmap()->width(); h = TQMAX(h,pixmap()->height()+2*border); if (d->m_iconMode == TK::IconAndText && !d->m_text.isEmpty()) w += border; } if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty()) { TQFont tmp_font = KGlobalSettings::toolBarFont(); TQFontMetrics fm(tmp_font); h = TQMAX(h,fm.lineSpacing()+2*border); w += fm.width(d->m_text); } if (d->m_popup && !d->m_isToggle) w += 11; TQSize size(w,h); setMinimumSize(size); updateGeometry(); } void TKToolBarButton::setEnabled( bool enabled ) { if (isEnabled()==enabled) return; TQToolButton::setPixmap( (enabled ? defaultPixmap : disabledPixmap) ); TQToolButton::setEnabled( enabled ); } void TKToolBarButton::setText( const TQString& text) { d->m_text = text; repaint(false); } void TKToolBarButton::setIcon( const TQString& icon ) { d->m_iconName = icon; int iconSize = 16; setPixmap( BarIcon(icon, iconSize, KIcon::ActiveState, d->m_instance), false ); setDisabledPixmap( BarIcon(icon, iconSize, KIcon::DisabledState, d->m_instance) ); setDefaultPixmap( BarIcon(icon, iconSize, KIcon::DefaultState, d->m_instance) ); } void TKToolBarButton::setDisabledIcon( const TQString &icon ) { d->m_disabledIconName = icon; int iconSize = 16; setDisabledPixmap( BarIcon(icon, iconSize, KIcon::DisabledState, d->m_instance) ); } void TKToolBarButton::setDefaultIcon( const TQString &icon ) { d->m_defaultIconName = icon; int iconSize = 16; setDefaultPixmap( BarIcon(icon, iconSize, KIcon::DefaultState, d->m_instance) ); } TQPixmap TKToolBarButton::getActivePixmap() const { return activePixmap; } void TKToolBarButton::setPixmap( const TQPixmap &pixmap ) { setPixmap( pixmap, true ); } void TKToolBarButton::setPixmap( const TQPixmap &pixmap, bool generate ) { activePixmap = pixmap; if ( generate ) { makeDefaultPixmap(); makeDisabledPixmap(); } else { if (defaultPixmap.isNull()) defaultPixmap = activePixmap; if (disabledPixmap.isNull()) disabledPixmap = activePixmap; } TQToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap ); } void TKToolBarButton::setDefaultPixmap( const TQPixmap &pixmap ) { defaultPixmap = pixmap; TQToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap ); } void TKToolBarButton::setDisabledPixmap( const TQPixmap &pixmap ) { disabledPixmap = pixmap; TQToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap ); } void TKToolBarButton::setPopup(TQPopupMenu *p) { d->m_popup = p; d->m_popup->setFont(KGlobalSettings::toolBarFont()); p->installEventFilter(this); modeChange(); } TQPopupMenu *TKToolBarButton::popup() { return d->m_popup; } void TKToolBarButton::setDelayedPopup (TQPopupMenu *p, bool toggle ) { d->m_isPopup = true; setToggle(toggle); if (!d->m_delayTimer) { d->m_delayTimer = new TQTimer(this); connect(d->m_delayTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotDelayTimeout())); } setPopup(p); } void TKToolBarButton::setRaised(bool f) { d->m_isRaised = f; repaint(false); } void TKToolBarButton::setAutoRaised(bool f) { d->m_autoRaised = f; } void TKToolBarButton::leaveEvent(TQEvent *) { if (!d->m_isToggle && !(d->m_popup && d->m_popup->isVisible()) ) { TQToolButton::setPixmap(isEnabled() ? defaultPixmap : disabledPixmap); if (d->m_autoRaised) setRaised(false); } } void TKToolBarButton::enterEvent(TQEvent *) { if (!d->m_isToggle) { if (isEnabled()) { TQToolButton::setPixmap(activePixmap); if (d->m_autoRaised) setRaised(true); } else { TQToolButton::setPixmap(disabledPixmap); } repaint(false); } } bool TKToolBarButton::eventFilter(TQObject *o, TQEvent *ev) { if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) if (ev->type() == TQEvent::MouseButtonPress && d->m_popup && d->m_isPopup ) { if (!d->m_isToggle) { d->m_arrowPressed = arrowPressed( mapFromGlobal(TQCursor::pos()) ); } else { d->m_delayTimer->start(POPUP_DELAY); } } if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->m_popup)) { switch (ev->type()) { case TQEvent::Show: on(true); return false; case TQEvent::Hide: on(false); setDown(false); if ( !geometry().contains(parentWidget()->mapFromGlobal(TQCursor::pos())) ) leaveEvent(0L); return false; break; case TQEvent::MouseButtonPress: { d->m_arrowPressed = arrowPressed( mapFromGlobal(TQCursor::pos()) ); d->ignoreNextMousePress = d->m_arrowPressed; break; } default: break; } } return false; } void TKToolBarButton::drawButton( TQPainter* p ) { #define DRAW_PIXMAP_AND_TEXT \ int x = 3;\ if (pixmap()) {\ style().drawItem( p, TQRect( x, 0, pixmap()->width(), height() ), AlignCenter, colorGroup(), isEnabled(), pixmap(), TQString() );\ if (d->m_iconMode==TK::IconAndText && !d->m_text.isEmpty()) {\ x += pixmap()->width() + 3;\ }\ }\ if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty()) {\ TQFontMetrics fm(KGlobalSettings::toolBarFont());\ style().drawItem( p, TQRect( x, 0, fm.width(d->m_text), height() ), AlignCenter, colorGroup(), isEnabled(), 0, d->m_text );\ } const char* arrow[] = { "7 4 2 1", "# c Black", ". c None", "#######", ".#####.", "..###..", "...#..."}; TQPixmap arrow_pix(arrow); bool f = d->m_isOn || isDown(); if (d->m_popup && !d->m_isToggle) { if (d->m_isPopup) { TQStyle::SFlags flags = TQStyle::Style_Default; if (isEnabled()) flags |= TQStyle::Style_Enabled; if (isOn()) flags |= TQStyle::Style_On; if (d->m_isRaised) flags |= TQStyle::Style_Raised; if (hasFocus()) flags |= TQStyle::Style_HasFocus; style().drawComplexControl( TQStyle::CC_ToolButton, p, this, TQRect( 0, 0, width()-12, height() ), colorGroup(), flags, TQStyle::SC_ToolButton ); style().drawComplexControl( TQStyle::CC_ToolButton, p, this, TQRect( width()-13, 0, 13, height() ), colorGroup(), flags, TQStyle::SC_ToolButton ); style().drawItem( p, TQRect( width()-13, 0, 13, height() ), AlignCenter, colorGroup(), isEnabled(), &arrow_pix, TQString() ); if ( d->m_isRaised ) qDrawShadeLine( p, width()-12, 0, width()-12, height(), colorGroup(), true ); DRAW_PIXMAP_AND_TEXT } else { style().drawControl( TQStyle::CE_PushButton, p, this, TQRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f ); DRAW_PIXMAP_AND_TEXT int z = f ? 1:0; p->drawPixmap(width()-11+z,(height()-4)/2+z ,arrow_pix); } } else { style().drawControl( TQStyle::CE_PushButton, p, this, TQRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f ); DRAW_PIXMAP_AND_TEXT } } void TKToolBarButton::paletteChange(const TQPalette &) { makeDisabledPixmap(); if ( !isEnabled() ) TQToolButton::setPixmap( disabledPixmap ); else TQToolButton::setPixmap( defaultPixmap ); repaint(false); } void TKToolBarButton::makeDefaultPixmap() { if (activePixmap.isNull()) return; KIconEffect effect; defaultPixmap = effect.apply(activePixmap, KIcon::Toolbar, KIcon::DefaultState); } void TKToolBarButton::makeDisabledPixmap() { if (activePixmap.isNull()) return; KIconEffect effect; disabledPixmap = effect.apply(activePixmap, KIcon::Toolbar, KIcon::DisabledState); } TQSize TKToolBarButton::sizeHint() const { return minimumSize(); } TQSize TKToolBarButton::minimumSizeHint() const { return minimumSize(); } void TKToolBarButton::showMenu() { TQPoint p ( mapToGlobal( TQPoint( 0, 0 ) ) ); const int deskHeight = KGlobalSettings::desktopGeometry(this).height(); if ( p.y() + height() + d->m_popup->height() > deskHeight ) p.setY( p.y() - d->m_popup->height() ); else p.setY( p.y() + height( )); d->m_popup->popup(p); } void TKToolBarButton::slotDelayTimeout() { d->m_delayTimer->stop(); showMenu(); } void TKToolBarButton::slotClicked() { if ( d->ignoreNextMousePress ) { d->ignoreNextMousePress=false; return; } if (d->m_popup && !d->m_isPopup) showMenu(); else emit buttonClicked(); } void TKToolBarButton::slotPressed() { if ( d->ignoreNextMousePress ) return; if (d->m_popup) { if (!d->m_isPopup || d->m_isPopup && d->m_arrowPressed) showMenu(); } else emit buttonPressed(); d->ignoreNextMousePress = false; } void TKToolBarButton::slotReleased() { if (d->m_popup && d->m_isPopup) d->m_delayTimer->stop(); emit buttonReleased(); } void TKToolBarButton::slotToggled() { emit buttonToggled(); } void TKToolBarButton::on(bool flag) { d->m_isOn = flag; repaint(); } void TKToolBarButton::toggle() { on(!d->m_isOn); } void TKToolBarButton::setToggle(bool flag) { d->m_isToggle = flag; if (flag == true) connect(this, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotToggled())); else disconnect(this, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotToggled())); modeChange(); repaint(); } void TKToolBarButton::setIconMode( TK::IconMode m ) { d->m_iconMode = m; modeChange(); repaint(); } #include