[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:
Slava Monich 2020-09-28 02:37:14 +03:00
parent e4cbab0301
commit 04e5a721e8
10 changed files with 204 additions and 175 deletions

View file

@ -84,6 +84,13 @@ SilicaFlickable {
if (footnoteView) footnoteView.hide()
}
function bzzz() {
if (!hapticFeedback) {
hapticFeedback = hapticFeedbackComponent.createObject(root)
}
hapticFeedback.play()
}
onOrientationChanged: {
if (footnoteView) {
footnoteView.cancel()
@ -94,10 +101,7 @@ SilicaFlickable {
onSelectingChanged: {
if (selecting) {
if (!hapticFeedback) {
hapticFeedback = hapticFeedbackComponent.createObject(root)
}
hapticFeedback.play()
bzzz()
} else if (!selectionEmpty) {
notification.publish()
}
@ -105,21 +109,25 @@ SilicaFlickable {
Component {
id: linkMenuComponent
BooksLinkMenu { }
}
Component {
id: imageViewComponent
BooksImageView { }
}
Component {
id: footnoteViewComponent
BooksFootnoteView { }
}
Component {
id: hapticFeedbackComponent
ThemeEffect { effect: ThemeEffect.Press }
}
@ -127,27 +135,32 @@ SilicaFlickable {
MenuItem {
//% "Back to library"
text: qsTrId("harbour-books-book-view-back")
onClicked: root.closeBook()
}
}
BookModel {
id: bookModel
book: root.book ? root.book : null
size: bookViewWatcher.size
leftMargin: Theme.horizontalPageMargin
rightMargin: Theme.horizontalPageMargin
topMargin: Theme.itemSizeSmall
bottomMargin: Theme.itemSizeSmall
onJumpToPage: bookView.jumpTo(page)
}
Notification {
id: notification
//: Pop-up notification
//% "Copied to clipboard"
previewBody: qsTrId("harbour-books-book-view-copied_to_clipboard")
expireTimeout: 2000
Component.onCompleted: {
if ("icon" in notification) {
notification.icon = "icon-s-clipboard"
@ -157,6 +170,7 @@ SilicaFlickable {
SilicaListView {
id: bookView
model: bookModel
anchors.fill: parent
flickDeceleration: maximumFlickVelocity
@ -167,12 +181,14 @@ SilicaFlickable {
opacity: loading ? 0 : 1
visible: opacity > 0
interactive: root.interactive
readonly property real maxContentX: Math.max(0, contentWidth - width)
readonly property int currentPage: stackModel.currentPage
property bool completed
Component.onCompleted: {
bookViewWatcher.positionViewAtIndex(currentPage)
pager.setPage(currentPage)
completed = true
}
@ -180,6 +196,7 @@ SilicaFlickable {
if (completed && !moving && !scrollAnimation.running) {
bookViewWatcher.positionViewAtIndex(currentPage)
}
pager.setPage(currentPage)
}
onCurrentIndexChanged: {
@ -189,17 +206,19 @@ SilicaFlickable {
}
onMovingChanged: {
if (!moving) {
if (!moving && currentIndex >= 0) {
updateModel()
}
}
delegate: BooksPageView {
id: pageView
width: bookView.width
height: bookView.height
model: bookModel
page: index
bookModel: bookView.model
page: model.pageIndex
bookPos: model.bookPos
leftMargin: bookModel.leftMargin
rightMargin: bookModel.rightMargin
topMargin: bookModel.topMargin
@ -210,6 +229,7 @@ SilicaFlickable {
pageNumberVisible: _currentState.page
currentPage: ListView.isCurrentItem
title: bookModel.title
onJumpToPage: bookView.jumpTo(page)
onPushPosition: stackModel.pushPosition(position) // bookView.jumpTo(page)
onPageClicked: {
@ -248,17 +268,11 @@ SilicaFlickable {
}
}
property int jumpingTo: -1
function jumpTo(page) {
if (book && page >=0 && page !== currentIndex) {
jumpingTo = page
if (book && page >=0) {
console.log("showing page", page)
bookViewWatcher.positionViewAtIndex(page)
pager.currentPage = page
jumpingTo = -1
if (currentIndex !== page) {
console.log("oops, still at", currentPage)
resetPager.restart()
}
stackModel.currentPage = page
}
}
@ -282,19 +296,18 @@ SilicaFlickable {
function updateModel() {
hideViews()
stackModel.currentPage = currentIndex
if (!pager.pressed) {
pager.currentPage = currentIndex
}
stackModel.currentPage = bookViewWatcher.currentIndex
}
ListWatcher {
id: bookViewWatcher
listView: bookView
}
NumberAnimation {
id: scrollAnimation
target: bookView
property: "contentX"
duration: 500
@ -303,17 +316,9 @@ SilicaFlickable {
Behavior on opacity { FadeAnimation {} }
Timer {
id: resetPager
interval: 0
onTriggered: {
console.log("resetting pager to", bookView.currentIndex)
pager.currentPage = bookView.currentIndex
}
}
BooksPageTools {
id: pageTools
anchors {
top: parent.top
left: parent.left
@ -323,13 +328,16 @@ SilicaFlickable {
rightMargin: bookModel.rightMargin
opacity: _currentState.tools ? 1 : 0
visible: opacity > 0 && book && bookModel.pageCount && !loading
Behavior on opacity { FadeAnimation {} }
onIncreaseFontSize: bookModel.increaseFontSize()
onDecreaseFontSize: bookModel.decreaseFontSize()
Behavior on opacity { FadeAnimation {} }
}
BooksPager {
id: pager
anchors {
left: parent.left
right: parent.right
@ -341,15 +349,19 @@ SilicaFlickable {
stack: stackModel
pageCount: bookModel.pageCount
width: parent.width
opacity: (_currentState.pager && book && bookModel.pageCount) ? 0.75 : 0
opacity: (_currentState.pager && pageCount) ? 0.75 : 0
visible: opacity > 0
onPageChanged: bookView.jumpTo(page)
onFeedback: bzzz()
Behavior on opacity { FadeAnimation {} }
}
}
BooksTitleLabel {
id: titleLabel
anchors {
top: parent.top
left: parent.left
@ -365,6 +377,7 @@ SilicaFlickable {
BusyIndicator {
id: busyIndicator
anchors.centerIn: parent
size: BusyIndicatorSize.Large
running: loading
@ -384,10 +397,12 @@ SilicaFlickable {
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
}
onClicked: root.closeBook()
enabled: loading && bookModel.resetReason === BookModel.ReasonLoading
visible: opacity > 0
opacity: enabled ? 1.0 : 0.0
onClicked: root.closeBook()
Behavior on opacity { FadeAnimation { } }
}
@ -402,7 +417,6 @@ SilicaFlickable {
color: Theme.highlightColor
opacity: loading ? 1 : 0
visible: opacity > 0
Behavior on opacity { FadeAnimation {} }
text: bookModel ? (bookModel.resetReason == BookModel.ReasonLoading ?
//% "Loading..."
qsTrId("harbour-books-book-view-loading") :
@ -414,10 +428,11 @@ SilicaFlickable {
qsTrId("harbour-books-book-view-applying_smaller_fonts") :
//% "Formatting..."
qsTrId("harbour-books-book-view-formatting")) : ""
Behavior on opacity { FadeAnimation {} }
}
function performAction(action)
{
function performAction(action) {
switch (action) {
case BooksSettings.ActionPreviousPage:
bookView.prevPage()
@ -431,8 +446,10 @@ SilicaFlickable {
MediaKey {
enabled: viewActive && haveVolumeUpAction
key: Qt.Key_VolumeUp
onPressed: volumeUpAction()
onRepeat: volumeUpAction()
function volumeUpAction() {
performAction(Settings.volumeUpAction)
}
@ -441,8 +458,10 @@ SilicaFlickable {
MediaKey {
enabled: viewActive && haveVolumeDownAction
key: Qt.Key_VolumeDown
onPressed: volumeDownAction()
onRepeat: volumeDownAction()
function volumeDownAction() {
performAction(Settings.volumeDownAction)
}
@ -455,6 +474,7 @@ SilicaFlickable {
Resource {
id: volumeKeysResource
type: Resource.ScaleButton
optional: true
}

View file

@ -42,8 +42,9 @@ Rectangle {
color: Settings.pageBackgroundColor
property alias model: widget.model
property alias page: widget.page
property alias bookPos: widget.bookPos
property alias bookModel: widget.model
property alias leftMargin: widget.leftMargin
property alias rightMargin: widget.rightMargin
property alias topMargin: widget.topMargin

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2017 Jolla Ltd.
Contact: Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2020 Jolla Ltd.
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
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
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Jolla Ltd nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
3. Neither the names of the copyright holders nor the names of its
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"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -36,6 +37,7 @@ import harbour.books 1.0
Item {
id: root
height: slider.height
property var stack
@ -45,10 +47,24 @@ Item {
readonly property bool canGoForward: haveHistory && (stack.currentIndex < (stack.count - 1))
property real leftMargin: Theme.horizontalPageMargin
property real rightMargin: Theme.horizontalPageMargin
property alias currentPage: slider.value
property alias pressed: slider.pressed
property bool _externalChange
signal pageChanged(var page)
signal feedback()
function clearStack() {
if (haveHistory) {
stack.clear()
feedback()
}
}
function setPage(page) {
_externalChange = true
slider.value = page
_externalChange = false
}
states: [
State {
@ -71,23 +87,25 @@ Item {
MouseArea {
id: navigateBackArea
property bool down: pressed && containsMouse
width: navigateBack.width + root.leftMargin
height: navigateBack.height
visible: navigateBack.visible
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
onClicked: stack.back()
onPressAndHold: stack.clear()
onPressAndHold: clearStack()
}
IconButton {
id: navigateBack
icon.source: "image://theme/icon-m-left?" + Settings.primaryPageToolColor
opacity: canGoBack ? 1 : 0
visible: opacity > 0
Behavior on opacity { FadeAnimation {} }
down: navigateBackArea.down || (pressed && containsMouse)
anchors {
left: parent.left
@ -95,56 +113,58 @@ Item {
verticalCenter: parent.verticalCenter
}
onClicked: stack.back()
onPressAndHold: stack.clear()
onPressAndHold: clearStack()
Behavior on opacity { FadeAnimation {} }
}
BooksPageSlider {
id: slider
anchors {
bottom: parent.bottom
}
anchors.bottom: parent.bottom
width: parent.width - 2*x
stepSize: 1
minimumValue: 0
maximumValue: pageCount > 0 ? pageCount - 1 : 0
valueText: ""
label: ""
leftMargin: Theme.horizontalPageMargin
rightMargin: Theme.horizontalPageMargin
primaryColor: Settings.primaryPageToolColor
secondaryColor: Settings.primaryPageToolColor
highlightColor: Settings.highlightPageToolColor
secondaryHighlightColor: Settings.highlightPageToolColor
onSliderValueChanged: root.pageChanged(value)
onMaximumValueChanged: _updateHighlightToValue()
onSliderValueChanged: if (!_externalChange) pageChanged(value)
Behavior on x { SmoothedAnimation { duration: 250 } }
}
MouseArea {
id: navigateForwardArea
property bool down: pressed && containsMouse
width: navigateForward.width + root.rightMargin
height: navigateForward.height
visible: navigateForward.visible
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
onClicked: stack.forward()
onPressAndHold: stack.clear()
onPressAndHold: clearStack()
}
IconButton {
id: navigateForward
icon.source: "image://theme/icon-m-right?" + Settings.primaryPageToolColor
down: navigateForwardArea.down || (pressed && containsMouse)
opacity: canGoForward ? 1 : 0
visible: opacity > 0
Behavior on opacity { FadeAnimation {} }
anchors {
right: parent.right
rightMargin: root.rightMargin
verticalCenter: parent.verticalCenter
}
onClicked: stack.forward()
onPressAndHold: stack.clear()
onPressAndHold: clearStack()
Behavior on opacity { FadeAnimation {} }
}
}

View file

@ -1,6 +1,6 @@
/*
Copyright (C) 2015-2019 Jolla Ltd.
Copyright (C) 2015-2019 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2015-2020 Jolla Ltd.
Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of BSD license as follows:
@ -172,6 +172,7 @@ SilicaFlickable {
flickDeceleration: maximumFlickVelocity
orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem
highlightRangeMode: ListView.StrictlyEnforceRange
spacing: Theme.paddingMedium
interactive: !dragInProgress && !dragScrollAnimation.running

View file

@ -299,7 +299,8 @@ void BooksBookModel::PagingTask::performTask()
// ==========================================================================
enum BooksBookModelRole {
BooksBookModelPageIndex = Qt::UserRole
BooksBookModelPageIndex = Qt::UserRole,
BooksBookModelBookPos
};
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)
{
const int newPageCount = pageCount();
if (aPrevPageCount != newPageCount) {
HDEBUG(aPrevPageCount << "->" << newPageCount);
emitBookPosChanged();
if (newPageCount > aPrevPageCount) {
beginInsertRows(QModelIndex(), aPrevPageCount, newPageCount-1);
endInsertRows();
@ -695,6 +708,7 @@ QHash<int,QByteArray> BooksBookModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(BooksBookModelPageIndex, "pageIndex");
roles.insert(BooksBookModelBookPos, "bookPos");
return roles;
}
@ -705,10 +719,13 @@ int BooksBookModel::rowCount(const QModelIndex&) const
QVariant BooksBookModel::data(const QModelIndex& aIndex, int aRole) const
{
const int i = aIndex.row();
if (i >= 0 && i < pageCount()) {
switch (aRole) {
case BooksBookModelPageIndex: return i;
const int row = aIndex.row();
if (row >= 0 && row < pageCount()) {
switch ((BooksBookModelRole)aRole) {
case BooksBookModelPageIndex:
return row;
case BooksBookModelBookPos:
return QVariant::fromValue(iData->iPageMarks.at(row));
}
}
return QVariant();

View file

@ -124,14 +124,15 @@ public:
int fontSizeAdjust() const;
// QAbstractListModel
virtual QHash<int,QByteArray> roleNames() const;
virtual int rowCount(const QModelIndex& aParent) const;
virtual QVariant data(const QModelIndex& aIndex, int aRole) const;
virtual QHash<int,QByteArray> roleNames() const Q_DECL_OVERRIDE;
virtual int rowCount(const QModelIndex& aParent) const Q_DECL_OVERRIDE;
virtual QVariant data(const QModelIndex& aIndex, int aRole) const Q_DECL_OVERRIDE;
private:
void updateSize();
void updateModel(int aPrevPageCount);
void startReset(ResetReason aReason = ReasonUnknown, bool aFull = true);
void emitBookPosChanged();
private Q_SLOTS:
void onResetProgress(int aProgress);
@ -141,11 +142,11 @@ private Q_SLOTS:
void onHashChanged();
Q_SIGNALS:
void loadingChanged() Q_DECL_OVERRIDE;
void sizeChanged();
void bookChanged();
void bookModelChanged();
void titleChanged();
void loadingChanged();
void pageCountChanged();
void pageMarksChanged();
void progressChanged();

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2017 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
*
* 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
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Jolla Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* 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" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ -27,7 +27,7 @@
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* 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.
*/
@ -49,7 +49,7 @@ BooksListWatcher::BooksListWatcher(QObject* aParent) :
iContentY(0),
iListView(NULL),
iCenterMode(-1),
iPositionIsChanging(false),
iPositionIsChanging(0),
iResizeTimer(new QTimer(this))
{
iResizeTimer->setSingleShot(true);
@ -121,6 +121,7 @@ void BooksListWatcher::positionViewAtIndex(int aIndex)
if (iListView) {
HDEBUG(aIndex);
doPositionViewAtIndex(aIndex);
updateCurrentIndex();
}
}
@ -146,21 +147,15 @@ void BooksListWatcher::doPositionViewAtIndex(int aIndex)
iCenterMode = 1;
}
}
iPositionIsChanging = true;
iPositionIsChanging++;
positionViewAtIndex(aIndex, iCenterMode);
// This is probably a bug in QQuickListView - it first calculates
// the item position and then starts instantiating the delegates.
// 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) {
const int currentIndex = getCurrentIndex();
if (currentIndex != aIndex) {
// Didn't work from the first try, give it another go
HDEBUG("retrying...");
HDEBUG("still" << currentIndex << ", retrying...");
positionViewAtIndex(aIndex, iCenterMode);
}
iPositionIsChanging = false;
updateCurrentIndex();
iPositionIsChanging--;
}
void BooksListWatcher::positionViewAtIndex(int aIndex, int aMode)
@ -208,10 +203,12 @@ int BooksListWatcher::getCurrentIndex()
void BooksListWatcher::tryToRestoreCurrentIndex()
{
HASSERT(!iPositionIsChanging);
const int index = getCurrentIndex();
if (iCurrentIndex != index) {
if (iCurrentIndex >= 0) {
if (iCurrentIndex >= 0 && !iPositionIsChanging) {
const int index = getCurrentIndex();
if (iCurrentIndex != index) {
HDEBUG(index << "->" << iCurrentIndex);
doPositionViewAtIndex(iCurrentIndex);
HDEBUG(getCurrentIndex());
}
}
}
@ -219,9 +216,9 @@ void BooksListWatcher::tryToRestoreCurrentIndex()
void BooksListWatcher::updateCurrentIndex()
{
HASSERT(!iPositionIsChanging);
if (contentWidth() > 0 || contentHeight() > 0) {
if (!iPositionIsChanging && (contentWidth() > 0 || contentHeight() > 0)) {
const int index = getCurrentIndex();
if (iCurrentIndex != index) {
if (iCurrentIndex != index && index >= 0) {
iCurrentIndex = index;
HDEBUG(index << contentWidth() << "x" << contentHeight());
Q_EMIT currentIndexChanged();
@ -234,7 +231,7 @@ void BooksListWatcher::updateCurrentIndex()
void BooksListWatcher::updateSize()
{
const QSize size(iListView->width(), iListView->height());
HDEBUG(size);
HDEBUG(size << getCurrentIndex());
if (iSize != size) {
const QSize oldSize(iSize);
iSize = size;
@ -282,7 +279,7 @@ void BooksListWatcher::onContentXChanged()
{
HASSERT(sender() == iListView);
iContentX = contentX();
if (!iPositionIsChanging) {
if (!iPositionIsChanging && !iResizeTimer->isActive()) {
updateCurrentIndex();
}
}
@ -291,7 +288,7 @@ void BooksListWatcher::onContentYChanged()
{
HASSERT(sender() == iListView);
iContentY = contentY();
if (!iPositionIsChanging) {
if (!iPositionIsChanging && !iResizeTimer->isActive()) {
updateCurrentIndex();
}
}
@ -299,7 +296,7 @@ void BooksListWatcher::onContentYChanged()
void BooksListWatcher::onContentSizeChanged()
{
HASSERT(sender() == iListView);
if (!iPositionIsChanging) {
if (!iPositionIsChanging && !iResizeTimer->isActive()) {
tryToRestoreCurrentIndex();
updateCurrentIndex();
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2017 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2020 Slava Monich <slava.monich@jolla.com>
*
* 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
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Jolla Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* 3. Neither the names of the copyright holders nor the names of its
* 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" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ -96,7 +96,7 @@ private:
qreal iContentY;
QQuickItem* iListView;
int iCenterMode;
bool iPositionIsChanging;
int iPositionIsChanging;
QTimer* iResizeTimer;
};

View file

@ -546,7 +546,7 @@ void BooksPageWidget::setPressed(bool aPressed)
if (iPressed != aPressed) {
iPressed = aPressed;
if (!iPressed && iSelecting) {
HDEBUG("leaving selection mode");
HDEBUG("page" << iPage << "leaving selection mode");
iSelecting = false;
Q_EMIT selectingChanged();
}
@ -558,7 +558,7 @@ void BooksPageWidget::setCurrentPage(bool aCurrentPage)
{
if (iCurrentPage != aCurrentPage) {
iCurrentPage = aCurrentPage;
HDEBUG(iCurrentPage);
HDEBUG("page" << iPage << iCurrentPage);
if (!iCurrentPage) clearSelection();
Q_EMIT currentPageChanged();
}
@ -578,19 +578,11 @@ void BooksPageWidget::setModel(BooksBookModel* aModel)
}
#endif // HARBOUR_DEBUG
iTextStyle = iModel->textStyle();
iPageMark = iModel->pageMark(iPage);
connect(iModel, SIGNAL(bookModelChanged()),
SLOT(onBookModelChanged()));
connect(iModel, SIGNAL(destroyed()),
SLOT(onBookModelDestroyed()));
connect(iModel, SIGNAL(pageMarksChanged()),
SLOT(onBookModelPageMarksChanged()));
connect(iModel, SIGNAL(loadingChanged()),
SLOT(onBookModelLoadingChanged()));
connect(iModel, SIGNAL(textStyleChanged()),
SLOT(onTextStyleChanged()));
} else {
iPageMark.invalidate();
iTextStyle = BooksTextStyle::defaults();
}
resetView();
@ -613,14 +605,6 @@ void BooksPageWidget::onColorsChanged()
scheduleRepaint();
}
void BooksPageWidget::onBookModelChanged()
{
HDEBUG(iModel->title());
BooksLoadingSignalBlocker block(this);
iPageMark = iModel->pageMark(iPage);
resetView();
}
void BooksPageWidget::onBookModelDestroyed()
{
HDEBUG("model destroyed");
@ -631,46 +615,26 @@ void BooksPageWidget::onBookModelDestroyed()
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)
{
if (iPage != aPage) {
BooksLoadingSignalBlocker block(this);
iPage = aPage;
HDEBUG(iPage);
const BooksPos pos = iModel->pageMark(iPage);
if (iPageMark != pos) {
iPageMark = pos;
resetView();
}
resetView();
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)
{
if (iMargins.iLeft != aMargin) {
@ -717,7 +681,7 @@ void BooksPageWidget::paint(QPainter* aPainter)
HDEBUG("page" << iPage);
aPainter->drawImage(0, 0, iImage);
iEmpty = false;
} else if (iPage >= 0 && iPageMark.valid() && !iData.isNull()) {
} else if (iPage >= 0 && iBookPos.valid() && !iData.isNull()) {
if (!iRenderTask) {
HDEBUG("page" << iPage << "(scheduled)");
scheduleRepaint();
@ -755,18 +719,19 @@ void BooksPageWidget::resetView()
iFootnoteTask->release(this);
iFootnoteTask = NULL;
}
iImage = QImage();
iData.reset();
if (iPage >= 0 && iPageMark.valid() &&
if (iPage >= 0 && iBookPos.valid() &&
width() > 0 && height() > 0 && iModel) {
shared_ptr<ZLTextModel> textModel = iModel->bookTextModel();
if (!textModel.isNull()) {
(iResetTask = new ResetTask(iTaskQueue->pool(), textModel, iTextStyle,
width(), height(), iMargins, iPageMark))->
width(), height(), iMargins, iBookPos))->
submit(this, SLOT(onResetTaskDone()));
cancelRepaint();
}
}
if (!iResetTask && !iEmpty) {
if (!iEmpty) {
update();
}
}
@ -788,8 +753,7 @@ void BooksPageWidget::scheduleRepaint()
const int h = height();
if (w > 0 && h > 0 && !iData.isNull() && !iData->iView.isNull()) {
const shared_ptr<BooksTextView> view(iData->iView);
BooksSettings* settings = iSettings.data();
view->setInvertColors(settings->invertColors());
view->setInvertColors(iSettings->invertColors());
(iRenderTask = new RenderTask(iTaskQueue->pool(), iData, w, h))->
submit(this, SLOT(onRenderTaskDone()));
} else {
@ -1013,6 +977,8 @@ void BooksPageWidget::onWidthChanged()
HVERBOSE((int)width());
// Width change will probably be followed by height change
iResizeTimer->start();
iImage = QImage();
update();
}
void BooksPageWidget::onHeightChanged()
@ -1024,6 +990,8 @@ void BooksPageWidget::onHeightChanged()
updateSize();
} else {
iResizeTimer->start();
iImage = QImage();
update();
}
}

View file

@ -62,6 +62,7 @@ class BooksPageWidget: public QQuickPaintedItem, private BooksLoadingProperty
Q_PROPERTY(int topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
Q_PROPERTY(BooksBookModel* model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(BooksPos bookPos READ bookPos WRITE setBookPos NOTIFY bookPosChanged)
public:
class Data;
@ -85,6 +86,9 @@ public:
BooksBookModel* model() const;
void setModel(BooksBookModel* aModel);
const BooksPos& bookPos() const;
void setBookPos(const BooksPos& aBookPos);
int leftMargin() const;
int rightMargin() const;
int topMargin() const;
@ -103,13 +107,14 @@ public:
Q_INVOKABLE void clearSelection();
Q_SIGNALS:
void loadingChanged();
void loadingChanged() Q_DECL_OVERRIDE;
void pressedChanged();
void selectingChanged();
void selectionEmptyChanged();
void currentPageChanged();
void pageChanged();
void modelChanged();
void bookPosChanged();
void leftMarginChanged();
void rightMarginChanged();
void topMarginChanged();
@ -125,10 +130,7 @@ private Q_SLOTS:
void onWidthChanged();
void onHeightChanged();
void onResizeTimeout();
void onBookModelChanged();
void onBookModelDestroyed();
void onBookModelPageMarksChanged();
void onBookModelLoadingChanged();
void onTextStyleChanged();
void onColorsChanged();
void onResetTaskDone();
@ -141,7 +143,7 @@ private Q_SLOTS:
void onFootnoteTaskDone();
private:
void paint(QPainter *painter);
void paint(QPainter *painter) Q_DECL_OVERRIDE;
void updateSize();
void resetView();
void releaseExtendSelectionTasks();
@ -160,7 +162,7 @@ private:
QSharedPointer<BooksSettings> iSettings;
shared_ptr<BooksTaskQueue> iTaskQueue;
shared_ptr<ZLTextStyle> iTextStyle;
BooksPos iPageMark;
BooksPos iBookPos;
QTimer* iResizeTimer;
BooksBookModel* iModel;
BooksMargins iMargins;
@ -192,6 +194,8 @@ inline bool BooksPageWidget::currentPage() const
{ return iCurrentPage; }
inline int BooksPageWidget::page() const
{ return iPage; }
inline const BooksPos& BooksPageWidget::bookPos() const
{ return iBookPos; }
inline BooksBookModel* BooksPageWidget::model() const
{ return iModel; }
inline int BooksPageWidget::leftMargin() const