Browse Source

Flesh out image model with image size info

Introduce simple list view for testing

Change-Id: I627200351bb4a979d205a72d7ae4e26ea0e5c0f5
Donald Carr 8 years ago
parent
commit
e41407fc52
8 changed files with 117 additions and 36 deletions
  1. 14 2
      qml/common/ArtImage.qml
  2. 17 1
      qml/main.qml
  3. 0 2
      qml/physics/ArtDelegate.qml
  4. 1 0
      qml/qml.qrc
  5. 12 0
      qml/simplelistview/SimpleListView.qml
  6. 1 2
      src/main.cpp
  7. 65 24
      src/picturemodel.cpp
  8. 7 5
      src/picturemodel.h

+ 14 - 2
qml/common/ArtImage.qml

@@ -1,14 +1,26 @@
 import QtQuick 2.5
+import PictureModel 1.0
 
 Image {
     property var effect
+    property int modelIndex
 
-    fillMode: Image.PreserveAspectCrop
-    source: imageModel.randomPicture()
+    asynchronous: true
+    fillMode: Image.PreserveAspectFit
+    //fillMode: Image.PreserveAspectCrop
+
+    source: imageModel.data(modelIndex)
+
+    height: width/imageModel.data(modelIndex, PictureModel.RatioRole)
     width: parent.width
+
     mirror: globalSettings.randomlyMirrorArt && (Math.random() < 0.5)
     smooth: globalSettings.smoothArt
 
     sourceSize.height: height
     sourceSize.width: width
+
+    Component.onCompleted: {
+        modelIndex = Math.floor(Math.random()*imageModel.count)
+    }
 }

+ 17 - 1
qml/main.qml

@@ -1,6 +1,7 @@
 import QtQuick 2.5
 import QtQuick.Window 2.2
 import Qt.labs.settings 1.0
+import PictureModel 1.0
 
 Window {
     id: appWindow
@@ -13,6 +14,10 @@ Window {
         loader.source = globalSettings.view.toLowerCase() + "/" + globalSettings.view + ".qml"
     }
 
+    PictureModel {
+        id: imageModel
+    }
+
     QtObject {
         id: d
         property int primedColumns: 0
@@ -55,6 +60,7 @@ Window {
         property string view: "Physics"
         property bool smoothArt: false
         property bool randomlyMirrorArt: true
+        property bool fullscreen: true
 
         property bool commonFeed: true
         property bool commonFeedRoundRobin: true
@@ -115,5 +121,15 @@ Window {
         }
     }
 
-    Component.onCompleted: showFullScreen()
+    Component.onCompleted: {
+        globalSettings.fullscreen ? showFullScreen() : show()
+    }
+
+    /*Connections {
+        target: imageModel
+        onCountChanged: {
+            //console.log('Count adjusted to:' + imageModel.count)
+            console.log('Image model data:' + imageModel.get(0))
+        }
+    }*/
 }

+ 0 - 2
qml/physics/ArtDelegate.qml

@@ -20,6 +20,4 @@ ImageBoxBody {
 
     fixedRotation: physicsSettings.fixedRotation
     bodyType: Body.Dynamic
-
-    source: imageModel.randomPicture()
 }

+ 1 - 0
qml/qml.qrc

@@ -15,5 +15,6 @@
         <file>effects/Effects.qml</file>
         <file>common/ArtImage.qml</file>
         <file>common/View.qml</file>
+        <file>simplelistview/SimpleListView.qml</file>
     </qresource>
 </RCC>

+ 12 - 0
qml/simplelistview/SimpleListView.qml

@@ -0,0 +1,12 @@
+import QtQuick 2.5
+
+import ".."
+
+ListView {
+    delegate: ArtImage {
+        source: path
+        height: size.height
+        width: size.width
+    }
+    model: imageModel
+}

+ 1 - 2
src/main.cpp

@@ -71,9 +71,8 @@ int main(int argc, char *argv[])
     }
 
     QQmlApplicationEngine engine;
-    PictureModel model;
+    qmlRegisterType<PictureModel>("PictureModel", 1, 0, "PictureModel");
 
-    engine.rootContext()->setContextProperty("imageModel", &model);
     engine.rootContext()->setContextProperty("fileReader", new FileReader(&app));
     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
 

+ 65 - 24
src/picturemodel.cpp

@@ -27,16 +27,23 @@
 #include <QMimeDatabase>
 
 struct FSNode {
-  FSNode(const QString& rname, const FSNode *pparent = nullptr)
-      : name(rname),
-        parent(pparent) { /**/ }
+  FSNode(const QString& rname, const FSNode *pparent = nullptr);
 
   static QString qualifyNode(const FSNode *node);
 
   const QString name;
   const FSNode *parent;
+
+  QSize size;
+  qreal ratio;
 };
 
