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 }