diff options
Diffstat (limited to 'demos')
30 files changed, 599 insertions, 735 deletions
diff --git a/demos/boxes/boxes.pro b/demos/boxes/boxes.pro index a7b19a3..33f1f14 100644 --- a/demos/boxes/boxes.pro +++ b/demos/boxes/boxes.pro @@ -15,8 +15,7 @@ HEADERS += 3rdparty/fbm.h \ qtbox.h \ roundedbox.h \ scene.h \ - trackball.h \ - vector.h + trackball.h SOURCES += 3rdparty/fbm.c \ glbuffers.cpp \ glextensions.cpp \ diff --git a/demos/boxes/glbuffers.cpp b/demos/boxes/glbuffers.cpp index b2a594e..a25a425 100644 --- a/demos/boxes/glbuffers.cpp +++ b/demos/boxes/glbuffers.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "glbuffers.h" +#include <QtGui/qmatrix4x4.h> //============================================================================// // GLTexture // @@ -346,7 +347,7 @@ void GLRenderTargetCube::end() m_fbo.setAsRenderTarget(false); } -void GLRenderTargetCube::getViewMatrix(gfx::Matrix4x4f& mat, int face) +void GLRenderTargetCube::getViewMatrix(QMatrix4x4& mat, int face) { if (face < 0 || face >= 6) { qWarning("GLRenderTargetCube::getViewMatrix: 'face' must be in the range [0, 6). (face == %d)", face); @@ -371,20 +372,21 @@ void GLRenderTargetCube::getViewMatrix(gfx::Matrix4x4f& mat, int face) {-1.0f, -1.0f, +1.0f}, }; - memset(mat.bits(), 0, sizeof(float) * 16); + memset(mat.data(), 0, sizeof(float) * 16); for (int i = 0; i < 3; ++i) - mat(perm[face][i], i) = signs[face][i]; + mat(i, perm[face][i]) = signs[face][i]; mat(3, 3) = 1.0f; } -void GLRenderTargetCube::getProjectionMatrix(gfx::Matrix4x4f& mat, float nearZ, float farZ) +void GLRenderTargetCube::getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ) { - float proj[] = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, (nearZ+farZ)/(nearZ-farZ), -1.0f, - 0.0f, 0.0f, 2.0f*nearZ*farZ/(nearZ-farZ), 0.0f, - }; - - memcpy(mat.bits(), proj, sizeof(float) * 16); + static const QMatrix4x4 reference( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f); + + mat = reference; + mat(2, 2) = (nearZ+farZ)/(nearZ-farZ); + mat(2, 3) = 2.0f*nearZ*farZ/(nearZ-farZ); } diff --git a/demos/boxes/glbuffers.h b/demos/boxes/glbuffers.h index 88de4e8..392924e 100644 --- a/demos/boxes/glbuffers.h +++ b/demos/boxes/glbuffers.h @@ -48,8 +48,6 @@ #include <QtGui> #include <QtOpenGL> -#include "vector.h" - #define BUFFER_OFFSET(i) ((char*)0 + (i)) #define SIZE_OF_MEMBER(cls, member) sizeof(static_cast<cls *>(0)->member) @@ -60,6 +58,8 @@ if (m_failed || !(assertion)) { returnStatement; \ } +class QMatrix4x4; + class GLTexture { public: @@ -135,8 +135,8 @@ public: void end(); virtual bool failed() {return m_failed || m_fbo.failed();} - static void getViewMatrix(gfx::Matrix4x4f& mat, int face); - static void getProjectionMatrix(gfx::Matrix4x4f& mat, float nearZ, float farZ); + static void getViewMatrix(QMatrix4x4& mat, int face); + static void getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ); private: GLFrameBufferObject m_fbo; }; diff --git a/demos/boxes/qtbox.cpp b/demos/boxes/qtbox.cpp index 0607698..ba9f95d 100644 --- a/demos/boxes/qtbox.cpp +++ b/demos/boxes/qtbox.cpp @@ -269,19 +269,20 @@ bool ItemBase::isInResizeArea(const QPointF &pos) QtBox::QtBox(int size, int x, int y) : ItemBase(size, x, y), m_texture(0) { for (int i = 0; i < 8; ++i) { - m_vertices[i][0] = (i & 1 ? 0.5f : -0.5f); - m_vertices[i][1] = (i & 2 ? 0.5f : -0.5f); - m_vertices[i][2] = (i & 4 ? 0.5f : -0.5f); + m_vertices[i].setX(i & 1 ? 0.5f : -0.5f); + m_vertices[i].setY(i & 2 ? 0.5f : -0.5f); + m_vertices[i].setZ(i & 4 ? 0.5f : -0.5f); } for (int i = 0; i < 4; ++i) { - m_texCoords[i][0] = (i & 1 ? 1.0f : 0.0f); - m_texCoords[i][1] = (i & 2 ? 1.0f : 0.0f); - } - memset(m_normals, 0, sizeof(m_normals)); - for (int i = 0; i < 3; ++i) { - m_normals[2 * i + 0][i] = -1.0f; - m_normals[2 * i + 1][i] = 1.0f; + m_texCoords[i].setX(i & 1 ? 1.0f : 0.0f); + m_texCoords[i].setY(i & 2 ? 1.0f : 0.0f); } + m_normals[0] = QVector3D(-1.0f, 0.0f, 0.0f); + m_normals[1] = QVector3D(1.0f, 0.0f, 0.0f); + m_normals[2] = QVector3D(0.0f, -1.0f, 0.0f); + m_normals[3] = QVector3D(0.0f, 1.0f, 0.0f); + m_normals[4] = QVector3D(0.0f, 0.0f, -1.0f); + m_normals[5] = QVector3D(0.0f, 0.0f, 1.0f); } QtBox::~QtBox() @@ -351,21 +352,21 @@ void QtBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWi glColor4f(1.0f, 1.0f, 1.0f, 1.0); glBegin(GL_TRIANGLE_STRIP); - glNormal3fv(m_normals[2 * dir + 0].bits()); + glNormal3fv(reinterpret_cast<float *>(&m_normals[2 * dir + 0])); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { - glTexCoord2fv(m_texCoords[(j << 1) | i].bits()); - glVertex3fv(m_vertices[(i << ((dir + 2) % 3)) | (j << ((dir + 1) % 3))].bits()); + glTexCoord2fv(reinterpret_cast<float *>(&m_texCoords[(j << 1) | i])); + glVertex3fv(reinterpret_cast<float *>(&m_vertices[(i << ((dir + 2) % 3)) | (j << ((dir + 1) % 3))])); } } glEnd(); glBegin(GL_TRIANGLE_STRIP); - glNormal3fv(m_normals[2 * dir + 1].bits()); + glNormal3fv(reinterpret_cast<float *>(&m_normals[2 * dir + 1])); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { - glTexCoord2fv(m_texCoords[(j << 1) | i].bits()); - glVertex3fv(m_vertices[(1 << dir) | (i << ((dir + 1) % 3)) | (j << ((dir + 2) % 3))].bits()); + glTexCoord2fv(reinterpret_cast<float *>(&m_texCoords[(j << 1) | i])); + glVertex3fv(reinterpret_cast<float *>(&m_vertices[(1 << dir) | (i << ((dir + 1) % 3)) | (j << ((dir + 2) % 3))])); } } glEnd(); diff --git a/demos/boxes/qtbox.h b/demos/boxes/qtbox.h index aae8256..5042077 100644 --- a/demos/boxes/qtbox.h +++ b/demos/boxes/qtbox.h @@ -44,7 +44,7 @@ #include <QtGui> -#include "vector.h" +#include <QtGui/qvector3d.h> #include "glbuffers.h" class ItemBase : public QObject, public QGraphicsItem @@ -85,9 +85,9 @@ public: protected: virtual ItemBase *createNew(int size, int x, int y); private: - gfx::Vector3f m_vertices[8]; - gfx::Vector2f m_texCoords[4]; - gfx::Vector3f m_normals[6]; + QVector3D m_vertices[8]; + QVector3D m_texCoords[4]; + QVector3D m_normals[6]; GLTexture *m_texture; }; diff --git a/demos/boxes/roundedbox.cpp b/demos/boxes/roundedbox.cpp index f238da2..93ebce7 100644 --- a/demos/boxes/roundedbox.cpp +++ b/demos/boxes/roundedbox.cpp @@ -46,9 +46,10 @@ //============================================================================// VertexDescription P3T2N3Vertex::description[] = { - {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, position) / sizeof(float), offsetof(P3T2N3Vertex, position), 0}, - {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, texCoord) / sizeof(float), offsetof(P3T2N3Vertex, texCoord), 0}, - {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, normal) / sizeof(float), offsetof(P3T2N3Vertex, normal), 0}, + {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, position) / sizeof(float), 0, 0}, + {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, texCoord) / sizeof(float), sizeof(QVector3D), 0}, + {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, normal) / sizeof(float), sizeof(QVector3D) + sizeof(QVector2D), 0}, + {VertexDescription::Null, 0, 0, 0, 0}, }; @@ -78,10 +79,9 @@ GLRoundedBox::GLRoundedBox(float r, float scale, int n) } for (int corner = 0; corner < 8; ++corner) { - gfx::Vector3f centre; - centre[0] = (corner & 1 ? 1.0f : -1.0f); - centre[1] = (corner & 2 ? 1.0f : -1.0f); - centre[2] = (corner & 4 ? 1.0f : -1.0f); + QVector3D centre(corner & 1 ? 1.0f : -1.0f, + corner & 2 ? 1.0f : -1.0f, + corner & 4 ? 1.0f : -1.0f); int winding = (corner & 1) ^ ((corner >> 1) & 1) ^ (corner >> 2); int offsX = ((corner ^ 1) - corner) * vertexCountPerCorner; int offsY = ((corner ^ 2) - corner) * vertexCountPerCorner; @@ -129,12 +129,13 @@ GLRoundedBox::GLRoundedBox(float r, float scale, int n) } for (int j = 0; j <= i; ++j) { - gfx::Vector3f normal = gfx::Vector3f::vector(i - j, j, n + 1 - i).normalized(); - gfx::Vector3f pos = centre * (0.5f - r + r * normal); + QVector3D normal = QVector3D(i - j, j, n + 1 - i).normalized(); + QVector3D offset(0.5f - r, 0.5f - r, 0.5f - r); + QVector3D pos = centre * (offset + r * normal); vp[vidx].position = scale * pos; vp[vidx].normal = centre * normal; - vp[vidx].texCoord = gfx::Vector2f::vector(pos[0], pos[1]) + 0.5f; + vp[vidx].texCoord = QVector2D(pos.x() + 0.5f, pos.y() + 0.5f); // Corner polygons if (i < n + 1) { diff --git a/demos/boxes/roundedbox.h b/demos/boxes/roundedbox.h index b934ade..65b545e 100644 --- a/demos/boxes/roundedbox.h +++ b/demos/boxes/roundedbox.h @@ -49,14 +49,15 @@ #include <QtOpenGL> #include "gltrianglemesh.h" -#include "vector.h" +#include <QtGui/qvector3d.h> +#include <QtGui/qvector2d.h> #include "glbuffers.h" struct P3T2N3Vertex { - gfx::Vector3f position; - gfx::Vector2f texCoord; - gfx::Vector3f normal; + QVector3D position; + QVector2D texCoord; + QVector3D normal; static VertexDescription description[]; }; diff --git a/demos/boxes/scene.cpp b/demos/boxes/scene.cpp index 5f1fe14..e2aa16b 100644 --- a/demos/boxes/scene.cpp +++ b/demos/boxes/scene.cpp @@ -39,7 +39,10 @@ ** ****************************************************************************/ +#include <QDebug> #include "scene.h" +#include <QtGui/qmatrix4x4.h> +#include <QtGui/qvector3d.h> #include "3rdparty/fbm.h" @@ -484,9 +487,9 @@ Scene::Scene(int width, int height, int maxTextureSize) { setSceneRect(0, 0, width, height); - m_trackBalls[0] = TrackBall(0.0005f, gfx::Vector3f::vector(0, 1, 0), TrackBall::Sphere); - m_trackBalls[1] = TrackBall(0.0001f, gfx::Vector3f::vector(0, 0, 1), TrackBall::Sphere); - m_trackBalls[2] = TrackBall(0.0f, gfx::Vector3f::vector(0, 1, 0), TrackBall::Plane); + m_trackBalls[0] = TrackBall(0.05f, QVector3D(0, 1, 0), TrackBall::Sphere); + m_trackBalls[1] = TrackBall(0.005f, QVector3D(0, 0, 1), TrackBall::Sphere); + m_trackBalls[2] = TrackBall(0.0f, QVector3D(0, 1, 0), TrackBall::Plane); m_renderOptions = new RenderOptionsDialog; m_renderOptions->move(20, 120); @@ -620,11 +623,11 @@ void Scene::initGL() if (!program->link()) { qWarning("Failed to compile and link shader program"); qWarning("Vertex shader log:"); - qWarning() << m_vertexShader->errors(); + qWarning() << m_vertexShader->log(); qWarning() << "Fragment shader log ( file =" << file.absoluteFilePath() << "):"; - qWarning() << shader->errors(); + qWarning() << shader->log(); qWarning("Shader program log:"); - qWarning() << program->errors(); + qWarning() << program->log(); delete shader; delete program; @@ -648,9 +651,9 @@ void Scene::initGL() // If one of the boxes should not be rendered, set excludeBox to its index. // If the main box should not be rendered, set excludeBox to -1. -void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) +void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) { - gfx::Matrix4x4f invView = view.inverse(); + QMatrix4x4 invView = view.inverted(); // If multi-texturing is supported, use three saplers. if (glActiveTexture) { @@ -666,11 +669,11 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); - gfx::Matrix4x4f viewRotation(view); + QMatrix4x4 viewRotation(view); viewRotation(3, 0) = viewRotation(3, 1) = viewRotation(3, 2) = 0.0f; viewRotation(0, 3) = viewRotation(1, 3) = viewRotation(2, 3) = 0.0f; viewRotation(3, 3) = 1.0f; - glLoadMatrixf(viewRotation.bits()); + glLoadMatrixf(viewRotation.data()); glScalef(20.0f, 20.0f, 20.0f); // Don't render the environment if the environment texture can't be set for the correct sampler. @@ -685,7 +688,7 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) m_environment->unbind(); } - glLoadMatrixf(view.bits()); + glLoadMatrixf(view.data()); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); @@ -695,9 +698,11 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) continue; glPushMatrix(); - gfx::Matrix4x4f m; - m_trackBalls[1].rotation().matrix(m); - glMultMatrixf(m.bits()); + QMatrix4x4 m; + m.rotate(m_trackBalls[1].rotation()); + m = m.transposed(); + + glMultMatrixf(m.data()); glRotatef(360.0f * i / m_programs.size(), 0.0f, 0.0f, 1.0f); glTranslatef(2.0f, 0.0f, 0.0f); @@ -713,12 +718,8 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) m_programs[i]->setUniformValue("tex", GLint(0)); m_programs[i]->setUniformValue("env", GLint(1)); m_programs[i]->setUniformValue("noise", GLint(2)); - QMatrix4x4 mview; - QMatrix4x4 minvview; - memcpy(mview.data(), view.bits(), sizeof(float) * 16); - memcpy(minvview.data(), invView.bits(), sizeof(float) * 16); - m_programs[i]->setUniformValue("view", mview); - m_programs[i]->setUniformValue("invView", minvview); + m_programs[i]->setUniformValue("view", view); + m_programs[i]->setUniformValue("invView", invView); m_box->draw(); m_programs[i]->disable(); @@ -732,9 +733,10 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) } if (-1 != excludeBox) { - gfx::Matrix4x4f m; - m_trackBalls[0].rotation().matrix(m); - glMultMatrixf(m.bits()); + QMatrix4x4 m; + m.rotate(m_trackBalls[0].rotation()); + m = m.transposed(); + glMultMatrixf(m.data()); if (glActiveTexture) { if (m_dynamicCubemap) @@ -747,12 +749,8 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) m_programs[m_currentShader]->setUniformValue("tex", GLint(0)); m_programs[m_currentShader]->setUniformValue("env", GLint(1)); m_programs[m_currentShader]->setUniformValue("noise", GLint(2)); - QMatrix4x4 mview; - QMatrix4x4 minvview; - memcpy(mview.data(), view.bits(), sizeof(float) * 16); - memcpy(minvview.data(), invView.bits(), sizeof(float) * 16); - m_programs[m_currentShader]->setUniformValue("view", mview); - m_programs[m_currentShader]->setUniformValue("invView", minvview); + m_programs[m_currentShader]->setUniformValue("view", view); + m_programs[m_currentShader]->setUniformValue("invView", invView); m_box->draw(); m_programs[m_currentShader]->disable(); @@ -839,31 +837,32 @@ void Scene::renderCubemaps() // To speed things up, only update the cubemaps for the small cubes every N frames. const int N = (m_updateAllCubemaps ? 1 : 3); - gfx::Matrix4x4f mat; + QMatrix4x4 mat; GLRenderTargetCube::getProjectionMatrix(mat, 0.1f, 100.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadMatrixf(mat.bits()); + glLoadMatrixf(mat.data()); glMatrixMode(GL_MODELVIEW); glPushMatrix(); - gfx::Vector3f center; + QVector3D center; for (int i = m_frame % N; i < m_cubemaps.size(); i += N) { if (0 == m_cubemaps[i]) continue; float angle = 2.0f * PI * i / m_cubemaps.size(); - center = m_trackBalls[1].rotation().transform(gfx::Vector3f::vector(cos(angle), sin(angle), 0)); + + center = m_trackBalls[1].rotation().rotateVector(QVector3D(cos(angle), sin(angle), 0.0f)); for (int face = 0; face < 6; ++face) { m_cubemaps[i]->begin(face); GLRenderTargetCube::getViewMatrix(mat, face); - gfx::Vector4f v = gfx::Vector4f::vector(-center[0], -center[1], -center[2], 1.0); - mat[3] = v * mat; + QVector4D v = QVector4D(-center.x(), -center.y(), -center.z(), 1.0); + mat.setColumn(3, v * mat); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderBoxes(mat, i); @@ -907,12 +906,9 @@ void Scene::drawBackground(QPainter *painter, const QRectF &) glMatrixMode(GL_MODELVIEW); - //gfx::Matrix4x4f view = gfx::Matrix4x4f::identity(); - //view(3, 2) -= 2.0f * exp(m_distExp / 1200.0f); - - gfx::Matrix4x4f view; - m_trackBalls[2].rotation().matrix(view); - view(3, 2) -= 2.0f * exp(m_distExp / 1200.0f); + QMatrix4x4 view; + view.rotate(m_trackBalls[2].rotation()); + view(2, 3) -= 2.0f * exp(m_distExp / 1200.0f); renderBoxes(view); defaultStates(); @@ -946,10 +942,10 @@ void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } if (event->buttons() & Qt::MidButton) { - m_trackBalls[2].move(pixelPosToViewPos(event->scenePos()), gfx::Quaternionf::identity()); + m_trackBalls[2].move(pixelPosToViewPos(event->scenePos()), QQuaternion()); event->accept(); } else { - m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), gfx::Quaternionf::identity()); + m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), QQuaternion()); } } @@ -970,7 +966,7 @@ void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) } if (event->buttons() & Qt::MidButton) { - m_trackBalls[2].push(pixelPosToViewPos(event->scenePos()), gfx::Quaternionf::identity()); + m_trackBalls[2].push(pixelPosToViewPos(event->scenePos()), QQuaternion()); event->accept(); } } @@ -992,7 +988,7 @@ void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } if (event->button() == Qt::MidButton) { - m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), gfx::Quaternionf::identity()); + m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), QQuaternion()); event->accept(); } } diff --git a/demos/boxes/scene.h b/demos/boxes/scene.h index c056739..48ecaba 100644 --- a/demos/boxes/scene.h +++ b/demos/boxes/scene.h @@ -50,13 +50,13 @@ #include "roundedbox.h" #include "gltrianglemesh.h" -#include "vector.h" #include "trackball.h" #include "glbuffers.h" #include "qtbox.h" #define PI 3.14159265358979 +class QMatrix4x4; class ParameterEdit : public QWidget { public: @@ -194,7 +194,7 @@ public slots: void setFloatParameter(const QString &name, float value); void newItem(ItemDialog::ItemType type); protected: - void renderBoxes(const gfx::Matrix4x4f &view, int excludeBox = -2); + void renderBoxes(const QMatrix4x4 &view, int excludeBox = -2); void setStates(); void setLights(); void defaultStates(); @@ -237,6 +237,4 @@ private: QGLShaderProgram *m_environmentProgram; }; - - #endif diff --git a/demos/boxes/trackball.cpp b/demos/boxes/trackball.cpp index 980f6ed..a8bfe44 100644 --- a/demos/boxes/trackball.cpp +++ b/demos/boxes/trackball.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "trackball.h" +#include "scene.h" //============================================================================// // TrackBall // @@ -51,23 +52,23 @@ TrackBall::TrackBall(TrackMode mode) , m_pressed(false) , m_mode(mode) { - m_axis = gfx::Vector3f::vector(0, 1, 0); - m_rotation = gfx::Quaternionf::quaternion(1.0f, 0.0f, 0.0f, 0.0f); + m_axis = QVector3D(0, 1, 0); + m_rotation = QQuaternion(); m_lastTime = QTime::currentTime(); } -TrackBall::TrackBall(float angularVelocity, const gfx::Vector3f& axis, TrackMode mode) +TrackBall::TrackBall(float angularVelocity, const QVector3D& axis, TrackMode mode) : m_axis(axis) , m_angularVelocity(angularVelocity) , m_paused(false) , m_pressed(false) , m_mode(mode) { - m_rotation = gfx::Quaternionf::quaternion(1.0f, 0.0f, 0.0f, 0.0f); + m_rotation = QQuaternion(); m_lastTime = QTime::currentTime(); } -void TrackBall::push(const QPointF& p, const gfx::Quaternionf &) +void TrackBall::push(const QPointF& p, const QQuaternion &) { m_rotation = rotation(); m_pressed = true; @@ -76,7 +77,7 @@ void TrackBall::push(const QPointF& p, const gfx::Quaternionf &) m_angularVelocity = 0.0f; } -void TrackBall::move(const QPointF& p, const gfx::Quaternionf &transformation) +void TrackBall::move(const QPointF& p, const QQuaternion &transformation) { if (!m_pressed) return; @@ -90,44 +91,45 @@ void TrackBall::move(const QPointF& p, const gfx::Quaternionf &transformation) case Plane: { QLineF delta(m_lastPos, p); - m_angularVelocity = delta.length() / msecs; - m_axis = gfx::Vector3f::vector(delta.dy(), -delta.dx(), 0.0f).normalized(); - m_axis = transformation.transform(m_axis); - m_rotation *= gfx::Quaternionf::rotation(delta.length(), m_axis); + m_angularVelocity = 180*delta.length() / (PI*msecs); + m_axis = QVector3D(delta.dy(), -delta.dx(), 0.0f).normalized(); + m_axis = transformation.rotateVector(m_axis); + m_rotation *= QQuaternion::fromAxisAndAngle(m_axis, delta.length()); } break; case Sphere: { - gfx::Vector3f lastPos3D = gfx::Vector3f::vector(m_lastPos.x(), m_lastPos.y(), 0); - float sqrZ = 1 - lastPos3D.sqrNorm(); + QVector3D lastPos3D = QVector3D(m_lastPos.x(), m_lastPos.y(), 0.0f); + float sqrZ = 1 - QVector3D::dotProduct(lastPos3D, lastPos3D); if (sqrZ > 0) - lastPos3D[2] = sqrt(sqrZ); + lastPos3D.setZ(sqrt(sqrZ)); else lastPos3D.normalize(); - gfx::Vector3f currentPos3D = gfx::Vector3f::vector(p.x(), p.y(), 0); - sqrZ = 1 - currentPos3D.sqrNorm(); + QVector3D currentPos3D = QVector3D(p.x(), p.y(), 0.0f); + sqrZ = 1 - QVector3D::dotProduct(currentPos3D, currentPos3D); if (sqrZ > 0) - currentPos3D[2] = sqrt(sqrZ); + currentPos3D.setZ(sqrt(sqrZ)); else currentPos3D.normalize(); - m_axis = gfx::Vector3f::cross(currentPos3D, lastPos3D); - float angle = asin(sqrt(m_axis.sqrNorm())); + m_axis = QVector3D::crossProduct(currentPos3D, lastPos3D); + float angle = asin(sqrt(QVector3D::dotProduct(m_axis, m_axis))); - m_angularVelocity = angle / msecs; + m_angularVelocity = 180*angle / (PI*msecs); m_axis.normalize(); - m_axis = transformation.transform(m_axis); - m_rotation *= gfx::Quaternionf::rotation(angle, m_axis); + m_axis = transformation.rotateVector(m_axis); + m_rotation *= QQuaternion::fromAxisAndAngle(m_axis, angle); } break; } + m_lastPos = p; m_lastTime = currentTime; } -void TrackBall::release(const QPointF& p, const gfx::Quaternionf &transformation) +void TrackBall::release(const QPointF& p, const QQuaternion &transformation) { // Calling move() caused the rotation to stop if the framerate was too low. move(p, transformation); @@ -146,13 +148,13 @@ void TrackBall::stop() m_paused = true; } -gfx::Quaternionf TrackBall::rotation() const +QQuaternion TrackBall::rotation() const { if (m_paused || m_pressed) return m_rotation; QTime currentTime = QTime::currentTime(); float angle = m_angularVelocity * m_lastTime.msecsTo(currentTime); - return m_rotation * gfx::Quaternionf::rotation(angle, m_axis); + return m_rotation * QQuaternion::fromAxisAndAngle(m_axis, angle); } diff --git a/demos/boxes/trackball.h b/demos/boxes/trackball.h index 5e3f40c..66e9b68 100644 --- a/demos/boxes/trackball.h +++ b/demos/boxes/trackball.h @@ -44,7 +44,8 @@ #include <QtGui> -#include "vector.h" +#include <QtGui/qvector3d.h> +#include <QtGui/qquaternion.h> class TrackBall { @@ -55,17 +56,17 @@ public: Sphere, }; TrackBall(TrackMode mode = Sphere); - TrackBall(float angularVelocity, const gfx::Vector3f& axis, TrackMode mode = Sphere); + TrackBall(float angularVelocity, const QVector3D& axis, TrackMode mode = Sphere); // coordinates in [-1,1]x[-1,1] - void push(const QPointF& p, const gfx::Quaternionf &transformation); - void move(const QPointF& p, const gfx::Quaternionf &transformation); - void release(const QPointF& p, const gfx::Quaternionf &transformation); + void push(const QPointF& p, const QQuaternion &transformation); + void move(const QPointF& p, const QQuaternion &transformation); + void release(const QPointF& p, const QQuaternion &transformation); void start(); // starts clock void stop(); // stops clock - gfx::Quaternionf rotation() const; + QQuaternion rotation() const; private: - gfx::Quaternionf m_rotation; - gfx::Vector3f m_axis; + QQuaternion m_rotation; + QVector3D m_axis; float m_angularVelocity; QPointF m_lastPos; diff --git a/demos/boxes/vector.h b/demos/boxes/vector.h deleted file mode 100644 index bb24531..0000000 --- a/demos/boxes/vector.h +++ /dev/null @@ -1,602 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VECTOR_H -#define VECTOR_H - -#include <cassert> -#include <cmath> -#include <iostream> - -namespace gfx -{ - -template<class T, int n> -struct Vector -{ - // Keep the Vector struct a plain old data (POD) struct by avoiding constructors - - static Vector vector(T x) - { - Vector result; - for (int i = 0; i < n; ++i) - result.v[i] = x; - return result; - } - - // Use only for 2D vectors - static Vector vector(T x, T y) - { - assert(n == 2); - Vector result; - result.v[0] = x; - result.v[1] = y; - return result; - } - - // Use only for 3D vectors - static Vector vector(T x, T y, T z) - { - assert(n == 3); - Vector result; - result.v[0] = x; - result.v[1] = y; - result.v[2] = z; - return result; - } - - // Use only for 4D vectors - static Vector vector(T x, T y, T z, T w) - { - assert(n == 4); - Vector result; - result.v[0] = x; - result.v[1] = y; - result.v[2] = z; - result.v[3] = w; - return result; - } - - // Pass 'n' arguments to this function. - static Vector vector(T *v) - { - Vector result; - for (int i = 0; i < n; ++i) - result.v[i] = v[i]; - return result; - } - - T &operator [] (int i) {return v[i];} - T operator [] (int i) const {return v[i];} - -#define VECTOR_BINARY_OP(op, arg, rhs) \ - Vector operator op (arg) const \ - { \ - Vector result; \ - for (int i = 0; i < n; ++i) \ - result.v[i] = v[i] op rhs; \ - return result; \ - } - - VECTOR_BINARY_OP(+, const Vector &u, u.v[i]) - VECTOR_BINARY_OP(-, const Vector &u, u.v[i]) - VECTOR_BINARY_OP(*, const Vector &u, u.v[i]) - VECTOR_BINARY_OP(/, const Vector &u, u.v[i]) - VECTOR_BINARY_OP(+, T s, s) - VECTOR_BINARY_OP(-, T s, s) - VECTOR_BINARY_OP(*, T s, s) - VECTOR_BINARY_OP(/, T s, s) -#undef VECTOR_BINARY_OP - - Vector operator - () const - { - Vector result; - for (int i = 0; i < n; ++i) - result.v[i] = -v[i]; - return result; - } - -#define VECTOR_ASSIGN_OP(op, arg, rhs) \ - Vector &operator op (arg) \ - { \ - for (int i = 0; i < n; ++i) \ - v[i] op rhs; \ - return *this; \ - } - - VECTOR_ASSIGN_OP(+=, const Vector &u, u.v[i]) - VECTOR_ASSIGN_OP(-=, const Vector &u, u.v[i]) - VECTOR_ASSIGN_OP(=, T s, s) - VECTOR_ASSIGN_OP(*=, T s, s) - VECTOR_ASSIGN_OP(/=, T s, s) -#undef VECTOR_ASSIGN_OP - - static T dot(const Vector &u, const Vector &v) - { - T sum(0); - for (int i = 0; i < n; ++i) - sum += u.v[i] * v.v[i]; - return sum; - } - - static Vector cross(const Vector &u, const Vector &v) - { - assert(n == 3); - return vector(u.v[1] * v.v[2] - u.v[2] * v.v[1], - u.v[2] * v.v[0] - u.v[0] * v.v[2], - u.v[0] * v.v[1] - u.v[1] * v.v[0]); - } - - T sqrNorm() const - { - return dot(*this, *this); - } - - // requires floating point type T - void normalize() - { - T s = sqrNorm(); - if (s != 0) - *this /= sqrt(s); - } - - // requires floating point type T - Vector normalized() const - { - T s = sqrNorm(); - if (s == 0) - return *this; - return *this / sqrt(s); - } - - T *bits() {return v;} - const T *bits() const {return v;} - - T v[n]; -}; - -#define SCALAR_VECTOR_BINARY_OP(op) \ -template<class T, int n> \ -Vector<T, n> operator op (T s, const Vector<T, n>& u) \ -{ \ - Vector<T, n> result; \ - for (int i = 0; i < n; ++i) \ - result[i] = s op u[i]; \ - return result; \ -} - -SCALAR_VECTOR_BINARY_OP(+) -SCALAR_VECTOR_BINARY_OP(-) -SCALAR_VECTOR_BINARY_OP(*) -SCALAR_VECTOR_BINARY_OP(/) -#undef SCALAR_VECTOR_BINARY_OP - -template<class T, int n> -std::ostream &operator << (std::ostream &os, const Vector<T, n> &v) -{ - assert(n > 0); - os << "[" << v[0]; - for (int i = 1; i < n; ++i) - os << ", " << v[i]; - os << "]"; - return os; -} - -typedef Vector<float, 2> Vector2f; -typedef Vector<float, 3> Vector3f; -typedef Vector<float, 4> Vector4f; - -template<class T, int rows, int cols> -struct Matrix -{ - // Keep the Matrix struct a plain old data (POD) struct by avoiding constructors - - static Matrix matrix(T x) - { - Matrix result; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) - result.v[i][j] = x; - } - return result; - } - - static Matrix matrix(T *m) - { - Matrix result; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - result.v[i][j] = *m; - ++m; - } - } - return result; - } - - T &operator () (int i, int j) {return v[i][j];} - T operator () (int i, int j) const {return v[i][j];} - Vector<T, cols> &operator [] (int i) {return v[i];} - const Vector<T, cols> &operator [] (int i) const {return v[i];} - - // TODO: operators, methods - - Vector<T, rows> operator * (const Vector<T, cols> &u) const - { - Vector<T, rows> result; - for (int i = 0; i < rows; ++i) - result[i] = Vector<T, cols>::dot(v[i], u); - return result; - } - - template<int k> - Matrix<T, rows, k> operator * (const Matrix<T, cols, k> &m) - { - Matrix<T, rows, k> result; - for (int i = 0; i < rows; ++i) - result[i] = v[i] * m; - return result; - } - - T* bits() {return reinterpret_cast<T *>(this);} - const T* bits() const {return reinterpret_cast<const T *>(this);} - - // Simple Gauss elimination. - // TODO: Optimize and improve stability. - Matrix inverse(bool *ok = 0) const - { - assert(rows == cols); - Matrix rhs = identity(); - Matrix lhs(*this); - T temp; - // Down - for (int i = 0; i < rows; ++i) { - // Pivoting - int pivot = i; - for (int j = i; j < rows; ++j) { - if (qAbs(lhs(j, i)) > lhs(pivot, i)) - pivot = j; - } - // TODO: fuzzy compare. - if (lhs(pivot, i) == T(0)) { - if (ok) - *ok = false; - return rhs; - } - if (pivot != i) { - for (int j = i; j < cols; ++j) { - temp = lhs(pivot, j); - lhs(pivot, j) = lhs(i, j); - lhs(i, j) = temp; - } - for (int j = 0; j < cols; ++j) { - temp = rhs(pivot, j); - rhs(pivot, j) = rhs(i, j); - rhs(i, j) = temp; - } - } - - // Normalize i-th row - rhs[i] /= lhs(i, i); - for (int j = cols - 1; j > i; --j) - lhs(i, j) /= lhs(i, i); - - // Eliminate non-zeros in i-th column below the i-th row. - for (int j = i + 1; j < rows; ++j) { - rhs[j] -= lhs(j, i) * rhs[i]; - for (int k = i + 1; k < cols; ++k) - lhs(j, k) -= lhs(j, i) * lhs(i, k); - } - } - // Up - for (int i = rows - 1; i > 0; --i) { - for (int j = i - 1; j >= 0; --j) - rhs[j] -= lhs(j, i) * rhs[i]; - } - if (ok) - *ok = true; - return rhs; - } - - Matrix<T, cols, rows> transpose() const - { - Matrix<T, cols, rows> result; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) - result.v[j][i] = v[i][j]; - } - return result; - } - - static Matrix identity() - { - Matrix result = matrix(T(0)); - for (int i = 0; i < rows && i < cols; ++i) - result.v[i][i] = T(1); - return result; - } - - Vector<T, cols> v[rows]; -}; - -template<class T, int rows, int cols> -Vector<T, cols> operator * (const Vector<T, rows> &u, const Matrix<T, rows, cols> &m) -{ - Vector<T, cols> result = Vector<T, cols>::vector(T(0)); - for (int i = 0; i < rows; ++i) - result += m[i] * u[i]; - return result; -} - -template<class T, int rows, int cols> -std::ostream &operator << (std::ostream &os, const Matrix<T, rows, cols> &m) -{ - assert(rows > 0); - os << "[" << m[0]; - for (int i = 1; i < rows; ++i) - os << ", " << m[i]; - os << "]"; - return os; -} - - -typedef Matrix<float, 2, 2> Matrix2x2f; -typedef Matrix<float, 3, 3> Matrix3x3f; -typedef Matrix<float, 4, 4> Matrix4x4f; - -template<class T> -struct Quaternion -{ - // Keep the Quaternion struct a plain old data (POD) struct by avoiding constructors - - static Quaternion quaternion(T s, T x, T y, T z) - { - Quaternion result; - result.scalar = s; - result.vector[0] = x; - result.vector[1] = y; - result.vector[2] = z; - return result; - } - - static Quaternion quaternion(T s, const Vector<T, 3> &v) - { - Quaternion result; - result.scalar = s; - result.vector = v; - return result; - } - - static Quaternion identity() - { - return quaternion(T(1), T(0), T(0), T(0)); - } - - // assumes that all the elements are packed tightly - T& operator [] (int i) {return reinterpret_cast<T *>(this)[i];} - T operator [] (int i) const {return reinterpret_cast<const T *>(this)[i];} - -#define QUATERNION_BINARY_OP(op, arg, rhs) \ - Quaternion operator op (arg) const \ - { \ - Quaternion result; \ - for (int i = 0; i < 4; ++i) \ - result[i] = (*this)[i] op rhs; \ - return result; \ - } - - QUATERNION_BINARY_OP(+, const Quaternion &q, q[i]) - QUATERNION_BINARY_OP(-, const Quaternion &q, q[i]) - QUATERNION_BINARY_OP(*, T s, s) - QUATERNION_BINARY_OP(/, T s, s) -#undef QUATERNION_BINARY_OP - - Quaternion operator - () const - { - return Quaternion(-scalar, -vector); - } - - Quaternion operator * (const Quaternion &q) const - { - Quaternion result; - result.scalar = scalar * q.scalar - Vector<T, 3>::dot(vector, q.vector); - result.vector = scalar * q.vector + vector * q.scalar + Vector<T, 3>::cross(vector, q.vector); - return result; - } - - Quaternion operator * (const Vector<T, 3> &v) const - { - Quaternion result; - result.scalar = -Vector<T, 3>::dot(vector, v); - result.vector = scalar * v + Vector<T, 3>::cross(vector, v); - return result; - } - - friend Quaternion operator * (const Vector<T, 3> &v, const Quaternion &q) - { - Quaternion result; - result.scalar = -Vector<T, 3>::dot(v, q.vector); - result.vector = v * q.scalar + Vector<T, 3>::cross(v, q.vector); - return result; - } - -#define QUATERNION_ASSIGN_OP(op, arg, rhs) \ - Quaternion &operator op (arg) \ - { \ - for (int i = 0; i < 4; ++i) \ - (*this)[i] op rhs; \ - return *this; \ - } - - QUATERNION_ASSIGN_OP(+=, const Quaternion &q, q[i]) - QUATERNION_ASSIGN_OP(-=, const Quaternion &q, q[i]) - QUATERNION_ASSIGN_OP(=, T s, s) - QUATERNION_ASSIGN_OP(*=, T s, s) - QUATERNION_ASSIGN_OP(/=, T s, s) -#undef QUATERNION_ASSIGN_OP - - Quaternion& operator *= (const Quaternion &q) - { - Quaternion result; - result.scalar = scalar * q.scalar - Vector<T, 3>::dot(vector, q.vector); - result.vector = scalar * q.vector + vector * q.scalar + Vector<T, 3>::cross(vector, q.vector); - return (*this = result); - } - - Quaternion& operator *= (const Vector<T, 3> &v) - { - Quaternion result; - result.scalar = -Vector<T, 3>::dot(vector, v); - result.vector = scalar * v + Vector<T, 3>::cross(vector, v); - return (*this = result); - } - - Quaternion conjugate() const - { - return quaternion(scalar, -vector); - } - - T sqrNorm() const - { - return scalar * scalar + vector.sqrNorm(); - } - - Quaternion inverse() const - { - return conjugate() / sqrNorm(); - } - - // requires floating point type T - Quaternion normalized() const - { - T s = sqrNorm(); - if (s == 0) - return *this; - return *this / sqrt(s); - } - - void matrix(Matrix<T, 3, 3>& m) const - { - T bb = vector[0] * vector[0]; - T cc = vector[1] * vector[1]; - T dd = vector[2] * vector[2]; - T diag = scalar * scalar - bb - cc - dd; - T ab = scalar * vector[0]; - T ac = scalar * vector[1]; - T ad = scalar * vector[2]; - T bc = vector[0] * vector[1]; - T cd = vector[1] * vector[2]; - T bd = vector[2] * vector[0]; - m(0, 0) = diag + 2 * bb; - m(0, 1) = 2 * (bc - ad); - m(0, 2) = 2 * (ac + bd); - m(1, 0) = 2 * (ad + bc); - m(1, 1) = diag + 2 * cc; - m(1, 2) = 2 * (cd - ab); - m(2, 0) = 2 * (bd - ac); - m(2, 1) = 2 * (ab + cd); - m(2, 2) = diag + 2 * dd; - } - - void matrix(Matrix<T, 4, 4>& m) const - { - T bb = vector[0] * vector[0]; - T cc = vector[1] * vector[1]; - T dd = vector[2] * vector[2]; - T diag = scalar * scalar - bb - cc - dd; - T ab = scalar * vector[0]; - T ac = scalar * vector[1]; - T ad = scalar * vector[2]; - T bc = vector[0] * vector[1]; - T cd = vector[1] * vector[2]; - T bd = vector[2] * vector[0]; - m(0, 0) = diag + 2 * bb; - m(0, 1) = 2 * (bc - ad); - m(0, 2) = 2 * (ac + bd); - m(0, 3) = 0; - m(1, 0) = 2 * (ad + bc); - m(1, 1) = diag + 2 * cc; - m(1, 2) = 2 * (cd - ab); - m(1, 3) = 0; - m(2, 0) = 2 * (bd - ac); - m(2, 1) = 2 * (ab + cd); - m(2, 2) = diag + 2 * dd; - m(2, 3) = 0; - m(3, 0) = 0; - m(3, 1) = 0; - m(3, 2) = 0; - m(3, 3) = 1; - } - - // assumes that 'this' is normalized - Vector<T, 3> transform(const Vector<T, 3> &v) const - { - Matrix<T, 3, 3> m; - matrix(m); - return v * m; - } - - // assumes that all the elements are packed tightly - T* bits() {return reinterpret_cast<T *>(this);} - const T* bits() const {return reinterpret_cast<const T *>(this);} - - // requires floating point type T - static Quaternion rotation(T angle, const Vector<T, 3> &unitAxis) - { - T s = sin(angle / 2); - T c = cos(angle / 2); - return quaternion(c, unitAxis * s); - } - - T scalar; - Vector<T, 3> vector; -}; - -template<class T> -Quaternion<T> operator * (T s, const Quaternion<T>& q) -{ - return Quaternion<T>::quaternion(s * q.scalar, s * q.vector); -} - -typedef Quaternion<float> Quaternionf; - -} // end namespace gfx - -#endif diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/content/ImageDetails.qml new file mode 100644 index 0000000..7b16831 --- /dev/null +++ b/demos/declarative/flickr/content/ImageDetails.qml @@ -0,0 +1,103 @@ +Flipable { + id: Container + + property var frontContainer: ContainerFront + property var flickableArea: Flickable + property var fullScreenArea: BigImage + property string photoTitle: "" + property string photoDescription: "" + property int photoWidth + property int photoHeight + property string photoType + property string photoAuthor + property string photoDate + property string photoUrl + property int rating: 2 + + signal closed + + axis: Axis { startX: Container.width / 2; endX: Container.width / 2; endY: 1 } + + front: Item { + id: ContainerFront; anchors.fill: Container + + Rect { + anchors.fill: parent + color: "black"; opacity: 0.4 + pen.color: "white"; pen.width: 2 + } + + MediaButton { + id: BackButton; x: 630; y: 370; text: "Back" + onClicked: { Container.closed.emit() } + } + + MediaButton { + id: MoreButton; x: 530; y: 370; text: "View..." + onClicked: { Container.state='Back' } + } + + Text { id: TitleText; style: "Raised"; styleColor: "black"; color: "white"; elide: "ElideRight" + x: 220; y: 30; width: parent.width - 240; text: Container.photoTitle; font.size: 22 } + + LikeOMeter { x: 40; y: 250; rating: Container.rating } + + Flickable { id: Flickable; x: 220; width: 480; height: 230; y: 120; clip: true + viewportWidth: 480; viewportHeight: DescriptionText.height + + WebView { id: DescriptionText; width: parent.width + html: "<style TYPE=\"text/css\">body {color: white;} a:link {color: cyan; text-decoration: underline; }</style>" + Container.photoDescription } + } + + Text { id: Size; color: "white"; width: 300; x: 40; y: 300 + text: "<b>Size:</b> " + Container.photoWidth + 'x' + Container.photoHeight } + Text { id: Type; color: "white"; width: 300; x: 40; anchors.top: Size.bottom + text: "<b>Type:</b> " + Container.photoType } + + Text { id: Author; color: "white"; width: 300; x: 220; y: 80 + text: "<b>Author:</b> " + Container.photoAuthor } + Text { id: Date; color: "white"; width: 300; x: 220; anchors.top: Author.bottom + text: "<b>Published:</b> " + Container.photoDate } + + ScrollBar { id: ScrollBar; x: 720; y: Flickable.y; width: 7; height: Flickable.height; opacity: 0; + flickableArea: Flickable; clip: true } + } + + back: Item { + anchors.fill: Container + + Rect { anchors.fill: parent; color: "black"; opacity: 0.4; pen.color: "white"; pen.width: 2 } + + Loading { anchors.centeredIn: parent; visible: BigImage.status } + Flickable { + id: Flick; width: Container.width - 10; height: Container.height - 10 + x: 5; y: 5; clip: true; viewportWidth: (BigImage.width * BigImage.scale) + BigImage.x; + viewportHeight: BigImage.height * BigImage.scale + + Image { + id: BigImage; source: Container.photoUrl; scale: Slider.value + x:Math.max(0, ((Flick.width/2)-(width * scale / 2))); + y:Math.max(0, (Flick.height/2)-(height * scale / 2)); + } + } + + MediaButton { + id: BackButton2; x: 630; y: 370; text: "Back"; onClicked: { Container.state = '' } + } + + Slider { id: Slider; x: 25; y: 374; imageWidth: Container.photoWidth; imageHeight: Container.photoHeight } + } + + states: [ + State { + name: "Back" + SetProperty { target: Container; property: "rotation"; value: 180 } + } + ] + + transitions: [ + Transition { + NumericAnimation { easing: "easeInOutQuad"; properties: "rotation"; duration: 500 } + } + ] +} diff --git a/demos/declarative/flickr/content/LikeOMeter.qml b/demos/declarative/flickr/content/LikeOMeter.qml new file mode 100644 index 0000000..61317ae --- /dev/null +++ b/demos/declarative/flickr/content/LikeOMeter.qml @@ -0,0 +1,33 @@ +Item { + id: Container + + property int rating: 2 + + HorizontalLayout { + Star { + rating: 0 + onClicked: { Container.rating = rating } + on: Container.rating >= 0 + } + Star { + rating: 1 + onClicked: { Container.rating = rating } + on: Container.rating >= 1 + } + Star { + rating: 2 + onClicked: { Container.rating = rating } + on: Container.rating >= 2 + } + Star { + rating: 3 + onClicked: { Container.rating = rating } + on: Container.rating >= 3 + } + Star { + rating: 4 + onClicked: { Container.rating = rating } + on: Container.rating >= 4 + } + } +} diff --git a/demos/declarative/flickr/content/Loading.qml b/demos/declarative/flickr/content/Loading.qml new file mode 100644 index 0000000..cf27e38 --- /dev/null +++ b/demos/declarative/flickr/content/Loading.qml @@ -0,0 +1,6 @@ +Image { + id: Loading; source: "pics/loading.png"; transformOrigin: "Center" + rotation: NumericAnimation { + id: "RotationAnimation"; from: 0; to: 360; running:true; repeat: true; duration: 900 + } +} diff --git a/demos/declarative/flickr/content/MediaButton.qml b/demos/declarative/flickr/content/MediaButton.qml new file mode 100644 index 0000000..6392a13 --- /dev/null +++ b/demos/declarative/flickr/content/MediaButton.qml @@ -0,0 +1,39 @@ +Item { + id: Container + + signal clicked + + property string text + + Image { + id: Image + source: "pics/button.png" + } + Image { + id: Pressed + source: "pics/button-pressed.png" + opacity: 0 + } + MouseRegion { + id: MouseRegion + anchors.fill: Image + onClicked: { Container.clicked.emit(); } + } + Text { + font.bold: true + color: "white" + anchors.centeredIn: Image + text: Container.text + } + width: Image.width + states: [ + State { + name: "Pressed" + when: MouseRegion.pressed == true + SetProperties { + target: Pressed + opacity: 1 + } + } + ] +} diff --git a/demos/declarative/flickr/content/ScrollBar.qml b/demos/declarative/flickr/content/ScrollBar.qml new file mode 100644 index 0000000..2c4ff54 --- /dev/null +++ b/demos/declarative/flickr/content/ScrollBar.qml @@ -0,0 +1,38 @@ +Item { + id: Container + + property var flickableArea + + Rect { + radius: 5 + color: "black" + opacity: 0.3 + pen.color: "white" + pen.width: 2 + x: 0 + y: flickableArea.pageYPosition * Container.height + width: parent.width + height: flickableArea.pageHeight * Container.height + } + states: [ + State { + name: "show" + when: flickableArea.moving + SetProperties { + target: Container + opacity: 1 + } + } + ] + transitions: [ + Transition { + fromState: "*" + toState: "*" + NumericAnimation { + target: Container + properties: "opacity" + duration: 400 + } + } + ] +} diff --git a/demos/declarative/flickr/content/Slider.qml b/demos/declarative/flickr/content/Slider.qml new file mode 100644 index 0000000..ba9d842 --- /dev/null +++ b/demos/declarative/flickr/content/Slider.qml @@ -0,0 +1,24 @@ +Item { + id: Slider; width: 400; height: 16 + + property var value: Handle.x / Slider.xMax + property int xMax: Slider.width - Handle.width - 2 + property int imageWidth + property int imageHeight + + Rect { + id: Container; anchors.fill: parent; gradientColor: "#66000000"; + pen.color: "white"; pen.width: 1; color: "#66343434"; radius: 8 + } + + Rect { + id: Handle + x: Slider.width / 2 - Handle.width / 2; y: 2; width: 30; height: 12 + color: "lightgray"; gradientColor: "gray"; radius: 6 + + MouseRegion { + anchors.fill: parent; drag.target: parent + drag.axis: "x"; drag.xmin: 2; drag.xmax: Slider.xMax + } + } +} diff --git a/demos/declarative/flickr/content/Star.qml b/demos/declarative/flickr/content/Star.qml new file mode 100644 index 0000000..22fc138 --- /dev/null +++ b/demos/declarative/flickr/content/Star.qml @@ -0,0 +1,44 @@ +Item { + id: Container + width: 24 + height: 24 + + property string rating + property string on + + signal clicked + + Image { + id: Image + source: "pics/ghns_star.png" + x: 6 + y: 7 + opacity: 0.4 + scale: 0.5 + } + MouseRegion { + anchors.fill: Container + onClicked: { Container.clicked.emit() } + } + states: [ + State { + name: "on" + when: Container.on == true + SetProperties { + target: Image + opacity: 1 + scale: 1 + x: 1 + y: 0 + } + } + ] + transitions: [ + Transition { + NumericAnimation { + properties: "opacity,scale,x,y" + easing: "easeOutBounce" + } + } + ] +} diff --git a/demos/declarative/flickr/content/pics/background.png b/demos/declarative/flickr/content/pics/background.png Binary files differnew file mode 100644 index 0000000..5b37072 --- /dev/null +++ b/demos/declarative/flickr/content/pics/background.png diff --git a/demos/declarative/flickr/content/pics/button-pressed.png b/demos/declarative/flickr/content/pics/button-pressed.png Binary files differnew file mode 100644 index 0000000..e434d32 --- /dev/null +++ b/demos/declarative/flickr/content/pics/button-pressed.png diff --git a/demos/declarative/flickr/content/pics/button.png b/demos/declarative/flickr/content/pics/button.png Binary files differnew file mode 100644 index 0000000..56a63ce --- /dev/null +++ b/demos/declarative/flickr/content/pics/button.png diff --git a/demos/declarative/flickr/content/pics/ghns_star.png b/demos/declarative/flickr/content/pics/ghns_star.png Binary files differnew file mode 100644 index 0000000..4ad43cc --- /dev/null +++ b/demos/declarative/flickr/content/pics/ghns_star.png diff --git a/demos/declarative/flickr/content/pics/loading.png b/demos/declarative/flickr/content/pics/loading.png Binary files differnew file mode 100644 index 0000000..47a1589 --- /dev/null +++ b/demos/declarative/flickr/content/pics/loading.png diff --git a/demos/declarative/flickr/content/pics/reflection.png b/demos/declarative/flickr/content/pics/reflection.png Binary files differnew file mode 100644 index 0000000..c143a48 --- /dev/null +++ b/demos/declarative/flickr/content/pics/reflection.png diff --git a/demos/declarative/flickr/content/pics/shadow-bottom.png b/demos/declarative/flickr/content/pics/shadow-bottom.png Binary files differnew file mode 100644 index 0000000..523f6e7 --- /dev/null +++ b/demos/declarative/flickr/content/pics/shadow-bottom.png diff --git a/demos/declarative/flickr/content/pics/shadow-corner.png b/demos/declarative/flickr/content/pics/shadow-corner.png Binary files differnew file mode 100644 index 0000000..ef8c856 --- /dev/null +++ b/demos/declarative/flickr/content/pics/shadow-corner.png diff --git a/demos/declarative/flickr/content/pics/shadow-right-screen.png b/demos/declarative/flickr/content/pics/shadow-right-screen.png Binary files differnew file mode 100644 index 0000000..9856c4f --- /dev/null +++ b/demos/declarative/flickr/content/pics/shadow-right-screen.png diff --git a/demos/declarative/flickr/content/pics/shadow-right.png b/demos/declarative/flickr/content/pics/shadow-right.png Binary files differnew file mode 100644 index 0000000..f534a35 --- /dev/null +++ b/demos/declarative/flickr/content/pics/shadow-right.png diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr.qml new file mode 100644 index 0000000..0ff539d --- /dev/null +++ b/demos/declarative/flickr/flickr.qml @@ -0,0 +1,178 @@ +import "content" + +Item { + id: MainWindow; width: 800; height: 450 + + property bool showPathView : false + + resources: [ + XmlListModel { + id: FeedModel + source: "http://api.flickr.com/services/feeds/photos_public.gne?format=rss2" + query: "doc($src)/rss/channel/item" + namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" + + Role { name: "title"; query: "title/string()" } + Role { name: "imagePath"; query: "media:thumbnail/@url/string()" } + Role { name: "url"; query: "media:content/@url/string()" } + Role { name: "description"; query: "description/string()"; isCData: true } + Role { name: "photoWidth"; query: "media:content/@width/string()" } + Role { name: "photoHeight"; query: "media:content/@height/string()" } + Role { name: "photoType"; query: "media:content/@type/string()" } + Role { name: "photoAuthor"; query: "author/string()" } + Role { name: "photoDate"; query: "pubDate/string()" } + }, + + Component { + id: PhotoDelegate + Item { + id: Wrapper; width: 85; height: 85 + scale: Wrapper.PathView.scale; z: Wrapper.PathView.z + + transform: [ + Rotation3D { id: Rotation; axis.startX: 30; axis.endX: 30; axis.endY: 60; angle: Wrapper.PathView.angle } + ] + + Connection { + sender: ImageDetails; signal: "closed()" + script: { if (Wrapper.state == 'Details') Wrapper.state = '' } + } + + Script { + function photoClicked() { + ImageDetails.photoTitle = title; + ImageDetails.flickableArea.yPosition = 0; + ImageDetails.fullScreenArea.source = ""; + ImageDetails.photoDescription = description; + ImageDetails.photoWidth = photoWidth; + ImageDetails.photoHeight = photoHeight; + ImageDetails.photoType = photoType; + ImageDetails.photoAuthor = photoAuthor; + ImageDetails.photoDate = photoDate; + ImageDetails.photoUrl = url; + ImageDetails.rating = 0; + Wrapper.state = "Details"; + } + } + + Rect { + id: WhiteRect; anchors.fill: parent; color: "white"; radius: 5 + + Loading { x: 26; y: 26; visible: Thumb.status } + Image { id: Thumb; source: imagePath; x: 5; y: 5 } + + Item { + id: Shadows + Image { source: "content/pics/shadow-right.png"; x: WhiteRect.width; height: WhiteRect.height } + Image { source: "content/pics/shadow-bottom.png"; y: WhiteRect.height; width: WhiteRect.width } + Image { id: Corner; source: "content/pics/shadow-corner.png"; x: WhiteRect.width; y: WhiteRect.height } + } + } + + MouseRegion { anchors.fill: Wrapper; onClicked: { photoClicked() } } + + states: [ + State { + name: "Details" + ParentChange { target: Wrapper; parent: ImageDetails.frontContainer } + SetProperties { target: Wrapper; x: 45; y: 35; scale: 1 } + SetProperties { target: Rotation; angle: 0 } + SetProperties { target: Shadows; opacity: 0 } + SetProperties { target: ImageDetails; y: 20 } + SetProperties { target: PhotoGridView; y: "-480" } + SetProperties { target: PhotoPathView; y: "-480" } + SetProperties { target: CloseButton; opacity: 0 } + SetProperties { target: FetchButton; opacity: 0 } + SetProperties { target: CategoryText; y: "-50" } + } + ] + + transitions: [ + Transition { + fromState: "*"; toState: "*" + ParentChangeAction { } + NumericAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + } + ] + } + } + ] + + Item { + id: Background + + Image { source: "content/pics/background.png"; opaque: true } + + GridView { + id: PhotoGridView; model: FeedModel; delegate: PhotoDelegate + cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330 + } + + PathView { + id: PhotoPathView; model: FeedModel; delegate: PhotoDelegate + y: -380; width: 800; height: 330; pathItemCount: 10 + path: Path { + startX: -50; startY: 40; + + PathAttribute { name: "scale"; value: 1 } + PathAttribute { name: "angle"; value: -45 } + + PathCubic { + x: 400; y: 220 + control1X: 140; control1Y: 40 + control2X: 210; control2Y: 220 + } + + PathAttribute { name: "scale"; value: 1.2 } + PathAttribute { name: "z"; value: 1 } + PathAttribute { name: "angle"; value: 0 } + + PathCubic { + x: 850; y: 40 + control2X: 660; control2Y: 40 + control1X: 590; control1Y: 220 + } + + PathAttribute { name: "scale"; value: 1 } + PathAttribute { name: "angle"; value: 45 } + } + + } + + ImageDetails { id: ImageDetails; width: 750; x: 25; y: 500; height: 410 } + + MediaButton { + id: CloseButton; x: 680; y: 410; text: "View Mode" + onClicked: { if (MainWindow.showPathView == true) MainWindow.showPathView = false; else MainWindow.showPathView = true } + } + + MediaButton { + id: FetchButton + text: "Update" + anchors.right: CloseButton.left; anchors.rightMargin: 5 + anchors.top: CloseButton.top + onClicked: { FeedModel.fetch(); } + } + + states: [ + State { + name: "PathView" + when: MainWindow.showPathView == true + SetProperties { target: PhotoPathView; y: 80 } + SetProperties { target: PhotoGridView; y: -380 } + } + ] + + transitions: [ + Transition { + fromState: "*"; toState: "*" + NumericAnimation { properties: "y"; duration: 650; easing: "easeOutBounce(amplitude:0.1)" } + } + ] + } + + Text { + id: CategoryText; anchors.horizontalCenter: parent.horizontalCenter; y: 15; text: "Flickr - Uploads from everyone" + font.size: 16; font.bold: true; color: "white"; style: "Raised"; styleColor: "black" + } +} |