|
|
|
# Routing
|
|
|
|
|
|
|
|
To navigate between the different view, the application use a routing system.
|
|
|
|
|
|
|
|
A route is set as a hierarchical dictionnary, each level defines some properties:
|
|
|
|
|
|
|
|
* name: the name of the subview
|
|
|
|
* properties: properties that should be applied to the view
|
|
|
|
|
|
|
|
Views that embed sub-view usually defines a "view" property to define the
|
|
|
|
properties of the sub-view, this property is expected by the PageLoader which is
|
|
|
|
our main way to implement sub-views.
|
|
|
|
|
|
|
|
The history is organized as a stack when you click a tab button or open the
|
|
|
|
player, a new path is pushed on the stack, the stack can be navigated back to go
|
|
|
|
to the previous view, views are popped from the stack, you can only go
|
|
|
|
backwards.
|
|
|
|
|
|
|
|
The `History` class will propose methods to manipulate the history stack:
|
|
|
|
|
|
|
|
* `History.push(<the history object>)` to push and go to a new page
|
|
|
|
|
|
|
|
* `History.update(<the history object>)`, to udpate the current history node
|
|
|
|
without navigating to it. this allows to save properties that will be
|
|
|
|
restored when the view is reloaded later on
|
|
|
|
|
|
|
|
* `History.previous()` to go back in the history
|
|
|
|
|
|
|
|
* `History.current` gives the current history node
|
|
|
|
|
|
|
|
Note that you can pass `History.Stay` as a second argument of the `push` and
|
|
|
|
`previous` method to manipulate the history without changing the current view.
|
|
|
|
|
|
|
|
## specifying an history path
|
|
|
|
|
|
|
|
Usually we use a "short" form to target a specific view:
|
|
|
|
|
|
|
|
```qml
|
|
|
|
History.push(["mc", "video", "all", "group", { parentId: model.id, title: model.title }])
|
|
|
|
```
|
|
|
|
|
|
|
|
Each string of the list denote a subview, and each dictionary adds specifies
|
|
|
|
properties to the subview before.
|
|
|
|
|
|
|
|
which is equivalent to
|
|
|
|
|
|
|
|
```qml
|
|
|
|
History.push({
|
|
|
|
view: {
|
|
|
|
name: "mc",
|
|
|
|
properties: {
|
|
|
|
view: {
|
|
|
|
name: "video",
|
|
|
|
properties: {
|
|
|
|
view: {
|
|
|
|
name: "all",
|
|
|
|
properties: {
|
|
|
|
name: "group",
|
|
|
|
properties; {
|
|
|
|
parentId: model.id,
|
|
|
|
title: model.title
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
|
|
|
The structure is a convention used by the PageLoader to load and setup subview
|
|
|
|
|
|
|
|
|
|
|
|
## implementing a subview
|
|
|
|
|
|
|
|
to create a subview in QML, you need to use `Widgets.PageLoader`
|
|
|
|
|
|
|
|
```qml
|
|
|
|
//implemeting the ["mc", "music"] subview
|
|
|
|
Widgets.PageLoader {
|
|
|
|
|
|
|
|
//what are our subviews
|
|
|
|
pageModel: [{
|
|
|
|
//name of the subview
|
|
|
|
name: "artists",
|
|
|
|
//url of the subview
|
|
|
|
url: "qrc:///medialibrary/MusicArtistsDisplay.qml"
|
|
|
|
}, {
|
|
|
|
name: "albums",
|
|
|
|
//prevent loading of "album" if the condition is not met
|
|
|
|
guard: function(prop) { return prop.foo !== undefined; },
|
|
|
|
url: "qrc:///medialibrary/MusicAlbumsDisplay.qml"
|
|
|
|
}, {
|
|
|
|
name: "genre",
|
|
|
|
//sub pages can also be components
|
|
|
|
component: sourceBrowseComponent,
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
//defines wich view should be loaded by default
|
|
|
|
loadDefaultView: function () {
|
|
|
|
//update the history to state that we are actually on the artist subview
|
|
|
|
History.update(["mc", "music", "artists"])
|
|
|
|
//load explicitly the artist subview
|
|
|
|
loadPage("artists")
|
|
|
|
}
|
|
|
|
|
|
|
|
Component {
|
|
|
|
id: browseGenreComponent
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
see:
|
|
|
|
|
|
|
|
* util/navigation_history.cpp
|
|
|
|
|
|
|
|
* widget/qml/PageLoader.qml
|
|
|
|
|
|
|
|
* widget/qml/StackViewExt.qml |