From 692782c4d11cf7352a7923633cb015c3580e2704 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 18 May 2009 16:46:12 +1000 Subject: Fix pens. Now corresponds to standard Qt painting; in particular, penwidth extends outside rectangle. Task-number: 249318 --- src/declarative/canvas/qsimplecanvasitem.cpp | 10 +- src/declarative/canvas/qsimplecanvasitem.h | 1 + src/declarative/canvas/qsimplecanvasitem_p.h | 3 +- src/declarative/fx/qfxrect.cpp | 157 ++++++++++++++++----------- src/declarative/fx/qfxrect.h | 2 +- 5 files changed, 108 insertions(+), 65 deletions(-) diff --git a/src/declarative/canvas/qsimplecanvasitem.cpp b/src/declarative/canvas/qsimplecanvasitem.cpp index 12c725c..4449e2b 100644 --- a/src/declarative/canvas/qsimplecanvasitem.cpp +++ b/src/declarative/canvas/qsimplecanvasitem.cpp @@ -180,10 +180,18 @@ void QSimpleCanvasItem::childrenChanged() { } +int QSimpleCanvasItem::setPaintMargin(qreal margin) +{ + Q_D(QSimpleCanvasItem); + if (margin < d->paintmargin) + update(); // schedule repaint of old boundingRect + d->paintmargin = margin; +} + QRectF QSimpleCanvasItem::boundingRect() const { Q_D(const QSimpleCanvasItem); - return QRectF(0., 0., d->width, d->height); + return QRectF(-d->paintmargin, -d->paintmargin, d->width+d->paintmargin*2, d->height+d->paintmargin*2); } void QSimpleCanvasItem::paintContents(QPainter &) diff --git a/src/declarative/canvas/qsimplecanvasitem.h b/src/declarative/canvas/qsimplecanvasitem.h index cab8492..1c729b1 100644 --- a/src/declarative/canvas/qsimplecanvasitem.h +++ b/src/declarative/canvas/qsimplecanvasitem.h @@ -183,6 +183,7 @@ public: }; + int setPaintMargin(qreal margin); QRectF boundingRect() const; virtual void paintContents(QPainter &); virtual void paintGLContents(GLPainter &); diff --git a/src/declarative/canvas/qsimplecanvasitem_p.h b/src/declarative/canvas/qsimplecanvasitem_p.h index cfe0bba..7fe16a3 100644 --- a/src/declarative/canvas/qsimplecanvasitem_p.h +++ b/src/declarative/canvas/qsimplecanvasitem_p.h @@ -139,7 +139,7 @@ public: focusable(false), wantsActiveFocusPanelPendingCanvas(false), hasBeenActiveFocusPanel(false), hasFocus(false), hasActiveFocus(false), needsZOrder(false), - widthValid(false), heightValid(false), width(0), height(0), scale(1), + widthValid(false), heightValid(false), width(0), height(0), paintmargin(0), scale(1), graphicsItem(0), data_ptr(0) { } @@ -173,6 +173,7 @@ public: qreal width; qreal height; + qreal paintmargin; qreal scale; QSimpleGraphicsItem *graphicsItem; diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index dafd8a2..cd5a4c3 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -86,8 +86,26 @@ QML_DEFINE_TYPE(QFxPen,Pen); void QFxPen::setColor(const QColor &c) { _color = c; - emit updated(); _valid = _color.alpha() ? true : false; + emit updated(); +} + +/*! + \property QFxPen::width + \brief the width of the pen. + + \qml + // rect with green border using hexidecimal notation + Rect { pen.width: 4 } + \endqml + + Odd pen widths generally lead to half-pixel painting. +*/ +void QFxPen::setWidth(int w) +{ + _width = w; + _valid = (_width < 1) ? false : true; + emit updated(); } @@ -167,6 +185,8 @@ void QFxRect::doUpdate() Q_D(QFxRect); d->_rectTexture.clear(); #endif + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + setPaintMargin((pw+1)/2); update(); } @@ -372,14 +392,19 @@ void QFxRect::generateRoundedRect() { Q_D(QFxRect); if (d->_rectImage.isNull()) { - d->_rectImage = QImage(d->_radius*2 + 1, d->_radius*2 + 1, QImage::Format_ARGB32_Premultiplied); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + d->_rectImage = QImage(d->_radius*2 + 1 + pw*2, d->_radius*2 + 1 + pw*2, QImage::Format_ARGB32_Premultiplied); d->_rectImage.fill(0); QPainter p(&(d->_rectImage)); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } p.setBrush(d->_color); - p.drawRoundedRect(0, 0, d->_rectImage.width(), d->_rectImage.height(), d->_radius, d->_radius); + p.drawRoundedRect((pw+1)/2, (pw+1)/2, d->_rectImage.width()-(pw+1)/2*2, d->_rectImage.height()-(pw+1)/2*2, d->_radius, d->_radius); } } @@ -387,14 +412,19 @@ void QFxRect::generateBorderedRect() { Q_D(QFxRect); if (d->_rectImage.isNull()) { - d->_rectImage = QImage(d->pen()->width()*2 + 1, d->pen()->width()*2 + 1, QImage::Format_ARGB32_Premultiplied); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + d->_rectImage = QImage(d->pen()->width()*2 + 1 + pw*2, d->pen()->width()*2 + 1 + pw*2, QImage::Format_ARGB32_Premultiplied); d->_rectImage.fill(0); QPainter p(&(d->_rectImage)); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } p.setBrush(d->_color); - p.drawRect(0, 0, d->_rectImage.width(), d->_rectImage.height()); + p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, d->_rectImage.width()-(pw+1)/2*2, d->_rectImage.height()-(pw+1)/2*2); } } #elif defined(QFX_RENDER_OPENGL) @@ -402,14 +432,15 @@ void QFxRect::generateRoundedRect() { Q_D(QFxRect); if (d->_rectTexture.isNull()) { - QImage roundRect(int(d->_radius*2 + 1), int(d->_radius*2 + 1), QImage::Format_ARGB32); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + QImage roundRect(d->_radius*2 + 4 + pw*2, d->_radius*2 + 4 + pw*2, QImage::Format_ARGB32_Premultiplied); roundRect.fill(0); QPainter p(&roundRect); QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); p.setPen(pn); p.setBrush(d->_color); - p.drawRoundedRect(0, 0, roundRect.width(), roundRect.height(), d->_radius, d->_radius); + p.drawRoundedRect((pw+1)/2, (pw+1)/2, roundRect.width()-(pw+1)/2*2, roundRect.height()-(pw+1)/2*2, d->_radius, d->_radius); d->_rectTexture.setImage(roundRect); } } @@ -418,14 +449,15 @@ void QFxRect::generateBorderedRect() { Q_D(QFxRect); if (d->_rectTexture.isNull()) { - QImage borderedRect(d->pen()->width()*2 + 1, d->pen()->width()*2 + 1, QImage::Format_ARGB32_Premultiplied); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + QImage borderedRect(pw*2 + 4, pw*2 + 4, QImage::Format_ARGB32_Premultiplied); borderedRect.fill(0); QPainter p(&(borderedRect)); QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); p.setPen(pn); p.setBrush(d->_color); - p.drawRect(0, 0, borderedRect.width(), borderedRect.height()); + p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, borderedRect.width()-(pw+1)/2*2, borderedRect.height()-(pw+1)/2*2); d->_rectTexture.setImage(borderedRect); } } @@ -458,9 +490,13 @@ void QFxRect::drawRect(QPainter &p) // XXX This path is still slower than the image path // Image path won't work for gradients though p.save(); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } if (d->_gradcolor.isValid()){ QLinearGradient grad(0, 0, 0, height()); grad.setColorAt(0, d->_color); @@ -476,13 +512,15 @@ void QFxRect::drawRect(QPainter &p) p.restore(); } else { int offset = 0; + const int pw = d->_pen && d->_pen->isValid() ? (d->_pen->width()+1)/2*2 : 0; + if (d->_radius > 0) { generateRoundedRect(); //### implicit conversion to int - offset = d->_radius; + offset = int(d->_radius+0.5+pw); } else { generateBorderedRect(); - offset = d->pen()->width(); + offset = pw; } //basically same code as QFxImage uses to paint sci images @@ -490,40 +528,42 @@ void QFxRect::drawRect(QPainter &p) int ySide = qMin(offset * 2, int(height()));; // Upper left - p.drawImage(QRect(0, 0, offset, offset), d->_rectImage, QRect(0, 0, offset, offset)); + p.drawImage(QRect(-pw/2, -pw/2, offset, offset), d->_rectImage, QRect(0, 0, offset, offset)); // Upper middle if (d->_rectImage.width() - xSide) - p.drawImage(QRect(offset, 0, width() - xSide, offset), d->_rectImage, - QRect(offset, 0, d->_rectImage.width() - xSide, offset)); + p.drawImage(QRect(offset-pw/2, -pw/2, width() - xSide + pw, offset), d->_rectImage, + QRect(d->_rectImage.width()/2, 0, 1, offset)); // Upper right if (d->_rectImage.width() - offset) { - p.drawImage(QPoint(width()-offset, 0), d->_rectImage, + p.drawImage(QPoint(width()-offset+pw/2, -pw/2), d->_rectImage, QRect(d->_rectImage.width()-offset, 0, offset, offset)); } // Middle left if (d->_rectImage.height() - ySide) - p.drawImage(QRect(0, offset, offset, height() - ySide), d->_rectImage, - QRect(0, offset, offset, d->_rectImage.height() - ySide)); + p.drawImage(QRect(-pw/2, offset-pw/2, offset, height() - ySide + pw), d->_rectImage, + QRect(0, d->_rectImage.height()/2, offset, 1)); // Middle if (d->_rectImage.width() - xSide && d->_rectImage.height() - ySide) - p.drawImage(QRect(offset, offset, width() - xSide, height() - ySide), d->_rectImage, - QRect(offset, offset, d->_rectImage.width() - xSide, d->_rectImage.height() - ySide)); - // Midlle right + // XXX paint errors in animation example + //p.fillRect(offset-pw/2, offset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor()); + p.drawImage(QRect(offset-pw/2, offset-pw/2, width() - xSide + pw, height() - ySide + pw), d->_rectImage, + QRect(d->_rectImage.width()/2, d->_rectImage.height()/2, 1, 1)); + // Middle right if (d->_rectImage.height() - ySide) - p.drawImage(QRect(width()-offset, offset, offset, height() - ySide), d->_rectImage, - QRect(d->_rectImage.width()-offset, offset, offset, d->_rectImage.height() - ySide)); + p.drawImage(QRect(width()-offset+pw/2, offset-pw/2, offset, height() - ySide + pw), d->_rectImage, + QRect(d->_rectImage.width()-offset, d->_rectImage.height()/2, offset, 1)); // Lower left - p.drawImage(QPoint(0, height() - offset), d->_rectImage, QRect(0, d->_rectImage.height() - offset, offset, offset)); + p.drawImage(QPoint(-pw/2, height() - offset + pw/2), d->_rectImage, QRect(0, d->_rectImage.height() - offset, offset, offset)); // Lower Middle if (d->_rectImage.width() - xSide) - p.drawImage(QRect(offset, height() - offset, width() - xSide, offset), d->_rectImage, - QRect(offset, d->_rectImage.height() - offset, d->_rectImage.width() - xSide, offset)); + p.drawImage(QRect(offset-pw/2, height() - offset +pw/2, width() - xSide + pw, offset), d->_rectImage, + QRect(d->_rectImage.width()/2, d->_rectImage.height() - offset, 1, offset)); // Lower Right if (d->_rectImage.width() - offset) - p.drawImage(QPoint(width()-offset, height() - offset), d->_rectImage, + p.drawImage(QPoint(width()-offset+pw/2, height() - offset+pw/2), d->_rectImage, QRect(d->_rectImage.width()-offset, d->_rectImage.height() - offset, offset, offset)); } } @@ -586,12 +626,14 @@ void QFxRect::paintGLContents(GLPainter &p) } } else { qreal offset = 0; + qreal pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0.0; + if (d->_radius > 0) { generateRoundedRect(); - offset = d->_radius; + offset = d->_radius + pw+1.5; } else { generateBorderedRect(); - offset = d->pen()->width(); + offset = pw+1.5; } QGLShaderProgram *shader = p.useTextureShader(); @@ -601,38 +643,29 @@ void QFxRect::paintGLContents(GLPainter &p) if (!imgWidth || !imgHeight) return; - float widthV = width(); - float heightV = height(); + float widthV = qreal(width())+pw/2; + float heightV = qreal(height())+pw/2; - float texleft = 0; - float texright = 1; - float textop = 1; - float texbottom = 0; - float imgleft = 0; - float imgright = widthV; - float imgtop = 0; - float imgbottom = heightV; - - texleft = float(offset) / imgWidth; - imgleft = offset; - texright = 1. - float(offset) / imgWidth; - imgright = widthV - offset; - textop = 1. - float(offset) / imgHeight; - imgtop = offset; - texbottom = float(offset) / imgHeight; - imgbottom = heightV - offset; + float texleft = float(offset) / imgWidth; + float imgleft = offset-pw/2; + float texright = float(imgWidth-offset) / imgWidth; + float imgright = widthV - offset; + float textop = float(imgHeight-offset) / imgHeight; + float imgtop = offset-pw/2; + float texbottom = float(offset) / imgHeight; + float imgbottom = heightV - offset; //Bug 231768: Inappropriate interpolation was occuring on 3x3 textures if (offset==1) texleft=texright=textop=texbottom=0.5; - float vert1[] = { 0, 0, - 0, imgtop, - imgleft, 0, + float vert1[] = { -pw/2, -pw/2, + -pw/2, imgtop, + imgleft, -pw/2, imgleft, imgtop, - imgright, 0, + imgright, -pw/2, imgright, imgtop, - widthV, 0, + widthV, -pw/2, widthV, imgtop }; float tex1[] = { 0, 0, 0, textop, @@ -642,8 +675,8 @@ void QFxRect::paintGLContents(GLPainter &p) texright, textop, 1, 0, 1, textop }; - float vert2[] = { 0, imgtop, - 0, imgbottom, + float vert2[] = { -pw/2, imgtop, + -pw/2, imgbottom, imgleft, imgtop, imgleft, imgbottom, imgright, imgtop, @@ -658,8 +691,8 @@ void QFxRect::paintGLContents(GLPainter &p) texright, texbottom, 1, textop, 1, texbottom }; - float vert3[] = { 0, imgbottom, - 0, heightV, + float vert3[] = { -pw/2, imgbottom, + -pw/2, heightV, imgleft, imgbottom, imgleft, heightV, imgright, imgbottom, diff --git a/src/declarative/fx/qfxrect.h b/src/declarative/fx/qfxrect.h index 42e7b2f..339a7d8 100644 --- a/src/declarative/fx/qfxrect.h +++ b/src/declarative/fx/qfxrect.h @@ -62,7 +62,7 @@ public: {} int width() const { return _width; } - void setWidth(int w) { _width = w; emit updated(); _valid = (_width < 1) ? false : true; } + void setWidth(int w); QColor color() const { return _color; } void setColor(const QColor &c); -- cgit v0.12 From 3b97e2d22ac184590b5049cff720a259f9aa6b42 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 19 May 2009 12:41:06 +1000 Subject: Fix pens, at small sizes See 504c489d40e815397235ba26df7f06aae821c88a Also fixes 0 width (hairline) pens. --- src/declarative/fx/qfxrect.cpp | 147 +++++++++++++++++++++++++---------------- src/declarative/fx/qfxrect.h | 2 +- 2 files changed, 90 insertions(+), 59 deletions(-) diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index 6f13d7c..b61baec 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -52,6 +52,11 @@ QML_DEFINE_TYPE(QFxPen,Pen); \ingroup group_utility \brief The QFxPen class provides a pen used for drawing rect borders on a QFxView. + By default, the pen is invalid and nothing is drawn. You must either set a color (then the default + width is 0) or a width (then the default color is black). + + A width of 0 is a single-pixel line on the border of the item being painted. + Example: \qml Rect { pen.width: 2; pen.color: "red" ... } @@ -61,8 +66,9 @@ QML_DEFINE_TYPE(QFxPen,Pen); /*! \property QFxPen::width \brief the width of the pen. - The default width is 1. If the width is less than 1 the pen is considered invalid - and won't be used. + A width of 0 is a single-pixel line on the border of the item being painted. + + If the width is less than 0 the pen is considered invalid and won't be used. */ /*! @@ -99,12 +105,14 @@ void QFxPen::setColor(const QColor &c) Rect { pen.width: 4 } \endqml + A width of 0 creates a thin line. For no line, use a negative width or a transparent color. + Odd pen widths generally lead to half-pixel painting. */ void QFxPen::setWidth(int w) { _width = w; - _valid = (_width < 1) ? false : true; + _valid = (_width < 0) ? false : true; emit updated(); } @@ -436,9 +444,13 @@ void QFxRect::generateRoundedRect() QImage roundRect(d->_radius*2 + 4 + pw*2, d->_radius*2 + 4 + pw*2, QImage::Format_ARGB32_Premultiplied); roundRect.fill(0); QPainter p(&roundRect); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } p.setBrush(d->_color); p.drawRoundedRect((pw+1)/2, (pw+1)/2, roundRect.width()-(pw+1)/2*2, roundRect.height()-(pw+1)/2*2, d->_radius, d->_radius); d->_rectTexture.setImage(roundRect); @@ -453,9 +465,13 @@ void QFxRect::generateBorderedRect() QImage borderedRect(pw*2 + 4, pw*2 + 4, QImage::Format_ARGB32_Premultiplied); borderedRect.fill(0); QPainter p(&(borderedRect)); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } p.setBrush(d->_color); p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, borderedRect.width()-(pw+1)/2*2, borderedRect.height()-(pw+1)/2*2); d->_rectTexture.setImage(borderedRect); @@ -524,18 +540,22 @@ void QFxRect::drawRect(QPainter &p) } //basically same code as QFxImage uses to paint sci images - int w = width(); - int h = height(); + int w = width()+pw; + int h = height()+pw; int xOffset = offset; int xSide = xOffset * 2; + bool xMiddles=true; if (xSide > w) { - xOffset = w/2; + xMiddles=false; + xOffset = w/2 + 1; xSide = xOffset * 2; } int yOffset = offset; int ySide = yOffset * 2; + bool yMiddles=true; if (ySide > h) { - yOffset = h/2; + yMiddles = false; + yOffset = h/2 + 1; ySide = yOffset * 2; } @@ -543,40 +563,37 @@ void QFxRect::drawRect(QPainter &p) p.drawImage(QRect(-pw/2, -pw/2, xOffset, yOffset), d->_rectImage, QRect(0, 0, xOffset, yOffset)); // Upper middle - if (d->_rectImage.width() - xSide) + if (xMiddles) p.drawImage(QRect(xOffset-pw/2, -pw/2, width() - xSide + pw, yOffset), d->_rectImage, QRect(d->_rectImage.width()/2, 0, 1, yOffset)); // Upper right - if (d->_rectImage.width() - xOffset) { - p.drawImage(QPoint(width()-xOffset+pw/2, -pw/2), d->_rectImage, - QRect(d->_rectImage.width()-xOffset, 0, xOffset, yOffset)); - } + p.drawImage(QPoint(width()-xOffset+pw/2, -pw/2), d->_rectImage, + QRect(d->_rectImage.width()-xOffset, 0, xOffset, yOffset)); // Middle left - if (d->_rectImage.height() - ySide) + if (yMiddles) p.drawImage(QRect(-pw/2, yOffset-pw/2, xOffset, height() - ySide + pw), d->_rectImage, QRect(0, d->_rectImage.height()/2, xOffset, 1)); // Middle - if (d->_rectImage.width() - xSide && d->_rectImage.height() - ySide) + if (xMiddles && yMiddles) // XXX paint errors in animation example //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor()); p.drawImage(QRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw), d->_rectImage, QRect(d->_rectImage.width()/2, d->_rectImage.height()/2, 1, 1)); // Middle right - if (d->_rectImage.height() - ySide) + if (yMiddles) p.drawImage(QRect(width()-xOffset+pw/2, yOffset-pw/2, xOffset, height() - ySide + pw), d->_rectImage, QRect(d->_rectImage.width()-xOffset, d->_rectImage.height()/2, xOffset, 1)); // Lower left p.drawImage(QPoint(-pw/2, height() - yOffset + pw/2), d->_rectImage, QRect(0, d->_rectImage.height() - yOffset, xOffset, yOffset)); // Lower Middle - if (d->_rectImage.width() - xSide) + if (xMiddles) p.drawImage(QRect(xOffset-pw/2, height() - yOffset +pw/2, width() - xSide + pw, yOffset), d->_rectImage, QRect(d->_rectImage.width()/2, d->_rectImage.height() - yOffset, 1, yOffset)); // Lower Right - if (d->_rectImage.width() - xOffset) - p.drawImage(QPoint(width()-xOffset+pw/2, height() - yOffset+pw/2), d->_rectImage, - QRect(d->_rectImage.width()-xOffset, d->_rectImage.height() - yOffset, xOffset, yOffset)); + p.drawImage(QPoint(width()-xOffset+pw/2, height() - yOffset+pw/2), d->_rectImage, + QRect(d->_rectImage.width()-xOffset, d->_rectImage.height() - yOffset, xOffset, yOffset)); } } #endif @@ -650,22 +667,36 @@ void QFxRect::paintGLContents(GLPainter &p) QGLShaderProgram *shader = p.useTextureShader(); - float imgWidth = d->_rectTexture.width(); - float imgHeight = d->_rectTexture.height(); - if (!imgWidth || !imgHeight) + float texWidth = d->_rectTexture.width(); + float texHeight = d->_rectTexture.height(); + if (!texWidth || !texHeight) return; float widthV = qreal(width())+pw/2; float heightV = qreal(height())+pw/2; - float texleft = float(offset) / imgWidth; - float imgleft = offset-pw/2; - float texright = float(imgWidth-offset) / imgWidth; - float imgright = widthV - offset; - float textop = float(imgHeight-offset) / imgHeight; - float imgtop = offset-pw/2; - float texbottom = float(offset) / imgHeight; - float imgbottom = heightV - offset; + float xOffset = offset; + bool xMiddles = true; + if (xOffset*2 > width()+pw) { + xMiddles = false; + xOffset = (width()+pw)/2; + } + float yOffset = offset; + bool yMiddles = true; + if (yOffset*2 > height()+pw) { + yMiddles = false; + yOffset = (height()+pw)/2; + } + + float texleft = xOffset / texWidth; + float imgleft = xOffset-pw/2; + float texright = (texWidth-xOffset) / texWidth; + float imgright = widthV - xOffset; + + float textop = yOffset / texHeight; + float imgtop = yOffset-pw/2; + float texbottom = (texHeight-yOffset) / texHeight; + float imgbottom = heightV - yOffset; //Bug 231768: Inappropriate interpolation was occuring on 3x3 textures if (offset==1) @@ -703,31 +734,31 @@ void QFxRect::paintGLContents(GLPainter &p) texright, texbottom, 1, textop, 1, texbottom }; - float vert3[] = { -pw/2, imgbottom, - -pw/2, heightV, - imgleft, imgbottom, + float vert3[] = { -pw/2, heightV, + -pw/2, imgbottom, imgleft, heightV, - imgright, imgbottom, + imgleft, imgbottom, imgright, heightV, - widthV, imgbottom, - widthV, heightV }; - float tex3[] = { 0, texbottom, - 0, 0, + imgright, imgbottom, + widthV, heightV, + widthV, imgbottom }; + float tex3[] = { 0, 1, + 0, texbottom, + texleft, 1, texleft, texbottom, - texleft, 0, + texright, 1, texright, texbottom, - texright, 0, - 1, texbottom, - 1, 0 }; - - glBindTexture(GL_TEXTURE_2D, d->_rectTexture.texture()); + 1, 1, + 1, texbottom }; shader->setAttributeArray(SingleTextureShader::Vertices, vert1, 2); shader->setAttributeArray(SingleTextureShader::TextureCoords, tex1, 2); glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); - shader->setAttributeArray(SingleTextureShader::Vertices, vert2, 2); - shader->setAttributeArray(SingleTextureShader::TextureCoords, tex2, 2); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); + if (yMiddles) { + shader->setAttributeArray(SingleTextureShader::Vertices, vert2, 2); + shader->setAttributeArray(SingleTextureShader::TextureCoords, tex2, 2); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); + } shader->setAttributeArray(SingleTextureShader::Vertices, vert3, 2); shader->setAttributeArray(SingleTextureShader::TextureCoords, tex3, 2); glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); @@ -806,9 +837,9 @@ void QFxRect::paintGLContents(GLPainter &p) glColor4f(1, 1, 1, p.activeOpacity); } - float imgWidth = d->_rectTexture.width(); - float imgHeight = d->_rectTexture.height(); - if (!imgWidth || !imgHeight) + float texWidth = d->_rectTexture.width(); + float texHeight = d->_rectTexture.height(); + if (!texWidth || !texHeight) return; float widthV = width(); @@ -823,13 +854,13 @@ void QFxRect::paintGLContents(GLPainter &p) float imgtop = 0; float imgbottom = heightV; - texleft = float(offset) / imgWidth; + texleft = float(offset) / texWidth; imgleft = offset; - texright = 1. - float(offset) / imgWidth; + texright = 1. - float(offset) / texWidth; imgright = widthV - offset; - textop = 1. - float(offset) / imgHeight; + textop = 1. - float(offset) / texHeight; imgtop = offset; - texbottom = float(offset) / imgHeight; + texbottom = float(offset) / texHeight; imgbottom = heightV - offset; float vert1[] = { 0, 0, diff --git a/src/declarative/fx/qfxrect.h b/src/declarative/fx/qfxrect.h index 339a7d8..84a9c57 100644 --- a/src/declarative/fx/qfxrect.h +++ b/src/declarative/fx/qfxrect.h @@ -58,7 +58,7 @@ class Q_DECLARATIVE_EXPORT QFxPen : public QObject Q_PROPERTY(QColor color READ color WRITE setColor) public: QFxPen(QObject *parent=0) - : QObject(parent), _width(1), _color("#000000"), _valid(false) + : QObject(parent), _width(0), _color("#000000"), _valid(false) {} int width() const { return _width; } -- cgit v0.12 From 6fee456cff928c504a48df74bb3986fb453fc97a Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 19 May 2009 16:33:34 +1000 Subject: Use pngs instead of svgs for dial example. --- examples/declarative/dial/DialLibrary/Dial.qml | 8 +- .../declarative/dial/DialLibrary/background.png | Bin 0 -> 35876 bytes .../declarative/dial/DialLibrary/background.svg | 385 --------------------- examples/declarative/dial/DialLibrary/needle.png | Bin 0 -> 1078 bytes examples/declarative/dial/DialLibrary/needle.svg | 26 -- .../declarative/dial/DialLibrary/needle_shadow.png | Bin 0 -> 1401 bytes .../declarative/dial/DialLibrary/needle_shadow.svg | 30 -- examples/declarative/dial/DialLibrary/overlay.png | Bin 0 -> 4389 bytes examples/declarative/dial/DialLibrary/overlay.svg | 47 --- 9 files changed, 4 insertions(+), 492 deletions(-) create mode 100644 examples/declarative/dial/DialLibrary/background.png delete mode 100644 examples/declarative/dial/DialLibrary/background.svg create mode 100644 examples/declarative/dial/DialLibrary/needle.png delete mode 100644 examples/declarative/dial/DialLibrary/needle.svg create mode 100644 examples/declarative/dial/DialLibrary/needle_shadow.png delete mode 100644 examples/declarative/dial/DialLibrary/needle_shadow.svg create mode 100644 examples/declarative/dial/DialLibrary/overlay.png delete mode 100644 examples/declarative/dial/DialLibrary/overlay.svg diff --git a/examples/declarative/dial/DialLibrary/Dial.qml b/examples/declarative/dial/DialLibrary/Dial.qml index e3fd382..32c58cd 100644 --- a/examples/declarative/dial/DialLibrary/Dial.qml +++ b/examples/declarative/dial/DialLibrary/Dial.qml @@ -3,10 +3,10 @@ Item { width: 210; height: 210 - Image { id: Background; source: "background.svg" } + Image { id: Background; source: "background.png" } Image { - source: "needle_shadow.svg" + source: "needle_shadow.png" transform: Rotation { originX: 104; originY: 102 angle: NeedleRotation.angle @@ -14,7 +14,7 @@ Item { } Image { id: Needle - source: "needle.svg" + source: "needle.png" transform: Rotation { id: NeedleRotation originX: 102; originY: 98 @@ -26,5 +26,5 @@ Item { } } } - Image { source: "overlay.svg" } + Image { source: "overlay.png" } } diff --git a/examples/declarative/dial/DialLibrary/background.png b/examples/declarative/dial/DialLibrary/background.png new file mode 100644 index 0000000..75d555d Binary files /dev/null and b/examples/declarative/dial/DialLibrary/background.png differ diff --git a/examples/declarative/dial/DialLibrary/background.svg b/examples/declarative/dial/DialLibrary/background.svg deleted file mode 100644 index 415320d..0000000 --- a/examples/declarative/dial/DialLibrary/background.svg +++ /dev/null @@ -1,385 +0,0 @@ - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - -1 -0 - -2 -0 - -3 -0 - -4 -0 - -5 -0 - -6 -0 - -7 -0 - -8 -0 - -9 -0 - -1 -0 -0 - -1 -1 -0 - -1 -2 -0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/declarative/dial/DialLibrary/needle.png b/examples/declarative/dial/DialLibrary/needle.png new file mode 100644 index 0000000..c171b43 Binary files /dev/null and b/examples/declarative/dial/DialLibrary/needle.png differ diff --git a/examples/declarative/dial/DialLibrary/needle.svg b/examples/declarative/dial/DialLibrary/needle.svg deleted file mode 100644 index dce7d7e..0000000 --- a/examples/declarative/dial/DialLibrary/needle.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - -]> - - - - - - - - - - - - - - - - - diff --git a/examples/declarative/dial/DialLibrary/needle_shadow.png b/examples/declarative/dial/DialLibrary/needle_shadow.png new file mode 100644 index 0000000..4e1ac0c Binary files /dev/null and b/examples/declarative/dial/DialLibrary/needle_shadow.png differ diff --git a/examples/declarative/dial/DialLibrary/needle_shadow.svg b/examples/declarative/dial/DialLibrary/needle_shadow.svg deleted file mode 100644 index 6aab197..0000000 --- a/examples/declarative/dial/DialLibrary/needle_shadow.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - -]> - - - - - - diff --git a/examples/declarative/dial/DialLibrary/overlay.png b/examples/declarative/dial/DialLibrary/overlay.png new file mode 100644 index 0000000..3341a16 Binary files /dev/null and b/examples/declarative/dial/DialLibrary/overlay.png differ diff --git a/examples/declarative/dial/DialLibrary/overlay.svg b/examples/declarative/dial/DialLibrary/overlay.svg deleted file mode 100644 index 8530dd5..0000000 --- a/examples/declarative/dial/DialLibrary/overlay.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - -]> - - - - - - - - - - - - - - - - - -- cgit v0.12 From 8c2f6d4b70bc6e3579c99b49a1dd842678bd7ebe Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 19 May 2009 16:44:16 +1000 Subject: Make sure Flippable updates its back transform correctly. Previously we didn't update the back transform on geometry changes to the back element. Now we make sure it is up-to-date whenever we show it. Also updated anchors (they no longer need to work around this). --- src/declarative/fx/qfxanchors.cpp | 1 - src/declarative/fx/qfxflipable.cpp | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/declarative/fx/qfxanchors.cpp b/src/declarative/fx/qfxanchors.cpp index 3eaf47a..235511f 100644 --- a/src/declarative/fx/qfxanchors.cpp +++ b/src/declarative/fx/qfxanchors.cpp @@ -234,7 +234,6 @@ void QFxAnchorsPrivate::remDepend(QFxItem *item) bool QFxAnchorsPrivate::isItemComplete() const { - return true; return item->isComponentComplete(); } diff --git a/src/declarative/fx/qfxflipable.cpp b/src/declarative/fx/qfxflipable.cpp index 24ae428..edcc7cb 100644 --- a/src/declarative/fx/qfxflipable.cpp +++ b/src/declarative/fx/qfxflipable.cpp @@ -169,7 +169,6 @@ void QFxFlipable::setBack(QFxItem *back) children()->append(d->back); if (Front == d->current) d->back->setOpacity(0.); - d->setBackTransform(); } /*! @@ -203,8 +202,6 @@ void QFxFlipablePrivate::_q_updateAxis() axisRotation.axis()->setEndX(axis->endX()); axisRotation.axis()->setEndY(axis->endY()); axisRotation.axis()->setEndZ(axis->endZ()); - - setBackTransform(); } void QFxFlipablePrivate::setBackTransform() @@ -273,8 +270,10 @@ void QFxFlipable::setRotation(qreal angle) d->current = newSide; if (d->front) d->front->setOpacity((d->current==Front)?1.:0.); - if (d->back) + if (d->back) { + d->setBackTransform(); d->back->setOpacity((d->current==Back)?1.:0.); + } emit sideChanged(); } } -- cgit v0.12 From 3eb9a9404544a7b954d18f19d373883d0623da93 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Tue, 19 May 2009 17:31:46 +1000 Subject: More precise positioning to leave 1-pixel inner margin --- demos/declarative/flickr/content/Progress.qml | 2 +- demos/declarative/flickr/content/Slider.qml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/demos/declarative/flickr/content/Progress.qml b/demos/declarative/flickr/content/Progress.qml index 92a232e..aa2a2e6 100644 --- a/demos/declarative/flickr/content/Progress.qml +++ b/demos/declarative/flickr/content/Progress.qml @@ -5,7 +5,7 @@ Item { Rect { id: Container; anchors.fill: parent; gradientColor: "#66000000"; - pen.color: "white"; pen.width: 1; color: "#66343434"; radius: height/2 - 2 + pen.color: "white"; pen.width: 0; color: "#66343434"; radius: height/2 - 2 } Rect { diff --git a/demos/declarative/flickr/content/Slider.qml b/demos/declarative/flickr/content/Slider.qml index 92f4993..aae4631 100644 --- a/demos/declarative/flickr/content/Slider.qml +++ b/demos/declarative/flickr/content/Slider.qml @@ -3,25 +3,25 @@ Item { // value is read/write. property real value - onValueChanged: { Handle.x = (value - minimum) * Slider.xMax / (maximum - minimum); } + onValueChanged: { Handle.x = 2 + (value - minimum) * Slider.xMax / (maximum - minimum); } property real maximum: 1 property real minimum: 1 - property int xMax: Slider.width - Handle.width - 2 + property int xMax: Slider.width - Handle.width - 4 Rect { id: Container; anchors.fill: parent; gradientColor: "#66000000"; - pen.color: "white"; pen.width: 1; color: "#66343434"; radius: 8 + pen.color: "white"; pen.width: 0; color: "#66343434"; radius: 8 } Rect { id: Handle - x: Slider.width / 2 - Handle.width / 2; y: 2; width: 30; height: 12 + x: Slider.width / 2 - Handle.width / 2; y: 2; width: 30; height: Slider.height-4 color: "lightgray"; gradientColor: "gray"; radius: 6 MouseRegion { anchors.fill: parent; drag.target: parent - drag.axis: "x"; drag.xmin: 2; drag.xmax: Slider.xMax - onPositionChanged: { value = (maximum - minimum) * Handle.x / Slider.xMax + minimum; } + drag.axis: "x"; drag.xmin: 2; drag.xmax: Slider.xMax+2 + onPositionChanged: { value = (maximum - minimum) * (Handle.x-2) / Slider.xMax + minimum; } } } } -- cgit v0.12