[app] Added bookPos role to the book model
And fixed a bunch of paging/rotation issues (or at least tried to)
This commit is contained in:
parent
e4cbab0301
commit
04e5a721e8
10 changed files with 204 additions and 175 deletions
|
@ -84,6 +84,13 @@ SilicaFlickable {
|
||||||
if (footnoteView) footnoteView.hide()
|
if (footnoteView) footnoteView.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bzzz() {
|
||||||
|
if (!hapticFeedback) {
|
||||||
|
hapticFeedback = hapticFeedbackComponent.createObject(root)
|
||||||
|
}
|
||||||
|
hapticFeedback.play()
|
||||||
|
}
|
||||||
|
|
||||||
onOrientationChanged: {
|
onOrientationChanged: {
|
||||||
if (footnoteView) {
|
if (footnoteView) {
|
||||||
footnoteView.cancel()
|
footnoteView.cancel()
|
||||||
|
@ -94,10 +101,7 @@ SilicaFlickable {
|
||||||
|
|
||||||
onSelectingChanged: {
|
onSelectingChanged: {
|
||||||
if (selecting) {
|
if (selecting) {
|
||||||
if (!hapticFeedback) {
|
bzzz()
|
||||||
hapticFeedback = hapticFeedbackComponent.createObject(root)
|
|
||||||
}
|
|
||||||
hapticFeedback.play()
|
|
||||||
} else if (!selectionEmpty) {
|
} else if (!selectionEmpty) {
|
||||||
notification.publish()
|
notification.publish()
|
||||||
}
|
}
|
||||||
|
@ -105,21 +109,25 @@ SilicaFlickable {
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: linkMenuComponent
|
id: linkMenuComponent
|
||||||
|
|
||||||
BooksLinkMenu { }
|
BooksLinkMenu { }
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: imageViewComponent
|
id: imageViewComponent
|
||||||
|
|
||||||
BooksImageView { }
|
BooksImageView { }
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: footnoteViewComponent
|
id: footnoteViewComponent
|
||||||
|
|
||||||
BooksFootnoteView { }
|
BooksFootnoteView { }
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: hapticFeedbackComponent
|
id: hapticFeedbackComponent
|
||||||
|
|
||||||
ThemeEffect { effect: ThemeEffect.Press }
|
ThemeEffect { effect: ThemeEffect.Press }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,27 +135,32 @@ SilicaFlickable {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
//% "Back to library"
|
//% "Back to library"
|
||||||
text: qsTrId("harbour-books-book-view-back")
|
text: qsTrId("harbour-books-book-view-back")
|
||||||
|
|
||||||
onClicked: root.closeBook()
|
onClicked: root.closeBook()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BookModel {
|
BookModel {
|
||||||
id: bookModel
|
id: bookModel
|
||||||
|
|
||||||
book: root.book ? root.book : null
|
book: root.book ? root.book : null
|
||||||
size: bookViewWatcher.size
|
size: bookViewWatcher.size
|
||||||
leftMargin: Theme.horizontalPageMargin
|
leftMargin: Theme.horizontalPageMargin
|
||||||
rightMargin: Theme.horizontalPageMargin
|
rightMargin: Theme.horizontalPageMargin
|
||||||
topMargin: Theme.itemSizeSmall
|
topMargin: Theme.itemSizeSmall
|
||||||
bottomMargin: Theme.itemSizeSmall
|
bottomMargin: Theme.itemSizeSmall
|
||||||
|
|
||||||
onJumpToPage: bookView.jumpTo(page)
|
onJumpToPage: bookView.jumpTo(page)
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification {
|
Notification {
|
||||||
id: notification
|
id: notification
|
||||||
|
|
||||||
//: Pop-up notification
|
//: Pop-up notification
|
||||||
//% "Copied to clipboard"
|
//% "Copied to clipboard"
|
||||||
previewBody: qsTrId("harbour-books-book-view-copied_to_clipboard")
|
previewBody: qsTrId("harbour-books-book-view-copied_to_clipboard")
|
||||||
expireTimeout: 2000
|
expireTimeout: 2000
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if ("icon" in notification) {
|
if ("icon" in notification) {
|
||||||
notification.icon = "icon-s-clipboard"
|
notification.icon = "icon-s-clipboard"
|
||||||
|
@ -157,6 +170,7 @@ SilicaFlickable {
|
||||||
|
|
||||||
SilicaListView {
|
SilicaListView {
|
||||||
id: bookView
|
id: bookView
|
||||||
|
|
||||||
model: bookModel
|
model: bookModel
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
flickDeceleration: maximumFlickVelocity
|
flickDeceleration: maximumFlickVelocity
|
||||||
|
@ -167,12 +181,14 @@ SilicaFlickable {
|
||||||
opacity: loading ? 0 : 1
|
opacity: loading ? 0 : 1
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
interactive: root.interactive
|
interactive: root.interactive
|
||||||
|
|
||||||
readonly property real maxContentX: Math.max(0, contentWidth - width)
|
readonly property real maxContentX: Math.max(0, contentWidth - width)
|
||||||
readonly property int currentPage: stackModel.currentPage
|
readonly property int currentPage: stackModel.currentPage
|
||||||
property bool completed
|
property bool completed
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
bookViewWatcher.positionViewAtIndex(currentPage)
|
bookViewWatcher.positionViewAtIndex(currentPage)
|
||||||
|
pager.setPage(currentPage)
|
||||||
completed = true
|
completed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +196,7 @@ SilicaFlickable {
|
||||||
if (completed && !moving && !scrollAnimation.running) {
|
if (completed && !moving && !scrollAnimation.running) {
|
||||||
bookViewWatcher.positionViewAtIndex(currentPage)
|
bookViewWatcher.positionViewAtIndex(currentPage)
|
||||||
}
|
}
|
||||||
|
pager.setPage(currentPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
|
@ -189,17 +206,19 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMovingChanged: {
|
onMovingChanged: {
|
||||||
if (!moving) {
|
if (!moving && currentIndex >= 0) {
|
||||||
updateModel()
|
updateModel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: BooksPageView {
|
delegate: BooksPageView {
|
||||||
id: pageView
|
id: pageView
|
||||||
|
|
||||||
width: bookView.width
|
width: bookView.width
|
||||||
height: bookView.height
|
height: bookView.height
|
||||||
model: bookModel
|
bookModel: bookView.model
|
||||||
page: index
|
page: model.pageIndex
|
||||||
|
bookPos: model.bookPos
|
||||||
leftMargin: bookModel.leftMargin
|
leftMargin: bookModel.leftMargin
|
||||||
rightMargin: bookModel.rightMargin
|
rightMargin: bookModel.rightMargin
|
||||||
topMargin: bookModel.topMargin
|
topMargin: bookModel.topMargin
|
||||||
|
@ -210,6 +229,7 @@ SilicaFlickable {
|
||||||
pageNumberVisible: _currentState.page
|
pageNumberVisible: _currentState.page
|
||||||
currentPage: ListView.isCurrentItem
|
currentPage: ListView.isCurrentItem
|
||||||
title: bookModel.title
|
title: bookModel.title
|
||||||
|
|
||||||
onJumpToPage: bookView.jumpTo(page)
|
onJumpToPage: bookView.jumpTo(page)
|
||||||
onPushPosition: stackModel.pushPosition(position) // bookView.jumpTo(page)
|
onPushPosition: stackModel.pushPosition(position) // bookView.jumpTo(page)
|
||||||
onPageClicked: {
|
onPageClicked: {
|
||||||
|
@ -248,17 +268,11 @@ SilicaFlickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property int jumpingTo: -1
|
|
||||||
function jumpTo(page) {
|
function jumpTo(page) {
|
||||||
if (book && page >=0 && page !== currentIndex) {
|
if (book && page >=0) {
|
||||||
jumpingTo = page
|
console.log("showing page", page)
|
||||||
bookViewWatcher.positionViewAtIndex(page)
|
bookViewWatcher.positionViewAtIndex(page)
|
||||||
pager.currentPage = page
|
stackModel.currentPage = page
|
||||||
jumpingTo = -1
|
|
||||||
if (currentIndex !== page) {
|
|
||||||
console.log("oops, still at", currentPage)
|
|
||||||
resetPager.restart()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,19 +296,18 @@ SilicaFlickable {
|
||||||
|
|
||||||
function updateModel() {
|
function updateModel() {
|
||||||
hideViews()
|
hideViews()
|
||||||
stackModel.currentPage = currentIndex
|
stackModel.currentPage = bookViewWatcher.currentIndex
|
||||||
if (!pager.pressed) {
|
|
||||||
pager.currentPage = currentIndex
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListWatcher {
|
ListWatcher {
|
||||||
id: bookViewWatcher
|
id: bookViewWatcher
|
||||||
|
|
||||||
listView: bookView
|
listView: bookView
|
||||||
}
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
id: scrollAnimation
|
id: scrollAnimation
|
||||||
|
|
||||||
target: bookView
|
target: bookView
|
||||||
property: "contentX"
|
property: "contentX"
|
||||||
duration: 500
|
duration: 500
|
||||||
|
@ -303,17 +316,9 @@ SilicaFlickable {
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: resetPager
|
|
||||||
interval: 0
|
|
||||||
onTriggered: {
|
|
||||||
console.log("resetting pager to", bookView.currentIndex)
|
|
||||||
pager.currentPage = bookView.currentIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BooksPageTools {
|
BooksPageTools {
|
||||||
id: pageTools
|
id: pageTools
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
@ -323,13 +328,16 @@ SilicaFlickable {
|
||||||
rightMargin: bookModel.rightMargin
|
rightMargin: bookModel.rightMargin
|
||||||
opacity: _currentState.tools ? 1 : 0
|
opacity: _currentState.tools ? 1 : 0
|
||||||
visible: opacity > 0 && book && bookModel.pageCount && !loading
|
visible: opacity > 0 && book && bookModel.pageCount && !loading
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
onIncreaseFontSize: bookModel.increaseFontSize()
|
onIncreaseFontSize: bookModel.increaseFontSize()
|
||||||
onDecreaseFontSize: bookModel.decreaseFontSize()
|
onDecreaseFontSize: bookModel.decreaseFontSize()
|
||||||
|
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksPager {
|
BooksPager {
|
||||||
id: pager
|
id: pager
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
@ -341,15 +349,19 @@ SilicaFlickable {
|
||||||
stack: stackModel
|
stack: stackModel
|
||||||
pageCount: bookModel.pageCount
|
pageCount: bookModel.pageCount
|
||||||
width: parent.width
|
width: parent.width
|
||||||
opacity: (_currentState.pager && book && bookModel.pageCount) ? 0.75 : 0
|
opacity: (_currentState.pager && pageCount) ? 0.75 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
|
||||||
onPageChanged: bookView.jumpTo(page)
|
onPageChanged: bookView.jumpTo(page)
|
||||||
|
onFeedback: bzzz()
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksTitleLabel {
|
BooksTitleLabel {
|
||||||
id: titleLabel
|
id: titleLabel
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
@ -365,6 +377,7 @@ SilicaFlickable {
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
id: busyIndicator
|
id: busyIndicator
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
size: BusyIndicatorSize.Large
|
size: BusyIndicatorSize.Large
|
||||||
running: loading
|
running: loading
|
||||||
|
@ -384,10 +397,12 @@ SilicaFlickable {
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
onClicked: root.closeBook()
|
|
||||||
enabled: loading && bookModel.resetReason === BookModel.ReasonLoading
|
enabled: loading && bookModel.resetReason === BookModel.ReasonLoading
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
opacity: enabled ? 1.0 : 0.0
|
opacity: enabled ? 1.0 : 0.0
|
||||||
|
|
||||||
|
onClicked: root.closeBook()
|
||||||
|
|
||||||
Behavior on opacity { FadeAnimation { } }
|
Behavior on opacity { FadeAnimation { } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +417,6 @@ SilicaFlickable {
|
||||||
color: Theme.highlightColor
|
color: Theme.highlightColor
|
||||||
opacity: loading ? 1 : 0
|
opacity: loading ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
text: bookModel ? (bookModel.resetReason == BookModel.ReasonLoading ?
|
text: bookModel ? (bookModel.resetReason == BookModel.ReasonLoading ?
|
||||||
//% "Loading..."
|
//% "Loading..."
|
||||||
qsTrId("harbour-books-book-view-loading") :
|
qsTrId("harbour-books-book-view-loading") :
|
||||||
|
@ -414,10 +428,11 @@ SilicaFlickable {
|
||||||
qsTrId("harbour-books-book-view-applying_smaller_fonts") :
|
qsTrId("harbour-books-book-view-applying_smaller_fonts") :
|
||||||
//% "Formatting..."
|
//% "Formatting..."
|
||||||
qsTrId("harbour-books-book-view-formatting")) : ""
|
qsTrId("harbour-books-book-view-formatting")) : ""
|
||||||
|
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
function performAction(action)
|
function performAction(action) {
|
||||||
{
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case BooksSettings.ActionPreviousPage:
|
case BooksSettings.ActionPreviousPage:
|
||||||
bookView.prevPage()
|
bookView.prevPage()
|
||||||
|
@ -431,8 +446,10 @@ SilicaFlickable {
|
||||||
MediaKey {
|
MediaKey {
|
||||||
enabled: viewActive && haveVolumeUpAction
|
enabled: viewActive && haveVolumeUpAction
|
||||||
key: Qt.Key_VolumeUp
|
key: Qt.Key_VolumeUp
|
||||||
|
|
||||||
onPressed: volumeUpAction()
|
onPressed: volumeUpAction()
|
||||||
onRepeat: volumeUpAction()
|
onRepeat: volumeUpAction()
|
||||||
|
|
||||||
function volumeUpAction() {
|
function volumeUpAction() {
|
||||||
performAction(Settings.volumeUpAction)
|
performAction(Settings.volumeUpAction)
|
||||||
}
|
}
|
||||||
|
@ -441,8 +458,10 @@ SilicaFlickable {
|
||||||
MediaKey {
|
MediaKey {
|
||||||
enabled: viewActive && haveVolumeDownAction
|
enabled: viewActive && haveVolumeDownAction
|
||||||
key: Qt.Key_VolumeDown
|
key: Qt.Key_VolumeDown
|
||||||
|
|
||||||
onPressed: volumeDownAction()
|
onPressed: volumeDownAction()
|
||||||
onRepeat: volumeDownAction()
|
onRepeat: volumeDownAction()
|
||||||
|
|
||||||
function volumeDownAction() {
|
function volumeDownAction() {
|
||||||
performAction(Settings.volumeDownAction)
|
performAction(Settings.volumeDownAction)
|
||||||
}
|
}
|
||||||
|
@ -455,6 +474,7 @@ SilicaFlickable {
|
||||||
|
|
||||||
Resource {
|
Resource {
|
||||||
id: volumeKeysResource
|
id: volumeKeysResource
|
||||||
|
|
||||||
type: Resource.ScaleButton
|
type: Resource.ScaleButton
|
||||||
optional: true
|
optional: true
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,9 @@ Rectangle {
|
||||||
|
|
||||||
color: Settings.pageBackgroundColor
|
color: Settings.pageBackgroundColor
|
||||||
|
|
||||||
property alias model: widget.model
|
|
||||||
property alias page: widget.page
|
property alias page: widget.page
|
||||||
|
property alias bookPos: widget.bookPos
|
||||||
|
property alias bookModel: widget.model
|
||||||
property alias leftMargin: widget.leftMargin
|
property alias leftMargin: widget.leftMargin
|
||||||
property alias rightMargin: widget.rightMargin
|
property alias rightMargin: widget.rightMargin
|
||||||
property alias topMargin: widget.topMargin
|
property alias topMargin: widget.topMargin
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2015-2017 Jolla Ltd.
|
Copyright (C) 2015-2020 Jolla Ltd.
|
||||||
Contact: Slava Monich <slava.monich@jolla.com>
|
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
|
||||||
|
|
||||||
You may use this file under the terms of BSD license as follows:
|
You may use this file under the terms of BSD license as follows:
|
||||||
|
|
||||||
|
@ -8,14 +8,15 @@
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
are met:
|
are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
1. Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer
|
||||||
documentation and/or other materials provided with the distribution.
|
in the documentation and/or other materials provided with the
|
||||||
* Neither the name of Jolla Ltd nor the names of its contributors may
|
distribution.
|
||||||
be used to endorse or promote products derived from this software
|
3. Neither the names of the copyright holders nor the names of its
|
||||||
without specific prior written permission.
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
@ -36,6 +37,7 @@ import harbour.books 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
height: slider.height
|
height: slider.height
|
||||||
|
|
||||||
property var stack
|
property var stack
|
||||||
|
@ -45,10 +47,24 @@ Item {
|
||||||
readonly property bool canGoForward: haveHistory && (stack.currentIndex < (stack.count - 1))
|
readonly property bool canGoForward: haveHistory && (stack.currentIndex < (stack.count - 1))
|
||||||
property real leftMargin: Theme.horizontalPageMargin
|
property real leftMargin: Theme.horizontalPageMargin
|
||||||
property real rightMargin: Theme.horizontalPageMargin
|
property real rightMargin: Theme.horizontalPageMargin
|
||||||
property alias currentPage: slider.value
|
|
||||||
property alias pressed: slider.pressed
|
property alias pressed: slider.pressed
|
||||||
|
property bool _externalChange
|
||||||
|
|
||||||
signal pageChanged(var page)
|
signal pageChanged(var page)
|
||||||
|
signal feedback()
|
||||||
|
|
||||||
|
function clearStack() {
|
||||||
|
if (haveHistory) {
|
||||||
|
stack.clear()
|
||||||
|
feedback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPage(page) {
|
||||||
|
_externalChange = true
|
||||||
|
slider.value = page
|
||||||
|
_externalChange = false
|
||||||
|
}
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
|
@ -71,23 +87,25 @@ Item {
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: navigateBackArea
|
id: navigateBackArea
|
||||||
|
|
||||||
property bool down: pressed && containsMouse
|
property bool down: pressed && containsMouse
|
||||||
width: navigateBack.width + root.leftMargin
|
width: navigateBack.width + root.leftMargin
|
||||||
height: navigateBack.height
|
height: navigateBack.height
|
||||||
|
visible: navigateBack.visible
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
onClicked: stack.back()
|
onClicked: stack.back()
|
||||||
onPressAndHold: stack.clear()
|
onPressAndHold: clearStack()
|
||||||
}
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
id: navigateBack
|
id: navigateBack
|
||||||
|
|
||||||
icon.source: "image://theme/icon-m-left?" + Settings.primaryPageToolColor
|
icon.source: "image://theme/icon-m-left?" + Settings.primaryPageToolColor
|
||||||
opacity: canGoBack ? 1 : 0
|
opacity: canGoBack ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
down: navigateBackArea.down || (pressed && containsMouse)
|
down: navigateBackArea.down || (pressed && containsMouse)
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
|
@ -95,56 +113,58 @@ Item {
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
onClicked: stack.back()
|
onClicked: stack.back()
|
||||||
onPressAndHold: stack.clear()
|
onPressAndHold: clearStack()
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksPageSlider {
|
BooksPageSlider {
|
||||||
id: slider
|
id: slider
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
}
|
|
||||||
width: parent.width - 2*x
|
width: parent.width - 2*x
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
minimumValue: 0
|
minimumValue: 0
|
||||||
maximumValue: pageCount > 0 ? pageCount - 1 : 0
|
maximumValue: pageCount > 0 ? pageCount - 1 : 0
|
||||||
valueText: ""
|
|
||||||
label: ""
|
|
||||||
leftMargin: Theme.horizontalPageMargin
|
leftMargin: Theme.horizontalPageMargin
|
||||||
rightMargin: Theme.horizontalPageMargin
|
rightMargin: Theme.horizontalPageMargin
|
||||||
primaryColor: Settings.primaryPageToolColor
|
primaryColor: Settings.primaryPageToolColor
|
||||||
secondaryColor: Settings.primaryPageToolColor
|
secondaryColor: Settings.primaryPageToolColor
|
||||||
highlightColor: Settings.highlightPageToolColor
|
highlightColor: Settings.highlightPageToolColor
|
||||||
secondaryHighlightColor: Settings.highlightPageToolColor
|
secondaryHighlightColor: Settings.highlightPageToolColor
|
||||||
onSliderValueChanged: root.pageChanged(value)
|
onMaximumValueChanged: _updateHighlightToValue()
|
||||||
|
onSliderValueChanged: if (!_externalChange) pageChanged(value)
|
||||||
Behavior on x { SmoothedAnimation { duration: 250 } }
|
Behavior on x { SmoothedAnimation { duration: 250 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: navigateForwardArea
|
id: navigateForwardArea
|
||||||
|
|
||||||
property bool down: pressed && containsMouse
|
property bool down: pressed && containsMouse
|
||||||
width: navigateForward.width + root.rightMargin
|
width: navigateForward.width + root.rightMargin
|
||||||
height: navigateForward.height
|
height: navigateForward.height
|
||||||
|
visible: navigateForward.visible
|
||||||
anchors {
|
anchors {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
onClicked: stack.forward()
|
onClicked: stack.forward()
|
||||||
onPressAndHold: stack.clear()
|
onPressAndHold: clearStack()
|
||||||
}
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
id: navigateForward
|
id: navigateForward
|
||||||
|
|
||||||
icon.source: "image://theme/icon-m-right?" + Settings.primaryPageToolColor
|
icon.source: "image://theme/icon-m-right?" + Settings.primaryPageToolColor
|
||||||
down: navigateForwardArea.down || (pressed && containsMouse)
|
down: navigateForwardArea.down || (pressed && containsMouse)
|
||||||
opacity: canGoForward ? 1 : 0
|
opacity: canGoForward ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
anchors {
|
anchors {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: root.rightMargin
|
rightMargin: root.rightMargin
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
onClicked: stack.forward()
|
onClicked: stack.forward()
|
||||||
onPressAndHold: stack.clear()
|
onPressAndHold: clearStack()
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2015-2019 Jolla Ltd.
|
Copyright (C) 2015-2020 Jolla Ltd.
|
||||||
Copyright (C) 2015-2019 Slava Monich <slava.monich@jolla.com>
|
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
|
||||||
|
|
||||||
You may use this file under the terms of BSD license as follows:
|
You may use this file under the terms of BSD license as follows:
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ SilicaFlickable {
|
||||||
flickDeceleration: maximumFlickVelocity
|
flickDeceleration: maximumFlickVelocity
|
||||||
orientation: ListView.Horizontal
|
orientation: ListView.Horizontal
|
||||||
snapMode: ListView.SnapOneItem
|
snapMode: ListView.SnapOneItem
|
||||||
|
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
interactive: !dragInProgress && !dragScrollAnimation.running
|
interactive: !dragInProgress && !dragScrollAnimation.running
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,8 @@ void BooksBookModel::PagingTask::performTask()
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
enum BooksBookModelRole {
|
enum BooksBookModelRole {
|
||||||
BooksBookModelPageIndex = Qt::UserRole
|
BooksBookModelPageIndex = Qt::UserRole,
|
||||||
|
BooksBookModelBookPos
|
||||||
};
|
};
|
||||||
|
|
||||||
BooksBookModel::BooksBookModel(QObject* aParent) :
|
BooksBookModel::BooksBookModel(QObject* aParent) :
|
||||||
|
@ -528,11 +529,23 @@ void BooksBookModel::setBottomMargin(int aMargin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BooksBookModel::emitBookPosChanged()
|
||||||
|
{
|
||||||
|
const int n = pageCount();
|
||||||
|
if (n > 0) {
|
||||||
|
const QModelIndex topLeft(index(0));
|
||||||
|
const QModelIndex bottomRight(index(n - 1));
|
||||||
|
const QVector<int> roles(1, BooksBookModelBookPos);
|
||||||
|
Q_EMIT dataChanged(topLeft, bottomRight, roles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BooksBookModel::updateModel(int aPrevPageCount)
|
void BooksBookModel::updateModel(int aPrevPageCount)
|
||||||
{
|
{
|
||||||
const int newPageCount = pageCount();
|
const int newPageCount = pageCount();
|
||||||
if (aPrevPageCount != newPageCount) {
|
if (aPrevPageCount != newPageCount) {
|
||||||
HDEBUG(aPrevPageCount << "->" << newPageCount);
|
HDEBUG(aPrevPageCount << "->" << newPageCount);
|
||||||
|
emitBookPosChanged();
|
||||||
if (newPageCount > aPrevPageCount) {
|
if (newPageCount > aPrevPageCount) {
|
||||||
beginInsertRows(QModelIndex(), aPrevPageCount, newPageCount-1);
|
beginInsertRows(QModelIndex(), aPrevPageCount, newPageCount-1);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
@ -695,6 +708,7 @@ QHash<int,QByteArray> BooksBookModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
roles.insert(BooksBookModelPageIndex, "pageIndex");
|
roles.insert(BooksBookModelPageIndex, "pageIndex");
|
||||||
|
roles.insert(BooksBookModelBookPos, "bookPos");
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,10 +719,13 @@ int BooksBookModel::rowCount(const QModelIndex&) const
|
||||||
|
|
||||||
QVariant BooksBookModel::data(const QModelIndex& aIndex, int aRole) const
|
QVariant BooksBookModel::data(const QModelIndex& aIndex, int aRole) const
|
||||||
{
|
{
|
||||||
const int i = aIndex.row();
|
const int row = aIndex.row();
|
||||||
if (i >= 0 && i < pageCount()) {
|
if (row >= 0 && row < pageCount()) {
|
||||||
switch (aRole) {
|
switch ((BooksBookModelRole)aRole) {
|
||||||
case BooksBookModelPageIndex: return i;
|
case BooksBookModelPageIndex:
|
||||||
|
return row;
|
||||||
|
case BooksBookModelBookPos:
|
||||||
|
return QVariant::fromValue(iData->iPageMarks.at(row));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
|
@ -124,14 +124,15 @@ public:
|
||||||
int fontSizeAdjust() const;
|
int fontSizeAdjust() const;
|
||||||
|
|
||||||
// QAbstractListModel
|
// QAbstractListModel
|
||||||
virtual QHash<int,QByteArray> roleNames() const;
|
virtual QHash<int,QByteArray> roleNames() const Q_DECL_OVERRIDE;
|
||||||
virtual int rowCount(const QModelIndex& aParent) const;
|
virtual int rowCount(const QModelIndex& aParent) const Q_DECL_OVERRIDE;
|
||||||
virtual QVariant data(const QModelIndex& aIndex, int aRole) const;
|
virtual QVariant data(const QModelIndex& aIndex, int aRole) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateSize();
|
void updateSize();
|
||||||
void updateModel(int aPrevPageCount);
|
void updateModel(int aPrevPageCount);
|
||||||
void startReset(ResetReason aReason = ReasonUnknown, bool aFull = true);
|
void startReset(ResetReason aReason = ReasonUnknown, bool aFull = true);
|
||||||
|
void emitBookPosChanged();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onResetProgress(int aProgress);
|
void onResetProgress(int aProgress);
|
||||||
|
@ -141,11 +142,11 @@ private Q_SLOTS:
|
||||||
void onHashChanged();
|
void onHashChanged();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void loadingChanged() Q_DECL_OVERRIDE;
|
||||||
void sizeChanged();
|
void sizeChanged();
|
||||||
void bookChanged();
|
void bookChanged();
|
||||||
void bookModelChanged();
|
void bookModelChanged();
|
||||||
void titleChanged();
|
void titleChanged();
|
||||||
void loadingChanged();
|
|
||||||
void pageCountChanged();
|
void pageCountChanged();
|
||||||
void pageMarksChanged();
|
void pageMarksChanged();
|
||||||
void progressChanged();
|
void progressChanged();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2017 Jolla Ltd.
|
* Copyright (C) 2015-2020 Jolla Ltd.
|
||||||
* Contact: Slava Monich <slava.monich@jolla.com>
|
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
|
||||||
*
|
*
|
||||||
* You may use this file under the terms of the BSD license as follows:
|
* You may use this file under the terms of the BSD license as follows:
|
||||||
*
|
*
|
||||||
|
@ -8,15 +8,15 @@
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in
|
* notice, this list of conditions and the following disclaimer
|
||||||
* the documentation and/or other materials provided with the
|
* in the documentation and/or other materials provided with the
|
||||||
* distribution.
|
* distribution.
|
||||||
* * Neither the name of Jolla Ltd nor the names of its contributors
|
* 3. Neither the names of the copyright holders nor the names of its
|
||||||
* may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived
|
||||||
* software without specific prior written permission.
|
* from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ``USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ BooksListWatcher::BooksListWatcher(QObject* aParent) :
|
||||||
iContentY(0),
|
iContentY(0),
|
||||||
iListView(NULL),
|
iListView(NULL),
|
||||||
iCenterMode(-1),
|
iCenterMode(-1),
|
||||||
iPositionIsChanging(false),
|
iPositionIsChanging(0),
|
||||||
iResizeTimer(new QTimer(this))
|
iResizeTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
iResizeTimer->setSingleShot(true);
|
iResizeTimer->setSingleShot(true);
|
||||||
|
@ -121,6 +121,7 @@ void BooksListWatcher::positionViewAtIndex(int aIndex)
|
||||||
if (iListView) {
|
if (iListView) {
|
||||||
HDEBUG(aIndex);
|
HDEBUG(aIndex);
|
||||||
doPositionViewAtIndex(aIndex);
|
doPositionViewAtIndex(aIndex);
|
||||||
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,21 +147,15 @@ void BooksListWatcher::doPositionViewAtIndex(int aIndex)
|
||||||
iCenterMode = 1;
|
iCenterMode = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iPositionIsChanging = true;
|
iPositionIsChanging++;
|
||||||
positionViewAtIndex(aIndex, iCenterMode);
|
positionViewAtIndex(aIndex, iCenterMode);
|
||||||
// This is probably a bug in QQuickListView - it first calculates
|
const int currentIndex = getCurrentIndex();
|
||||||
// the item position and then starts instantiating the delegates.
|
if (currentIndex != aIndex) {
|
||||||
// If there are no delegates yet, then the average item size is zero
|
|
||||||
// and the resulting item position will always turn out to be zero.
|
|
||||||
// So if we are trying to position the list at a non-zero index and
|
|
||||||
// instead we got positioned at zero, try it again.
|
|
||||||
if (aIndex > 0 && getCurrentIndex() == 0) {
|
|
||||||
// Didn't work from the first try, give it another go
|
// Didn't work from the first try, give it another go
|
||||||
HDEBUG("retrying...");
|
HDEBUG("still" << currentIndex << ", retrying...");
|
||||||
positionViewAtIndex(aIndex, iCenterMode);
|
positionViewAtIndex(aIndex, iCenterMode);
|
||||||
}
|
}
|
||||||
iPositionIsChanging = false;
|
iPositionIsChanging--;
|
||||||
updateCurrentIndex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksListWatcher::positionViewAtIndex(int aIndex, int aMode)
|
void BooksListWatcher::positionViewAtIndex(int aIndex, int aMode)
|
||||||
|
@ -208,10 +203,12 @@ int BooksListWatcher::getCurrentIndex()
|
||||||
void BooksListWatcher::tryToRestoreCurrentIndex()
|
void BooksListWatcher::tryToRestoreCurrentIndex()
|
||||||
{
|
{
|
||||||
HASSERT(!iPositionIsChanging);
|
HASSERT(!iPositionIsChanging);
|
||||||
const int index = getCurrentIndex();
|
if (iCurrentIndex >= 0 && !iPositionIsChanging) {
|
||||||
if (iCurrentIndex != index) {
|
const int index = getCurrentIndex();
|
||||||
if (iCurrentIndex >= 0) {
|
if (iCurrentIndex != index) {
|
||||||
|
HDEBUG(index << "->" << iCurrentIndex);
|
||||||
doPositionViewAtIndex(iCurrentIndex);
|
doPositionViewAtIndex(iCurrentIndex);
|
||||||
|
HDEBUG(getCurrentIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,9 +216,9 @@ void BooksListWatcher::tryToRestoreCurrentIndex()
|
||||||
void BooksListWatcher::updateCurrentIndex()
|
void BooksListWatcher::updateCurrentIndex()
|
||||||
{
|
{
|
||||||
HASSERT(!iPositionIsChanging);
|
HASSERT(!iPositionIsChanging);
|
||||||
if (contentWidth() > 0 || contentHeight() > 0) {
|
if (!iPositionIsChanging && (contentWidth() > 0 || contentHeight() > 0)) {
|
||||||
const int index = getCurrentIndex();
|
const int index = getCurrentIndex();
|
||||||
if (iCurrentIndex != index) {
|
if (iCurrentIndex != index && index >= 0) {
|
||||||
iCurrentIndex = index;
|
iCurrentIndex = index;
|
||||||
HDEBUG(index << contentWidth() << "x" << contentHeight());
|
HDEBUG(index << contentWidth() << "x" << contentHeight());
|
||||||
Q_EMIT currentIndexChanged();
|
Q_EMIT currentIndexChanged();
|
||||||
|
@ -234,7 +231,7 @@ void BooksListWatcher::updateCurrentIndex()
|
||||||
void BooksListWatcher::updateSize()
|
void BooksListWatcher::updateSize()
|
||||||
{
|
{
|
||||||
const QSize size(iListView->width(), iListView->height());
|
const QSize size(iListView->width(), iListView->height());
|
||||||
HDEBUG(size);
|
HDEBUG(size << getCurrentIndex());
|
||||||
if (iSize != size) {
|
if (iSize != size) {
|
||||||
const QSize oldSize(iSize);
|
const QSize oldSize(iSize);
|
||||||
iSize = size;
|
iSize = size;
|
||||||
|
@ -282,7 +279,7 @@ void BooksListWatcher::onContentXChanged()
|
||||||
{
|
{
|
||||||
HASSERT(sender() == iListView);
|
HASSERT(sender() == iListView);
|
||||||
iContentX = contentX();
|
iContentX = contentX();
|
||||||
if (!iPositionIsChanging) {
|
if (!iPositionIsChanging && !iResizeTimer->isActive()) {
|
||||||
updateCurrentIndex();
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +288,7 @@ void BooksListWatcher::onContentYChanged()
|
||||||
{
|
{
|
||||||
HASSERT(sender() == iListView);
|
HASSERT(sender() == iListView);
|
||||||
iContentY = contentY();
|
iContentY = contentY();
|
||||||
if (!iPositionIsChanging) {
|
if (!iPositionIsChanging && !iResizeTimer->isActive()) {
|
||||||
updateCurrentIndex();
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,7 +296,7 @@ void BooksListWatcher::onContentYChanged()
|
||||||
void BooksListWatcher::onContentSizeChanged()
|
void BooksListWatcher::onContentSizeChanged()
|
||||||
{
|
{
|
||||||
HASSERT(sender() == iListView);
|
HASSERT(sender() == iListView);
|
||||||
if (!iPositionIsChanging) {
|
if (!iPositionIsChanging && !iResizeTimer->isActive()) {
|
||||||
tryToRestoreCurrentIndex();
|
tryToRestoreCurrentIndex();
|
||||||
updateCurrentIndex();
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015-2017 Jolla Ltd.
|
* Copyright (C) 2015-2020 Jolla Ltd.
|
||||||
* Contact: Slava Monich <slava.monich@jolla.com>
|
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
|
||||||
*
|
*
|
||||||
* You may use this file under the terms of the BSD license as follows:
|
* You may use this file under the terms of the BSD license as follows:
|
||||||
*
|
*
|
||||||
|
@ -8,15 +8,15 @@
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in
|
* notice, this list of conditions and the following disclaimer
|
||||||
* the documentation and/or other materials provided with the
|
* in the documentation and/or other materials provided with the
|
||||||
* distribution.
|
* distribution.
|
||||||
* * Neither the name of Jolla Ltd nor the names of its contributors
|
* 3. Neither the names of the copyright holders nor the names of its
|
||||||
* may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived
|
||||||
* software without specific prior written permission.
|
* from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
@ -96,7 +96,7 @@ private:
|
||||||
qreal iContentY;
|
qreal iContentY;
|
||||||
QQuickItem* iListView;
|
QQuickItem* iListView;
|
||||||
int iCenterMode;
|
int iCenterMode;
|
||||||
bool iPositionIsChanging;
|
int iPositionIsChanging;
|
||||||
QTimer* iResizeTimer;
|
QTimer* iResizeTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -546,7 +546,7 @@ void BooksPageWidget::setPressed(bool aPressed)
|
||||||
if (iPressed != aPressed) {
|
if (iPressed != aPressed) {
|
||||||
iPressed = aPressed;
|
iPressed = aPressed;
|
||||||
if (!iPressed && iSelecting) {
|
if (!iPressed && iSelecting) {
|
||||||
HDEBUG("leaving selection mode");
|
HDEBUG("page" << iPage << "leaving selection mode");
|
||||||
iSelecting = false;
|
iSelecting = false;
|
||||||
Q_EMIT selectingChanged();
|
Q_EMIT selectingChanged();
|
||||||
}
|
}
|
||||||
|
@ -558,7 +558,7 @@ void BooksPageWidget::setCurrentPage(bool aCurrentPage)
|
||||||
{
|
{
|
||||||
if (iCurrentPage != aCurrentPage) {
|
if (iCurrentPage != aCurrentPage) {
|
||||||
iCurrentPage = aCurrentPage;
|
iCurrentPage = aCurrentPage;
|
||||||
HDEBUG(iCurrentPage);
|
HDEBUG("page" << iPage << iCurrentPage);
|
||||||
if (!iCurrentPage) clearSelection();
|
if (!iCurrentPage) clearSelection();
|
||||||
Q_EMIT currentPageChanged();
|
Q_EMIT currentPageChanged();
|
||||||
}
|
}
|
||||||
|
@ -578,19 +578,11 @@ void BooksPageWidget::setModel(BooksBookModel* aModel)
|
||||||
}
|
}
|
||||||
#endif // HARBOUR_DEBUG
|
#endif // HARBOUR_DEBUG
|
||||||
iTextStyle = iModel->textStyle();
|
iTextStyle = iModel->textStyle();
|
||||||
iPageMark = iModel->pageMark(iPage);
|
|
||||||
connect(iModel, SIGNAL(bookModelChanged()),
|
|
||||||
SLOT(onBookModelChanged()));
|
|
||||||
connect(iModel, SIGNAL(destroyed()),
|
connect(iModel, SIGNAL(destroyed()),
|
||||||
SLOT(onBookModelDestroyed()));
|
SLOT(onBookModelDestroyed()));
|
||||||
connect(iModel, SIGNAL(pageMarksChanged()),
|
|
||||||
SLOT(onBookModelPageMarksChanged()));
|
|
||||||
connect(iModel, SIGNAL(loadingChanged()),
|
|
||||||
SLOT(onBookModelLoadingChanged()));
|
|
||||||
connect(iModel, SIGNAL(textStyleChanged()),
|
connect(iModel, SIGNAL(textStyleChanged()),
|
||||||
SLOT(onTextStyleChanged()));
|
SLOT(onTextStyleChanged()));
|
||||||
} else {
|
} else {
|
||||||
iPageMark.invalidate();
|
|
||||||
iTextStyle = BooksTextStyle::defaults();
|
iTextStyle = BooksTextStyle::defaults();
|
||||||
}
|
}
|
||||||
resetView();
|
resetView();
|
||||||
|
@ -613,14 +605,6 @@ void BooksPageWidget::onColorsChanged()
|
||||||
scheduleRepaint();
|
scheduleRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksPageWidget::onBookModelChanged()
|
|
||||||
{
|
|
||||||
HDEBUG(iModel->title());
|
|
||||||
BooksLoadingSignalBlocker block(this);
|
|
||||||
iPageMark = iModel->pageMark(iPage);
|
|
||||||
resetView();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BooksPageWidget::onBookModelDestroyed()
|
void BooksPageWidget::onBookModelDestroyed()
|
||||||
{
|
{
|
||||||
HDEBUG("model destroyed");
|
HDEBUG("model destroyed");
|
||||||
|
@ -631,46 +615,26 @@ void BooksPageWidget::onBookModelDestroyed()
|
||||||
resetView();
|
resetView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksPageWidget::onBookModelPageMarksChanged()
|
|
||||||
{
|
|
||||||
const BooksPos pos = iModel->pageMark(iPage);
|
|
||||||
if (iPageMark != pos) {
|
|
||||||
BooksLoadingSignalBlocker block(this);
|
|
||||||
iPageMark = pos;
|
|
||||||
HDEBUG("page" << iPage);
|
|
||||||
resetView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BooksPageWidget::onBookModelLoadingChanged()
|
|
||||||
{
|
|
||||||
BooksLoadingSignalBlocker block(this);
|
|
||||||
if (!iModel->loading()) {
|
|
||||||
HDEBUG("page" << iPage);
|
|
||||||
const BooksPos pos = iModel->pageMark(iPage);
|
|
||||||
if (iPageMark != pos) {
|
|
||||||
iPageMark = pos;
|
|
||||||
resetView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BooksPageWidget::setPage(int aPage)
|
void BooksPageWidget::setPage(int aPage)
|
||||||
{
|
{
|
||||||
if (iPage != aPage) {
|
if (iPage != aPage) {
|
||||||
BooksLoadingSignalBlocker block(this);
|
BooksLoadingSignalBlocker block(this);
|
||||||
iPage = aPage;
|
iPage = aPage;
|
||||||
HDEBUG(iPage);
|
HDEBUG(iPage);
|
||||||
const BooksPos pos = iModel->pageMark(iPage);
|
|
||||||
if (iPageMark != pos) {
|
|
||||||
iPageMark = pos;
|
|
||||||
resetView();
|
|
||||||
}
|
|
||||||
resetView();
|
|
||||||
Q_EMIT pageChanged();
|
Q_EMIT pageChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BooksPageWidget::setBookPos(const BooksPos& aBookPos)
|
||||||
|
{
|
||||||
|
if (iBookPos != aBookPos) {
|
||||||
|
iBookPos = aBookPos;
|
||||||
|
HDEBUG("page" << iPage << iBookPos);
|
||||||
|
resetView();
|
||||||
|
Q_EMIT bookPosChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BooksPageWidget::setLeftMargin(int aMargin)
|
void BooksPageWidget::setLeftMargin(int aMargin)
|
||||||
{
|
{
|
||||||
if (iMargins.iLeft != aMargin) {
|
if (iMargins.iLeft != aMargin) {
|
||||||
|
@ -717,7 +681,7 @@ void BooksPageWidget::paint(QPainter* aPainter)
|
||||||
HDEBUG("page" << iPage);
|
HDEBUG("page" << iPage);
|
||||||
aPainter->drawImage(0, 0, iImage);
|
aPainter->drawImage(0, 0, iImage);
|
||||||
iEmpty = false;
|
iEmpty = false;
|
||||||
} else if (iPage >= 0 && iPageMark.valid() && !iData.isNull()) {
|
} else if (iPage >= 0 && iBookPos.valid() && !iData.isNull()) {
|
||||||
if (!iRenderTask) {
|
if (!iRenderTask) {
|
||||||
HDEBUG("page" << iPage << "(scheduled)");
|
HDEBUG("page" << iPage << "(scheduled)");
|
||||||
scheduleRepaint();
|
scheduleRepaint();
|
||||||
|
@ -755,18 +719,19 @@ void BooksPageWidget::resetView()
|
||||||
iFootnoteTask->release(this);
|
iFootnoteTask->release(this);
|
||||||
iFootnoteTask = NULL;
|
iFootnoteTask = NULL;
|
||||||
}
|
}
|
||||||
|
iImage = QImage();
|
||||||
iData.reset();
|
iData.reset();
|
||||||
if (iPage >= 0 && iPageMark.valid() &&
|
if (iPage >= 0 && iBookPos.valid() &&
|
||||||
width() > 0 && height() > 0 && iModel) {
|
width() > 0 && height() > 0 && iModel) {
|
||||||
shared_ptr<ZLTextModel> textModel = iModel->bookTextModel();
|
shared_ptr<ZLTextModel> textModel = iModel->bookTextModel();
|
||||||
if (!textModel.isNull()) {
|
if (!textModel.isNull()) {
|
||||||
(iResetTask = new ResetTask(iTaskQueue->pool(), textModel, iTextStyle,
|
(iResetTask = new ResetTask(iTaskQueue->pool(), textModel, iTextStyle,
|
||||||
width(), height(), iMargins, iPageMark))->
|
width(), height(), iMargins, iBookPos))->
|
||||||
submit(this, SLOT(onResetTaskDone()));
|
submit(this, SLOT(onResetTaskDone()));
|
||||||
cancelRepaint();
|
cancelRepaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!iResetTask && !iEmpty) {
|
if (!iEmpty) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -788,8 +753,7 @@ void BooksPageWidget::scheduleRepaint()
|
||||||
const int h = height();
|
const int h = height();
|
||||||
if (w > 0 && h > 0 && !iData.isNull() && !iData->iView.isNull()) {
|
if (w > 0 && h > 0 && !iData.isNull() && !iData->iView.isNull()) {
|
||||||
const shared_ptr<BooksTextView> view(iData->iView);
|
const shared_ptr<BooksTextView> view(iData->iView);
|
||||||
BooksSettings* settings = iSettings.data();
|
view->setInvertColors(iSettings->invertColors());
|
||||||
view->setInvertColors(settings->invertColors());
|
|
||||||
(iRenderTask = new RenderTask(iTaskQueue->pool(), iData, w, h))->
|
(iRenderTask = new RenderTask(iTaskQueue->pool(), iData, w, h))->
|
||||||
submit(this, SLOT(onRenderTaskDone()));
|
submit(this, SLOT(onRenderTaskDone()));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1013,6 +977,8 @@ void BooksPageWidget::onWidthChanged()
|
||||||
HVERBOSE((int)width());
|
HVERBOSE((int)width());
|
||||||
// Width change will probably be followed by height change
|
// Width change will probably be followed by height change
|
||||||
iResizeTimer->start();
|
iResizeTimer->start();
|
||||||
|
iImage = QImage();
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BooksPageWidget::onHeightChanged()
|
void BooksPageWidget::onHeightChanged()
|
||||||
|
@ -1024,6 +990,8 @@ void BooksPageWidget::onHeightChanged()
|
||||||
updateSize();
|
updateSize();
|
||||||
} else {
|
} else {
|
||||||
iResizeTimer->start();
|
iResizeTimer->start();
|
||||||
|
iImage = QImage();
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ class BooksPageWidget: public QQuickPaintedItem, private BooksLoadingProperty
|
||||||
Q_PROPERTY(int topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
|
Q_PROPERTY(int topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
|
||||||
Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
|
Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
|
||||||
Q_PROPERTY(BooksBookModel* model READ model WRITE setModel NOTIFY modelChanged)
|
Q_PROPERTY(BooksBookModel* model READ model WRITE setModel NOTIFY modelChanged)
|
||||||
|
Q_PROPERTY(BooksPos bookPos READ bookPos WRITE setBookPos NOTIFY bookPosChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Data;
|
class Data;
|
||||||
|
@ -85,6 +86,9 @@ public:
|
||||||
BooksBookModel* model() const;
|
BooksBookModel* model() const;
|
||||||
void setModel(BooksBookModel* aModel);
|
void setModel(BooksBookModel* aModel);
|
||||||
|
|
||||||
|
const BooksPos& bookPos() const;
|
||||||
|
void setBookPos(const BooksPos& aBookPos);
|
||||||
|
|
||||||
int leftMargin() const;
|
int leftMargin() const;
|
||||||
int rightMargin() const;
|
int rightMargin() const;
|
||||||
int topMargin() const;
|
int topMargin() const;
|
||||||
|
@ -103,13 +107,14 @@ public:
|
||||||
Q_INVOKABLE void clearSelection();
|
Q_INVOKABLE void clearSelection();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void loadingChanged();
|
void loadingChanged() Q_DECL_OVERRIDE;
|
||||||
void pressedChanged();
|
void pressedChanged();
|
||||||
void selectingChanged();
|
void selectingChanged();
|
||||||
void selectionEmptyChanged();
|
void selectionEmptyChanged();
|
||||||
void currentPageChanged();
|
void currentPageChanged();
|
||||||
void pageChanged();
|
void pageChanged();
|
||||||
void modelChanged();
|
void modelChanged();
|
||||||
|
void bookPosChanged();
|
||||||
void leftMarginChanged();
|
void leftMarginChanged();
|
||||||
void rightMarginChanged();
|
void rightMarginChanged();
|
||||||
void topMarginChanged();
|
void topMarginChanged();
|
||||||
|
@ -125,10 +130,7 @@ private Q_SLOTS:
|
||||||
void onWidthChanged();
|
void onWidthChanged();
|
||||||
void onHeightChanged();
|
void onHeightChanged();
|
||||||
void onResizeTimeout();
|
void onResizeTimeout();
|
||||||
void onBookModelChanged();
|
|
||||||
void onBookModelDestroyed();
|
void onBookModelDestroyed();
|
||||||
void onBookModelPageMarksChanged();
|
|
||||||
void onBookModelLoadingChanged();
|
|
||||||
void onTextStyleChanged();
|
void onTextStyleChanged();
|
||||||
void onColorsChanged();
|
void onColorsChanged();
|
||||||
void onResetTaskDone();
|
void onResetTaskDone();
|
||||||
|
@ -141,7 +143,7 @@ private Q_SLOTS:
|
||||||
void onFootnoteTaskDone();
|
void onFootnoteTaskDone();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paint(QPainter *painter);
|
void paint(QPainter *painter) Q_DECL_OVERRIDE;
|
||||||
void updateSize();
|
void updateSize();
|
||||||
void resetView();
|
void resetView();
|
||||||
void releaseExtendSelectionTasks();
|
void releaseExtendSelectionTasks();
|
||||||
|
@ -160,7 +162,7 @@ private:
|
||||||
QSharedPointer<BooksSettings> iSettings;
|
QSharedPointer<BooksSettings> iSettings;
|
||||||
shared_ptr<BooksTaskQueue> iTaskQueue;
|
shared_ptr<BooksTaskQueue> iTaskQueue;
|
||||||
shared_ptr<ZLTextStyle> iTextStyle;
|
shared_ptr<ZLTextStyle> iTextStyle;
|
||||||
BooksPos iPageMark;
|
BooksPos iBookPos;
|
||||||
QTimer* iResizeTimer;
|
QTimer* iResizeTimer;
|
||||||
BooksBookModel* iModel;
|
BooksBookModel* iModel;
|
||||||
BooksMargins iMargins;
|
BooksMargins iMargins;
|
||||||
|
@ -192,6 +194,8 @@ inline bool BooksPageWidget::currentPage() const
|
||||||
{ return iCurrentPage; }
|
{ return iCurrentPage; }
|
||||||
inline int BooksPageWidget::page() const
|
inline int BooksPageWidget::page() const
|
||||||
{ return iPage; }
|
{ return iPage; }
|
||||||
|
inline const BooksPos& BooksPageWidget::bookPos() const
|
||||||
|
{ return iBookPos; }
|
||||||
inline BooksBookModel* BooksPageWidget::model() const
|
inline BooksBookModel* BooksPageWidget::model() const
|
||||||
{ return iModel; }
|
{ return iModel; }
|
||||||
inline int BooksPageWidget::leftMargin() const
|
inline int BooksPageWidget::leftMargin() const
|
||||||
|
|
Loading…
Reference in a new issue