- Enginio Manual
- Enginio QML Types and Examples
- Enginio QML Examples - Image Gallery
- Enginio 1.2.1 Reference Documentation

# Enginio QML Examples - Image Gallery

The user interface is a list of images with their meta-information and a button to upload more images.

## Backend Configuration

The Enginio backend needs to be set up to get this example working.

Go to the Enginio Dashboard and create a new backend with the `Image Gallery` template.

The template will construct a new custom backend by executing the following steps:

- Create a new object type `objects.image` (on the Object Types page).

  Add two properties to the image object: `name:"name"`, `type: "String"` and `name: "file"`, `type: "Ref"` with `target "files"`.

- Add a file processor by clicking the `file` property. Choose Image processor, and in Variants enter:

      {
          "thumbnail": { "crop":"100x100" }
      }

  This JSON snippet triggers the server to generate thumbnails for all uploaded images. In the image gallery the thumbnails will be used in the list view. The full image will be shown when the thumbnail is clicked.

Copy the backend id from the Enginio dashboard. They need to be entered into the example when it is executed for the first time.

## The Example Code

The first step is to set up the Enginio client.

    EnginioClient {
        id: client
        backendId: backendHelper.backendId
        onError: console.log("Enginio error: " + reply.errorCode + ": " + reply.errorString)
    }

Then the model is initialized with that client.

    EnginioModel {
        id: enginioModel
        client: client
        query: { // query for all objects of type "objects.image" and include not null references to files
            "objectType": "objects.image",
            "include": {"file": {}},
            "query" : { "file": { "$ne": null } }
        }
    }

A delegate is needed to present the images nicely. The model is used to get the list of image objects, but the images are only attached to the objects as file references. Thus the image's thumbnail is fetched by each delegate.

Note: In a real application it might be necessary to cache the images.

The `Component.onCompleted` function is used to fetch the image. When the delegate is created, it has the JSON image object data. The information needed is the `file.id` reference. The `file` property was introduced in the backend setup section. Every object (files are just objects) contains an ID that uniquely identifies the image file. The thumbnail url of the image is retrieved using the ID ("variant": "thumbnail").

    Image {
        id: image
        x: 10
        width: 100
        height: 100
        anchors.verticalCenter: parent.verticalCenter
        opacity: image.status == Image.Ready ? 1 : 0
        Behavior on opacity { NumberAnimation { duration: 100 } }
        Component.onCompleted: {
            if (id in imagesUrl) {
                image.source = imagesUrl[id]
            } else {
                var data = { "id": file.id,
                    "variant": "thumbnail"}
                var reply = client.downloadUrl(data)
                reply.finished.connect(function() {
                    imagesUrl[id] = reply.data.expiringUrl
                    if (image && reply.data.expiringUrl) // It may be deleted as it is delegate
                        image.source = reply.data.expiringUrl
                })
            }
        }
    }
    Rectangle {
        color: "transparent"
        anchors.fill: image
        border.color: "#aaa"
        Rectangle {
            id: progressBar
            property real value:  image.progress
            anchors.bottom: parent.bottom
            width: image.width * value
            height: 4
            color: "#49f"
            opacity: image.status != Image.Ready ? 1 : 0
            Behavior on opacity {NumberAnimation {duration: 100}}
        }
    }

The meta-information about each image is displayed in simple `Text` elements. For the filename, it is possible to directly reference the `name` property as defined in the JSON.

    Text { text: name }

Files:

- image-gallery/image-gallery.qml
- image-gallery/gallery.qrc
- image-gallery/image-gallery.pro