Warning, /libraries/kirigami-addons/src/components/ImageMaximizeDelegate.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
0002 // SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 import QtQuick 2.15
0005 import QtQuick.Controls 2.15 as QQC2
0006 import QtQuick.Layouts 1.15
0007 import Qt.labs.platform 1.1
0008 
0009 import org.kde.kirigami 2.15 as Kirigami
0010 
0011 Item {
0012     id: root
0013 
0014     /**
0015      * @brief The source for the image to be viewed.
0016      */
0017     required property string source
0018 
0019     /**
0020      * @brief The size of the source image.
0021      *
0022      * This is used to calculate the maximum size of the content and temporary image.
0023      */
0024     required property real sourceWidth
0025 
0026     /**
0027      * @brief The size of the source image.
0028      *
0029      * This is used to calculate the maximum size of the content and temporary image.
0030      */
0031     required property real sourceHeight
0032 
0033     /**
0034      * @brief Source for the temporary content.
0035      *
0036      * Typically used when downloading the image to show a thumbnail or other
0037      * temporary image while the main image downloads.
0038      */
0039     required property string tempSource
0040 
0041     /**
0042      * @brief The caption for the item.
0043      *
0044      * Typically set to the filename if no caption is available.
0045      *
0046      * @note Declared here so that parent components can access this parameter
0047      *       when used as a listView delegate.
0048      */
0049     required property string caption
0050 
0051     /**
0052      * @brief The delegate type for this item.
0053      *
0054      * @note Declared here so that parent components can access this parameter
0055      *       when used as a listView delegate.
0056      */
0057     readonly property int type: AlbumModelItem.Image
0058 
0059     /**
0060      * @brief The padding around the content image.
0061      *
0062      * The padding is factored in when calculating the maximum size of the content
0063      * image.
0064      */
0065     property var padding: Kirigami.Units.largeSpacing
0066 
0067     /**
0068      * @brief Multiple by which the image is scaled.
0069      */
0070     property var scaleFactor: 1
0071 
0072     /**
0073      * @brief The angle by which the content image is rotated.
0074      *
0075      * The default orientation of the image is 0 degrees.
0076      */
0077     property int rotationAngle: 0
0078 
0079     /**
0080      * @brief Emitted when the background space around the content item is clicked.
0081      */
0082     signal backgroundClicked()
0083 
0084     /**
0085      * @brief Emitted when the content image is right clicked.
0086      */
0087     signal itemRightClicked()
0088 
0089     /**
0090      * @brief Start media playback.
0091      */
0092     function play() {
0093         image.paused = false
0094     }
0095 
0096     /**
0097      * @brief Pause media playback.
0098      */
0099     function pause() {
0100         image.paused = true
0101     }
0102 
0103     clip: true
0104 
0105     // AnimatedImage so we can handle GIFs.
0106     AnimatedImage {
0107         id: image
0108 
0109         property var rotationInsensitiveWidth: {
0110             if (sourceWidth > 0) {
0111                 return Math.min(root.sourceWidth, root.width - root.padding * 2);
0112             } else {
0113                 return Math.min(sourceSize.width, root.width - root.padding * 2);
0114             }
0115         }
0116         property var rotationInsensitiveHeight: {
0117             if (sourceHeight > 0) {
0118                 return Math.min(root.sourceHeight, root.height - root.padding * 2)
0119             } else {
0120                 return Math.min(sourceSize.height, root.height - root.padding * 2)
0121             }
0122         }
0123 
0124         anchors.centerIn: parent
0125 
0126         source: root.source
0127 
0128         width: root.rotationAngle % 180 === 0 ? rotationInsensitiveWidth : rotationInsensitiveHeight
0129         height: root.rotationAngle % 180 === 0 ? rotationInsensitiveHeight : rotationInsensitiveWidth
0130         fillMode: Image.PreserveAspectFit
0131         clip: true
0132 
0133         Behavior on width {
0134             NumberAnimation {duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic}
0135         }
0136         Behavior on height {
0137             NumberAnimation {duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic}
0138         }
0139 
0140         Image {
0141             id: tempImage
0142             anchors.centerIn: parent
0143             visible: source && status === Image.Ready && image.status !== Image.Ready
0144             width:  root.sourceWidth > 0 || image.sourceSize.width > 0 ? root.sourceWidth : tempImage.sourceSize.width
0145             height: root.sourceHeight > 0 || image.sourceSize.height > 0 ? root.sourceHeight : tempImage.sourceSize.height
0146             source: root.tempSource
0147         }
0148 
0149         transform: [
0150             Rotation {
0151                 origin.x: image.width / 2
0152                 origin.y: image.height / 2
0153                 angle: root.rotationAngle
0154 
0155                 Behavior on angle {
0156                     RotationAnimation {duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic}
0157                 }
0158             },
0159             Scale {
0160                 origin.x: image.width / 2
0161                 origin.y: image.height / 2
0162                 xScale: root.scaleFactor
0163                 yScale: root.scaleFactor
0164 
0165                 Behavior on xScale {
0166                     NumberAnimation {duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic}
0167                 }
0168                 Behavior on yScale {
0169                     NumberAnimation {duration: Kirigami.Units.longDuration; easing.type: Easing.InOutCubic}
0170                 }
0171             }
0172         ]
0173 
0174         MouseArea {
0175             anchors.fill: parent
0176             acceptedButtons: Qt.RightButton
0177             onClicked: root.itemRightClicked()
0178         }
0179     }
0180     QQC2.BusyIndicator {
0181         anchors.centerIn: parent
0182         visible: image.status !== Image.Ready && tempImage.status !== Image.Ready
0183         running: visible
0184     }
0185     MouseArea {
0186         anchors.fill: parent
0187         acceptedButtons: Qt.LeftButton
0188         onClicked: root.backgroundClicked()
0189     }
0190 }