plasma looking progressbars by tiling qpixmapitems

This commit is contained in:
Marco Martin 2011-11-14 14:36:36 +01:00
parent ca2e34e48e
commit a347b2ec04
3 changed files with 118 additions and 19 deletions

View File

@ -19,6 +19,7 @@
import QtQuick 1.0
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.qtextracomponents 0.1
Item {
id: progressBar
@ -32,9 +33,6 @@ Item {
// Plasma API
property int orientation: Qt.Horizontal
// Convinience API
property bool _isVertical: orientation == Qt.Vertical
width: 100
height: 20
opacity: enabled ? 1.0 : 0.5
@ -54,26 +52,57 @@ Item {
Item {
id: contents
property bool _isVertical: orientation == Qt.Vertical
width: _isVertical ? progressBar.height : progressBar.width
height: _isVertical ? progressBar.width : progressBar.height
rotation: _isVertical ? 90 : 0
anchors.centerIn: parent
PlasmaCore.FrameSvgItem {
id: background
anchors.fill: parent
imagePath: "widgets/bar_meter_horizontal"
prefix: "bar-inactive"
Timer {
id: resizeTimer
repeat: false
interval: 0
running: false
onTriggered: {
barFrameSvg.resizeFrame(Qt.size(Math.floor(contents.height/1.6), contents.height))
barPixmapItem.pixmap = barFrameSvg.framePixmap()
backgroundFrameSvg.resizeFrame(Qt.size(Math.floor(contents.height/1.6), contents.height))
backgroundPixmapItem.pixmap = backgroundFrameSvg.framePixmap()
}
}
PlasmaCore.FrameSvg {
id: barFrameSvg
Component.onCompleted: {
barFrameSvg.setImagePath("widgets/bar_meter_horizontal")
barFrameSvg.setElementPrefix("bar-active")
resizeTimer.restart()
}
}
PlasmaCore.FrameSvg {
id: backgroundFrameSvg
Component.onCompleted: {
backgroundFrameSvg.setImagePath("widgets/bar_meter_horizontal")
backgroundFrameSvg.setElementPrefix("bar-inactive")
resizeTimer.restart()
}
}
QPixmapItem {
id: backgroundPixmapItem
fillMode: QPixmapItem.Tile
width: Math.floor(parent.width/(height/1.6))*Math.floor(height/1.6)
height: parent.height
onWidthChanged: resizeTimer.restart()
onHeightChanged: resizeTimer.restart()
}
PlasmaCore.FrameSvgItem {
id: bar
width: indeterminate ? contents.width / 4 : range.position
QPixmapItem {
id: barPixmapItem
fillMode: QPixmapItem.Tile
width: indeterminate ? Math.floor(height/1.6)*2 : range.position
height: contents.height
imagePath: "widgets/bar_meter_horizontal"
prefix: "bar-active"
visible: indeterminate || value > 0
SequentialAnimation {
@ -82,16 +111,16 @@ Item {
loops: Animation.Infinite
PropertyAnimation {
target: bar;
target: barPixmapItem
property: "x"
duration: 800
to: 0
}
PropertyAnimation {
target: bar;
target: barPixmapItem
property: "x"
duration: 800
to: background.width - bar.width
to: backgroundPixmapItem.width - barPixmapItem.width
}
}
}

View File

@ -24,7 +24,8 @@
QPixmapItem::QPixmapItem(QDeclarativeItem *parent)
: QDeclarativeItem(parent),
m_smooth(false)
m_smooth(false),
m_fillMode(QPixmapItem::Stretch)
{
setFlag(QGraphicsItem::ItemHasNoContents, false);
}
@ -71,6 +72,22 @@ int QPixmapItem::nativeHeight() const
return m_pixmap.size().height();
}
QPixmapItem::FillMode QPixmapItem::fillMode() const
{
return m_fillMode;
}
void QPixmapItem::setFillMode(QPixmapItem::FillMode mode)
{
if (mode == m_fillMode) {
return;
}
m_fillMode = mode;
update();
emit fillModeChanged();
}
void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
@ -85,7 +102,44 @@ void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
painter->setRenderHint(QPainter::Antialiasing, m_smooth);
painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
painter->drawPixmap(boundingRect(), m_pixmap, m_pixmap.rect());
QRect destRect;
switch (m_fillMode) {
case PreserveAspectFit: {
QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect());
const qreal scale = qMin(m_pixmap.width()/minimumRect.width(), m_pixmap.height()/minimumRect.height());
destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()*scale));
break;
}
case PreserveAspectCrop: {
QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect());
const qreal scale = qMax(m_pixmap.width()/minimumRect.width(), m_pixmap.height()/minimumRect.height());
destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()*scale));
break;
}
case TileVertically: {
QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect());
const qreal scale = m_pixmap.width()/minimumRect.width();
destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width()*scale, m_pixmap.height()));
break;
}
case TileHorizontally: {
QRect minimumRect = m_pixmap.rect().intersected(boundingRect().toRect());
const qreal scale = m_pixmap.height()/minimumRect.height();
destRect = QRect(QPoint(0, 0), QSize(m_pixmap.width(), m_pixmap.height()*scale));
break;
}
case Stretch:
case Tile:
default:
destRect = boundingRect().toRect();
}
if (m_fillMode >= Tile) {
painter->drawTiledPixmap(destRect, m_pixmap);
} else {
painter->drawPixmap(destRect, m_pixmap, m_pixmap.rect());
}
painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias);
painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform);
}

View File

@ -30,8 +30,19 @@ class QPixmapItem : public QDeclarativeItem
Q_PROPERTY(bool smooth READ smooth WRITE setSmooth)
Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged)
Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_ENUMS(FillMode)
public:
enum FillMode {
Stretch, // the image is scaled to fit
PreserveAspectFit, // the image is scaled uniformly to fit without cropping
PreserveAspectCrop, // the image is scaled uniformly to fill, cropping if necessary
Tile, // the image is duplicated horizontally and vertically
TileVertically, // the image is stretched horizontally and tiled vertically
TileHorizontally //the image is stretched vertically and tiled horizontally
};
QPixmapItem(QDeclarativeItem *parent=0);
~QPixmapItem();
@ -44,15 +55,20 @@ public:
int nativeWidth() const;
int nativeHeight() const;
FillMode fillMode() const;
void setFillMode(FillMode mode);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
Q_SIGNALS:
void nativeWidthChanged();
void nativeHeightChanged();
void fillModeChanged();
private:
QPixmap m_pixmap;
bool m_smooth;
FillMode m_fillMode;
};
#endif