Commit dbf1be9c authored by Shawn Rutledge's avatar Shawn Rutledge
Browse files

PdfMultiPageView: retain position after pinch zoom

If you do the pinch on a trackpad, the mouse cursor doesn't move, and
the same visible part of the page will remain under the cursor after the
page is re-rendered.  Likewise when doing the pinch on a touchscreen,
the centroid (midpoint between the two fingers) is held in place,
subject to the constraints that Flickable.returnToBounds() imposes.
Similar to 29cb44ee

.

Also corrected the horizontal scrolling range according to rotation;
added left and right margins so that the page edges are more visible
when the page is wider than the view, and thus the horizontal scrolling
range feels more accurate while the scrollbars are still shown.

Change-Id: Ia2a15eee5bcd5c9e7f025634f02a5a546e6aab68
Reviewed-by: default avatarShawn Rutledge <shawn.rutledge@qt.io>
Showing with 36 additions and 7 deletions
...@@ -121,13 +121,14 @@ Item { ...@@ -121,13 +121,14 @@ Item {
TableView { TableView {
id: tableView id: tableView
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 2
model: root.document === undefined ? 0 : root.document.pageCount model: root.document === undefined ? 0 : root.document.pageCount
rowSpacing: 6 rowSpacing: 6
property real rotationModulus: Math.abs(root.pageRotation % 180) property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360)
property bool rot90: rotationModulus > 45 && rotationModulus < 135 property bool rot90: rotationNorm == 90 || rotationNorm == 270
onRot90Changed: forceLayout() onRot90Changed: forceLayout()
property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0) property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0)
contentWidth: document === undefined ? 0 : document.maxPageWidth * root.renderScale contentWidth: document === undefined ? 0 : (rot90 ? document.maxPageHeight : document.maxPageWidth) * root.renderScale + vscroll.width + 2
// workaround for missing function (see https://codereview.qt-project.org/c/qt/qtdeclarative/+/248464) // workaround for missing function (see https://codereview.qt-project.org/c/qt/qtdeclarative/+/248464)
function itemAtPos(x, y, includeSpacing) { function itemAtPos(x, y, includeSpacing) {
// we don't care about x (assume col 0), and assume includeSpacing is true // we don't care about x (assume col 0), and assume includeSpacing is true
...@@ -139,7 +140,7 @@ Item { ...@@ -139,7 +140,7 @@ Item {
if (child.y < y && (!ret || child.y > ret.y)) if (child.y < y && (!ret || child.y > ret.y))
ret = child ret = child
} }
if (root.debug) if (root.debug && ret !== null)
console.log("given y", y, "found", ret, "@", ret.y) console.log("given y", y, "found", ret, "@", ret.y)
return ret // the delegate with the largest y that is less than the given y return ret // the delegate with the largest y that is less than the given y
} }
...@@ -164,7 +165,7 @@ Item { ...@@ -164,7 +165,7 @@ Item {
width: image.width width: image.width
height: image.height height: image.height
rotation: root.pageRotation rotation: root.pageRotation
anchors.centerIn: parent anchors.centerIn: pinch.active ? undefined : parent
property size pagePointSize: document.pagePointSize(index) property size pagePointSize: document.pagePointSize(index)
property real pageScale: image.paintedWidth / pagePointSize.width property real pageScale: image.paintedWidth / pagePointSize.width
Image { Image {
...@@ -223,19 +224,46 @@ Item { ...@@ -223,19 +224,46 @@ Item {
id: pinch id: pinch
minimumScale: 0.1 minimumScale: 0.1
maximumScale: root.renderScale < 4 ? 2 : 1 maximumScale: root.renderScale < 4 ? 2 : 1
minimumRotation: 0 minimumRotation: root.pageRotation
maximumRotation: 0 maximumRotation: root.pageRotation
enabled: image.sourceSize.width < 5000 enabled: image.sourceSize.width < 5000
onActiveChanged: onActiveChanged:
if (active) { if (active) {
paper.z = 10 paper.z = 10
} else { } else {
paper.z = 0 paper.z = 0
var centroidInPoints = Qt.point(pinch.centroid.position.x / root.renderScale,
pinch.centroid.position.y / root.renderScale)
var centroidInFlickable = tableView.mapFromItem(paper, pinch.centroid.position.x, pinch.centroid.position.y)
var newSourceWidth = image.sourceSize.width * paper.scale var newSourceWidth = image.sourceSize.width * paper.scale
var ratio = newSourceWidth / image.sourceSize.width var ratio = newSourceWidth / image.sourceSize.width
if (root.debug)
console.log("pinch ended on page", index, "with centroid", pinch.centroid.position, centroidInPoints, "wrt flickable", centroidInFlickable,
"page at", pageHolder.x.toFixed(2), pageHolder.y.toFixed(2),
"contentX/Y were", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2))
if (ratio > 1.1 || ratio < 0.9) { if (ratio > 1.1 || ratio < 0.9) {
var centroidOnPage = Qt.point(centroidInPoints.x * root.renderScale * ratio, centroidInPoints.y * root.renderScale * ratio)
paper.scale = 1 paper.scale = 1
paper.x = 0
paper.y = 0
root.renderScale *= ratio root.renderScale *= ratio
tableView.forceLayout()
if (tableView.rotationNorm == 0) {
tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.x - centroidInFlickable.x
tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.y - centroidInFlickable.y
} else if (tableView.rotationNorm == 90) {
tableView.contentX = pageHolder.x + tableView.originX + image.height - centroidOnPage.y - centroidInFlickable.x
tableView.contentY = pageHolder.y + tableView.originY + centroidOnPage.x - centroidInFlickable.y
} else if (tableView.rotationNorm == 180) {
tableView.contentX = pageHolder.x + tableView.originX + image.width - centroidOnPage.x - centroidInFlickable.x
tableView.contentY = pageHolder.y + tableView.originY + image.height - centroidOnPage.y - centroidInFlickable.y
} else if (tableView.rotationNorm == 270) {
tableView.contentX = pageHolder.x + tableView.originX + centroidOnPage.y - centroidInFlickable.x
tableView.contentY = pageHolder.y + tableView.originY + image.width - centroidOnPage.x - centroidInFlickable.y
}
if (root.debug)
console.log("contentX/Y adjusted to", tableView.contentX.toFixed(2), tableView.contentY.toFixed(2), "y @top", pageHolder.y)
tableView.returnToBounds()
} }
} }
grabPermissions: PointerHandler.CanTakeOverFromAnything grabPermissions: PointerHandler.CanTakeOverFromAnything
...@@ -298,6 +326,7 @@ Item { ...@@ -298,6 +326,7 @@ Item {
} }
} }
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
id: vscroll
property bool moved: false property bool moved: false
onPositionChanged: moved = true onPositionChanged: moved = true
onActiveChanged: { onActiveChanged: {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment