Warning, /multimedia/elisa/src/qml/NavigationActionBar.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
0003 SPDX-FileCopyrightText: 2023 (c) ivan tkachenko <me@ratijas.tk>
0004
0005 SPDX-License-Identifier: LGPL-3.0-or-later
0006 */
0007
0008 import QtQml 2.2
0009 import QtQuick 2.15
0010 import QtQuick.Layouts 1.3
0011 import QtQuick.Controls 2.15
0012 import Qt5Compat.GraphicalEffects
0013 import org.kde.kirigami 2.8 as Kirigami
0014 import org.kde.elisa 1.0
0015
0016 Item {
0017 id: navigationBar
0018
0019 property string mainTitle
0020 property string secondaryTitle
0021 property url image
0022 property bool allowArtistNavigation: false
0023 property bool showEnqueueButton: true
0024 property bool showCreateRadioButton
0025
0026 property string labelText
0027 property bool showRating: !Kirigami.Settings.isMobile
0028 property alias filterText: filterTextInput.text
0029 property alias filterRating: ratingFilter.starRating
0030 property bool enableGoBack: true
0031 property bool expandedFilterView
0032 property bool enableSorting: true
0033 property alias sortRole: sortMenu.sortRole
0034 property alias sortRoles: sortMenu.sortRoles
0035 property alias sortRoleNames: sortMenu.sortRoleNames
0036 property alias sortOrder: sortMenu.sortOrder
0037 property alias sortOrderNames: sortMenu.sortOrderNames
0038
0039 property ViewManager viewManager
0040
0041 signal enqueue();
0042 signal replaceAndPlay();
0043 signal createRadio();
0044 signal goBack();
0045 signal showArtist(string name)
0046
0047 property bool isWidescreen: mainWindow.width >= elisaTheme.viewSelectorSmallSizeThreshold
0048
0049 implicitHeight: layout.height
0050
0051 SortMenu {
0052 id: sortMenu
0053 onSortOrderChanged: if (viewManager) viewManager.sortOrderChanged(sortOrder)
0054 onSortRoleChanged: if (viewManager) viewManager.sortRoleChanged(sortRole)
0055 }
0056
0057 // shared actions between mobile and desktop
0058 Component {
0059 id: sortMenuComponent
0060 FlatButtonWithToolTip {
0061 function openMenu() {
0062 if (sortMenu.visible) {
0063 sortMenu.dismiss()
0064 } else {
0065 sortMenu.sortOrder = navigationBar.sortOrder
0066 sortMenu.popup(this, x, y + height)
0067 }
0068 }
0069
0070 display: AbstractButton.TextBesideIcon
0071 down: sortMenu.visible || pressed
0072 Accessible.role: Accessible.ButtonMenu
0073
0074 menu: sortMenu
0075
0076 icon.name: "view-sort"
0077 text: sortMenu.sortRoleName !== ""
0078 ? i18nc("@label:listbox Sort By Menu Title with no sort selected", "Sort: %1", sortMenu.sortRoleName)
0079 : i18nc("@label:listbox Sort By Menu Title with no sort selected", "Sort")
0080
0081 onPressed: openMenu()
0082 // Need this too because the base control sends onClicked for return/enter
0083 onClicked: openMenu()
0084 }
0085 }
0086
0087 Component {
0088 id: createRadioButton
0089 FlatButtonWithToolTip {
0090 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0091 Kirigami.Theme.inherit: false
0092 objectName: "createRadioButton"
0093 text: i18nc("@action:button", "Create a radio")
0094 icon.name: "list-add"
0095 display: Kirigami.Settings.isMobile && navigationBar.isWidescreen ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
0096 onClicked: createRadio()
0097 }
0098 }
0099 Component {
0100 id: enqueueButton
0101 FlatButtonWithToolTip {
0102 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0103 Kirigami.Theme.inherit: false
0104 objectName: "enqueueButton"
0105 text: i18nc("@action:button", "Add to Playlist")
0106 icon.name: "list-add"
0107 display: Kirigami.Settings.isMobile && navigationBar.isWidescreen ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
0108 onClicked: enqueue()
0109 }
0110 }
0111 Component {
0112 id: replaceAndPlayButton
0113 FlatButtonWithToolTip {
0114 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0115 Kirigami.Theme.inherit: false
0116 objectName: "replaceAndPlayButton"
0117 text: i18nc("@action:button", "Play now, replacing current playlist")
0118 icon.name: "media-playback-start"
0119 display: Kirigami.Settings.isMobile && navigationBar.isWidescreen ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
0120 onClicked: replaceAndPlay()
0121 }
0122 }
0123 Component {
0124 id: showArtistButton
0125 FlatButtonWithToolTip {
0126 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0127 Kirigami.Theme.inherit: false
0128 objectName: "showArtistButton"
0129 text: i18nc("@action:button navigate to the view for artist of this album", "Display Artist")
0130 icon.name: "view-media-artist"
0131 display: Kirigami.Settings.isMobile && navigationBar.isWidescreen ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
0132 onClicked: if (secondaryTitle) { navigationBar.showArtist(secondaryTitle) }
0133 }
0134 }
0135 Component {
0136 id: showPlaylistButton
0137 FlatButtonWithToolTip {
0138 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0139 Kirigami.Theme.inherit: false
0140 id: showPlaylistButton
0141 text: i18nc("@action:button", "Show Playlist")
0142 icon.name: "view-media-playlist"
0143 display: navigationBar.isWidescreen ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
0144 onClicked: navigationBar.isWidescreen ? mainWindow.toggleDrawer() : playlistDrawer.open()
0145 }
0146 }
0147
0148 // header layout
0149 ColumnLayout {
0150 id: layout
0151 anchors.left: parent.left
0152 anchors.right: parent.right
0153 anchors.top: parent.top
0154 spacing: 0
0155
0156 HeaderFooterToolbar {
0157 id: mainHeader
0158 toolbarType: Kirigami.Settings.isMobile || filterRow.visible ? HeaderFooterToolbar.ToolbarType.Other
0159 : HeaderFooterToolbar.ToolbarType.Header
0160 Layout.fillWidth: true
0161
0162 // on mobile, the header is translucent
0163 color: Kirigami.Settings.isMobile ? Qt.rgba(myPalette.window.r, myPalette.window.g, myPalette.window.b, 0.3) : myPalette.window
0164 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0165 Kirigami.Theme.inherit: false
0166
0167 contentItems: [
0168 FlatButtonWithToolTip {
0169 id: showSidebarButton
0170 objectName: "showSidebarButton"
0171 visible: Kirigami.Settings.isMobile
0172 text: i18nc("@action:button", "Open sidebar")
0173 icon.name: "open-menu-symbolic"
0174 onClicked: mainWindow.globalDrawer.open()
0175 },
0176 FlatButtonWithToolTip {
0177 id: goPreviousButton
0178 objectName: "goPreviousButton"
0179 visible: enableGoBack
0180 text: i18nc("@action:button navigate back in the view's stack", "Back")
0181 icon.name: (Qt.application.layoutDirection === Qt.RightToLeft) ? "go-next" : "go-previous"
0182 onClicked: goBack()
0183 },
0184 Kirigami.Icon {
0185 id: mainIcon
0186 visible: image.toString().length > 0
0187 && !Kirigami.Settings.isMobile // On mobile, we want more header space
0188 && navigationBar.enableGoBack // For top-level pages, the icon is redundant
0189 source: image
0190
0191 Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
0192 Layout.preferredWidth: Kirigami.Units.iconSizes.medium
0193 Layout.preferredHeight: Kirigami.Units.iconSizes.medium
0194 },
0195 ColumnLayout {
0196 id: authorAndAlbumLayout
0197 Layout.fillWidth: true
0198 Layout.fillHeight: true
0199 Layout.leftMargin: mainIcon.visible ? Kirigami.Units.smallSpacing : Kirigami.Units.largeSpacing
0200
0201 spacing: 0
0202
0203 LabelWithToolTip {
0204 id: albumLabel
0205 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0206 Layout.fillWidth: true
0207
0208 text: mainTitle
0209 level: authorLabel.visible ? 4 : 1
0210 }
0211 LabelWithToolTip {
0212 id: authorLabel
0213 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0214 Layout.fillWidth: true
0215
0216 visible: secondaryTitle !== ""
0217 opacity: 0.6
0218
0219 text: secondaryTitle
0220 elide: Text.ElideRight
0221
0222 TapHandler {
0223 id: showArtistTaphandler
0224 enabled: navigationBar.allowArtistNavigation && !navigationBar.showCreateRadioButton
0225 onTapped: navigationBar.showArtist(secondaryTitle)
0226 }
0227 HoverHandler {
0228 enabled: showArtistTaphandler.enabled
0229 cursorShape: Qt.PointingHandCursor
0230 }
0231 }
0232 },
0233 Loader {
0234 sourceComponent: sortMenuComponent
0235 active: !Kirigami.Settings.isMobile && enableSorting && !showCreateRadioButton
0236 Layout.maximumHeight: parent.height
0237 },
0238 Loader {
0239 sourceComponent: createRadioButton
0240 active: !Kirigami.Settings.isMobile && showCreateRadioButton
0241 Layout.maximumHeight: parent.height
0242 },
0243 Loader {
0244 sourceComponent: enqueueButton
0245 active: !Kirigami.Settings.isMobile && !showCreateRadioButton
0246 Layout.maximumHeight: parent.height
0247 },
0248 Loader {
0249 sourceComponent: replaceAndPlayButton
0250 active: !Kirigami.Settings.isMobile && !showCreateRadioButton
0251 Layout.maximumHeight: parent.height
0252 },
0253 FlatButtonWithToolTip {
0254 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0255 Kirigami.Theme.inherit: false
0256 objectName: "showFilterButton"
0257 visible: !showCreateRadioButton
0258 text: !navigationBar.expandedFilterView ? i18nc("@action:button Show filters in the navigation bar", "Search and Filter") : i18nc("@action:button Hide filters in the navigation bar", "Hide Search and Filter")
0259 icon.name: "search"
0260 checkable: true
0261 checked: expandedFilterView
0262 onClicked: persistentSettings.expandedFilterView = !persistentSettings.expandedFilterView;
0263 }
0264 ]
0265 }
0266
0267 // on mobile, move header buttons into a second row (there's limited horizontal space for track names and etc.)
0268 Loader {
0269 active: Kirigami.Settings.isMobile
0270 visible: active
0271
0272 Layout.fillWidth: true
0273 Layout.preferredHeight: Kirigami.Units.gridUnit * 2
0274
0275 sourceComponent: HeaderFooterToolbar {
0276 id: mobileActions
0277 toolbarType: Kirigami.Settings.isMobile || filterRow.visible ? HeaderFooterToolbar.ToolbarType.Other : HeaderFooterToolbar.ToolbarType.Header
0278
0279 // on mobile, the header is translucent
0280 color: Kirigami.Settings.isMobile ? Qt.rgba(myPalette.window.r, myPalette.window.g, myPalette.window.b, 0.3) : myPalette.window
0281 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0282 Kirigami.Theme.inherit: false
0283
0284 contentItems: [
0285 Loader {
0286 sourceComponent: sortMenuComponent
0287 active: enableSorting && !showCreateRadioButton
0288 Layout.maximumHeight: parent.height
0289 },
0290 Item {
0291 Layout.fillWidth: true
0292 },
0293 Loader {
0294 sourceComponent: createRadioButton
0295 active: showCreateRadioButton
0296 Layout.maximumHeight: parent.height
0297 },
0298 Loader {
0299 sourceComponent: enqueueButton
0300 active: !showCreateRadioButton
0301 Layout.maximumHeight: parent.height
0302 },
0303 Loader {
0304 sourceComponent: replaceAndPlayButton
0305 active: !showCreateRadioButton
0306 Layout.maximumHeight: parent.height
0307 },
0308 Loader {
0309 sourceComponent: showArtistButton
0310 active: allowArtistNavigation && !showCreateRadioButton
0311 Layout.maximumHeight: parent.height
0312 },
0313 Loader {
0314 sourceComponent: showPlaylistButton
0315 Layout.maximumHeight: parent.height
0316 }
0317 ]
0318 }
0319 }
0320
0321 // filter bar
0322 HeaderFooterToolbar {
0323 id: filterRow
0324 toolbarType: Kirigami.Settings.isMobile ? HeaderFooterToolbar.ToolbarType.Other : HeaderFooterToolbar.ToolbarType.Header
0325
0326 color: Kirigami.Settings.isMobile ? Qt.rgba(myPalette.window.r, myPalette.window.g, myPalette.window.b, 0.3) : myPalette.window
0327 Kirigami.Theme.colorSet: Kirigami.Settings.isMobile ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
0328 Kirigami.Theme.inherit: false
0329
0330 Layout.fillWidth: true
0331
0332 visible: opacity > 0.0
0333
0334 opacity: expandedFilterView ? 1 : 0
0335 Behavior on opacity {
0336 NumberAnimation {
0337 easing.type: Easing.Linear
0338 duration: Kirigami.Units.longDuration
0339 }
0340 }
0341 onVisibleChanged: {
0342 if (visible) {
0343 filterTextInput.forceActiveFocus();
0344 }
0345 }
0346
0347 contentItems: [
0348 Kirigami.SearchField {
0349 id: filterTextInput
0350 objectName: "filterTextInput"
0351
0352 Layout.fillWidth: true
0353 focusSequence: ""
0354
0355 selectByMouse: true
0356
0357 Accessible.role: Accessible.EditableText
0358
0359 placeholderText: i18nc("@info:placeholder", "Search for album name, artist, etc.")
0360
0361 Keys.onEscapePressed: persistentSettings.expandedFilterView = false;
0362 },
0363 Item {
0364 width: Kirigami.Units.largeSpacing
0365 visible: showRating && !ElisaApplication.useFavoriteStyleRatings
0366 },
0367 LabelWithToolTip {
0368 text: i18nc("@label:chooser", "Filter by rating: ")
0369
0370 visible: showRating && !ElisaApplication.useFavoriteStyleRatings
0371 },
0372 RatingStar {
0373 id: ratingFilter
0374 objectName: "ratingFilter"
0375
0376 visible: showRating && !ElisaApplication.useFavoriteStyleRatings
0377
0378 readOnly: false
0379 },
0380 FlatButtonWithToolTip {
0381 visible: showRating && ElisaApplication.useFavoriteStyleRatings
0382
0383 flat: false
0384 display: AbstractButton.TextBesideIcon
0385
0386 text: i18nc("@action:button", "Only Show Favorites")
0387 icon.name: "rating"
0388 checkable: true
0389 checked: ratingFilter.starRating === 10
0390 onToggled: {
0391 if (checked) {
0392 ratingFilter.starRating = 10;
0393 } else {
0394 ratingFilter.starRating = 0;
0395 }
0396 }
0397 }
0398 ]
0399 }
0400 }
0401
0402 // darken background
0403 Rectangle {
0404 anchors.fill: background
0405 visible: Kirigami.Settings.isMobile
0406
0407 z: -1
0408 color: "black"
0409 opacity: 0.8
0410 }
0411
0412 // mobile blurred background image
0413 Loader {
0414 id: background
0415 active: Kirigami.Settings.isMobile
0416 visible: active
0417
0418 anchors.fill: layout
0419 z: -1
0420
0421 sourceComponent: ImageWithFallback {
0422 source: ElisaApplication.manageHeaderBar.image
0423 fallback: elisaTheme.defaultBackgroundImage
0424 asynchronous: true
0425
0426 fillMode: Image.PreserveAspectCrop
0427
0428 // make the FastBlur effect more strong
0429 sourceSize.height: 10
0430
0431 layer.enabled: true
0432 layer.effect: HueSaturation {
0433 cached: true
0434
0435 lightness: -0.5
0436 saturation: 0.9
0437
0438 layer.enabled: true
0439 layer.effect: FastBlur {
0440 cached: true
0441 radius: 64
0442 transparentBorder: false
0443 }
0444 }
0445 }
0446 }
0447 }