#include <private/qsgadaptationlayer_p.h>
#include <QtGui/qpainter.h>
+#include <qmath.h>
QT_BEGIN_NAMESPACE
, paintedWidth(0)
, paintedHeight(0)
, pixmapChanged(false)
+ , hAlign(QSGImage::AlignHCenter)
+ , vAlign(QSGImage::AlignVCenter)
{
}
d->paintedHeight = heightScale * qreal(d->pix.height());
d->paintedWidth = widthScale * qreal(d->pix.width());
+ } else if (d->fillMode == Pad) {
+ d->paintedWidth = d->pix.width();
+ d->paintedHeight = d->pix.height();
} else {
d->paintedWidth = width();
d->paintedHeight = height();
QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
+ qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width();
+ qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height();
+
+ int xOffset = 0;
+ if (d->hAlign == QSGImage::AlignHCenter)
+ xOffset = qCeil((width() - pixWidth) / 2.);
+ else if (d->hAlign == QSGImage::AlignRight)
+ xOffset = qCeil(width() - pixWidth);
+
+ int yOffset = 0;
+ if (d->vAlign == QSGImage::AlignVCenter)
+ yOffset = qCeil((height() - pixHeight) / 2.);
+ else if (d->vAlign == QSGImage::AlignBottom)
+ yOffset = qCeil(height() - pixHeight);
+
switch (d->fillMode) {
default:
case Stretch:
break;
case PreserveAspectFit:
- targetRect = QRectF((width() - d->paintedWidth) / 2., (height() - d->paintedHeight) / 2.,
- d->paintedWidth, d->paintedHeight);
+ targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
sourceRect = d->pix.rect();
break;
if (wscale > hscale) {
int src = (hscale / wscale) * qreal(d->pix.height());
- sourceRect = QRectF(0, (d->pix.height() - src) / 2, d->pix.width(), src);
+ int y = 0;
+ if (d->vAlign == QSGImage::AlignVCenter)
+ y = qCeil((d->pix.height() - src) / 2.);
+ else if (d->vAlign == QSGImage::AlignBottom)
+ y = qCeil(d->pix.height() - src);
+ sourceRect = QRectF(0, y, d->pix.width(), src);
+
} else {
int src = (wscale / hscale) * qreal(d->pix.width());
- sourceRect = QRectF((d->pix.width() - src) / 2, 0, src, d->pix.height());
+ int x = 0;
+ if (d->hAlign == QSGImage::AlignHCenter)
+ x = qCeil((d->pix.width() - src) / 2.);
+ else if (d->hAlign == QSGImage::AlignRight)
+ x = qCeil(d->pix.width() - src);
+ sourceRect = QRectF(x, 0, src, d->pix.height());
+ }
}
- }
break;
case Tile:
targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(0, 0, width(), height());
+ sourceRect = QRectF(-xOffset, -yOffset, width(), height());
hWrap = QSGTexture::Repeat;
vWrap = QSGTexture::Repeat;
break;
case TileHorizontally:
targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(0, 0, width(), d->pix.height());
+ sourceRect = QRectF(-xOffset, 0, width(), d->pix.height());
hWrap = QSGTexture::Repeat;
break;
case TileVertically:
targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(0, 0, d->pix.width(), height());
+ sourceRect = QRectF(0, -yOffset, d->pix.width(), height());
vWrap = QSGTexture::Repeat;
break;
+ case Pad:
+ qreal w = qMin(qreal(d->pix.width()), width());
+ qreal h = qMin(qreal(d->pix.height()), height());
+ qreal x = (d->pix.width() > width()) ? -xOffset : 0;
+ qreal y = (d->pix.height() > height()) ? -yOffset : 0;
+ targetRect = QRectF(x + xOffset, y + yOffset, w, h);
+ sourceRect = QRectF(x, y, w, h);
+ break;
};
QRectF nsrect(sourceRect.x() / d->pix.width(),
d->pixmapChanged = true;
}
+QSGImage::VAlignment QSGImage::verticalAlignment() const
+{
+ Q_D(const QSGImage);
+ return d->vAlign;
+}
+
+void QSGImage::setVerticalAlignment(VAlignment align)
+{
+ Q_D(QSGImage);
+ if (d->vAlign == align)
+ return;
+
+ d->vAlign = align;
+ update();
+ updatePaintedGeometry();
+ emit verticalAlignmentChanged(align);
+}
+
+QSGImage::HAlignment QSGImage::horizontalAlignment() const
+{
+ Q_D(const QSGImage);
+ return d->hAlign;
+}
+
+void QSGImage::setHorizontalAlignment(HAlignment align)
+{
+ Q_D(QSGImage);
+ if (d->hAlign == align)
+ return;
+
+ d->hAlign = align;
+ update();
+ updatePaintedGeometry();
+ emit horizontalAlignmentChanged(align);
+}
+
QT_END_NAMESPACE
{
Q_OBJECT
Q_ENUMS(FillMode)
+ Q_ENUMS(HAlignment)
+ Q_ENUMS(VAlignment)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedGeometryChanged)
Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
Q_PROPERTY(QSGTexture *texture READ texture)
+ Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged)
+ Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
Q_INTERFACES(QSGTextureProvider)
QSGImage(QSGItem *parent=0);
~QSGImage();
- enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally };
+ enum HAlignment { AlignLeft = Qt::AlignLeft,
+ AlignRight = Qt::AlignRight,
+ AlignHCenter = Qt::AlignHCenter };
+ enum VAlignment { AlignTop = Qt::AlignTop,
+ AlignBottom = Qt::AlignBottom,
+ AlignVCenter = Qt::AlignVCenter };
+
+ enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally, Pad };
+
FillMode fillMode() const;
void setFillMode(FillMode);
virtual QSGTexture *texture() const;
+ HAlignment horizontalAlignment() const;
+ void setHorizontalAlignment(HAlignment align);
+
+ VAlignment verticalAlignment() const;
+ void setVerticalAlignment(VAlignment align);
+
Q_SIGNALS:
void fillModeChanged();
void paintedGeometryChanged();
+ void horizontalAlignmentChanged(HAlignment alignment);
+ void verticalAlignmentChanged(VAlignment alignment);
protected:
QSGImage(QSGImagePrivate &dd, QSGItem *parent);
--- /dev/null
+import QtQuick 2.0
+
+Rectangle {
+ id: main
+ width: 800; height: 600
+ focus: true
+ color: "#eeeeee"
+
+ property variant hAlign: Image.AlignHCenter
+ property variant vAlign: Image.AlignVCenter
+ property bool mirror: false
+ property string source: "qt-logo.png"
+
+ Flow {
+ anchors.fill: parent
+ anchors { topMargin: 20; leftMargin: 20; rightMargin: 20 }
+ spacing: 30
+
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ mirror: main.mirror; source: main.source
+ explicitSize: false
+ label: "implicit size"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ mirror: main.mirror; source: main.source
+ label: "explicit size"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.Pad
+ mirror: main.mirror; source: main.source
+ label: "padding"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.Tile
+ mirror: main.mirror; source: main.source
+ label: "tile"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.TileHorizontally
+ mirror: main.mirror; source: main.source
+ label: "tile horizontally"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.TileVertically
+ mirror: main.mirror; source: main.source
+ label: "tile vertically"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.PreserveAspectFit
+ mirror: main.mirror; source: main.source
+ label: "preserve aspect fit"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.PreserveAspectFit
+ width: 150; height: 200
+ mirror: main.mirror; source: main.source
+ label: "preserve aspect fit"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.PreserveAspectCrop
+ mirror: main.mirror; source: main.source
+ label: "preserve aspect crop"
+ }
+ ImageNG {
+ horizontalAlignment: main.hAlign; verticalAlignment: main.vAlign
+ fillMode: Image.PreserveAspectCrop
+ width: 150; height: 200
+ mirror: main.mirror; source: main.source
+ label: "preserve aspect crop"
+ }
+ }
+
+ Keys.onUpPressed: vAlign = Image.AlignTop
+ Keys.onDownPressed: vAlign = Image.AlignBottom
+ Keys.onLeftPressed: hAlign = Image.AlignLeft
+ Keys.onRightPressed: hAlign = Image.AlignRight
+ Keys.onPressed: {
+ if (event.key == Qt.Key_H)
+ hAlign = Image.AlignHCenter
+ else if (event.key == Qt.Key_V)
+ vAlign = Image.AlignVCenter
+ }
+}