Warning, /graphics/okular/mobile/components/DocumentView.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.15 0008 import QtQuick.Controls 2.15 as QQC2 0009 import org.kde.okular 2.0 0010 import "./private" 0011 0012 /** 0013 * A touchscreen optimized view for a document 0014 * 0015 * It supports changing pages by a swipe gesture, pinch zoom 0016 * and flicking to scroll around 0017 */ 0018 QQC2.ScrollView { 0019 id: root 0020 property DocumentItem document 0021 property PageItem page: mouseArea.currPageDelegate.pageItem 0022 signal clicked 0023 0024 //NOTE: on some themes it tries to set the flickable to interactive 0025 //but we need it always non interactive as we need to manage 0026 //dragging by ourselves 0027 Component.onCompleted: flick.interactive = false 0028 Flickable { 0029 id: flick 0030 interactive: false 0031 onWidthChanged: resizeTimer.restart() 0032 onHeightChanged: resizeTimer.restart() 0033 0034 Component.onCompleted: { 0035 flick.contentWidth = flick.width 0036 flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio 0037 } 0038 Connections { 0039 target: root.document 0040 function onUrlChanged() { 0041 resizeTimer.restart() 0042 } 0043 } 0044 Timer { 0045 id: resizeTimer 0046 interval: 250 0047 onTriggered: { 0048 flick.contentWidth = flick.width 0049 flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio 0050 } 0051 } 0052 0053 PinchArea { 0054 width: flick.contentWidth 0055 height: flick.contentHeight 0056 0057 property real initialWidth 0058 property real initialHeight 0059 0060 onPinchStarted: { 0061 initialWidth = mouseArea.currPageDelegate.implicitWidth * mouseArea.currPageDelegate.scaleFactor 0062 initialHeight = mouseArea.currPageDelegate.implicitHeight * mouseArea.currPageDelegate.scaleFactor 0063 } 0064 0065 onPinchUpdated: { 0066 // adjust content pos due to drag 0067 flick.contentX += pinch.previousCenter.x - pinch.center.x 0068 flick.contentY += pinch.previousCenter.y - pinch.center.y 0069 0070 // resize content 0071 //use the scale property during pinch, for speed reasons 0072 if (initialHeight * pinch.scale > flick.height && 0073 initialHeight * pinch.scale < flick.height * 3) { 0074 mouseArea.scale = pinch.scale; 0075 } 0076 resizeTimer.stop(); 0077 flick.returnToBounds(); 0078 } 0079 onPinchFinished: { 0080 flick.resizeContent(Math.max(flick.width+1, initialWidth * mouseArea.scale), Math.max(flick.height, initialHeight * mouseArea.scale), pinch.center); 0081 mouseArea.scale = 1; 0082 0083 resizeTimer.stop() 0084 flick.returnToBounds(); 0085 } 0086 MouseArea { 0087 id: mouseArea 0088 width: parent.width 0089 height: parent.height 0090 0091 property real oldMouseX 0092 property real oldMouseY 0093 property real startMouseX 0094 property real startMouseY 0095 property bool incrementing: true 0096 property Item currPageDelegate: page1 0097 property Item prevPageDelegate: page2 0098 property Item nextPageDelegate: page3 0099 0100 onPressed: { 0101 var pos = mapToItem(flick, mouse.x, mouse.y); 0102 startMouseX = oldMouseX = pos.x; 0103 startMouseY = oldMouseY = pos.y; 0104 } 0105 onPositionChanged: { 0106 var pos = mapToItem(flick, mouse.x, mouse.y); 0107 0108 flick.contentY = Math.max(0, Math.min(flick.contentHeight - flick.height, flick.contentY - (pos.y - oldMouseY))); 0109 0110 if ((pos.x - oldMouseX > 0 && flick.atXBeginning) || 0111 (pos.x - oldMouseX < 0 && flick.atXEnd)) { 0112 currPageDelegate.x += pos.x - oldMouseX; 0113 mouseArea.incrementing = currPageDelegate.x <= 0; 0114 } else { 0115 flick.contentX = Math.max(0, Math.min(flick.contentWidth - flick.width, flick.contentX - (pos.x - oldMouseX))); 0116 } 0117 0118 oldMouseX = pos.x; 0119 oldMouseY = pos.y; 0120 } 0121 onReleased: { 0122 if (root.document.currentPage > 0 && 0123 currPageDelegate.x > width/6) { 0124 switchAnimation.running = true; 0125 } else if (root.document.currentPage < document.pageCount-1 && 0126 currPageDelegate.x < -width/6) { 0127 switchAnimation.running = true; 0128 } else { 0129 resetAnim.running = true; 0130 } 0131 } 0132 onCanceled: { 0133 resetAnim.running = true; 0134 } 0135 onDoubleClicked: { 0136 flick.contentWidth = flick.width 0137 flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio 0138 } 0139 onClicked: { 0140 var pos = mapToItem(flick, mouse.x, mouse.y); 0141 if (Math.abs(startMouseX - pos.x) < 20 && 0142 Math.abs(startMouseY - pos.y) < 20) { 0143 root.clicked(); 0144 } 0145 } 0146 onWheel: { 0147 if (wheel.modifiers & Qt.ControlModifier) { 0148 //generate factors between 0.8 and 1.2 0149 var factor = (((wheel.angleDelta.y / 120)+1) / 5 )+ 0.8; 0150 0151 var newWidth = flick.contentWidth * factor; 0152 var newHeight = flick.contentHeight * factor; 0153 0154 if (newWidth < flick.width || newHeight < flick.height || 0155 newHeight > flick.height * 3) { 0156 return; 0157 } 0158 0159 flick.resizeContent(newWidth, newHeight, Qt.point(wheel.x, wheel.y)); 0160 flick.returnToBounds(); 0161 resizeTimer.stop(); 0162 } else { 0163 flick.contentY = Math.min(flick.contentHeight-flick.height, Math.max(0, flick.contentY - wheel.angleDelta.y)); 0164 } 0165 } 0166 0167 PageView { 0168 id: page1 0169 document: root.document 0170 z: 2 0171 } 0172 PageView { 0173 id: page2 0174 document: root.document 0175 z: 1 0176 } 0177 PageView { 0178 id: page3 0179 document: root.document 0180 z: 0 0181 } 0182 0183 0184 Binding { 0185 target: mouseArea.currPageDelegate 0186 property: "pageNumber" 0187 value: root.document.currentPage 0188 } 0189 Binding { 0190 target: mouseArea.currPageDelegate 0191 property: "visible" 0192 value: true 0193 } 0194 0195 Binding { 0196 target: mouseArea.prevPageDelegate 0197 property: "pageNumber" 0198 value: root.document.currentPage - 1 0199 } 0200 Binding { 0201 target: mouseArea.prevPageDelegate 0202 property: "visible" 0203 value: !mouseArea.incrementing && root.document.currentPage > 0 0204 } 0205 0206 Binding { 0207 target: mouseArea.nextPageDelegate 0208 property: "pageNumber" 0209 value: root.document.currentPage + 1 0210 } 0211 Binding { 0212 target: mouseArea.nextPageDelegate 0213 property: "visible" 0214 value: mouseArea.incrementing && root.document.currentPage < document.pageCount-1 0215 } 0216 0217 SequentialAnimation { 0218 id: switchAnimation 0219 ParallelAnimation { 0220 NumberAnimation { 0221 target: flick 0222 properties: "contentY" 0223 to: 0 0224 easing.type: Easing.InQuad 0225 //hardcoded number, we would need units from kirigami 0226 //which cannot depend from here 0227 duration: 250 0228 } 0229 NumberAnimation { 0230 target: mouseArea.currPageDelegate 0231 properties: "x" 0232 to: mouseArea.incrementing ? -mouseArea.currPageDelegate.width : mouseArea.currPageDelegate.width 0233 easing.type: Easing.InQuad 0234 //hardcoded number, we would need units from kirigami 0235 //which cannot depend from here 0236 duration: 250 0237 } 0238 } 0239 ScriptAction { 0240 script: { 0241 mouseArea.currPageDelegate.z = 0; 0242 mouseArea.prevPageDelegate.z = 1; 0243 mouseArea.nextPageDelegate.z = 2; 0244 } 0245 } 0246 ScriptAction { 0247 script: { 0248 mouseArea.currPageDelegate.x = 0 0249 var oldCur = mouseArea.currPageDelegate; 0250 var oldPrev = mouseArea.prevPageDelegate; 0251 var oldNext = mouseArea.nextPageDelegate; 0252 0253 if (mouseArea.incrementing) { 0254 root.document.currentPage++; 0255 mouseArea.currPageDelegate = oldNext; 0256 mouseArea.prevPageDelegate = oldCur; 0257 mouseArea. nextPageDelegate = oldPrev; 0258 } else { 0259 root.document.currentPage--; 0260 mouseArea.currPageDelegate = oldPrev; 0261 mouseArea.nextPageDelegate = oldCur; 0262 mouseArea.prevPageDelegate = oldNext; 0263 } 0264 mouseArea.currPageDelegate.z = 2; 0265 mouseArea.prevPageDelegate.z = 1; 0266 mouseArea.nextPageDelegate.z = 0; 0267 } 0268 } 0269 } 0270 NumberAnimation { 0271 id: resetAnim 0272 target: mouseArea.currPageDelegate 0273 properties: "x" 0274 to: 0 0275 easing.type: Easing.InQuad 0276 duration: 250 0277 } 0278 } 0279 } 0280 } 0281 }