/* This file is part of the KDE libraries Copyright (C) 1998 Jörg Habenicht (j.habenicht@europemail.com) Copyright (C) 2010 Christoph Feck This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kled.h" #include #include #include #include #include #include class KLed::Private { public: Private() : darkFactor( 300 ), state( On ), look( Raised ), shape( Circular ) { } int darkFactor; QColor color; State state; Look look; Shape shape; QPixmap cachedPixmap[2]; // for both states QStyle::ControlElement ce_indicatorLedCircular; QStyle::ControlElement ce_indicatorLedRectangular; }; KLed::KLed( QWidget *parent ) : QWidget( parent ), d( new Private ) { setColor( Qt::green ); } KLed::KLed( const QColor& color, QWidget *parent ) : QWidget( parent ), d( new Private ) { setColor( color ); } KLed::KLed( const QColor& color, State state, Look look, Shape shape, QWidget *parent ) : QWidget( parent ), d( new Private ) { d->state = (state == Off ? Off : On); d->look = look; d->shape = shape; setColor( color ); } KLed::~KLed() { delete d; } void KLed::paintEvent( QPaintEvent* ) { switch( d->shape ) { case Rectangular: switch ( d->look ) { case Sunken: paintRectFrame( false ); break; case Raised: paintRectFrame( true ); break; case Flat: paintRect(); break; } break; case Circular: switch ( d->look ) { case Flat: paintFlat(); break; case Raised: paintRaised(); break; case Sunken: paintSunken(); break; } break; } } int KLed::ledWidth() const { // Make sure the LED is round! int size = qMin(width(), height()); // leave one pixel border size -= 2; return qMax(0, size); } bool KLed::paintCachedPixmap() { if (d->cachedPixmap[d->state].isNull()) { return false; } QPainter painter(this); painter.drawPixmap(1, 1, d->cachedPixmap[d->state]); return true; } void KLed::paintFlat() { paintLed(Circular, Flat); } void KLed::paintRaised() { paintLed(Circular, Raised); } void KLed::paintSunken() { paintLed(Circular, Sunken); } void KLed::paintRect() { paintLed(Rectangular, Flat); } void KLed::paintRectFrame( bool raised ) { paintLed(Rectangular, raised ? Raised : Sunken); } KLed::State KLed::state() const { return d->state; } KLed::Shape KLed::shape() const { return d->shape; } QColor KLed::color() const { return d->color; } KLed::Look KLed::look() const { return d->look; } void KLed::setState( State state ) { if ( d->state == state) return; d->state = (state == Off ? Off : On); updateCachedPixmap(); } void KLed::setShape( Shape shape ) { if ( d->shape == shape ) return; d->shape = shape; updateCachedPixmap(); } void KLed::setColor( const QColor &color ) { if ( d->color == color ) return; d->color = color; updateCachedPixmap(); } void KLed::setDarkFactor( int darkFactor ) { if ( d->darkFactor == darkFactor ) return; d->darkFactor = darkFactor; updateCachedPixmap(); } int KLed::darkFactor() const { return d->darkFactor; } void KLed::setLook( Look look ) { if ( d->look == look) return; d->look = look; updateCachedPixmap(); } void KLed::toggle() { d->state = (d->state == On ? Off : On); updateCachedPixmap(); } void KLed::on() { setState( On ); } void KLed::off() { setState( Off ); } void KLed::resizeEvent( QResizeEvent * ) { updateCachedPixmap(); } QSize KLed::sizeHint() const { QStyleOption option; option.initFrom(this); int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, &option, this); return QSize( iconSize, iconSize ); } QSize KLed::minimumSizeHint() const { return QSize( 16, 16 ); } void KLed::updateCachedPixmap() { d->cachedPixmap[Off] = QPixmap(); d->cachedPixmap[On] = QPixmap(); update(); } void KLed::paintLed(Shape shape, Look look) { if (paintCachedPixmap()) { return; } QSize size(width() - 2, height() - 2); if (shape == Circular) { const int width = ledWidth(); size = QSize(width, width); } QPointF center(size.width() / 2.0, size.height() / 2.0); const int smallestSize = qMin(size.width(), size.height()); QPainter painter; QImage image(size, QImage::Format_ARGB32_Premultiplied); image.fill(0); QRadialGradient fillGradient(center, smallestSize / 2.0, QPointF(center.x(), size.height() / 3.0)); const QColor fillColor = d->state != Off ? d->color : d->color.dark(d->darkFactor); fillGradient.setColorAt(0.0, fillColor.light(250)); fillGradient.setColorAt(0.5, fillColor.light(130)); fillGradient.setColorAt(1.0, fillColor); QRadialGradient borderGradient(center, smallestSize, QPointF(center.x(), size.height() / 1.5)); QColor colorDark = palette().color(QPalette::Dark); QColor colorLight = palette().color(QPalette::Light); QColor borderColor = (look == Sunken) ? colorLight : colorDark; if (d->state == On) { QColor glowOverlay = fillColor; glowOverlay.setAlpha(80); borderColor = KColorUtils::overlayColors(borderColor, glowOverlay); } borderGradient.setColorAt(0.2, borderColor); borderGradient.setColorAt(0.5, (look == Sunken) ? colorDark : colorLight); borderGradient.setColorAt(0.8, borderColor); painter.begin(&image); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(look == Flat ? QBrush(fillColor) : QBrush(fillGradient)); const QBrush penBrush = (look == Flat) ? QBrush(borderColor) : QBrush(borderGradient); const qreal penWidth = smallestSize / 8.0; painter.setPen(QPen(penBrush, penWidth)); QRectF r(penWidth / 2.0, penWidth / 2.0, size.width() - penWidth, size.height() - penWidth); if (shape == Rectangular) { painter.drawRect(r); } else { painter.drawEllipse(r); } painter.end(); d->cachedPixmap[d->state] = QPixmap::fromImage(image); painter.begin(this); painter.drawPixmap(1, 1, d->cachedPixmap[d->state]); painter.end(); } #include "moc_kled.cpp"