+FSNode::FSNode(const QString& rname, const FSNode *pparent)
+    : name(rname),
+      parent(pparent)
+{
+}
+
 QString FSNode::qualifyNode(const FSNode *node) {
     QString qualifiedPath;
 
@@ -59,15 +66,15 @@ public:
     void setModelRoot(const QString& rootDir) { this->rootDir = rootDir; }
 
     int fileCount() const { return files.length(); }
-    QUrl randomFileUrl() const;
+    QList<FSNode*> files;
 public slots:
     void populate();
 signals:
     void countChanged();
 private:
-    QList<const FSNode*> files;
     QStringList extensions;
     QString rootDir;
+    QImageReader reader;
 };
 
 FSNodeTree::FSNodeTree(PictureModel *p)
@@ -86,14 +93,6 @@ FSNodeTree::FSNodeTree(PictureModel *p)
     }
 }
 
-
-QUrl FSNodeTree::randomFileUrl() const {
-    if (files.size() <= 0)
-        return QString("qrc:///qt_logo_green_rgb.png");
-
-    return QUrl::fromLocalFile(FSNode::qualifyNode(files.at(qrand()%files.size())));
-}
-
 void FSNodeTree::addModelNode(const FSNode* parentNode)
 {
     // TODO: Check for symlink recursion
@@ -109,9 +108,31 @@ void FSNodeTree::addModelNode(const FSNode* parentNode)
         if (!extensions.contains(extension))
             continue;
 
-        const FSNode *file = new FSNode(currentFile, parentNode);
-        files << file;
-        emit countChanged();
+        FSNode *file = new FSNode(currentFile, parentNode);
+        const QString fullPath = FSNode::qualifyNode(file);
+        reader.setFileName(fullPath);
+        QSize size = reader.size();
+
+        bool rational = false;
+        if (size.isValid()) {
+            file->size = size;
+            qreal ratio = qreal(size.width())/size.height();
+            if ((ratio < 0.01) || (ratio > 100)) {
+                qDebug() << "Image" << fullPath << "has excessive ratio" << ratio << "excluded";
+            } else {
+                rational = true;
+                file->ratio = ratio;
+            }
+        } else {
+            qDebug() << "Discarding" << fullPath << "due to invalid size";
+        }
+
+        if (rational) {
+            files << file;
+            emit countChanged();
+        }  else {
+            delete file;
+        }
     }
 }
 
@@ -176,23 +197,43 @@ int PictureModel::rowCount(const QModelIndex &parent) const
     return d->fsTree->fileCount();
 }
 
-QUrl PictureModel::randomPicture() const
-{   return d->fsTree->randomFileUrl();
-}
-
 QVariant PictureModel::data(const QModelIndex &index, int role) const
 {
-    Q_UNUSED(role)
-    if (index.row() < 0 || index.row() >= d->fsTree->fileCount())
-        return QVariant();
+    if (index.row() < 0 || index.row() >= d->fsTree->fileCount()) {
+        switch (role) {
+        case SizeRole:
+            return QSize(1222,900);
+        case NameRole:
+            return "Qt logo";
+        case PathRole:
+        default:
+            return QString("qrc:///qt_logo_green_rgb.png");
+        }
+    }
+
+
+    switch (role) {
+    case SizeRole:
+        return d->fsTree->files.at(index.row())->size;
+    case RatioRole:
+        return d->fsTree->files.at(index.row())->ratio;
+    case NameRole:
+        return d->fsTree->files.at(index.row())->name;
+    case PathRole:
+    default:
+        return QUrl::fromLocalFile(FSNode::qualifyNode(d->fsTree->files.at(index.row())));
+    }
 
-    return d->fsTree->randomFileUrl();
+    return QVariant();
 }
 
 QHash<int, QByteArray> PictureModel::roleNames() const
 {
     QHash<int, QByteArray> roles;
+    roles[NameRole] = "name";
     roles[PathRole] = "path";
+    roles[SizeRole] = "size";
+    roles[RatioRole] = "ratio";
     return roles;
 }
 

+ 7 - 5
src/picturemodel.h

@@ -28,17 +28,19 @@ class PictureModel : public QAbstractListModel
     Q_PROPERTY (int count READ rowCount NOTIFY countChanged)
 public:
     enum PictureRoles {
-        PathRole = Qt::UserRole + 1
+        NameRole = Qt::UserRole + 1,
+        PathRole,
+        SizeRole,
+        RatioRole
     };
+    Q_ENUM(PictureRoles)
 
     PictureModel(QObject *parent = nullptr);
     ~PictureModel();
 
     int rowCount(const QModelIndex & parent = QModelIndex()) const;
-
-    Q_INVOKABLE QUrl randomPicture() const;
-    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
-
+    Q_INVOKABLE QVariant data(const int &row, int role = PathRole) const { return data(index(row, 0), role); }
+    QVariant data(const QModelIndex & index, int role = PathRole) const;
 signals:
     void countChanged();