• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

kcapacitybar.cpp
Go to the documentation of this file.
00001 /*
00002  * This file is part of the KDE project
00003  * Copyright (C) 2008 Rafael Fernández López <ereslibre@kde.org>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library 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 GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kcapacitybar.h"
00022 #include <kstyle.h>
00023 
00024 #include <math.h>
00025 
00026 #include <QtGui/QApplication>
00027 #include <QtGui/QLabel>
00028 #include <QtGui/QStyle>
00029 #include <QtGui/QPainter>
00030 #include <QtGui/QBoxLayout>
00031 #include <QtGui/QPaintEvent>
00032 #include <QtGui/QPainterPath>
00033 #include <QtGui/QLinearGradient>
00034 #include <QtGui/QStyleOptionFrame>
00035 
00036 #include <kcolorscheme.h>
00037 
00038 #define ROUND_MARGIN     6
00039 #define VERTICAL_SPACING 1
00040 
00041 class KCapacityBar::Private
00042 {
00043 public:
00044     Private(KCapacityBar::DrawTextMode drawTextMode)
00045         : value(0)
00046         , fillFullBlocks(true)
00047         , continuous(true)
00048         , barHeight(12)
00049         , horizontalTextAlignment(Qt::AlignCenter)
00050         , drawTextMode(drawTextMode) {}
00051 
00052     ~Private() {}
00053 
00054     int value;
00055     QString text;
00056     bool fillFullBlocks;
00057     bool continuous;
00058     int barHeight;
00059     Qt::Alignment horizontalTextAlignment;
00060     QStyle::ControlElement ce_capacityBar;
00061 
00062     KCapacityBar::DrawTextMode drawTextMode;
00063 };
00064 
00065 KCapacityBar::KCapacityBar(KCapacityBar::DrawTextMode drawTextMode, QWidget *parent)
00066     : QWidget(parent)
00067     , d(new Private(drawTextMode))
00068 {
00069     d->ce_capacityBar = KStyle::customControlElement("CE_CapacityBar", this);
00070 }
00071 
00072 KCapacityBar::~KCapacityBar()
00073 {
00074     delete d;
00075 }
00076 
00077 void KCapacityBar::setValue(int value)
00078 {
00079     d->value = value;
00080     update();
00081 }
00082 
00083 int KCapacityBar::value() const
00084 {
00085     return d->value;
00086 }
00087 
00088 void KCapacityBar::setText(const QString &text)
00089 {
00090     bool updateGeom = d->text.isEmpty() || text.isEmpty();
00091     d->text = text;
00092     if (updateGeom) {
00093         updateGeometry();
00094     }
00095 
00096     setAccessibleName(text);
00097 
00098     update();
00099 }
00100 
00101 QString KCapacityBar::text() const
00102 {
00103     return d->text;
00104 }
00105 
00106 void KCapacityBar::setFillFullBlocks(bool fillFullBlocks)
00107 {
00108     d->fillFullBlocks = fillFullBlocks;
00109     update();
00110 }
00111 
00112 bool KCapacityBar::fillFullBlocks() const
00113 {
00114     return d->fillFullBlocks;
00115 }
00116 
00117 void KCapacityBar::setContinuous(bool continuous)
00118 {
00119     d->continuous = continuous;
00120     update();
00121 }
00122 
00123 bool KCapacityBar::continuous() const
00124 {
00125     return d->continuous;
00126 }
00127 
00128 void KCapacityBar::setBarHeight(int barHeight)
00129 {
00130     // automatically convert odd values to even. This will make the bar look
00131     // better.
00132     d->barHeight = (barHeight % 2) ? barHeight + 1 : barHeight;
00133     updateGeometry();
00134 }
00135 
00136 int KCapacityBar::barHeight() const
00137 {
00138     return d->barHeight;
00139 }
00140 
00141 void KCapacityBar::setHorizontalTextAlignment(Qt::Alignment horizontalTextAlignment)
00142 {
00143     Qt::Alignment alignment = horizontalTextAlignment;
00144 
00145     // if the value came with any vertical alignment flag, remove it.
00146     alignment &= ~Qt::AlignTop;
00147     alignment &= ~Qt::AlignBottom;
00148     alignment &= ~Qt::AlignVCenter;
00149 
00150     d->horizontalTextAlignment = alignment;
00151     update();
00152 }
00153 
00154 Qt::Alignment KCapacityBar::horizontalTextAlignment() const
00155 {
00156     return d->horizontalTextAlignment;
00157 }
00158 
00159 void KCapacityBar::setDrawTextMode(DrawTextMode mode)
00160 {
00161     d->drawTextMode = mode;
00162     update();
00163 }
00164 
00165 KCapacityBar::DrawTextMode KCapacityBar::drawTextMode() const
00166 {
00167     return d->drawTextMode;
00168 }
00169 
00170 void KCapacityBar::drawCapacityBar(QPainter *p, const QRect &rect) const
00171 {
00172     if (d->ce_capacityBar)
00173     {
00174         QStyleOptionProgressBar opt;
00175         opt.initFrom(this);
00176         opt.rect = rect;
00177         opt.minimum = 0;
00178         opt.maximum = 100;
00179         opt.progress = d->value;
00180         opt.text = d->text;
00181         opt.textAlignment = Qt::AlignCenter;
00182         opt.textVisible = true;
00183         style()->drawControl(d->ce_capacityBar, &opt, p, this);
00184 
00185         return;
00186     }
00187 
00188     p->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
00189 
00190     p->save();
00191 
00192     QRect drawRect(rect);
00193 
00194     if (d->drawTextMode == DrawTextOutline) {
00195         drawRect.setHeight(d->barHeight);
00196     }
00197 
00198     QPainterPath outline;
00199     outline.moveTo(rect.left() + ROUND_MARGIN / 4 + 1, rect.top());
00200     outline.lineTo(rect.left() + drawRect.width() - ROUND_MARGIN / 4 - 1, rect.top());
00201     outline.quadTo(rect.left() + drawRect.width() + ROUND_MARGIN / 2, drawRect.height() / 2 + rect.top(), rect.left() + drawRect.width() - ROUND_MARGIN / 4 - 1, drawRect.height() + rect.top());
00202     outline.lineTo(rect.left() + ROUND_MARGIN / 4 + 1, drawRect.height() + rect.top());
00203     outline.quadTo(-ROUND_MARGIN / 2 + rect.left(), drawRect.height() / 2 + rect.top(), rect.left() + ROUND_MARGIN / 4 + 1, rect.top());
00204     const QColor fillColor = KColorScheme::shade(palette().window().color(), KColorScheme::DarkShade);
00205     p->fillPath(outline, QColor(fillColor.red(), fillColor.green(), fillColor.blue(), 50));
00206 
00207     QRadialGradient bottomGradient(QPointF(rect.width() / 2, drawRect.bottom() + 1), rect.width() / 2);
00208     bottomGradient.setColorAt(0, KColorScheme::shade(palette().window().color(), KColorScheme::LightShade));
00209     bottomGradient.setColorAt(1, Qt::transparent);
00210     p->fillRect(QRect(rect.left(), drawRect.bottom() + rect.top(), rect.width(), 1), bottomGradient);
00211 
00212     p->translate(rect.left() + 2, rect.top() + 1);
00213 
00214     drawRect.setWidth(drawRect.width() - 4);
00215     drawRect.setHeight(drawRect.height() - 2);
00216 
00217     QPainterPath path;
00218     path.moveTo(ROUND_MARGIN / 4, 0);
00219     path.lineTo(drawRect.width() - ROUND_MARGIN / 4, 0);
00220     path.quadTo(drawRect.width() + ROUND_MARGIN / 2, drawRect.height() / 2, drawRect.width() - ROUND_MARGIN / 4, drawRect.height());
00221     path.lineTo(ROUND_MARGIN / 4, drawRect.height());
00222     path.quadTo(-ROUND_MARGIN / 2, drawRect.height() / 2, ROUND_MARGIN / 4, 0);
00223 
00224     QLinearGradient linearGradient(0, 0, 0, drawRect.height());
00225     linearGradient.setColorAt(0.5, KColorScheme::shade(palette().window().color(), KColorScheme::MidShade));
00226     linearGradient.setColorAt(1, KColorScheme::shade(palette().window().color(), KColorScheme::LightShade));
00227     p->fillPath(path, linearGradient);
00228 
00229     p->setBrush(Qt::NoBrush);
00230     p->setPen(Qt::NoPen);
00231 
00232     if (d->continuous || !d->fillFullBlocks) {
00233         int start = (layoutDirection() == Qt::LeftToRight) ? -1
00234                                                            : (drawRect.width() + 2) - (drawRect.width() + 2) * (d->value / 100.0);
00235 
00236         p->setClipRect(QRect(start, 0, (drawRect.width() + 2) * (d->value / 100.0), drawRect.height()), Qt::IntersectClip);
00237     }
00238 
00239     int left = (layoutDirection() == Qt::LeftToRight) ? 0
00240                                                       : drawRect.width();
00241 
00242     int right = (layoutDirection() == Qt::LeftToRight) ? drawRect.width()
00243                                                        : 0;
00244 
00245     int roundMargin = (layoutDirection() == Qt::LeftToRight) ? ROUND_MARGIN
00246                                                              : -ROUND_MARGIN;
00247 
00248     int spacing = 2;
00249     int verticalSpacing = VERTICAL_SPACING;
00250     int slotWidth = 6;
00251     int start = roundMargin / 4;
00252 
00253     QPainterPath internalBar;
00254     internalBar.moveTo(left + roundMargin / 4, 0);
00255     internalBar.lineTo(right - roundMargin / 4, 0);
00256     internalBar.quadTo(right + roundMargin / 2, drawRect.height() / 2, right - roundMargin / 4, drawRect.height());
00257     internalBar.lineTo(left + roundMargin / 4, drawRect.height());
00258     internalBar.quadTo(left - roundMargin / 2, drawRect.height() / 2, left + roundMargin / 4, 0);
00259 
00260     QLinearGradient fillInternalBar(left, 0, right, 0);
00261     fillInternalBar.setColorAt(0, KColorScheme::shade(palette().highlight().color(), KColorScheme::MidShade));
00262     fillInternalBar.setColorAt(0.5, KColorScheme::shade(palette().highlight().color(), KColorScheme::LightShade));
00263     fillInternalBar.setColorAt(1, KColorScheme::shade(palette().highlight().color(), KColorScheme::MidShade));
00264 
00265     if (d->drawTextMode == KCapacityBar::DrawTextInline) {
00266         p->save();
00267         p->setOpacity(p->opacity() * 0.7);
00268     }
00269 
00270     if (!d->continuous) {
00271         int numSlots = (drawRect.width() - ROUND_MARGIN - ((slotWidth + spacing) * 2)) / (slotWidth + spacing);
00272         int stopSlot = floor((numSlots + 2) * (d->value / 100.0));
00273 
00274         int plusOffset = d->fillFullBlocks ? ((drawRect.width() - ROUND_MARGIN - ((slotWidth + spacing) * 2)) - (numSlots * (slotWidth + spacing))) / 2.0
00275                                            : 0;
00276 
00277         if (!d->fillFullBlocks || stopSlot) {
00278             QPainterPath firstSlot;
00279             firstSlot.moveTo(left + roundMargin / 4, verticalSpacing);
00280             firstSlot.lineTo(left + slotWidth + roundMargin / 4 + plusOffset, verticalSpacing);
00281             firstSlot.lineTo(left + slotWidth + roundMargin / 4 + plusOffset, drawRect.height() - verticalSpacing);
00282             firstSlot.lineTo(left + roundMargin / 4, drawRect.height() - verticalSpacing);
00283             firstSlot.quadTo(left, drawRect.height() / 2, left + roundMargin / 4, verticalSpacing);
00284             p->fillPath(firstSlot, fillInternalBar);
00285             start += slotWidth + spacing + plusOffset;
00286 
00287             bool stopped = false;
00288             for (int i = 0; i < numSlots + 1; i++) {
00289                 if (d->fillFullBlocks && (i == (stopSlot + 1))) {
00290                     stopped = true;
00291                     break;
00292                 }
00293                 p->fillRect(QRect(rect.left() + start, rect.top() + verticalSpacing, slotWidth, drawRect.height() - verticalSpacing * 2), fillInternalBar);
00294                 start += slotWidth + spacing;
00295             }
00296 
00297             if (!d->fillFullBlocks || (!stopped && (stopSlot != (numSlots + 1)) && (stopSlot != numSlots))) {
00298                 QPainterPath lastSlot;
00299                 lastSlot.moveTo(start, verticalSpacing);
00300                 lastSlot.lineTo(start, drawRect.height() - verticalSpacing);
00301                 lastSlot.lineTo(start + slotWidth + plusOffset, drawRect.height() - verticalSpacing);
00302                 lastSlot.quadTo(start + roundMargin, drawRect.height() / 2, start + slotWidth + plusOffset, verticalSpacing);
00303                 lastSlot.lineTo(start, verticalSpacing);
00304                 p->fillPath(lastSlot, fillInternalBar);
00305             }
00306         }
00307     } else {
00308         p->fillPath(internalBar, fillInternalBar);
00309     }
00310 
00311     if (d->drawTextMode == KCapacityBar::DrawTextInline) {
00312         p->restore();
00313     }
00314 
00315     p->save();
00316     p->setClipping(false);
00317     QRadialGradient topGradient(QPointF(rect.width() / 2, drawRect.top()), rect.width() / 2);
00318     const QColor fillTopColor = KColorScheme::shade(palette().window().color(), KColorScheme::LightShade);
00319     topGradient.setColorAt(0, QColor(fillTopColor.red(), fillTopColor.green(), fillTopColor.blue(), 127));
00320     topGradient.setColorAt(1, Qt::transparent);
00321     p->fillRect(QRect(rect.left(), rect.top() + drawRect.top(), rect.width(), 2), topGradient);
00322     p->restore();
00323 
00324     p->save();
00325     p->setClipRect(QRect(-1, 0, rect.width(), drawRect.height() / 2), Qt::ReplaceClip);
00326     QLinearGradient glassGradient(0, -5, 0, drawRect.height());
00327     const QColor fillGlassColor = palette().base().color();
00328     glassGradient.setColorAt(0, QColor(fillGlassColor.red(), fillGlassColor.green(), fillGlassColor.blue(), 255));
00329     glassGradient.setColorAt(1, Qt::transparent);
00330     p->fillPath(internalBar, glassGradient);
00331     p->restore();
00332 
00333     p->restore();
00334 
00335     if (d->drawTextMode == KCapacityBar::DrawTextInline) {
00336         QRect rect(drawRect);
00337         rect.setHeight(rect.height() + 4);
00338         p->drawText(rect, Qt::AlignCenter, fontMetrics().elidedText(d->text, Qt::ElideRight, drawRect.width() - 2 * ROUND_MARGIN));
00339     } else {
00340         p->drawText(rect, Qt::AlignBottom | d->horizontalTextAlignment, fontMetrics().elidedText(d->text, Qt::ElideRight, drawRect.width()));
00341     }
00342 }
00343 
00344 void KCapacityBar::changeEvent(QEvent *event)
00345 {
00346     if (event->type() == QEvent::StyleChange) {
00347         d->ce_capacityBar = KStyle::customControlElement("CE_CapacityBar", this);
00348     }
00349 
00350     QWidget::changeEvent(event);
00351 }
00352 
00353 QSize KCapacityBar::minimumSizeHint() const
00354 {
00355     int width = (d->drawTextMode == KCapacityBar::DrawTextInline) ?
00356                 fontMetrics().width(d->text) + ROUND_MARGIN * 2 :
00357                 fontMetrics().width(d->text);
00358 
00359     int height = (d->drawTextMode == KCapacityBar::DrawTextInline) ?
00360                  qMax(fontMetrics().height(), d->barHeight) :
00361                  (d->text.isEmpty() ? 0 : fontMetrics().height() + VERTICAL_SPACING * 2) + d->barHeight;
00362 
00363     if (height % 2) {
00364         height++;
00365     }
00366 
00367     return QSize(width, height);
00368 }
00369 
00370 void KCapacityBar::paintEvent(QPaintEvent *event)
00371 {
00372     QPainter p(this);
00373     drawCapacityBar(&p, event->rect());
00374     p.end();
00375 }
00376 
00377 #include "kcapacitybar.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal