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 }