Przeglądaj źródła

Introduce Reel view

Donald Carr 8 lat temu
rodzic
commit
cd2b610bf0

+ 5 - 2
artriculate.pro

@@ -4,7 +4,8 @@ QT += qml quick dbus
 CONFIG += c++11
 
 SOURCES += src/main.cpp \
-    src/picturemodel.cpp
+    src/picturemodel.cpp \
+    src/helperfunctions.cpp
 
 RESOURCES += qml/qml.qrc resources/resources.qrc
 
@@ -25,4 +26,6 @@ INSTALLS += target desktop icon
 include(deployment.pri)
 
 HEADERS += \
-    src/picturemodel.h
+    src/picturemodel.h \
+    src/helperfunctions.h \
+    src/filereader.h

+ 2 - 0
qml/common/ArtImage.qml

@@ -8,6 +8,8 @@ Rectangle {
     property var effect
     property int modelIndex
 
+    property alias asynchronous: image.asynchronous
+
     color: globalSettings.randomTapestryColour ? Qt.rgba(Math.random(255), Math.random(255), Math.random(255), 1.0) : "black"
 
     height: Math.ceil(width/imageModel.data(modelIndex, PictureModel.RatioRole))

+ 6 - 5
qml/main.qml

@@ -75,7 +75,7 @@ Window {
         property string day
         property string month
         property string currentViewFilename
-        property string overrideViewFilename: "Procession"
+        property string overrideViewFilename
 
         function setView(view) {
             d.currentViewFilename = deriveViewPath(overrideViewFilename.length ? overrideViewFilename : view)
@@ -104,12 +104,12 @@ Window {
 
     Settings {
         id: globalSettings
-        property int columnCount: 5
+        property int columnCount: 6
         property int interval: 5
         property bool showViewItemCount: false
         property bool showScreenResolution: false
         property string effect: ""
-        property string view: "Cascade"
+        property string view: "Reel"
         property bool smoothArt: true
         property bool randomlyMirrorArt: false
         property bool fullscreen: true
@@ -124,8 +124,9 @@ Window {
         property bool randomTapestryColour: false
         property bool fadeInImages: true
 
-        property bool useGoldenRatio: true
-        property real lessGoldenRatio: 1.25
+        property bool useGoldenRatio: false
+        //property real lessGoldenRatio: 1.25
+        property real lessGoldenRatio: 1.35
 
         onColumnCountChanged: globalUtil.reset()
         Component.onCompleted: {

+ 1 - 0
qml/qml.qrc

@@ -14,6 +14,7 @@
         <file>conveyor/Conveyor.qml</file>
         <file>basic/Basic.qml</file>
         <file>reel/Reel.qml</file>
+        <file>reel/ReelImage.qml</file>
         <file>procession/Procession.qml</file>
         <file>procession/ProcessionImage.qml</file>
         <file>effects/Effect.qml</file>

+ 151 - 0
qml/reel/Reel.qml

@@ -0,0 +1,151 @@
+import QtQuick 2.5
+import Qt.labs.settings 1.0
+
+import ".."
+
+View {
+    id: root
+
+    property var pictureDelegate: Component {
+        ReelImage {}
+    }
+
+    Settings {
+        id: reelSettings
+        category: "Reel"
+        property int deathYawn: 5000
+    }
+
+    QtObject {
+        id: d
+        property var priorImage
+        property real velocity: 0
+        property bool initialized: false
+        property int imageBuffer: 1
+        property real columnRatio: globalSettings.useGoldenRatio ? globalVars.goldenRatio : globalSettings.lessGoldenRatio
+        property real columnWidth: root.width*globalUtil.columnWidthRatio(d.columnRatio, globalSettings.columnCount)
+
+        function animationStep() {
+            columnArray.forEach(function(column) { column.animationStep(); })
+        }
+
+        function killLastImage() {
+            if(!!priorImage) {
+                priorImage.destroy()
+                globalUtil.itemCount--
+            }
+            var col = columnArray[globalSettings.columnCount - 1]
+            priorImage = col.imageArray.shift()
+        }
+    }
+
+    Component {
+        id: columnComponent
+
+        Item {
+            id: column
+
+            property int columnIndex: index
+            property var imageArray: []
+            property var imageQueue: []
+
+            function stackHeight(imageIndex) {
+                var height = 0
+                for(var i = 0; i < imageIndex; i++) {
+                    height += imageArray[i].height
+                }
+                return height
+            }
+
+            function receptive() {
+                return imageQueue.length < d.imageBuffer
+            }
+
+            function addImage(image) {
+                image.parent = column
+                image.y = - image.height
+                imageQueue.push(image)
+            }
+
+            function animationStep() {
+                if (!imageArray.length || imageArray[imageArray.length - 1].y > -1) {
+                    if (imageQueue.length) {
+                        imageArray.push(imageQueue.pop())
+                    } else if (columnIndex === 0) {
+                        globalUtil.itemCount++
+                        addImage(pictureDelegate.createObject())
+                        imageArray.push(imageQueue.pop())
+                    }
+                }
+
+                for (var i = 0; i < imageArray.length; i++) {
+                    var image = imageArray[i]
+                    var restingY = root.height - image.height - stackHeight(i)
+                    var prospectiveY = image.y + d.velocity
+                    var lastColumn = columnIndex === (globalSettings.columnCount - 1)
+
+                    if (image.y > root.height) {
+                        imageArray.shift()
+                        if (!lastColumn) {
+                            columnArray[columnIndex+1].addImage(image)
+                        }
+                    } else if (( lastColumn || !columnArray[columnIndex+1].receptive()) && prospectiveY >= restingY) {
+                        image.y = restingY
+                        if (lastColumn) {
+                            deathTimer.start()
+                            if(!d.initialized) {
+                                d.initialized = true
+                                d.velocity = 4
+                            }
+                        }
+                    } else {
+                        image.y = prospectiveY
+                    }
+                }
+            }
+
+            Component.onCompleted: columnArray.push(this)
+
+            x: d.columnWidth/globalUtil.columnWidthRatio(d.columnRatio, index)
+            width: {
+                var colWidth = d.columnWidth*Math.pow(d.columnRatio, index);
+                (index === (globalSettings.columnCount - 1)) && (globalVars.imageWidthOverride = colWidth)
+                return colWidth
+            }
+            anchors { top: parent.top; bottom: parent.bottom }
+        }
+    }
+
+    // feed
+    Timer {
+        repeat: true
+        running: true
+        interval: 100/6
+        onTriggered: d.animationStep()
+    }
+
+    // accel
+    Timer {
+        repeat: true
+        running: !d.initialized
+        interval: 100
+        onTriggered: {
+            d.velocity += 0.1
+        }
+    }
+
+    // death
+    Timer {
+        id: deathTimer
+        repeat: false
+        running: false
+        interval: reelSettings.deathYawn
+        onTriggered: {
+            d.killLastImage()
+        }
+    }
+
+    Keys.onDownPressed: {
+        d.killLastImage()
+    }
+}

+ 8 - 0
qml/reel/ReelImage.qml

@@ -0,0 +1,8 @@
+import QtQuick 2.6
+
+import ".."
+
+ArtImage {
+    property bool doomed: false
+    asynchronous: false
+}

+ 24 - 0
src/filereader.h

@@ -0,0 +1,24 @@
+#ifndef FILEREADER_H
+#define FILEREADER_H
+
+#include <QObject>
+#include <QFile>
+#include <QTextStream>
+
+class FileReader : public QObject {
+    Q_OBJECT
+public:
+    FileReader(QObject *p) : QObject(p) { /**/ }
+    Q_INVOKABLE static QString readFile(const QString &fileName)
+    {
+        QString content;
+        QFile file(fileName);
+        if (file.open(QIODevice::ReadOnly)) {
+            QTextStream stream(&file);
+            content = stream.readAll();
+        }
+        return content;
+    }
+};
+
+#endif // FILEREADER_H

+ 16 - 0
src/helperfunctions.cpp

@@ -0,0 +1,16 @@
+#include "helperfunctions.h"
+
+HelperFunctions::HelperFunctions(QObject *parent) : QObject(parent)
+{
+    const int kAccelerationFactor = 1;
+    velocityArray = new qreal[kVelocityTableEntries];
+    for(int i = 0; i < kVelocityTableEntries; i++) {
+        velocityArray[i] = kAccelerationFactor*i/60;
+    }
+}
+
+qreal HelperFunctions::velocityForTick(int tick)
+{
+    int tock = qBound(0, tick, kVelocityTableEntries - 1);
+    return velocityArray[tock];
+}

+ 22 - 0
src/helperfunctions.h

@@ -0,0 +1,22 @@
+#ifndef HELPERFUNCTIONS_H
+#define HELPERFUNCTIONS_H
+
+#include <QObject>
+#include <qglobal.h>
+
+class HelperFunctions : public QObject
+{
+    Q_OBJECT
+public:
+    explicit HelperFunctions(QObject *parent = nullptr);
+    Q_SCRIPTABLE qreal velocityForTick(int tick);
+
+signals:
+
+public slots:
+private:
+    const int kVelocityTableEntries = 600;
+    qreal* velocityArray;
+};
+
+#endif // HELPERFUNCTIONS_H

+ 3 - 19
src/main.cpp

@@ -17,6 +17,8 @@
 ****************************************************************************/
 
 #include "picturemodel.h"
+#include "filereader.h"
+#include "helperfunctions.h"
 
 #include <QGuiApplication>
 #include <QQmlApplicationEngine>
@@ -26,7 +28,6 @@
 #include <QTimer>
 #include <QQuickWindow>
 #include <QDir>
-#include <QFile>
 #include <QFileInfo>
 #include <QTextStream>
 #include <QDebug>
@@ -34,22 +35,6 @@
 #include <QDBusInterface>
 #include <QDBusConnection>
 
-class FileReader : public QObject {
-    Q_OBJECT
-public:
-    FileReader(QObject *p) : QObject(p) { /**/ }
-    Q_INVOKABLE static QString readFile(const QString &fileName)
-    {
-        QString content;
-        QFile file(fileName);
-        if (file.open(QIODevice::ReadOnly)) {
-            QTextStream stream(&file);
-            content = stream.readAll();
-        }
-        return content;
-    }
-};
-
 int main(int argc, char *argv[])
 {
     qsrand(time(NULL));
@@ -106,9 +91,8 @@ int main(int argc, char *argv[])
 
     engine.rootContext()->setContextProperty("screenSize", app.screens().at(0)->availableSize());
     engine.rootContext()->setContextProperty("fileReader", new FileReader(&app));
+    engine.rootContext()->setContextProperty("nativeHelper", new HelperFunctions(&app));
     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
 
     return app.exec();
 }
-
-#include "main.moc"