diff options
Diffstat (limited to 'kicker/extensions/kasbar/kasitem.cpp')
-rw-r--r-- | kicker/extensions/kasbar/kasitem.cpp | 566 |
1 files changed, 566 insertions, 0 deletions
diff --git a/kicker/extensions/kasbar/kasitem.cpp b/kicker/extensions/kasbar/kasitem.cpp new file mode 100644 index 000000000..5cd8ef7f0 --- /dev/null +++ b/kicker/extensions/kasbar/kasitem.cpp @@ -0,0 +1,566 @@ +/* kasitem.cpp +** +** Copyright (C) 2001-2004 Richard Moore <[email protected]> +** Contributor: Mosfet +** All rights reserved. +** +** KasBar is dual-licensed: you can choose the GPL or the BSD license. +** Short forms of both licenses are included below. +*/ + +/* +** 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 in a file called COPYING; if not, write to +** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +** MA 02110-1301, USA. +*/ + +/* +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +*/ + +/* +** Bug reports and questions can be sent to [email protected] +*/ +#include <qcursor.h> +#include <qpainter.h> +#include <qdrawutil.h> +#include <qregexp.h> +#include <qtimer.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klocale.h> + +#include "kasitem.h" + +#include "kaspopup.h" +#include "kasitem.moc" + +/* XPM */ +static const char *tiny_arrow[]={ +"5 9 2 1", +". c None", +"# c #ffffff", +"....#", +"...##", +"..###", +".####", +"#####", +".####", +"..###", +"...##", +"....#"}; + +static const int KASITEM_CHECK_POPUP_DELAY = 500; + +KasItem::KasItem( KasBar *parent ) + : QObject( parent ), + kas( parent ), popupTimer( 0 ), dragTimer( 0 ), + title( i18n( "Kasbar" ) ), + mouseOver( false ), activated( false ), + customPopup( false ), lockPopup(false), groupItem( false ), + frame(true), modified(false), attention_(false), prog( -1 ), + anim(), aniFrame( 0 ), drawAnim( false ) +{ + connect( parent, SIGNAL( dragStarted() ), SLOT( hidePopup() ) ); + connect( this, SIGNAL( middleButtonClicked(QMouseEvent *) ), parent, SLOT( toggleOrientation() ) ); +} + +KasItem::~KasItem() +{ + delete (KasPopup *) pop; +} + +void KasItem::setActive( bool yesno ) +{ + if ( activated == yesno ) + return; + + activated = yesno; + update(); +} + +void KasItem::setText( const QString &text ) +{ + if ( title == text ) + return; + + title = text; + update(); +} + +void KasItem::setIcon( const QPixmap &p ) +{ + pix = p; + update(); +} + +void KasItem::setProgress( int percent ) +{ + if ( percent == prog ) + return; + + prog = percent; + update(); +} + +void KasItem::setShowFrame( bool yes ) +{ + if ( frame == yes ) + return; + + frame = yes; + update(); +} + +void KasItem::setModified( bool yes ) +{ + if ( modified == yes ) + return; + + modified = yes; + update(); +} + +void KasItem::setAttention( bool yes ) +{ + if ( attention_ == yes ) + return; + + attention_ = yes; + update(); +} + +void KasItem::mouseEnter() +{ + static const int POPUP_DELAY = 300; + + if ( (!customPopup) && (popupTimer == 0) ) { + popupTimer = new QTimer( this, "popupTimer" ); + connect( popupTimer, SIGNAL( timeout() ), SLOT( showPopup() ) ); + popupTimer->start( POPUP_DELAY, true ); + } + + mouseOver = true; + update(); +} + +void KasItem::mouseReleaseEvent( QMouseEvent *ev ) +{ + if ( ev->button() == LeftButton ) + emit leftButtonClicked( ev ); + else if ( ev->button() == RightButton ) + emit rightButtonClicked( ev ); + else if ( ev->button() == MidButton ) + emit middleButtonClicked( ev ); +} + +// Check periodically if the popup can be hidden (hack) +void KasItem::checkPopup() +{ + if ( pop.isNull() ) + return; + if ( !pop->isVisible() ) + return; + + QWidget *w = QApplication::widgetAt( QCursor::pos() ); + if ( !w ) { + if ( popupTimer ) { + delete popupTimer; + popupTimer = 0; + } + if ( (!customPopup) && (!lockPopup) ) + hidePopup(); + } + else { + QTimer::singleShot( KASITEM_CHECK_POPUP_DELAY, this, SLOT( checkPopup() ) ); + } +} + +void KasItem::dragEnter() +{ + static const int DRAG_SWITCH_DELAY = 1000; + + if ( dragTimer == 0 ) { + dragTimer = new QTimer( this, "dragTimer" ); + connect( dragTimer, SIGNAL( timeout() ), SLOT( dragOverAction() ) ); + dragTimer->start( DRAG_SWITCH_DELAY, true ); + } + + mouseOver = true; + update(); +} + +void KasItem::mouseLeave() +{ + if ( popupTimer ) { + delete popupTimer; + popupTimer = 0; + } + + mouseOver = false; + update(); +} + +void KasItem::dragLeave() +{ + if ( dragTimer ) { + delete dragTimer; + dragTimer = 0; + } + + mouseOver = false; + update(); +} + +bool KasItem::isShowingPopup() const +{ + if ( pop.isNull() ) + return false; + return pop->isVisible(); +} + +KasPopup *KasItem::createPopup() +{ + return 0; +} + +void KasItem::showPopup() +{ + if ( pop.isNull() ) + pop = createPopup(); + + if ( pop.isNull() ) + return; + + pop->show(); + update(); + + QTimer::singleShot( KASITEM_CHECK_POPUP_DELAY, this, SLOT( checkPopup() ) ); +} + +void KasItem::hidePopup() +{ + if ( pop.isNull() ) + return; + + pop->hide(); + activated = false; + update(); +} + +void KasItem::togglePopup() +{ + if ( activated ) + hidePopup(); + else + showPopup(); +} + +void KasItem::setPopup( KasPopup *popup ) +{ + if ( pop ) + pop->deleteLater(); + pop = popup; +} + +void KasItem::paintFrame( QPainter *p ) +{ + if ( !frame ) + return; + + qDrawShadePanel(p, 0, 0, extent(), extent(), colorGroup(), false, 2); + + QPen pen; + + if ( mouseOver ) { + if ( attention_ ) { + pen = QPen( resources()->attentionColor(), 2 ); + p->setPen( pen ); + p->drawRect( 0, 0, extent(), extent()); + } + else { + pen = QPen( Qt::white ); + p->setPen( pen ); + p->drawRect(0, 0, extent(), extent()); + } + } + else if ( kas->paintInactiveFrames() ) { + p->setPen( attention_ ? resources()->attentionColor() : Qt::black ); + p->drawRect(0, 0, extent(), extent()); + } +} + +void KasItem::paintLabel( QPainter *p ) +{ + QString text = title; + + if ( !groupItem ) { + p->fillRect( 2, 2, extent()-4, 13, QBrush( resources()->labelBgColor() ) ); + + if ( isProgressItem() ) { + QRegExp reg( "(1?[0-9]?[0-9])%" ); + if ( -1 != reg.search( text ) ) { + prog = reg.cap(1).toInt(); + paintProgress( p, prog ); + } + else { + prog = 0; + } + } + + p->setFont( KGlobalSettings::taskbarFont() ); + p->setPen( resources()->labelPenColor() ); + + if ( fontMetrics().width( text ) > extent()-4 ) + p->drawText( 2, 2, extent()-4, 12, AlignLeft | AlignVCenter, text ); + else + p->drawText( 2, 2, extent()-4, 12, AlignCenter, text ); + + return; + } + else { + QPixmap arrow( tiny_arrow ); + + QPoint popupPos = KasPopup::calcPosition( this, 10, 10 ); + QPoint iPos = kas->mapToGlobal( kas->itemPos( this ) ); + QWMatrix turn; + + if ( popupPos.x() < iPos.x() ) { + paintArrowLabel( p, arrow.width(), true ); + p->drawPixmap( 3, 4, arrow ); + } + else if ( popupPos.x() == iPos.x() ) { + if ( popupPos.y() < iPos.y() ) { + turn.rotate( 90.0 ); + arrow = arrow.xForm( turn ); + paintArrowLabel( p, arrow.width(), true ); + p->drawPixmap( 3, 6, arrow ); + } + else { + turn.rotate( 270.0 ); + arrow = arrow.xForm( turn ); + paintArrowLabel( p, arrow.width(), false ); + p->drawPixmap( extent()-12, 6, arrow ); + } + } + else { + turn.rotate( 180.0 ); + arrow = arrow.xForm( turn ); + paintArrowLabel( p, arrow.width(), false ); + p->drawPixmap( extent()-8, 4, arrow ); + } + } +} + +void KasItem::paintArrowLabel( QPainter *p, int arrowSize, bool arrowOnLeft ) +{ + QString text = title; + int lx = 2; + int ly = 2; + int w = extent()-4; + int h = 13; + arrowSize+=2; // Add a space + + p->fillRect( lx, ly, w, h, QBrush( resources()->labelBgColor() ) ); + + // Adjust for arrow + if ( arrowOnLeft ) { + lx += arrowSize; + w -= arrowSize; + } + else { + w -= arrowSize; + } + + p->setFont( KGlobalSettings::taskbarFont() ); + p->setPen( resources()->labelPenColor() ); + if ( fontMetrics().width( text ) > w ) + p->drawText( lx, ly, w, h-1, AlignLeft | AlignVCenter, text ); + else + p->drawText( lx, ly, w, h-1, AlignCenter, text ); +} + +void KasItem::paintModified( QPainter *p ) +{ + if ( modified ) + p->drawPixmap(extent()-12, extent()-22, resources()->modifiedIcon() ); +} + +void KasItem::paintBackground( QPainter *p ) +{ + if ( activated ) + p->drawPixmap( 0, 0, resources()->activeBg() ); + else if ( kas->isTransparent() ) + ; + else + p->drawPixmap( 0, 0, resources()->inactiveBg() ); +} + +void KasItem::paintProgress( QPainter *p, int percent ) +{ + double amt = (extent()-4) * (percent / 100.0L); + p->fillRect( 2, 13, (int) amt, 2, QBrush( resources()->progressColor() ) ); +} + +void KasItem::paintStateIcon( QPainter *p, uint state ) +{ + if ( kas->itemSize() != KasBar::Small ) { + switch(state) { + case StateIcon: + p->drawPixmap(extent()-11, extent()-11, resources()->minIcon() ); + break; + case StateShaded: + p->drawPixmap(extent()-11, extent()-11, resources()->shadeIcon() ); + break; + case StateNormal: + p->drawPixmap(extent()-11, extent()-11, resources()->maxIcon() ); + break; + default: + break; + } + } + else { + switch(state) { + case StateIcon: + p->drawPixmap(extent()-9, extent()-9, resources()->microMinIcon() ); + break; + case StateShaded: + p->drawPixmap(extent()-9, extent()-9, resources()->microShadeIcon() ); + break; + case StateNormal: + p->drawPixmap(extent()-9, extent()-9, resources()->microMaxIcon() ); + break; + default: + break; + } + } +} + +void KasItem::paintAttention( QPainter *p ) +{ + p->setPen( resources()->attentionColor() ); + p->drawPixmap( 3, extent()-11, resources()->attentionIcon() ); +} + +void KasItem::setAnimation( const PixmapList &frames ) +{ + anim = frames; + aniFrame = 0; +} + +void KasItem::advanceAnimation() +{ + aniFrame++; + + if ( aniFrame >= anim.count() ) + aniFrame = 0; + + update(); +} + +void KasItem::setShowAnimation( bool yes ) +{ + if ( yes == drawAnim ) + return; + + drawAnim = yes; + update(); +} + +void KasItem::paintAnimation( QPainter *p ) +{ + if ( (aniFrame+1) > anim.count() ) + return; + + QPixmap pix = anim[ aniFrame ]; + if ( pix.isNull() ) + return; + + if ( kas->itemSize() == KasBar::Small ) + p->drawPixmap( 4, 16, pix ); + else + p->drawPixmap( extent()-18, 16, pix ); +} + +void KasItem::paintIcon( QPainter *p ) +{ + if ( pix.isNull() ) + return; + + int x = (extent() - 4 - pix.width()) / 2; + int y = (extent() - 15 - pix.height()) / 2; + p->drawPixmap( x-4, y+15, pix ); +} + +void KasItem::paint( QPainter *p ) +{ + paintBackground( p ); + paintFrame( p ); + paintLabel( p ); + paintIcon( p ); + + if ( drawAnim ) + paintAnimation( p ); + + if ( attention_ ) + paintAttention( p ); +} + +void KasItem::paint( QPainter *p, int x, int y ) +{ + p->save(); + p->translate( x, y ); + paint( p ); + p->restore(); +} + +void KasItem::repaint() +{ + repaint( true ); +} + +void KasItem::repaint( bool erase ) +{ + if ( kas->isVisible() ) + kas->repaintItem( this, erase ); +} + +void KasItem::update() +{ + if ( kas->isVisible() ) + kas->updateItem( this ); +} + |