summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2010-11-18 15:19:13 +0100
committerYoann Lopes <yoann.lopes@nokia.com>2010-11-18 15:20:03 +0100
commitfcd388b3436bea4d5289832699329294c744a0ac (patch)
tree9d1862de228ecb64bd8d28ddfc2cbf9739f73641
parent4969d36d1bad2a856c0d9db03d739310f9852797 (diff)
Implemented rounded clip.
-rw-r--r--src/canvas/qxclipnode.cpp87
-rw-r--r--src/canvas/qxclipnode_p.h6
-rw-r--r--src/graphicsitems/qxrectangle.cpp6
-rw-r--r--tests/rrClip.qml15
4 files changed, 63 insertions, 51 deletions
diff --git a/src/canvas/qxclipnode.cpp b/src/canvas/qxclipnode.cpp
index a954b62..aded473 100644
--- a/src/canvas/qxclipnode.cpp
+++ b/src/canvas/qxclipnode.cpp
@@ -44,83 +44,80 @@
#include "qxclipnode_p.h"
#include "utilities.h"
+#include <QtGui/QVector2D>
#include <QtCore/qmath.h>
QxClipNode::QxClipNode(const QRectF &rect)
: m_rect(rect), m_radius(0)
{
- updateGeometry();
+ updateGeometryDescription(Utilities::getRectGeometryDescription(), GL_UNSIGNED_SHORT);
+ Utilities::setupRectGeometry(geometry(), m_rect);
setFlag(ClipIsRectangular, true);
}
void QxClipNode::setRect(const QRectF &rect)
{
m_rect = rect;
- updateGeometry();
+ setUpdateFlag(UpdateGeometry);
}
void QxClipNode::setRadius(qreal radius)
{
m_radius = radius;
- updateGeometry();
+ setUpdateFlag(UpdateGeometry);
setFlag(ClipIsRectangular, radius == 0);
}
+void QxClipNode::update(uint updateFlags)
+{
+ if (updateFlags & UpdateGeometry)
+ updateGeometry();
+}
+
void QxClipNode::updateGeometry()
{
if (qFuzzyIsNull(m_radius)) {
updateGeometryDescription(Utilities::getRectGeometryDescription(), GL_UNSIGNED_SHORT);
Utilities::setupRectGeometry(geometry(), m_rect);
} else {
- // ### Fix.
- updateGeometryDescription(Utilities::getRectGeometryDescription(), GL_UNSIGNED_SHORT);
- Utilities::setupRectGeometry(geometry(), m_rect);
- /*
- //XXX copy of what is in QxRectangle (we should reuse the geometry generated there if possible)
+ struct Vertex
+ {
+ QVector2D position;
+ };
+
+ Geometry *g = geometry();
+ int vertexCount = 0;
+
QRectF rect = m_rect;
- qreal radius = m_radius;
-
- QArray<QVector2D> vertices;
- QGLVertexBuffer v;
-
- qreal zero = 0. * M_PI/180.;
- qreal ninety = 90. * M_PI/180.;
- qreal oneeighty = 180. * M_PI/180.;
- qreal twoseventy = 270. * M_PI/180.;
- qreal nninety = -90. * M_PI/180.;
- qreal step = -1.5708/radius;
-
- //upper left
- QPointF cp(rect.x() + radius, rect.y() + radius);
- for (qreal angle = twoseventy; angle >= oneeighty; angle += step) {
- vertices.append(QVector2D(cp.x() + qFastSin(angle) * radius, cp.y() + qFastCos(angle) * radius));
- }
+ rect.adjust(m_radius, m_radius, -m_radius, -m_radius);
- //upper right
- cp = QPointF(rect.x() + rect.width() - radius, rect.y() + radius);
- for (qreal angle = oneeighty; angle >= ninety; angle += step) {
- vertices.append(QVector2D(cp.x() + qFastSin(angle) * radius, cp.y() + qFastCos(angle) * radius));
- }
+ int segments = qMin(15, qCeil(m_radius)); // Number of segments per corner.
- //lower right
- cp = QPointF(rect.x() + rect.width() - radius, rect.y() + rect.height() - radius);
- for (qreal angle = ninety; angle >= zero; angle += step) {
- vertices.append(QVector2D(cp.x() + qFastSin(angle) * radius, cp.y() + qFastCos(angle) * radius));
- }
+ // Overestimate the number of vertices and indices, reduce afterwards when the actual numbers are known.
+ g->setVertexCount((segments + 1) * 4);
+ g->setIndexCount(0);
+
+ Vertex *vertices = (Vertex *)g->vertexData();
+
+ for (int part = 0; part < 2; ++part) {
+ for (int i = 0; i <= segments; ++i) {
+ //### Should change to calculate sin/cos only once.
+ qreal angle = qreal(0.5 * M_PI) * (part + i / qreal(segments));
+ qreal s = qFastSin(angle);
+ qreal c = qFastCos(angle);
+ qreal y = (part ? rect.bottom() : rect.top()) - m_radius * c; // current inner y-coordinate.
+ qreal lx = rect.left() - m_radius * s; // current inner left x-coordinate.
+ qreal rx = rect.right() + m_radius * s; // current inner right x-coordinate.
- //lower left
- cp = QPointF(rect.x() + radius, rect.y() + rect.height() - radius);
- for (qreal angle = zero; angle >= nninety; angle += step) {
- vertices.append(QVector2D(cp.x() + qFastSin(angle) * radius, cp.y() + qFastCos(angle) * radius));
+ vertices[vertexCount++].position = QVector2D(rx, y);
+ vertices[vertexCount++].position = QVector2D(lx, y);
+ }
}
- vertices.append(QVector2D(rect.x(), rect.y() + radius));
- v.addAttribute(QGL::Position, vertices);
+ g->setDrawingMode(QGL::TriangleStrip);
+ g->setVertexCount(vertexCount);
- setDrawingMode(QGL::TriangleFan);
- setVertexBuffer(v);
- setIndexBuffer(Utilities::createIndexBuffer(vertices.count()));
- */
+ markDirty(DirtyGeometry);
}
setBoundingRect(m_rect);
}
diff --git a/src/canvas/qxclipnode_p.h b/src/canvas/qxclipnode_p.h
index 76d7bbf..0754897 100644
--- a/src/canvas/qxclipnode_p.h
+++ b/src/canvas/qxclipnode_p.h
@@ -49,6 +49,10 @@
class QxClipNode : public ClipNode
{
public:
+ enum UpdateFlag {
+ UpdateGeometry = 1
+ };
+
QxClipNode(const QRectF &);
void setRect(const QRectF &);
@@ -57,6 +61,8 @@ public:
void setRadius(qreal radius);
qreal radius() const { return m_radius; }
+ virtual void update(uint updateFlags);
+
private:
void updateGeometry();
QRectF m_rect;
diff --git a/src/graphicsitems/qxrectangle.cpp b/src/graphicsitems/qxrectangle.cpp
index ff3b174..6d240c5 100644
--- a/src/graphicsitems/qxrectangle.cpp
+++ b/src/graphicsitems/qxrectangle.cpp
@@ -41,6 +41,7 @@
#include "qxrectangle_p.h"
#include "qxrectangle_p_p.h"
+#include "qxclipnode_p.h"
#include "geometry.h"
#include "vertexcolormaterial.h"
@@ -177,10 +178,9 @@ void QxRectangle::setRadius(qreal radius)
if (d->node)
d->node->setRadius(radius);
-#ifdef ROUNDEDRECT_CLIP
if (d->clipNode)
d->clipNode->setRadius(d->radius);
-#endif
+
emit radiusChanged();
}
@@ -247,6 +247,8 @@ void QxRectangle::componentComplete()
d->updateGradient();
d->updateBorderWidth();
d->updateBorderColor();
+ if (d->clipNode)
+ d->clipNode->setRadius(d->radius);
setPaintNode(d->node); // Must call setRect() before calling setPaintNode() for clipping to be correct.
}
diff --git a/tests/rrClip.qml b/tests/rrClip.qml
index 7105ba0..ece7605 100644
--- a/tests/rrClip.qml
+++ b/tests/rrClip.qml
@@ -46,14 +46,21 @@ Rectangle {
height: 480
Rectangle {
- width: 400; height: 400
+ width: 400; height: 400;
anchors.centerIn: parent
- radius: 100
+ radius: 200
+ color: "transparent"
clip: true
Rectangle {
- anchors.fill: parent
- color: "green"
+ anchors.centerIn: parent
+ width: 400; height: 400
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "white" }
+ GradientStop { position: 1.0; color: "green" }
+ }
+
+ NumberAnimation on rotation { to: 360; duration: 3000; loops: -1 }
}
}
}