[app] Implemented a fancy way of closing the book

By swiping it up
This commit is contained in:
Slava Monich 2020-11-03 03:12:22 +02:00
parent a22d4f383a
commit cf51192137
3 changed files with 109 additions and 37 deletions

View file

@ -65,6 +65,7 @@ Item {
property alias viewInteractive: bookView.interactive property alias viewInteractive: bookView.interactive
property alias pullDownMenu: menu property alias pullDownMenu: menu
property alias isCurrentView: menu.visible
property bool pageActive property bool pageActive
readonly property bool viewActive: pageActive && Qt.application.active && book readonly property bool viewActive: pageActive && Qt.application.active && book
@ -131,11 +132,24 @@ Item {
ThemeEffect { effect: ThemeEffect.Press } ThemeEffect { effect: ThemeEffect.Press }
} }
Behavior on opacity {
enabled: menu.backToLibrary === 0
FadeAnimation { }
}
Binding on opacity {
// Fade out the page while menu is bouncing back
when: menu.backToLibrary < 0
value: menu.flickable.contentY / menu.backToLibrary
}
PullDownMenu { PullDownMenu {
id: menu id: menu
visible: false // BooksMainPage will make it visible when it's needed visible: false // BooksMainPage will make it visible when it's needed
property real backToLibrary
MenuItem { MenuItem {
//: Pulley menu item //: Pulley menu item
//% "Settings" //% "Settings"
@ -159,7 +173,16 @@ Item {
//% "Back to library" //% "Back to library"
text: qsTrId("harbour-books-book-view-back") text: qsTrId("harbour-books-book-view-back")
onClicked: root.closeBook() // Delay the actual action until bounce back is finished
onClicked: menu.backToLibrary = flickable.contentY
}
onActiveChanged: {
if (!active && backToLibrary < 0) {
// The actual "Back to library" action
backToLibrary = 0
root.closeBook()
}
} }
} }
@ -200,7 +223,7 @@ Item {
orientation: ListView.Horizontal orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem snapMode: ListView.SnapOneItem
preferredHighlightBegin: 0 preferredHighlightBegin: 0
preferredHighlightEnd: width preferredHighlightEnd: width + spacing
highlightRangeMode: ListView.StrictlyEnforceRange highlightRangeMode: ListView.StrictlyEnforceRange
spacing: Theme.paddingMedium spacing: Theme.paddingMedium
opacity: loading ? 0 : 1 opacity: loading ? 0 : 1

View file

@ -36,7 +36,7 @@ import Sailfish.Silica 1.0
import harbour.books 1.0 import harbour.books 1.0
Page { Page {
id: root id: page
allowedOrientations: window.allowedOrientations allowedOrientations: window.allowedOrientations
@ -45,28 +45,21 @@ Page {
readonly property Item currentView: Settings.currentBook ? bookView : storageView readonly property Item currentView: Settings.currentBook ? bookView : storageView
property Item bookView property Item bookView
readonly property real fadeInThreshold: height/4
readonly property real swipeAwayThreshold: 3 * height/4
Component.onCompleted: createBookViewIfNeeded() Component.onCompleted: createBookViewIfNeeded()
onCurrentViewChanged: updatePullDownMenu() onCurrentViewChanged: {
if (currentView) {
flickable.pullDownMenu = currentView.pullDownMenu
flickable.pullDownMenu.flickable = flickable
}
}
function createBookViewIfNeeded() { function createBookViewIfNeeded() {
if (Settings.currentBook && !bookView) { if (Settings.currentBook && !bookView) {
bookView = bookViewComponent.createObject(flickable.contentItem) bookView = bookViewComponent.createObject(flickable.contentItem)
updatePullDownMenu()
}
}
function updatePullDownMenu() {
var menu = currentView ? currentView.pullDownMenu : null
if (menu) {
menu.visible = true
}
if (flickable.pullDownMenu !== menu) {
var prevMenu = flickable.pullDownMenu
flickable.pullDownMenu = menu
if (prevMenu) {
prevMenu.visible = false
}
} }
} }
@ -75,26 +68,44 @@ Page {
onCurrentBookChanged: createBookViewIfNeeded() onCurrentBookChanged: createBookViewIfNeeded()
} }
Connections {
target: currentView
onPullDownMenuChanged: updatePullDownMenu()
}
SilicaFlickable { SilicaFlickable {
id: flickable id: flickable
anchors.fill: parent anchors.fill: parent
contentWidth: page.width
contentHeight: Settings.currentBook ? (2 * page.height) : page.height
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick
interactive: currentView && currentView.viewInteractive flickDeceleration: maximumFlickVelocity
interactive: currentView && currentView.viewInteractive && !swipeAwayAnimation.running
pressDelay: 0
BooksStorageView { BooksStorageView {
id: storageView id: storageView
anchors.fill: parent
pageActive: root.pageActive width: page.width
opacity: Settings.currentBook ? 0 : 1 height: page.height
y: Settings.currentBook ? flickable.contentY : 0
pageActive: page.pageActive
isCurrentView: currentView === storageView
opacity: Settings.currentBook ? ((y > fadeInThreshold) ? 1 : (y > 0) ? y/fadeInThreshold : 0) : 1
visible: opacity > 0 visible: opacity > 0
Behavior on opacity { FadeAnimation {} }
onOpenBook: Settings.currentBook = book onOpenBook: Settings.currentBook = book
Behavior on opacity {
enabled: !Settings.currentBook
FadeAnimation { }
}
}
onMovementEnded: {
if (contentY > 0 && Settings.currentBook) {
if (contentY > swipeAwayThreshold) {
swipeAwayAnimation.start()
} else {
unswipeAnimation.start()
}
}
} }
} }
@ -102,14 +113,51 @@ Page {
id: bookViewComponent id: bookViewComponent
BooksBookView { BooksBookView {
anchors.fill: parent id: bookView
opacity: Settings.currentBook ? 1 : 0
visible: opacity > 0 width: page.width
orientation: root.orientation height: page.height
pageActive: root.pageActive z: storageView.z + 1
visible: !!Settings.currentBook
orientation: page.orientation
isCurrentView: currentView === bookView
pageActive: page.pageActive
book: Settings.currentBook ? Settings.currentBook : null book: Settings.currentBook ? Settings.currentBook : null
onCloseBook: Settings.currentBook = null onCloseBook: Settings.currentBook = null
Behavior on opacity { FadeAnimation {} } onVisibleChanged: if (visible) opacity = 1
}
}
SequentialAnimation {
id: swipeAwayAnimation
alwaysRunToEnd: true
NumberAnimation {
target: flickable
property: "contentY"
to: page.height
duration: 150
easing.type: Easing.InQuad
}
ScriptAction {
script: {
Settings.currentBook = null
flickable.contentY = 0
}
}
}
SequentialAnimation {
id: unswipeAnimation
alwaysRunToEnd: true
NumberAnimation {
target: flickable
property: "contentY"
to: 0
duration: 150
easing.type: Easing.InOutQuad
} }
} }
} }

View file

@ -40,6 +40,7 @@ Item {
property alias viewInteractive: storageList.interactive property alias viewInteractive: storageList.interactive
property alias pullDownMenu: menu property alias pullDownMenu: menu
property alias isCurrentView: menu.visible
property bool pageActive property bool pageActive
property bool editMode: false property bool editMode: false
@ -96,8 +97,6 @@ Item {
PullDownMenu { PullDownMenu {
id: menu id: menu
visible: false // BooksMainPage will make it visible when it's needed
MenuItem { MenuItem {
//: Pulley menu item //: Pulley menu item
//% "Settings" //% "Settings"
@ -187,6 +186,8 @@ Item {
flickDeceleration: maximumFlickVelocity flickDeceleration: maximumFlickVelocity
orientation: ListView.Horizontal orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem snapMode: ListView.SnapOneItem
preferredHighlightBegin: 0
preferredHighlightEnd: width + spacing
highlightRangeMode: ListView.StrictlyEnforceRange highlightRangeMode: ListView.StrictlyEnforceRange
spacing: Theme.paddingMedium spacing: Theme.paddingMedium
interactive: !dragInProgress && !dragScrollAnimation.running interactive: !dragInProgress && !dragScrollAnimation.running