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