Initial import
authorMohammed Sameer <msameer@foolab.org>
Sat, 1 Sep 2012 13:22:17 +0000 (16:22 +0300)
committerMohammed Sameer <msameer@foolab.org>
Sat, 1 Sep 2012 13:22:17 +0000 (16:22 +0300)
13 files changed:
qml/CameraPage.qml [new file with mode: 0644]
qml/CheckButton.qml [new file with mode: 0644]
qml/CheckButtonData.qml [new file with mode: 0644]
qml/FlashButton.qml [new file with mode: 0644]
qml/ImagePage.qml [new file with mode: 0644]
qml/ModeButton.qml [new file with mode: 0644]
qml/ModeController.qml [new file with mode: 0644]
qml/PreviewImage.qml [new file with mode: 0644]
qml/SceneButton.qml [new file with mode: 0644]
qml/Selector.qml [new file with mode: 0644]
qml/VideoPage.qml [new file with mode: 0644]
qml/ZoomSlider.qml [new file with mode: 0644]
qml/main.qml [new file with mode: 0644]

diff --git a/qml/CameraPage.qml b/qml/CameraPage.qml
new file mode 100644 (file)
index 0000000..69e8467
--- /dev/null
@@ -0,0 +1,41 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+Page {
+        property Camera cam: null
+        property bool controlsVisible: true
+
+        anchors.fill: parent
+
+        property alias previewAnimationRunning: preview.animationRunning
+
+        function setPreview(image) {
+                preview.setPreview(image);
+        }
+
+        ModeButton {
+                anchors.bottom: parent.bottom
+                anchors.right: parent.right
+                anchors.rightMargin: 20
+                anchors.bottomMargin: 20
+                mode: cameraMode.mode
+                onModeChanged: {
+                        cameraMode.set(mode);
+                }
+        }
+
+        PreviewImage {
+                id: preview
+        }
+
+        ZoomSlider {
+                id: zoom
+                camera: cam
+                anchors.top: parent.top
+                anchors.topMargin: 0
+                anchors.horizontalCenter: parent.horizontalCenter
+                visible: controlsVisible
+        }
+}
diff --git a/qml/CheckButton.qml b/qml/CheckButton.qml
new file mode 100644 (file)
index 0000000..c0063ff
--- /dev/null
@@ -0,0 +1,18 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+
+Button {
+        id: button
+        property string normalIcon: ""
+        property string checkedIcon: ""
+        property QtObject controller: null
+        property QtObject fader: null
+        property int value: -1
+
+        visible: fader.enabled
+        width: visible ? 64 : 0
+        height: visible ? 64 : 0
+        iconSource: !visible ? "" : controller.value == value ? checkedIcon : normalIcon
+        onClicked: { controller.value = value; fader.enabled = !fader.enabled }
+}
diff --git a/qml/CheckButtonData.qml b/qml/CheckButtonData.qml
new file mode 100644 (file)
index 0000000..fa91fcc
--- /dev/null
@@ -0,0 +1,8 @@
+// -*- qml -*-
+import QtQuick 1.1
+
+QtObject {
+        property string normalIcon: ""
+        property string checkedIcon: ""
+        property int value: -1
+}
diff --git a/qml/FlashButton.qml b/qml/FlashButton.qml
new file mode 100644 (file)
index 0000000..c9b3ae0
--- /dev/null
@@ -0,0 +1,93 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+MouseArea {
+        id: mouse
+        anchors.fill: parent
+        enabled: false
+        onClicked: enabled = !enabled;
+        onEnabledChanged: button.checked = enabled;
+
+        function flashIcon(val) {
+                var x = row.children.length;
+                var i = 0;
+                for (i = 0; i < x; i++) {
+                        if (row.children[i].value == val) {
+                                return row.children[i].normalIcon;
+                        }
+                }
+        }
+
+        Timer {
+                interval: 2000
+                running: mouse.enabled
+                repeat: false
+                onTriggered: mouse.enabled = !mouse.enabled
+        }
+
+        Flash {
+                id: flash
+                camera: cam
+                // TODO: hardcoding
+                value: Flash.Auto
+        }
+
+        Button {
+                anchors.left: parent.left
+                id: button
+                width: 64
+                height: 64
+                opacity: 0.5
+                onClicked: mouse.enabled = !mouse.enabled;
+                checkable: true
+                iconSource: flashIcon(flash.value);
+        }
+
+        Row {
+                id: row
+                height: mouse.enabled ? 64 : 0
+                width: mouse.enabled ? (children.length * height) +  (children.length - 1) * spacing : 0
+                anchors.left: button.right
+                anchors.leftMargin: 20
+                spacing: 10
+
+                Behavior on width {
+                        // TODO: seems animation is not working
+                        PropertyAnimation { duration: 250; }
+                }
+
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-auto.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-auto-pressed.png"
+                        controller: flash
+                        value: Flash.Auto
+                        fader: mouse
+                }
+
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-always.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-always-pressed.png"
+                        controller: flash
+                        value: Flash.On
+                        fader: mouse
+                }
+
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-off.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-off-pressed.png"
+                        controller: flash
+                        value: Flash.Off
+                        fader: mouse
+                }
+
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-red-eye.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-flash-red-eye-pressed.png"
+                        controller: flash
+                        value: Flash.RedEye
+                        fader: mouse
+                }
+        }
+}
diff --git a/qml/ImagePage.qml b/qml/ImagePage.qml
new file mode 100644 (file)
index 0000000..51c5729
--- /dev/null
@@ -0,0 +1,66 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+CameraPage {
+        id: page
+
+        controlsVisible: capture.visible
+
+        Button {
+                id: capture
+                anchors.right: parent.right
+                anchors.rightMargin: 20
+                anchors.verticalCenter: parent.verticalCenter
+                iconSource: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-shutter.png"
+                width: 75
+                height: 75
+                opacity: 0.5
+                onClicked: imageMode.capture("/home/developer/foo.png");
+                visible: imageMode.canCapture && !cameraMode.animationRunning && !previewAnimationRunning
+        }
+
+        ImageMode {
+                id: imageMode
+                camera: cam
+                onPreviewAvailable: page.setPreview(preview);
+                nightMode: scene.sceneValue == Scene.Night
+        }
+
+        FlashButton {
+                id: flash
+                visible: capture.visible
+                anchors.top: parent.top
+                anchors.left: parent.left
+                anchors.topMargin: 20
+                anchors.leftMargin: 20
+        }
+
+        SceneButton {
+                id: scene
+                visible: capture.visible
+                anchors.top: parent.top
+                anchors.left: parent.left
+                anchors.topMargin: 20 + 64 + 10
+                anchors.leftMargin: 20
+        }
+
+        Selector {
+                id: evComp
+                visible: capture.visible
+                anchors.top: parent.top
+                anchors.left: parent.left
+                anchors.topMargin: 20 + 64 + 10 + 64 + 10
+                anchors.leftMargin: 20
+                timerConstraints: slider.pressed
+                widget: Slider {
+                        id: slider
+                        orientation: Qt.Horizontal
+//                        anchors.horizontalCenter: parent.horizontalCenter
+                }
+        }
+
+        // TODO: filenaming.
+        // TODO: metadata
+}
diff --git a/qml/ModeButton.qml b/qml/ModeButton.qml
new file mode 100644 (file)
index 0000000..1101144
--- /dev/null
@@ -0,0 +1,133 @@
+// -*- qml -*-
+
+import QtQuick 1.1
+import QtCamera 1.0
+
+Rectangle {
+        id: button
+        property int mode: Camera.ImageMode
+
+        color: "black"
+        width: 60
+        height: 120
+        smooth: true
+        radius: width
+        border.width: 2
+        border.color: "gray"
+
+        visible: cam.running && cam.idle && !cameraMode.animationRunning
+
+        Rectangle {
+                id: highlighter
+                width: parent.width
+                height: parent.width
+                color: mouse.pressed ? "lightblue" : "white"
+                radius: parent.width
+                y: mode == 1 ? video.y : image.y
+        }
+
+        Column {
+                Image {
+                        id: image
+                        width: button.width
+                        height: width
+//                        anchors.top: parent.top
+                        property string released: "icon-m-viewfinder-camera.png"
+                        property string active: "icon-m-viewfinder-camera-selected.png"
+                        source: mouse.pressed ? "/usr/share/themes/blanco/meegotouch/icons/" + released : button.mode == 0 ? "/usr/share/themes/blanco/meegotouch/icons/" + active : "/usr/share/themes/blanco/meegotouch/icons/" + released
+                }
+
+                Image {
+                        id: video
+                        width: button.width
+                        height: width
+                        property string released: "icon-m-camera-video-record.png"
+                        property string active: "icon-m-camera-video-selected.png"
+                        source: mouse.pressed ? "/usr/share/themes/blanco/meegotouch/icons/" + released : button.mode == 1 ? "/usr/share/themes/blanco/meegotouch/icons/" + active : "/usr/share/themes/blanco/meegotouch/icons/" + released
+                }
+        }
+
+        MouseArea {
+                anchors.fill: parent
+                id: mouse
+                drag.target: highlighter
+                drag.axis: Drag.YAxis
+                drag.minimumY: 0
+                drag.maximumY: parent.height / 2
+                onReleased: {
+                        if (!drag.active) {
+                        if (mode == 0) {
+                        mode = Camera.VideoMode;
+//                        highlighter.y = video.y;
+                        }
+                        else {
+                                mode = Camera.ImageMode;
+//                                highlighter.y = image.y;
+                        }
+                        return;
+                        }
+
+//                        var pos = 0;
+                        if (mouse.y >= video.y) {
+                                mode = Camera.VideoMode;
+//                                pos = video.y;
+                        }
+                        else {
+                                mode = Camera.ImageMode;
+//                                pos = image.y;
+                        }
+
+//                        highlighter.y = pos;
+                }
+
+                onPressed: {
+                        var y = mouse.y - highlighter.height / 2;
+
+                        if (y > drag.maximumY) {
+                                y = drag.maximumY;
+                        }
+
+                        else if (y < drag.minimumY) {
+                                y = 0;
+                        }
+
+                        highlighter.y = y
+                }
+        }
+
+/*
+        ListView {
+                anchors.fill: parent
+                interactive: false
+
+                model: ListModel {
+                        id: model
+                        ListElement {
+                                mode: 0
+                                released: "icon-m-viewfinder-camera.png"
+                                active: "icon-m-viewfinder-camera-selected.png"
+                        }
+
+                        ListElement {
+                                mode: 1
+                                released: "icon-m-camera-video-record.png"
+                                active: "icon-m-camera-video-selected.png"
+                        }
+                }
+
+                delegate: Rectangle {
+                        width: button.width
+                        height: button.width
+                        radius: parent.width
+                        smooth: true
+                        color: mouse.pressed ? "black" : button.mode == mode ? "white" : "black"
+                        Image {
+                                z: 10
+                                id: image
+                                source: mouse.pressed ? "/usr/share/themes/blanco/meegotouch/icons/" + released : button.mode == mode ? "/usr/share/themes/blanco/meegotouch/icons/" + active : "/usr/share/themes/blanco/meegotouch/icons/" + released
+                                anchors.fill: parent
+                        }
+                }
+        }
+               */
+}
diff --git a/qml/ModeController.qml b/qml/ModeController.qml
new file mode 100644 (file)
index 0000000..9238efc
--- /dev/null
@@ -0,0 +1,40 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+Item {
+        id: controller
+        property int mode: Camera.ImageMode
+        property Camera cam: null
+        property Item dimmer: null
+        property alias animationRunning: animation.running
+
+        SequentialAnimation {
+                id: animation
+                property int mode: 0
+
+                function setMode() {
+                        cam.mode = mode;
+                        controller.mode = mode;
+                }
+
+                NumberAnimation { target: dimmer; property: "opacity"; from: 0; to: 1; duration: 250; alwaysRunToEnd: true }
+                ParallelAnimation {
+                        ScriptAction { script: animation.setMode(); }
+                        PauseAnimation { duration: 100 }
+                }
+
+                NumberAnimation { target: dimmer; property: "opacity"; from: 1; to: 0; duration: 250; alwaysRunToEnd: true }
+        }
+
+        function set(newMode) {
+                if (mode == newMode) {
+                        return;
+                }
+
+                animation.start();
+
+                animation.mode = newMode;
+        }
+}
diff --git a/qml/PreviewImage.qml b/qml/PreviewImage.qml
new file mode 100644 (file)
index 0000000..38d2486
--- /dev/null
@@ -0,0 +1,26 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+Image {
+        id: image
+        anchors.fill: parent
+        property alias animationRunning: animation.running
+
+        visible: false
+        cache: false
+        fillMode: Image.PreserveAspectFit
+
+        SequentialAnimation {
+                id: animation
+                PauseAnimation { duration: 500; alwaysRunToEnd: true }
+                NumberAnimation { target: preview; property: "opacity"; from: 1; to: 0; duration: 250; alwaysRunToEnd: true }
+        }
+
+        function setPreview(preview) {
+                animation.start();
+                image.source = preview;
+                image.visible = true;
+        }
+}
diff --git a/qml/SceneButton.qml b/qml/SceneButton.qml
new file mode 100644 (file)
index 0000000..34cf69e
--- /dev/null
@@ -0,0 +1,106 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+MouseArea {
+        id: mouse
+        anchors.fill: parent
+        enabled: false
+        onClicked: enabled = !enabled;
+        onEnabledChanged: button.checked = enabled;
+
+        property alias sceneValue: scene.value
+
+        function sceneIcon(val) {
+                var x = row.children.length;
+                var i = 0;
+                for (i = 0; i < x; i++) {
+                        if (row.children[i].value == val) {
+                                return row.children[i].normalIcon;
+                        }
+                }
+        }
+
+        Timer {
+                interval: 2000
+                running: mouse.enabled
+                repeat: false
+                onTriggered: mouse.enabled = !mouse.enabled
+        }
+
+        Scene {
+                id: scene
+                camera: cam
+                // TODO: hardcoding
+                value: Scene.Auto
+        }
+
+        Button {
+                anchors.left: parent.left
+                id: button
+                width: 64
+                height: 64
+                opacity: 0.5
+                onClicked: mouse.enabled = !mouse.enabled;
+                checkable: true
+                iconSource: sceneIcon(scene.value);
+        }
+
+        Row {
+                id: row
+                height: mouse.enabled ? 64 : 0
+                width: mouse.enabled ? (children.length * height) +  (children.length - 1) * spacing : 0
+                anchors.left: button.right
+                anchors.leftMargin: 20
+                spacing: 10
+
+                Behavior on width {
+                        // TODO: seems animation is not working
+                        PropertyAnimation { duration: 250; }
+                }
+
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-auto.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-auto-selected.png"
+                        controller: scene
+                        value: Scene.Auto
+                        fader: mouse
+                }
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-macro.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-macro-selected.png"
+                        controller: scene
+                        value: Scene.Closeup
+                        fader: mouse
+                }
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-landscape.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-landscape-selected.png"
+                        controller: scene
+                        value: Scene.Landscape
+                        fader: mouse
+                }
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-portrait.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-portrait-selected.png"
+                        controller: scene
+                        value: Scene.Portrait
+                        fader: mouse
+                }
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-night.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-night-selected.png"
+                        controller: scene
+                        value: Scene.Night
+                        fader: mouse
+                }
+                CheckButton {
+                        normalIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-sports.png"
+                        checkedIcon: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-scene-sports-selected.png"
+                        controller: scene
+                        value: Scene.Sport
+                        fader: mouse
+                }
+        }
+}
diff --git a/qml/Selector.qml b/qml/Selector.qml
new file mode 100644 (file)
index 0000000..5b6dc6f
--- /dev/null
@@ -0,0 +1,41 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+Button {
+        id: button
+        width: 64
+        height: 64
+
+        property alias widget: __widget.children
+        property bool timerConstraints
+
+        checkable: true
+
+        function close() {
+                button.checked = false;
+        }
+
+        Timer {
+                interval: 2000
+                running: mouse.enabled && !button.timerConstraints
+                repeat: false
+                onTriggered: button.close();
+        }
+
+        MouseArea {
+                id: mouse
+                parent: button.parent
+                anchors.fill: parent
+                enabled: button.checked
+                onClicked: button.close();
+
+                Item {
+                        id: __widget
+                        y: button.y
+                        x: button.x + button.width + 20
+                        visible: button.checked
+                }
+        }
+}
diff --git a/qml/VideoPage.qml b/qml/VideoPage.qml
new file mode 100644 (file)
index 0000000..a282249
--- /dev/null
@@ -0,0 +1,39 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+CameraPage {
+        id: page
+
+        controlsVisible: recording.visible
+
+        orientationLock: PageOrientation.LockLandscape
+
+        Button {
+                id: recording
+                anchors.right: parent.right
+                anchors.rightMargin: 20
+                anchors.verticalCenter: parent.verticalCenter
+                iconSource: "/usr/share/themes/blanco/meegotouch/icons/icon-m-camera-video-record.png"
+                width: 75
+                height: 75
+                opacity: 0.5
+                onClicked: {
+                        if (!videoMode.recording) {
+                                videoMode.startRecording("/home/developer/foo.mp4");
+                        }
+                        else {
+                                videoMode.stopRecording();
+                        }
+                }
+
+                visible: (videoMode.recording || videoMode.canCapture) && !cameraMode.animationRunning && !previewAnimationRunning
+        }
+
+        VideoMode {
+                id: videoMode
+                camera: cam
+                onPreviewAvailable: page.setPreview(preview);
+        }
+}
diff --git a/qml/ZoomSlider.qml b/qml/ZoomSlider.qml
new file mode 100644 (file)
index 0000000..3ea490e
--- /dev/null
@@ -0,0 +1,47 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+Slider {
+        id: slider
+        property alias camera: zoom.camera
+        platformStyle: SliderStyle {
+                // HACK
+                handleBackground: " "
+                handleBackgroundPressed: " "
+        }
+
+        Zoom {
+                id: zoom
+                value: slider.value
+        }
+
+        orientation: Qt.Horizontal
+        width: 500
+        height: 50
+        stepSize:0.1
+        minimumValue: zoom.minimum
+        maximumValue: zoom.maximum
+
+        state: "hidden"
+        states: [
+        State {
+                name: "visible"
+                when: slider.pressed
+                PropertyChanges { target: slider; opacity: 1.0 }
+        },
+        State {
+                name: "hidden"
+                when: !slider.pressed
+                PropertyChanges { target: slider; opacity: 0.2 }
+        }]
+
+        transitions: Transition {
+                to: "hidden"
+                SequentialAnimation {
+                        PauseAnimation { duration: 2000 }
+                        NumberAnimation { target: slider; property: "opacity"; duration: 250 }
+                }
+        }
+}
diff --git a/qml/main.qml b/qml/main.qml
new file mode 100644 (file)
index 0000000..2040c17
--- /dev/null
@@ -0,0 +1,115 @@
+// -*- qml -*-
+import QtQuick 1.1
+import com.nokia.meego 1.1
+import QtCamera 1.0
+
+PageStackWindow {
+        id: root
+
+        property alias dimmer: camDimmer
+
+        showStatusBar: false
+        Component.onCompleted: theme.inverted = true;
+
+        // Stolen from https://qt.gitorious.org/qt-components/qt-components/blobs/master/examples/meego/QmlComponentGallery/qml/ListPage.qml
+        function replacePage(file) {
+                var component = Qt.createComponent(file)
+
+                if (component.status == Component.Ready) {
+                        pageStack.replace(component, {cam: cam}, true);
+                }
+                else {
+                        console.log("Error loading component:", component.errorString());
+                }
+        }
+
+        function openFile(file) {
+                var component = Qt.createComponent(file)
+
+                if (component.status == Component.Ready) {
+                        pageStack.push(component);
+                }
+                else {
+                        console.log("Error loading component:", component.errorString());
+                }
+        }
+
+        platformStyle: PageStackWindowStyle {
+                // TODO: Hack
+                background: " "
+                portraitBackground: " "
+                landscapeBackground: " "
+        }
+
+        Camera {
+                onDeviceIdChanged: cam.start();
+
+                id: cam
+                anchors.fill: parent
+
+                // TODO: hardcoding
+                Component.onCompleted: { cam.deviceId = 0; }
+
+                // TODO: Hack
+                z: -1
+
+                Rectangle {
+                        id: camDimmer
+                        z: 1
+                        anchors.fill: parent
+                        opacity: 0
+                        color: "black"
+                }
+        }
+
+        ModeController {
+                id: cameraMode
+                cam: cam
+                dimmer: root.dimmer
+        }
+
+        Connections {
+                target: cam
+                onModeChanged: {
+                        if (cam.mode == Camera.VideoMode) {
+                                replacePage("VideoPage.qml");
+                        }
+                        else {
+                                replacePage("ImagePage.qml");
+                        }
+                }
+        }
+
+        Button {
+                text: "select camera"
+                anchors.left: parent.left
+                anchors.bottom: parent.bottom
+                onClicked: sel.open();
+        }
+
+        SelectionDialog {
+                id: sel
+                titleText: "Select camera";
+                // http://forum.meego.com/showthread.php?t=3873
+                selectedIndex: 0
+                model: ListModel { id: model }
+
+                onAccepted: cam.deviceId = cam.deviceId = selectedIndex;
+
+                function populate() {
+                        var n = cam.deviceCount;
+                        var x;
+                        for (x = 0; x < n; x++) {
+                        var nm = cam.deviceName(x);
+                        console.log(nm);
+                        model.append({"name": nm});
+                        }
+                }
+
+                Component.onCompleted: populate();
+        }
+
+
+        // TODO: hardcoding
+        initialPage: ImagePage { cam: cam }
+}