ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #07955
[Merge] lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-content-centered into lp:ubuntu-docviewer-app
Stefano Verzegnassi has proposed merging lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-content-centered into lp:ubuntu-docviewer-app.
Commit message:
LibreOffice viewer:
* Show the viewer content at the center of the canvas (excluded spreadsheets)
* Fixed some bug in ScalingPinchArea
* Added a ScalingMouseArea component, for handling the double-tap-to-zoom gesture
* Set the zoom behaviour according to the parameters returned by LOZoom class
* Changed background color for the viewer
* Fixed 'rebound' behaviour for the LOK Viewer
* Added missing signal emissions in LOZoom
Requested reviews:
Ubuntu Document Viewer Developers (ubuntu-docviewer-dev)
Related bugs:
Bug #1501424 in Ubuntu Document Viewer App: "Follow zoom maximum/minimum limit in view controls"
https://bugs.launchpad.net/ubuntu-docviewer-app/+bug/1501424
Bug #1515655 in Ubuntu Document Viewer App: "LO content should be centred to the window, if it's smaller than the window itself."
https://bugs.launchpad.net/ubuntu-docviewer-app/+bug/1515655
Bug #1541582 in Ubuntu Document Viewer App: "Add double-tap-to-zoom gesture in the LibreOffice viewer"
https://bugs.launchpad.net/ubuntu-docviewer-app/+bug/1541582
For more details, see:
https://code.launchpad.net/~verzegnassi-stefano/ubuntu-docviewer-app/lok-content-centered/+merge/283196
LibreOffice viewer:
* Show the viewer content at the center of the canvas (excluded spreadsheets)
* Fixed some bug in ScalingPinchArea
* Added a ScalingMouseArea component, for handling the double-tap-to-zoom gesture
* Set the zoom behaviour according to the parameters returned by LOZoom class
* Changed background color for the viewer
* Fixed 'rebound' behaviour for the LOK Viewer
* Added missing signal emissions in LOZoom
--
Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-content-centered into lp:ubuntu-docviewer-app.
=== added file 'src/app/qml/common/ScalingMouseArea.qml'
--- src/app/qml/common/ScalingMouseArea.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/common/ScalingMouseArea.qml 2016-02-03 21:36:44 +0000
@@ -0,0 +1,116 @@
+import QtQuick 2.4
+
+MouseArea {
+ id: mouseArea
+ property Flickable targetFlickable: null
+ property real totalScale: 1
+
+ property real minimumZoom: 0.5
+ property real thresholdZoom: 1.0
+ property real maximumZoom: 4.0
+ property int zoomDuration: 100
+
+ property real zoomValue: 1
+
+ onDoubleClicked: {
+ var flick = targetFlickable
+
+ var tpt = mouseArea.mapToItem(flick, mouse.x, mouse.y )
+ tpt.x -= flick.width * 0.5
+ tpt.y -= flick.height * 0.5
+
+ var pt = mouseArea.mapToItem(flick.contentItem, mouse.x, mouse.y)
+
+ scaleInfo.fromZoom = zoomValue
+
+ if (zoomValue <= thresholdZoom) {
+ scaleInfo.toZoom = maximumZoom
+ } else {
+ scaleInfo.toZoom = minimumZoom
+ }
+
+ scaleInfo.tempContentX = tpt.x * scaleInfo.effectiveZoom - (flick.width * 0.5)
+ scaleInfo.tempContentY = tpt.y * scaleInfo.effectiveZoom - (flick.height * 0.5)
+
+ scaleInfo.finalContentX = Math.max(0, Math.min(pt.x * scaleInfo.effectiveZoom - (flick.width * 0.5),
+ (flick.contentWidth * scaleInfo.effectiveZoom) - flick.width))
+
+ scaleInfo.finalContentY = Math.max(0, Math.min(pt.y * scaleInfo.effectiveZoom - (flick.height * 0.5),
+ (flick.contentHeight * scaleInfo.effectiveZoom) - flick.height))
+
+ if (zoomValue <= thresholdZoom) {
+ zoomInAnimation.start()
+ } else {
+ zoomOutAnimation.start()
+ }
+ }
+
+
+ QtObject {
+ id: scaleInfo
+
+ property real fromZoom: 1.0
+ property real toZoom: 1.0
+ property real effectiveZoom: toZoom / fromZoom
+
+ property int tempContentX: 0
+ property int tempContentY: 0
+
+ property int finalContentX: 0
+ property int finalContentY: 0
+ }
+
+ SequentialAnimation {
+ id: zoomInAnimation
+
+ ScriptAction { script: targetFlickable.interactive = false; }
+
+ // Fake zooming
+ ParallelAnimation {
+ NumberAnimation {
+ target: targetFlickable.contentItem
+ property: "scale"
+ duration: mouseArea.zoomDuration
+ to: scaleInfo.effectiveZoom
+ }
+
+ NumberAnimation {
+ target: targetFlickable
+ property: "contentX"
+ duration: mouseArea.zoomDuration
+ to: scaleInfo.tempContentX
+ }
+
+ NumberAnimation {
+ target: targetFlickable
+ property: "contentY"
+ duration: mouseArea.zoomDuration
+ to: scaleInfo.tempContentY
+ }
+ }
+
+ ScriptAction { script: targetFlickable.contentItem.scale = 1; }
+
+ ScriptAction { script: totalScale = scaleInfo.toZoom; }
+ ScriptAction { script: targetFlickable.contentX = scaleInfo.finalContentX; }
+ ScriptAction { script: targetFlickable.contentY = scaleInfo.finalContentY; }
+
+ ScriptAction { script: targetFlickable.returnToBounds(); }
+
+ ScriptAction { script: targetFlickable.interactive = true; }
+ }
+
+ SequentialAnimation {
+ id: zoomOutAnimation
+
+ ScriptAction { script: targetFlickable.interactive = false; }
+
+ ScriptAction { script: totalScale = scaleInfo.toZoom; }
+ ScriptAction { script: targetFlickable.contentX = scaleInfo.finalContentX; }
+ ScriptAction { script: targetFlickable.contentY = scaleInfo.finalContentY; }
+
+ ScriptAction { script: targetFlickable.returnToBounds(); }
+
+ ScriptAction { script: targetFlickable.interactive = true; }
+ }
+}
=== modified file 'src/app/qml/common/ScalingPinchArea.qml'
--- src/app/qml/common/ScalingPinchArea.qml 2015-11-21 18:47:25 +0000
+++ src/app/qml/common/ScalingPinchArea.qml 2016-02-03 21:36:44 +0000
@@ -3,53 +3,57 @@
PinchArea {
id: pinchArea
- property var targetFlickable: null
+ property Flickable targetFlickable: null
property real totalScale: 1
+ property real minimumZoom: 0.5
+ property real maximumZoom: 4.0
+ property alias zoomValue: zoomHelper.scale
+
+ pinch {
+ target: Item { id: zoomHelper }
+ minimumScale: pinchArea.minimumZoom
+ maximumScale: pinchArea.maximumZoom
+ }
+
+ onPinchStarted: {
+ targetFlickable.interactive = false
+ }
+
onPinchUpdated: {
pinchUpdatedHandler(pinch)
}
+
onPinchFinished: {
+ targetFlickable.interactive = true
pinchFinishedHandler()
}
- // ------------------------ Desktop DEBUG
-
-// MouseArea {
-// id: testMa
-// anchors.fill: parent
-// visible: Qt.platform.os == "linux"
-// z: 19
-// acceptedButtons: Qt.RightButton
-
-// property int touchPointY
-// property int touchPointX
-// onPressed: {
-// touchPointY = mouse.y
-// touchPointX = mouse.x
-// }
-// onPositionChanged: {
-// var sc = (1 + (mouse.y - touchPointY) / 200)
-// pinchUpdatedHandler({"center" : { "x" : mouse.x, "y" : mouse.y }, "scale" : sc })
-// }
-// onReleased: {
-// pinchFinishedHandler()
-// }
-// }
-
- // ------------------------ Desktop DEBUG end
-
function pinchUpdatedHandler(pinch) {
- targetFlickable.scale = pinch.scale
+ if (zoomHelper.scale < pinchArea.maximumZoom &&
+ zoomHelper.scale > pinchArea.minimumZoom) {
+ targetFlickable.scale = pinch.scale
+ }
}
function pinchFinishedHandler() {
var pt = pinchArea.mapFromItem(targetFlickable, -targetFlickable.contentX , -targetFlickable.contentY )
// console.log("pinchFinishedHandler", -myItem.contentX, -myItem.contentY, Math.round(pt.x), Math.round(pt.y))
- targetFlickable.contentX = -pt.x
- targetFlickable.contentY = -pt.y
- totalScale = targetFlickable.scale * totalScale
+ totalScale = zoomHelper.scale
targetFlickable.scale = 1
+
+ // Overwrite contentX and contentY values.
+ // This is required since a change in contentWidth or contentHeight causes
+ // the Flickable to reset the position of the its content.
+
+ if (targetFlickable.contentWidth > targetFlickable.width)
+ targetFlickable.contentX = -pt.x
+
+ if (targetFlickable.contentHeight > targetFlickable.height)
+ targetFlickable.contentY = -pt.y
+
+ // Return to the legal bounds
+ targetFlickable.returnToBounds()
}
}
=== modified file 'src/app/qml/loView/LOViewPage.qml'
--- src/app/qml/loView/LOViewPage.qml 2016-01-29 12:12:54 +0000
+++ src/app/qml/loView/LOViewPage.qml 2016-02-03 21:36:44 +0000
@@ -95,10 +95,26 @@
id: pinchArea
objectName: "pinchArea"
Layouts.item: "pinchArea"
+ clip: true
targetFlickable: loView
onTotalScaleChanged: targetFlickable.updateContentSize(totalScale)
+ maximumZoom: loView.zoomSettings.maximumZoom
+ minimumZoom: {
+ if (DocumentViewer.desktopMode || mainView.wideWindow)
+ return loView.zoomSettings.minimumZoom
+
+ switch(loView.document.documentType) {
+ case LibreOffice.Document.TextDocument:
+ return loView.zoomSettings.valueFitToWidthZoom
+ case LibreOffice.Document.PresentationDocument:
+ return loView.zoomSettings.valueAutomaticZoom
+ default:
+ return loView.zoomSettings.minimumZoom
+ }
+ }
+
anchors {
top: parent.top
left: parent.left
@@ -106,12 +122,26 @@
bottom: bottomBar.top
}
+ Binding {
+ when: !pinchArea.pinch.active
+ target: pinchArea
+ property: "zoomValue"
+ value: loView.zoomSettings.zoomFactor
+ }
+
+ Rectangle {
+ // Since UITK 1.3, the MainView background is white.
+ // We need to set a different color, otherwise pages
+ // boundaries are not visible.
+ anchors.fill: parent
+ color: "#f5f5f5"
+ }
+
LibreOffice.Viewer {
id: loView
objectName: "loView"
anchors.fill: parent
- clip: true
documentPath: file.path
function updateContentSize(tgtScale) {
@@ -154,6 +184,40 @@
}
}
+ ScalingMouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ targetFlickable: loView
+ onTotalScaleChanged: targetFlickable.updateContentSize(totalScale)
+
+ thresholdZoom: minimumZoom + (maximumZoom - minimumZoom) * 0.75
+ maximumZoom: {
+ if (DocumentViewer.desktopMode || mainView.wideWindow)
+ return 3.0
+
+ return minimumZoom * 3
+ }
+ minimumZoom: {
+ if (DocumentViewer.desktopMode || mainView.wideWindow)
+ return loView.zoomSettings.minimumZoom
+
+ switch(loView.document.documentType) {
+ case LibreOffice.Document.TextDocument:
+ return loView.zoomSettings.valueFitToWidthZoom
+ case LibreOffice.Document.PresentationDocument:
+ return loView.zoomSettings.valueAutomaticZoom
+ default:
+ return loView.zoomSettings.minimumZoom
+ }
+ }
+
+ Binding {
+ target: mouseArea
+ property: "zoomValue"
+ value: loView.zoomSettings.zoomFactor
+ }
+ }
+
Scrollbar { flickableItem: loView; parent: loView.parent }
Scrollbar { flickableItem: loView; parent: loView.parent; align: Qt.AlignBottom }
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lozoom.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lozoom.cpp 2016-01-29 12:12:54 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lozoom.cpp 2016-02-03 21:36:44 +0000
@@ -166,6 +166,8 @@
m_valueFitToWidthZoom = getZoomToFitWidth(m_view->parentFlickable()->width(),
m_view->document()->documentSize(currentPart).width());
+ Q_EMIT valueFitToWidthZoomChanged();
+
if (m_zoomFactor != m_valueFitToWidthZoom) {
setZoomFactor(m_valueFitToWidthZoom);
@@ -189,6 +191,8 @@
m_valueFitToHeightZoom = getZoomToFitHeight(m_view->parentFlickable()->height(),
m_view->document()->documentSize(currentPart).height());
+ Q_EMIT valueFitToHeightZoomChanged();
+
if (m_zoomFactor != m_valueFitToHeightZoom) {
setZoomFactor(m_valueFitToHeightZoom);
@@ -217,6 +221,10 @@
m_valueAutomaticZoom = qMin(m_valueFitToWidthZoom, m_valueFitToHeightZoom);
+ Q_EMIT valueFitToWidthZoomChanged();
+ Q_EMIT valueFitToHeightZoomChanged();
+ Q_EMIT valueAutomaticZoomChanged();
+
if (m_zoomFactor != m_valueAutomaticZoom) {
setZoomFactor(m_valueAutomaticZoom);
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml'
--- src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml 2016-01-20 21:48:21 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml 2016-02-03 21:36:44 +0000
@@ -109,17 +109,41 @@
contentHeight: view.height
contentWidth: view.width
+ topMargin: internal.isSpreadSheet ? 0 : Math.max((rootFlickable.height - view.height) * 0.5, 0)
+ leftMargin: internal.isSpreadSheet ? 0 : Math.max((rootFlickable.width - view.width) * 0.5, 0)
+
boundsBehavior: Flickable.StopAtBounds
+ // WORKAROUND: By default, the rebound transition is active only
+ // when returnToBounds() is called (since 'boundsBehavior' is set to
+ // StopAtBounds - see above).
+ // The default transition is not so aesthetic when we call returnToBounds()
+ // (i.e. while switching current part, or after a zoom gesture), for that
+ // reason we completely disable the transition.
+ // FIXME: This is completely broken if a different transition is set by an Item
+ // that uses the Viewer. Should we perhaps store the default transition somewhere,
+ // apply the "fake" transition only when required, and then restore the default
+ // transition?
+ rebound: Transition {
+ NumberAnimation { properties: "x,y"; duration: 0 }
+ }
+
LibreOffice.View {
id: view
-
parentFlickable: rootFlickable
onCurrentPartChanged: {
// Position view at top-left corner
rootFlickable.contentX = 0
rootFlickable.contentY = 0
+
+ rootFlickable.returnToBounds()
}
}
+
+ QtObject {
+ id: internal
+
+ property bool isSpreadSheet: document.documentType == LibreOffice.Document.SpreadsheetDocument
+ }
}
Follow ups