summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Martin <notmart@gmail.com>2015-09-24 15:47:26 (GMT)
committerMarco Martin <notmart@gmail.com>2015-09-24 15:47:26 (GMT)
commit79622ee9a34930f156a7716cdd9a17e65adf5ec7 (patch)
tree18545ce38f75e2c2c497644d4afd64defa682878
parent709121c37cea63479e752362e5b09abff1b8fb66 (diff)
A touchscreen optimized view for a document
It supports changing pages by a swipe gesture, pinch zoom and flicking to scroll around. The mobile application will be ported to this new component
-rw-r--r--mobile/components/CMakeLists.txt2
-rw-r--r--mobile/components/DocumentView.qml224
-rw-r--r--mobile/components/private/PageView.qml112
-rw-r--r--mobile/components/qmldir2
-rw-r--r--mobile/components/testDocumentView.qml35
5 files changed, 374 insertions, 1 deletions
diff --git a/mobile/components/CMakeLists.txt b/mobile/components/CMakeLists.txt
index 336fb9d..a5db04e 100644
--- a/mobile/components/CMakeLists.txt
+++ b/mobile/components/CMakeLists.txt
@@ -33,5 +33,7 @@ target_link_libraries(okularplugin
install(TARGETS okularplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular)
install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular)
+install(FILES DocumentView.qml DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular)
+install(FILES private/PageView.qml DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular/private)
#add_subdirectory(test)
diff --git a/mobile/components/DocumentView.qml b/mobile/components/DocumentView.qml
new file mode 100644
index 0000000..569c1ef
--- /dev/null
+++ b/mobile/components/DocumentView.qml
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2015 by Marco Martin <mart@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import QtQuick 2.2
+import org.kde.okular 2.0
+import "./private"
+
+/**
+ * A touchscreen optimized view for a document
+ *
+ * It supports changing pages by a swipe gesture, pinch zoom
+ * and flicking to scroll around
+ */
+Item {
+ id: root
+ width: 500
+ height: 600
+
+ property DocumentItem documentItem
+
+ Flickable {
+ id: flick
+ anchors.fill: parent
+
+ Component.onCompleted: {
+ flick.contentWidth = flick.width
+ flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio
+ }
+ onWidthChanged: {
+ flick.contentWidth = flick.width
+ flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio
+ }
+
+ PinchArea {
+ width: flick.contentWidth
+ height: flick.contentHeight
+
+ property real initialWidth
+ property real initialHeight
+
+ onPinchStarted: {
+ initialWidth = mouseArea.currPageDelegate.implicitWidth * mouseArea.currPageDelegate.scaleFactor
+ initialHeight = mouseArea.currPageDelegate.implicitHeight * mouseArea.currPageDelegate.scaleFactor
+ }
+
+ onPinchUpdated: {
+ // adjust content pos due to drag
+ flick.contentX += pinch.previousCenter.x - pinch.center.x
+ flick.contentY += pinch.previousCenter.y - pinch.center.y
+
+ // resize content
+ flick.resizeContent(Math.max(flick.width+1, initialWidth * pinch.scale), Math.max(flick.height, initialHeight * pinch.scale), pinch.center);
+ flick.returnToBounds();
+ }
+ MouseArea {
+ id: mouseArea
+ width: parent.width
+ height: parent.height
+
+ property real oldMouseX
+ property real oldMouseY
+ property bool incrementing: true
+ property Item currPageDelegate: page1
+ property Item prevPageDelegate: page2
+ property Item nextPageDelegate: page3
+
+ onPressed: {
+ var pos = mapToItem(flick, mouse.x, mouse.y);
+ oldMouseX = pos.x;
+ oldMouseY = pos.y;
+ }
+ onPositionChanged: {
+ var pos = mapToItem(flick, mouse.x, mouse.y);
+ currPageDelegate.x += pos.x - oldMouseX;
+ mouseArea.incrementing = currPageDelegate.x <= 0;
+
+ preventStealing = (currPageDelegate.x > 0 && flick.atXBeginning) || (currPageDelegate.x < 0 && flick.atXEnd);
+
+ flick.contentY = Math.max(0, Math.min(flick.contentHeight - flick.height, flick.contentY - (pos.y - oldMouseY)));
+
+ oldMouseX = pos.x;
+ oldMouseY = pos.y;
+ }
+ onReleased: {
+ if (root.documentItem.currentPage > 0 &&
+ currPageDelegate.x > width/6) {
+ switchAnimation.running = true;
+ } else if (root.documentItem.currentPage < documentItem.pageCount-1 &&
+ currPageDelegate.x < -width/6) {
+ switchAnimation.running = true;
+ } else {
+ resetAnim.running = true;
+ }
+ preventStealing = false;
+ }
+ onCanceled: {
+ resetAnim.running = true;
+ preventStealing = false;
+ }
+ onDoubleClicked: {
+ flick.contentWidth = flick.width
+ flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio
+ }
+
+ PageView {
+ id: page1
+ document: root.documentItem
+ z: 2
+ }
+ PageView {
+ id: page2
+ document: root.documentItem
+ z: 1
+ }
+ PageView {
+ id: page3
+ document: root.documentItem
+ z: 0
+ }
+
+
+ Binding {
+ target: mouseArea.currPageDelegate
+ property: "pageNumber"
+ value: root.documentItem.currentPage
+ }
+ Binding {
+ target: mouseArea.currPageDelegate
+ property: "visible"
+ value: true
+ }
+
+ Binding {
+ target: mouseArea.prevPageDelegate
+ property: "pageNumber"
+ value: root.documentItem.currentPage - 1
+ }
+ Binding {
+ target: mouseArea.prevPageDelegate
+ property: "visible"
+ value: !mouseArea.incrementing && root.documentItem.currentPage > 0
+ }
+
+ Binding {
+ target: mouseArea.nextPageDelegate
+ property: "pageNumber"
+ value: root.documentItem.currentPage + 1
+ }
+ Binding {
+ target: mouseArea.nextPageDelegate
+ property: "visible"
+ value: mouseArea.incrementing && root.documentItem.currentPage < documentItem.pageCount-1
+ }
+
+ SequentialAnimation {
+ id: switchAnimation
+ NumberAnimation {
+ target: mouseArea.currPageDelegate
+ properties: "x"
+ to: mouseArea.incrementing ? -mouseArea.currPageDelegate.width : mouseArea.currPageDelegate.width
+ easing.type: Easing.InQuad
+ //hardcoded number, we would need units from plasma
+ //which cannot depend from here
+ duration: 250
+ }
+ ScriptAction {
+ script: {
+ mouseArea.currPageDelegate.z = 0;
+ mouseArea.prevPageDelegate.z = 1;
+ mouseArea.nextPageDelegate.z = 2;
+ }
+ }
+ ScriptAction {
+ script: {
+ mouseArea.currPageDelegate.x = 0
+ var oldCur = mouseArea.currPageDelegate;
+ var oldPrev = mouseArea.prevPageDelegate;
+ var oldNext = mouseArea.nextPageDelegate;
+
+ if (mouseArea.incrementing) {
+ root.documentItem.currentPage++;
+ mouseArea.currPageDelegate = oldNext;
+ mouseArea.prevPageDelegate = oldCur;
+ mouseArea. nextPageDelegate = oldPrev;
+ } else {
+ root.documentItem.currentPage--;
+ mouseArea.currPageDelegate = oldPrev;
+ mouseArea.prevPageDelegate = oldCur;
+ mouseArea. nextPageDelegate = oldNext;
+ }
+ mouseArea.currPageDelegate.z = 2;
+ mouseArea.prevPageDelegate.z = 1;
+ mouseArea.nextPageDelegate.z = 0;
+ }
+ }
+ }
+ NumberAnimation {
+ id: resetAnim
+ target: mouseArea.currPageDelegate
+ properties: "x"
+ to: 0
+ easing.type: Easing.InQuad
+ duration: 250
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mobile/components/private/PageView.qml b/mobile/components/private/PageView.qml
new file mode 100644
index 0000000..dc4e4d6
--- /dev/null
+++ b/mobile/components/private/PageView.qml
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2015 by Marco Martin <mart@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import org.kde.okular 2.0 as Okular
+
+Item {
+ width: parent.width
+ height: parent.height
+ property alias document: page.document
+ property alias pageNumber: page.pageNumber
+ implicitWidth: page.implicitWidth
+ implicitHeight: page.implicitHeight
+ property real pageRatio: page.implicitWidth / page.implicitHeight
+ property real scaleFactor: page.width / page.implicitWidth
+
+ Okular.PageItem {
+ id: page
+ property bool sameOrientation: parent.width / parent.height > pageRatio
+ anchors.centerIn: parent
+ width: sameOrientation ? parent.height * pageRatio : parent.width
+ height: !sameOrientation ? parent.width / pageRatio : parent.height
+ document: null
+ }
+
+ //FIXME: this should use units, but can't depend from plasma from here
+ Text {
+ id: unit
+ text: "M"
+ visible: false
+ }
+ Rectangle {
+ id: backgroundRectangle
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ left: page.left
+ right: page.right
+ topMargin: -unit.height * 10
+ bottomMargin: -unit.height * 10
+ }
+ z: -1
+ color: "white"
+
+ LinearGradient {
+ width: unit.width
+ anchors {
+ right: parent.left
+ top: parent.top
+ bottom: parent.bottom
+ }
+ start: Qt.point(0, 0)
+ end: Qt.point(unit.width, 0)
+ gradient: Gradient {
+ GradientStop {
+ position: 0.0
+ color: "transparent"
+ }
+ GradientStop {
+ position: 0.7
+ color: Qt.rgba(0, 0, 0, 0.08)
+ }
+ GradientStop {
+ position: 1.0
+ color: Qt.rgba(0, 0, 0, 0.2)
+ }
+ }
+ }
+
+ LinearGradient {
+ width: unit.width
+ anchors {
+ left: parent.right
+ top: parent.top
+ bottom: parent.bottom
+ }
+ start: Qt.point(0, 0)
+ end: Qt.point(unit.width, 0)
+ gradient: Gradient {
+ GradientStop {
+ position: 0.0
+ color: Qt.rgba(0, 0, 0, 0.2)
+ }
+ GradientStop {
+ position: 0.3
+ color: Qt.rgba(0, 0, 0, 0.08)
+ }
+ GradientStop {
+ position: 1.0
+ color: "transparent"
+ }
+ }
+ }
+ }
+}
diff --git a/mobile/components/qmldir b/mobile/components/qmldir
index 4d3cc27..26164a8 100644
--- a/mobile/components/qmldir
+++ b/mobile/components/qmldir
@@ -1,3 +1,3 @@
module org.kde.okular
plugin okularplugin
-
+DocumentView 2.0 DocumentView.qml
diff --git a/mobile/components/testDocumentView.qml b/mobile/components/testDocumentView.qml
new file mode 100644
index 0000000..c913810
--- /dev/null
+++ b/mobile/components/testDocumentView.qml
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012 by Marco Martin <mart@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import QtQuick 2.2
+import QtQuick.Controls 1.0
+import org.kde.okular 2.0 as Okular
+
+Item {
+ width: 500
+ height: 600
+ Okular.DocumentItem {
+ id: docItem
+ path: "pageitem.cpp"
+ }
+ Okular.DocumentView {
+ anchors.fill: parent
+ documentItem: docItem
+ }
+} \ No newline at end of file