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 }