From 7825c0e89fffc1a41d71e5e7a791b10d3c182e32 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 7 May 2009 10:42:43 +1000 Subject: Use correct 'from' value for repeating animations. Each loop, we need to check whether the user has set a from value, and if not get the current value. --- doc/src/declarative/animation.qdoc | 17 ++++++----------- src/declarative/util/qmlanimation.cpp | 3 +++ src/declarative/util/qmlanimation_p.h | 14 +++++++++++--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index f7e03ee..f17f5c9 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -25,7 +25,7 @@ Other Features: \o Animation synchronization \endlist -The simplest form of animation is using \c NumericAnimation +The simplest form of animation is using \l NumericAnimation The following example creates a bouncing effect: \code @@ -34,20 +34,15 @@ Rect { width: 120; height: 200; color: "white" Image { id: img - source: "pics/qtlogo.png" + source: "qt-logo.png" x: 60-img.width/2 - y: 200-img.height + y: 0 y: SequentialAnimation { running: true repeat: true - NumericAnimation { - to: 200-img.height - easing: "easeOutBounce(amplitude:100)" - duration: 2000 - } - PauseAnimation { - duration: 1000 - } + NumericAnimation { to: 200-img.height; easing: "easeOutBounce"; duration: 2000 } + PauseAnimation { duration: 1000 } + NumericAnimation { to: 0; easing: "easeOutQuad"; duration: 1000 } } } } diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index 08a7a28..dd4e1eb 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -791,6 +791,7 @@ void QmlColorAnimation::prepare(QmlMetaProperty &p) d->fromSourced = false; d->value.QmlTimeLineValue::setValue(0.); d->ca->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped); + d->ca->setFromSourcedValue(&d->fromSourced); } QAbstractAnimation *QmlColorAnimation::qtAnimation() @@ -1595,6 +1596,7 @@ void QmlNumericAnimation::prepare(QmlMetaProperty &p) d->fromSourced = false; d->value.QmlTimeLineValue::setValue(0.); d->na->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped); + d->na->setFromSourcedValue(&d->fromSourced); } QAbstractAnimation *QmlNumericAnimation::qtAnimation() @@ -2152,6 +2154,7 @@ void QmlVariantAnimation::prepare(QmlMetaProperty &p) d->fromSourced = false; d->value.QmlTimeLineValue::setValue(0.); d->va->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped); + d->va->setFromSourcedValue(&d->fromSourced); } void QmlVariantAnimation::transition(QmlStateActions &actions, diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h index 06b7c08..00937a6 100644 --- a/src/declarative/util/qmlanimation_p.h +++ b/src/declarative/util/qmlanimation_p.h @@ -116,8 +116,7 @@ private: class QmlTimeLineValueAnimator : public QVariantAnimation { public: - QmlTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), policy(KeepWhenStopped) {} - QmlTimeLineValueAnimator(QmlTimeLineValue *value, QObject *parent = 0) : QVariantAnimation(parent), animValue(value), policy(KeepWhenStopped) {} + QmlTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {} void setAnimValue(QmlTimeLineValue *value, DeletionPolicy p) { if (state() == Running) @@ -125,6 +124,10 @@ public: animValue = value; policy = p; } + void setFromSourcedValue(bool *value) + { + fromSourced = value; + } protected: virtual void updateCurrentValue(const QVariant &value) { @@ -134,7 +137,11 @@ protected: virtual void updateState(State oldState, State newState) { QVariantAnimation::updateState(oldState, newState); - if (newState == Stopped && policy == DeleteWhenStopped) { + if (newState == Running) { + //check for new from every loop + if (fromSourced) + *fromSourced = false; + } else if (newState == Stopped && policy == DeleteWhenStopped) { delete animValue; animValue = 0; } @@ -142,6 +149,7 @@ protected: private: QmlTimeLineValue *animValue; + bool *fromSourced; DeletionPolicy policy; }; -- cgit v0.12 From d2dbe01664c1adb8d1848b566621dbe4470f184b Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 7 May 2009 13:40:12 +1000 Subject: Use VisualModel --- demos/declarative/flickr/flickr2.qml | 274 +++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 demos/declarative/flickr/flickr2.qml diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml new file mode 100644 index 0000000..4875fa4 --- /dev/null +++ b/demos/declarative/flickr/flickr2.qml @@ -0,0 +1,274 @@ +import "content" + +Item { + id: MainWindow; width: 800; height: 450 + + property bool showPathView : false + + VisualModel { + id: MyVisualModel + model: + XmlListModel { + id: FeedModel + property string tags : "" + source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")+"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: "tags"; query: "media:category/string()" } + 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()" } + } + + delegate: Package { + 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.photoTags = tags; + 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" + SetProperties { target: ImageDetails; z: 2 } + ParentChange { target: Wrapper; parent: ImageDetails.frontContainer } + SetProperties { target: Wrapper; x: 45; y: 35; scale: 1; z: 1000 } + 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: "Details" + ParentChangeAction { } + NumericAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + }, + Transition { + fromState: "Details"; toState: "*" + SequentialAnimation { + ParentChangeAction { } + NumericAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + SetPropertyAction { filter: Wrapper; properties: "z" } + } + } + ] + } + + Item { + Package.name: "rightBox" + id: RightBox; x: 200; width: 85; height: 85 + } + + Item { + Package.name: "leftBox" + id: LeftBox; width: 85; height: 85 + } + + Item { + id: MyItem + states: [ + State { + name: "left" + when: MainWindow.showPathView == true + SetProperty { + target: Wrapper + property: "moveToParent" + value: LeftBox + } + }, + State { + name: "right" + when: MainWindow.showPathView == false + SetProperty { + target: Wrapper + property: "moveToParent" + value: RightBox + } + } + ] + transitions: [ + Transition { + fromState: "*" + toState: "*" + SequentialAnimation { + SetPropertyAction { + target: Wrapper + property: "moveToParent" + value: Bounce + } + ParallelAnimation { + NumericAnimation { + target: Wrapper + properties: "x" + to: 0 + duration: 250 + } + NumericAnimation { + target: Wrapper + properties: "y" + to: 0 + easing: "easeInQuad" + duration: 250 + } + } + SetPropertyAction { + target: Wrapper + property: "moveToParent" + } + ParallelAnimation { + NumericAnimation { + target: Wrapper + properties: "x" + to: 0 + duration: 250 + } + NumericAnimation { + target: Wrapper + properties: "y" + to: 0 + easing: "easeOutQuad" + duration: 250 + } + } + } + } + ] + state: "right" + } + + } + } + + + Item { + id: Background + + Image { source: "content/pics/background.png"; opaque: true } + + GridView { + id: PhotoGridView; model: MyVisualModel.parts.leftBox + cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 + } + + PathView { + id: PhotoPathView; model: MyVisualModel.parts.rightBox + y: 80; width: 800; height: 330; z: 1 + 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.reload(); } + } + + states: [ + State { + name: "PathView" + } + ] + + 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 - " + + (FeedModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + FeedModel.tags) + font.size: 16; font.bold: true; color: "white"; style: "Raised"; styleColor: "black" + } +} -- cgit v0.12 From 78dd666b4f9dd2acc987926eff9513217fff490a Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 7 May 2009 13:55:24 +1000 Subject: Add missing 'Quit' menu item. --- tools/qmlviewer/qmlviewer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index dbbe233..7962ed1 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -79,6 +79,12 @@ void QmlViewer::createMenuBar() connect(reloadAction, SIGNAL(triggered()), this, SLOT(reload())); fileMenu->addAction(reloadAction); + QAction *quitAction = new QAction(tr("&Quit"), this); + quitAction->setShortcut(QKeySequence("Ctrl+Q")); + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + fileMenu->addSeparator(); + fileMenu->addAction(quitAction); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); QAction *aboutAction = new QAction(tr("&About Qt..."), this); connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -- cgit v0.12 From 9e9ee6ac63038c050ef02b102c23ebb899c45374 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 7 May 2009 14:11:05 +1000 Subject: Tweaks to viewer. --- tools/qmlviewer/main.cpp | 1 - tools/qmlviewer/qmlviewer.cpp | 36 +++++++++++++++++++++++++++++++----- tools/qmlviewer/qmlviewer.h | 3 +++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp index b588111..3f74ef6 100644 --- a/tools/qmlviewer/main.cpp +++ b/tools/qmlviewer/main.cpp @@ -60,7 +60,6 @@ int main(int argc, char ** argv) char raster[] = "raster"; newargv[argc+1] = raster; - QApplication app(newargc, newargv); app.setApplicationName("viewer"); diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 7962ed1..04054ec 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -53,7 +53,8 @@ QmlViewer::QmlViewer(QFxTestEngine::TestMode testMode, const QString &testDir, Q setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_NoSystemBackground); - createMenuBar(); + if (!(flags & Qt::FramelessWindowHint)) + createMenuBar(); canvas = new QFxView(this); if(testMode != QFxTestEngine::NoTest) @@ -85,12 +86,38 @@ void QmlViewer::createMenuBar() fileMenu->addSeparator(); fileMenu->addAction(quitAction); + /*QMenu *recordMenu = menuBar()->addMenu(tr("&Recording")); + + QAction *snapshotAction = new QAction(tr("&Take Snapsot"), this); + connect(snapshotAction, SIGNAL(triggered()), this, SLOT(takeSnapShot())); + recordMenu->addAction(snapshotAction); + + recordAction = new QAction(tr("&Start Recording Video"), this); + connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecording())); + recordMenu->addAction(recordAction);*/ + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); QAction *aboutAction = new QAction(tr("&About Qt..."), this); connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); helpMenu->addAction(aboutAction); } +void QmlViewer::takeSnapShot() +{ + static int snapshotcount = 1; + QString snapFileName = QString(QLatin1String("snapshot%1.png")).arg(snapshotcount); + canvas->asImage().save(snapFileName); + qDebug() << "Wrote" << snapFileName; + ++snapshotcount; +} + +void QmlViewer::toggleRecording() +{ + bool recording = recordTimer.isActive(); + //recordAction->setText(recording ? tr("&Start Recording Video") : tr("&End Recording Video")); + setRecording(!recording); +} + void QmlViewer::reload() { openQml(currentFileName); @@ -303,10 +330,9 @@ void QmlViewer::keyPressEvent(QKeyEvent *event) << "device keys: 0=quit, 1..8=F1..F8" ; } else if (event->key() == Qt::Key_F2 || (event->key() == Qt::Key_2 && devicemode)) { - setRecording(!recordTimer.isActive()); + toggleRecording(); } else if (event->key() == Qt::Key_F3 || (event->key() == Qt::Key_3 && devicemode)) { - canvas->asImage().save("snapshot.png"); - qDebug() << "Wrote snapshot.png"; + takeSnapShot(); } else if (event->key() == Qt::Key_F4 || (event->key() == Qt::Key_4 && devicemode)) { canvas->dumpItems(); canvas->checkState(); @@ -404,7 +430,7 @@ void QmlViewer::setRecording(bool on) args << "-delay" << QString::number(record_period/10); args << inputs; args << record_file; - qDebug() << "Converting..." << record_file; + qDebug() << "Converting..." << record_file << "(this may take a while)"; if (0!=QProcess::execute("convert", args)) { qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted"; inputs.clear(); // don't remove them diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h index b4117a2..405e8d9 100644 --- a/tools/qmlviewer/qmlviewer.h +++ b/tools/qmlviewer/qmlviewer.h @@ -48,6 +48,8 @@ public slots: void openQml(const QString& fileName); void open(); void reload(); + void takeSnapShot(); + void toggleRecording(); protected: virtual void keyPressEvent(QKeyEvent *); @@ -70,6 +72,7 @@ private: int record_period; int record_autotime; bool devicemode; + QAction *recordAction; QFxTestEngine *testEngine; }; -- cgit v0.12