Warning, /maui/mauikit/src/controls.5/ImageViewer.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: false
0024     
0025     ScrollBar.vertical: ScrollBar
0026     {
0027         visible: false
0028     }
0029     
0030     ScrollBar.horizontal: ScrollBar 
0031     {
0032         visible: false
0033     }
0034     
0035     /**
0036      * image : Image
0037      */
0038     property alias image:  image
0039     
0040     property alias sourceSize : image.sourceSize
0041     /**
0042      * fillMode : Image.fillMode
0043      */
0044     property int fillMode: Image.PreserveAspectFit
0045     
0046     /**
0047      * asynchronous : bool
0048      */
0049     property alias asynchronous : image.asynchronous
0050     
0051     /**
0052      * cache : bool
0053      */
0054     property alias cache: image.cache
0055     
0056     /**
0057      * imageWidth : int
0058      */
0059     property alias imageWidth: image.sourceSize.width
0060     
0061     /**
0062      * imageHeight : int
0063      */
0064     property alias imageHeight: image.sourceSize.height
0065     
0066     /**
0067      * source : url
0068      */
0069     property alias source : image.source
0070     
0071     /**
0072      * rightClicked
0073      */
0074     signal rightClicked()
0075     
0076     /**
0077      * pressAndHold
0078      */
0079     signal pressAndHold()
0080     
0081     PinchArea 
0082     {
0083         width: Math.max(flick.contentWidth, flick.width)
0084         height: Math.max(flick.contentHeight, flick.height)
0085         
0086         property real initialWidth
0087         property real initialHeight
0088         
0089         onPinchStarted: {
0090             initialWidth = flick.contentWidth
0091             initialHeight = flick.contentHeight
0092         }
0093         
0094         onPinchUpdated: {
0095             // adjust content pos due to drag
0096             flick.contentX += pinch.previousCenter.x - pinch.center.x
0097             flick.contentY += pinch.previousCenter.y - pinch.center.y
0098             
0099             // resize content
0100             flick.resizeContent(Math.max(flick.width*0.7, initialWidth * pinch.scale), Math.max(flick.height*0.7, initialHeight * pinch.scale), pinch.center)
0101         }
0102         
0103         onPinchFinished: {
0104             // Move its content within bounds.
0105             if (flick.contentWidth < flick.width ||
0106                 flick.contentHeight < flick.height) {
0107                 zoomAnim.x = 0;
0108             zoomAnim.y = 0;
0109             zoomAnim.width = flick.width;
0110             zoomAnim.height = flick.height;
0111             zoomAnim.running = true;
0112                 } else {
0113                     flick.returnToBounds();
0114                 }
0115         }
0116         
0117         ParallelAnimation {
0118             id: zoomAnim
0119             property real x: 0
0120             property real y: 0
0121             property real width: flick.width
0122             property real height: flick.height
0123             NumberAnimation {
0124                 target: flick
0125                 property: "contentWidth"
0126                 from: flick.contentWidth
0127                 to: zoomAnim.width
0128                 duration: Maui.Style.units.longDuration
0129                 easing.type: Easing.InOutQuad
0130             }
0131             NumberAnimation {
0132                 target: flick
0133                 property: "contentHeight"
0134                 from: flick.contentHeight
0135                 to: zoomAnim.height
0136                 duration: Maui.Style.units.longDuration
0137                 easing.type: Easing.InOutQuad
0138             }
0139             NumberAnimation {
0140                 target: flick
0141                 property: "contentY"
0142                 from: flick.contentY
0143                 to: zoomAnim.y
0144                 duration: Maui.Style.units.longDuration
0145                 easing.type: Easing.InOutQuad
0146             }
0147             NumberAnimation {
0148                 target: flick
0149                 property: "contentX"
0150                 from: flick.contentX
0151                 to: zoomAnim.x
0152                 duration: Maui.Style.units.longDuration
0153                 easing.type: Easing.InOutQuad
0154             }
0155         }
0156         
0157         Image
0158         {
0159             id: image
0160             width: flick.contentWidth
0161             height: flick.contentHeight
0162             fillMode: Image.PreserveAspectFit
0163             autoTransform: true
0164             asynchronous: true
0165             
0166             Maui.ProgressIndicator
0167             {
0168                 width: parent.width
0169                 anchors.bottom: parent.bottom
0170                 visible: image.status === Image.Loading
0171             }
0172             
0173             Maui.Holder
0174             {
0175                 anchors.fill: parent
0176                 visible: image.status === Image.Error || image.status === Image.Null 
0177                 title: i18nd("mauikit", "Oops!")
0178                 body: i18nd("mauikit", "The image could not be loaded.")
0179                 emoji: "qrc:/assets/dialog-information.svg"
0180             }
0181             
0182             MouseArea {
0183                 anchors.fill: parent
0184                 acceptedButtons:  Qt.RightButton | Qt.LeftButton
0185                 onClicked:  if(!Maui.Handy.isMobile && mouse.button === Qt.RightButton)
0186                 flick.rightClicked()
0187                 
0188                 onPressAndHold: flick.pressAndHold()
0189                 onDoubleClicked: {
0190                     if (flick.interactive) {
0191                         zoomAnim.x = 0;
0192                         zoomAnim.y = 0;
0193                         zoomAnim.width = flick.width;
0194                         zoomAnim.height = flick.height;
0195                         zoomAnim.running = true;
0196                         flick.interactive = !flick.interactive
0197                     } else {
0198                         zoomAnim.x = mouse.x * 2;
0199                         zoomAnim.y = mouse.y *2;
0200                         zoomAnim.width = flick.width * 3;
0201                         zoomAnim.height = flick.height * 3;
0202                         zoomAnim.running = true;
0203                         flick.interactive = !flick.interactive
0204                     }
0205                 }
0206                 onWheel: {
0207                     if (wheel.modifiers & Qt.ControlModifier) {
0208                         if (wheel.angleDelta.y != 0) {
0209                             var factor = 1 + wheel.angleDelta.y / 600;
0210                             zoomAnim.running = false;
0211                             
0212                             zoomAnim.width = Math.min(Math.max(flick.width, zoomAnim.width * factor), flick.width * 4);
0213                             zoomAnim.height = Math.min(Math.max(flick.height, zoomAnim.height * factor), flick.height * 4);
0214                             
0215                             //actual factors, may be less than factor
0216                             var xFactor = zoomAnim.width / flick.contentWidth;
0217                             var yFactor = zoomAnim.height / flick.contentHeight;
0218                             
0219                             zoomAnim.x = flick.contentX * xFactor + (((wheel.x - flick.contentX) * xFactor) - (wheel.x - flick.contentX))
0220                             zoomAnim.y = flick.contentY * yFactor + (((wheel.y - flick.contentY) * yFactor) - (wheel.y - flick.contentY))
0221                             zoomAnim.running = true;
0222                             
0223                         } else if (wheel.pixelDelta.y != 0) {
0224                             flick.resizeContent(Math.min(Math.max(flick.width, flick.contentWidth + wheel.pixelDelta.y), flick.width * 4),
0225                                                 Math.min(Math.max(flick.height, flick.contentHeight + wheel.pixelDelta.y), flick.height * 4),
0226                                                 wheel);
0227                         }
0228                     } else {
0229                         
0230                         if(zoomAnim.width !== flick.contentWidth || zoomAnim.height !== flick.contentHeight)
0231                         {
0232                             flick.contentX += wheel.pixelDelta.x;
0233                             flick.contentY += wheel.pixelDelta.y;
0234                         }else
0235                         {
0236                             wheel.accepted = false
0237                         }
0238                     }
0239                 }
0240             }
0241         }
0242     }
0243     
0244     
0245     /**
0246      * 
0247      */
0248     function fit()
0249     {
0250         image.width = image.sourceSize.width
0251     }
0252     
0253     /**
0254      * 
0255      */
0256     function fill()
0257     {
0258         image.width = parent.width
0259     }
0260     
0261     /**
0262      * 
0263      */
0264     function rotateLeft()
0265     {
0266         image.rotation = image.rotation - 90
0267     }
0268     
0269     /**
0270      * 
0271      */
0272     function rotateRight()
0273     {
0274         image.rotation = image.rotation + 90
0275     }
0276 }