// Copyright (C) 2017 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtCore import QtQuick import QtQuick.Controls import QtQuick.Dialogs import Qt.labs.folderlistmodel import "resources" pragma ComponentBehavior: Bound Window { id: root visible: true width: 1024; height: 600 color: "black" title: Application.displayName + " : " + folderModel.folder property real defaultSize: 200 property real surfaceViewportRatio: 1.5 property var imageNameFilters: ["*.png", "*.jpg", "*.gif"] // overridden in main.cpp FolderDialog { id: folderDialog title: qsTr("Choose a folder with some images") onAccepted: folderModel.folder = selectedFolder } ShaderEffect { readonly property vector3d iResolution: Qt.vector3d(width, height, 1.0) fragmentShader: "resources/shaders/gneiss.frag.qsb" anchors.fill: parent } ScrollView { id: flick anchors.fill: parent contentWidth: width * root.surfaceViewportRatio contentHeight: height * root.surfaceViewportRatio property int highestZ: 0 Repeater { model: FolderListModel { id: folderModel objectName: "folderModel" showDirs: false nameFilters: root.imageNameFilters } delegate: Rectangle { required property string fileModified required property string fileName required property string fileUrl id: photoFrame objectName: "frame-" + fileName width: image.width * (1 + 0.10 * image.height / image.width) height: image.height * 1.10 scale: root.defaultSize / Math.max(image.sourceSize.width, image.sourceSize.height) border.color: pinchHandler.active || dragHandler.active ? "darkturquoise" : mouse.hovered ? "darkseagreen" : "saddlebrown" border.width: 3 / scale antialiasing: true Component.onCompleted: { x = Math.random() * root.width - width / 2 y = Math.random() * root.height - height / 2 rotation = Math.random() * 13 - 6 } Image { id: image anchors.centerIn: parent fillMode: Image.PreserveAspectFit source: photoFrame.fileUrl antialiasing: true } Text { text: fileName + " ❖ " + Qt.formatDateTime(fileModified, Locale.LongFormat) horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight font.pixelSize: (parent.height - image.height) / 3 anchors { left: parent.left right: parent.right bottom: parent.bottom margins: font.pixelSize / 5 } } MomentumAnimation { id: anim target: photoFrame onFinished: { flick.contentWidth = Math.max(photoFrame.x + photoFrame.width, flick.contentWidth) flick.contentHeight = Math.max(photoFrame.y + photoFrame.height, flick.contentHeight) } } PinchHandler { id: pinchHandler minimumRotation: -360 maximumRotation: 360 minimumScale: 0.1 maximumScale: 10 grabPermissions: PointerHandler.CanTakeOverFromAnything // and never gonna give it up onActiveChanged: if (active) photoFrame.z = ++flick.highestZ } DragHandler { id: dragHandler onActiveChanged: { if (active) photoFrame.z = ++flick.highestZ else anim.restart(centroid.velocity) } } HoverHandler { id: mouse } WheelHandler { acceptedModifiers: Qt.ControlModifier property: "rotation" onActiveChanged: if (active) photoFrame.z = ++flick.highestZ } WheelHandler { acceptedModifiers: Qt.ShiftModifier property: "scale" onActiveChanged: if (active) photoFrame.z = ++flick.highestZ } } } } Image { id: folderIcon visible: false anchors.top: parent.top anchors.left: parent.left anchors.margins: 10 source: "resources/folder.png" TapHandler { onTapped: folderDialog.open() } HoverHandler { id: folderMouse } ToolTip.visible: folderMouse.hovered ToolTip.text: qsTr(`Open an image directory (${openShortcut.nativeText})`) ToolTip.delay: 1000 Shortcut { id: openShortcut sequence: StandardKey.Open onActivated: folderDialog.open() } } Text { visible: folderDialog.visible anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right anchors.margins: 20 color: "white" wrapMode: Text.WordWrap text: qsTr("Choose your own photo folder") } Shortcut { sequence: StandardKey.Quit; onActivated: Qt.quit() } SlideShow { id: welcomeSlides multiFrameSource: "welcome.pdf" anchors.fill: parent Component.onDestruction: { folderIcon.visible = true const lastArg = Application.arguments.slice(-1)[0] const standardPicturesLocations = StandardPaths.standardLocations(StandardPaths.PicturesLocation) const hasValidPicturesLocation = standardPicturesLocations.length > 0 if (hasValidPicturesLocation) folderDialog.currentFolder = standardPicturesLocations[0] if (/.*hotosurface.*|--+/.test(lastArg)) { if (hasValidPicturesLocation) folderModel.folder = standardPicturesLocations[0] else folderDialog.open() } else folderModel.folder = Qt.resolvedUrl("file:" + lastArg) } } }