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
frameworks
Marco Martin 11 years ago
parent 709121c37c
commit 79622ee9a3
  1. 2
      mobile/components/CMakeLists.txt
  2. 224
      mobile/components/DocumentView.qml
  3. 112
      mobile/components/private/PageView.qml
  4. 2
      mobile/components/qmldir
  5. 35
      mobile/components/testDocumentView.qml

@ -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)

@ -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
}
}
}
}
}

@ -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"
}
}
}
}
}

@ -1,3 +1,3 @@
module org.kde.okular
plugin okularplugin
DocumentView 2.0 DocumentView.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
}
}
Loading…
Cancel
Save