Warning, /maui/mauikit/src/controls.5/AnimatedImageViewer.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: (C) 2015 Vishesh Handa <vhanda@kde.org>
0003  * SPDX-FileCopyrightText: (C) 2017 Atul Sharma <atulsharma406@gmail.com>
0004  * SPDX-FileCopyrightText: (C) 2017 Marco Martin <mart@kde.org>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007  */
0008 
0009 import QtQuick 2.15
0010 import QtQuick.Controls 2.15
0011 import org.mauikit.controls 1.3 as Maui
0012 
0013 Flickable
0014 {
0015     id: flick
0016     property string currentImageSource
0017 
0018     contentWidth: width
0019     contentHeight: height
0020     boundsBehavior: Flickable.StopAtBounds
0021     boundsMovement: Flickable.StopAtBounds
0022     interactive: contentWidth > width || contentHeight > height
0023     clip: true
0024 
0025     ScrollBar.vertical: ScrollBar {
0026         visible: false
0027     }
0028     ScrollBar.horizontal: ScrollBar {
0029         visible: false
0030     }
0031 
0032     /**
0033       * image : Image
0034       */
0035    property alias image:  image
0036 
0037    property alias sourceSize : image.sourceSize
0038     /**
0039       * fillMode : Image.fillMode
0040       */
0041     property int fillMode: Image.PreserveAspectFit
0042 
0043     /**
0044       * asynchronous : bool
0045       */
0046     property alias asynchronous : image.asynchronous
0047 
0048     /**
0049       * cache : bool
0050       */
0051     property alias cache: image.cache
0052 
0053     /**
0054       * imageWidth : int
0055       */
0056     property alias imageWidth: image.sourceSize.width
0057 
0058     /**
0059       * imageHeight : int
0060       */
0061     property alias imageHeight: image.sourceSize.height
0062 
0063     /**
0064       * animated : bool
0065       */
0066     property bool animated: false
0067 
0068     /**
0069       * source : url
0070       */
0071     property alias source : image.source
0072 
0073     /**
0074       * rightClicked
0075       */
0076     signal rightClicked()
0077 
0078     /**
0079       * pressAndHold
0080       */
0081     signal pressAndHold()
0082 
0083     PinchArea {
0084         width: Math.max(flick.contentWidth, flick.width)
0085         height: Math.max(flick.contentHeight, flick.height)
0086 
0087         property real initialWidth
0088         property real initialHeight
0089 
0090         onPinchStarted: {
0091             initialWidth = flick.contentWidth
0092             initialHeight = flick.contentHeight
0093         }
0094 
0095         onPinchUpdated: {
0096             // adjust content pos due to drag
0097             flick.contentX += pinch.previousCenter.x - pinch.center.x
0098             flick.contentY += pinch.previousCenter.y - pinch.center.y
0099 
0100             // resize content
0101             flick.resizeContent(Math.max(flick.width*0.7, initialWidth * pinch.scale), Math.max(flick.height*0.7, initialHeight * pinch.scale), pinch.center)
0102         }
0103 
0104         onPinchFinished: {
0105             // Move its content within bounds.
0106             if (flick.contentWidth < flick.width ||
0107                 flick.contentHeight < flick.height) {
0108                 zoomAnim.x = 0;
0109                 zoomAnim.y = 0;
0110                 zoomAnim.width = flick.width;
0111                 zoomAnim.height = flick.height;
0112                 zoomAnim.running = true;
0113             } else {
0114                 flick.returnToBounds();
0115             }
0116         }
0117 
0118         ParallelAnimation {
0119             id: zoomAnim
0120             property real x: 0
0121             property real y: 0
0122             property real width: flick.width
0123             property real height: flick.height
0124             NumberAnimation {
0125                 target: flick
0126                 property: "contentWidth"
0127                 from: flick.contentWidth
0128                 to: zoomAnim.width
0129                 duration: Maui.Style.units.longDuration
0130                 easing.type: Easing.InOutQuad
0131             }
0132             NumberAnimation {
0133                 target: flick
0134                 property: "contentHeight"
0135                 from: flick.contentHeight
0136                 to: zoomAnim.height
0137                 duration: Maui.Style.units.longDuration
0138                 easing.type: Easing.InOutQuad
0139             }
0140             NumberAnimation {
0141                 target: flick
0142                 property: "contentY"
0143                 from: flick.contentY
0144                 to: zoomAnim.y
0145                 duration: Maui.Style.units.longDuration
0146                 easing.type: Easing.InOutQuad
0147             }
0148             NumberAnimation {
0149                 target: flick
0150                 property: "contentX"
0151                 from: flick.contentX
0152                 to: zoomAnim.x
0153                 duration: Maui.Style.units.longDuration
0154                 easing.type: Easing.InOutQuad
0155             }
0156         }
0157 
0158         AnimatedImage {
0159             id: image
0160             width: flick.contentWidth
0161             height: flick.contentHeight
0162             fillMode: AnimatedImage.PreserveAspectFit
0163             autoTransform: true
0164             asynchronous: true
0165             onStatusChanged: playing = (status == AnimatedImage.Ready)
0166 
0167             BusyIndicator
0168             {
0169                 anchors.centerIn: parent
0170                 running: parent.status === AnimatedImage.Loading
0171             }
0172 
0173             MouseArea {
0174                 anchors.fill: parent
0175                 acceptedButtons:  Qt.RightButton | Qt.LeftButton
0176                 onClicked:  if(!Maui.Handy.isMobile && mouse.button === Qt.RightButton)
0177                 flick.rightClicked()
0178 
0179                 onPressAndHold: flick.pressAndHold()
0180                 onDoubleClicked: {
0181                     if (flick.interactive) {
0182                         zoomAnim.x = 0;
0183                         zoomAnim.y = 0;
0184                         zoomAnim.width = flick.width;
0185                         zoomAnim.height = flick.height;
0186                         zoomAnim.running = true;
0187                         flick.interactive = !flick.interactive
0188                     } else {
0189                         zoomAnim.x = mouse.x * 2;
0190                         zoomAnim.y = mouse.y *2;
0191                         zoomAnim.width = flick.width * 3;
0192                         zoomAnim.height = flick.height * 3;
0193                         zoomAnim.running = true;
0194                         flick.interactive = !flick.interactive
0195                     }
0196                 }
0197                 onWheel: {
0198                     if (wheel.modifiers & Qt.ControlModifier) {
0199                         if (wheel.angleDelta.y != 0) {
0200                             var factor = 1 + wheel.angleDelta.y / 600;
0201                             zoomAnim.running = false;
0202 
0203                             zoomAnim.width = Math.min(Math.max(flick.width, zoomAnim.width * factor), flick.width * 4);
0204                             zoomAnim.height = Math.min(Math.max(flick.height, zoomAnim.height * factor), flick.height * 4);
0205 
0206                             //actual factors, may be less than factor
0207                             var xFactor = zoomAnim.width / flick.contentWidth;
0208                             var yFactor = zoomAnim.height / flick.contentHeight;
0209 
0210                             zoomAnim.x = flick.contentX * xFactor + (((wheel.x - flick.contentX) * xFactor) - (wheel.x - flick.contentX))
0211                             zoomAnim.y = flick.contentY * yFactor + (((wheel.y - flick.contentY) * yFactor) - (wheel.y - flick.contentY))
0212                             zoomAnim.running = true;
0213 
0214                         } else if (wheel.pixelDelta.y != 0) {
0215                             flick.resizeContent(Math.min(Math.max(flick.width, flick.contentWidth + wheel.pixelDelta.y), flick.width * 4),
0216                                                 Math.min(Math.max(flick.height, flick.contentHeight + wheel.pixelDelta.y), flick.height * 4),
0217                                                 wheel);
0218                         }
0219                     } else {
0220                         flick.contentX += wheel.pixelDelta.x;
0221                         flick.contentY += wheel.pixelDelta.y;
0222                     }
0223                 }
0224             }
0225         }
0226     }
0227 
0228 
0229     /**
0230       *
0231       */
0232     function fit()
0233     {
0234         image.width = image.sourceSize.width
0235     }
0236 
0237     /**
0238       *
0239       */
0240     function fill()
0241     {
0242         image.width = parent.width
0243     }
0244 
0245     /**
0246       *
0247       */
0248     function rotateLeft()
0249     {
0250         image.rotation = image.rotation - 90
0251     }
0252 
0253     /**
0254       *
0255       */
0256     function rotateRight()
0257     {
0258         image.rotation = image.rotation + 90
0259     }
0260 }