// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \title Photo Surface
    \ingroup qtquickdemos
    \example demos/photosurface
    \image {qtquick-demo-photosurface-small.png} {A collection of photos}
    \meta {tag} {quick,touch}
    \meta {docdependencies} {QtPdf}
    \examplecategory {Application Examples}
    \brief A QML app for touch devices that uses a Repeater with a
    FolderListModel to access content in a folder, and a PinchHandler
    to handle pinch gestures on the fetched content.

    \e{Photo Surface} demonstrates how to use a \l{Repeater} with a \l
    FolderListModel and a \l FolderDialog to access images from a folder
    selected by a user. The example also shows how to handle dragging,
    rotation, and pinch zooming within the same item using \l {Qt Quick Input Handlers}.

    All the app code is contained in one QML file, \c photosurface.qml. Inline
    JavaScript code places, rotates, and scales images on the photo
    surface.

    \include examples-run.qdocinc

    \section1 Creating the Main Window

    To create the main window for the Photo Surface app, use the \l{Window}
    QML type as the root item. It automatically sets up the window for use with
    \l{Qt Quick} graphical types:

    \quotefromfile demos/photosurface/photosurface.qml
    \skipto Window {
    \printuntil imageNameFilters

    \section1 Accessing Folder Contents

    Use a \l{Repeater} QML type together with the \l FolderListModel to display
    the GIF, JPG, and PNG images located in a folder (although main.cpp
    may expand the list of supported image types):

    \quotefromfile demos/photosurface/photosurface.qml
    \skipto Repeater
    \printuntil }

    Import the FolderListModel type:

    \qml
    import Qt.labs.folderlistmodel
    \endqml

    A FolderDialog enables users to select the folder that contains
    the images:

    \quotefromfile demos/photosurface/photosurface.qml
    \skipto FolderDialog
    \printuntil }

    To use the FolderDialog type, add the following import statement:

    \qml
    import QtQuick.Dialogs
    \endqml

    The \c {folderDialog.open()} function opens the file dialog when the
    initial slide show finishes, unless a folder path has been given as a
    command-line argument:

    \skipto Component.onDestruction: {
    \printuntil }

    Users can also click the folder dialog icon to open it. Here, an \l{Image}
    QML type displays the icon. Inside the \l{Image} type, a \l TapHandler with
    the \c onTapped signal handler calls the \c {folderDialog.open()} function:

    \quotefromfile demos/photosurface/photosurface.qml
    \skipuntil Image {
    \skipto Image {
    \printuntil Shortcut {
    \printuntil }
    \printuntil }

    \section1 Displaying Images on the Photo Surface

    A \l{Rectangle} is used as a delegate for a \l{Repeater} to provide a frame
    for each image that the \l FolderListModel finds in the selected folder.
    JavaScript \c Math() methods place the frames randomly on the photo surface,
    rotate them at random angles, and scale the images. The border
    color indicates the state of interaction:

    \quotefromfile demos/photosurface/photosurface.qml
    \skipto Rectangle
    \printuntil Image
    \printuntil }

    \section1 Handling Drag and Pinch Gestures, and the Mouse

    A \l DragHandler and a \l PinchHandler in each photo frame handle dragging,
    pinch zooming, and rotation:

    \skipto PinchHandler
    \printto HoverHandler

    Because the PinchHandler is declared inside the Rectangle, the
    \c PinchHandler.target property is implicitly set so that pinch gestures
    manipulate the Rectangle. The rotation properties specify that the frames
    can be rotated to all angles, and the scale properties specify that they
    can be scaled between \c 0.1 and \c 10. The pinch gesture works equally
    well on a touchscreen or multi-touch touchpad. Transforming the frame
    transforms its contents (the \l Image).

    The \c DragHandler.target property is implicitly set as well, so that you
    can drag a photo with one finger on a touchscreen or touchpad, or with a
    mouse. In the DragHandler's \c onActiveChanged signal handler, the
    selected photo frame raises to the top by increasing the value of its \c z
    property (while the shared \c highestZ property holds the largest \c z
    value that has been used so far). When dragging ends, an animation begins
    to keep it moving in the same direction for a little while, slowing down
    and coming to a stop. If you "fling" a photo past the edge of the surface,
    the surface expands to accommodate its new position. You can move around to
    view different parts of the surface via the ScrollView that contains the
    Repeater and all the photo frames that it populates.

    Since you can drag two photos with two fingers via their DragHandlers, and
    you can also pinch one PinchHandler with two fingers, and collections of
    photos tend to pile on top of each other, you need to adjust \c
    grabPermissions so that the PinchHandler has priority: when the pinch
    gesture begins, it does not allow the DragHandlers to take over the
    touchpoint grabs again.

    To make the example more interactive on computers without touch devices,
    add the \l HoverHandler on which the border.color above depends, and two
    \l {WheelHandler}{WheelHandlers}. One allows you to hold down the Ctrl key
    and use the mouse wheel to twirl the photo around the mouse cursor; with
    the other, you can hold down the Shift key and use the mouse wheel to zoom
    in or out of the position under the cursor. Both of these also raise the
    photo in the same way that the DragHandler above does it:

    \skipto HoverHandler
    \printuntil }
    \printuntil }
    \printuntil }

    \section1 Source files

    \sa {QML Applications}, {Qt Quick Examples and Tutorials}
*/
