mirror of
https://github.com/linuxdeepin/deepin-music.git
synced 2026-10-17 05:30:46 +08:00
fix: improve search result UI and navigation
- Overhaul SearchResultWindow navigation with StackView for push/pop transitions - Adjust grid cell sizes for better artist and album display - Add requestClose signal and padding/radius improvements to SearchResultDialog - Remove sidebar auto-uncheck behavior when entering search page - Fix connection handlers for artist and album detail navigation fix: 优化搜索结果UI和导航 - 使用StackView重构SearchResultWindow导航,支持推入/弹出过渡动画 - 调整网格单元格大小以改善歌手和专辑显示 - 为SearchResultDialog添加requestClose信号和内边距/圆角改进 - 移除进入搜索页面时侧边栏自动取消勾选的行为 - 修复歌手和专辑详情页导航的连接处理
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
|
||||
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
@@ -18,6 +18,10 @@ Popup {
|
||||
id: searchResultRect
|
||||
width: 360
|
||||
height: (songList == null ? 0 : songList.length + artistModel.count + albumModel.count) * itemHeight + 110
|
||||
leftPadding: 8
|
||||
rightPadding: 8
|
||||
topPadding: 8
|
||||
bottomPadding: 8
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
@@ -64,6 +68,7 @@ Popup {
|
||||
id: itemRect
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
radius: 6
|
||||
color: "#00000000"
|
||||
Row {
|
||||
width: parent.width
|
||||
@@ -101,6 +106,7 @@ Popup {
|
||||
id: itemRect
|
||||
width: parent.width
|
||||
height: itemHeight
|
||||
radius: 6
|
||||
color: "#00000000"
|
||||
Row {
|
||||
width: parent.width
|
||||
@@ -133,7 +139,6 @@ Popup {
|
||||
itemRect.color = "transparent"
|
||||
}
|
||||
onClicked: {
|
||||
// console.log(model.type)
|
||||
var type = 0
|
||||
|
||||
if (model.type === "artist")
|
||||
|
||||
@@ -23,19 +23,22 @@ Rectangle {
|
||||
property ListModel albumsModel: ListModel{}
|
||||
property ListModel artistsModel: ListModel{}
|
||||
property int curIndex: tabArea.currentIndex
|
||||
signal itemDoubleClicked(var artistData)
|
||||
property int switchType: globalVariant.globalSwitchButtonStatus
|
||||
property string selectedArtistName: ""
|
||||
property string selectedAlbumName: ""
|
||||
signal itemDoubleClicked(var data)
|
||||
property var artistData
|
||||
|
||||
Component {
|
||||
id: artistSublistView
|
||||
ArtistSublistView {
|
||||
artistData:searchRootRect.artistData
|
||||
artistData: searchRootRect.artistData
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: albumSublistView
|
||||
AlbumSublistView {
|
||||
albumData:searchRootRect.artistData
|
||||
albumData: searchRootRect.artistData
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,226 +59,270 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
color: "transparent"
|
||||
StackView {
|
||||
id: navigationStackView
|
||||
anchors.fill: parent
|
||||
visible: curIndex < 0 ? false : true
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Rectangle {
|
||||
id: headArea
|
||||
width: parent.width - 40
|
||||
height: 72
|
||||
Layout.leftMargin: 20
|
||||
Layout.rightMargin: 20
|
||||
color: "transparent"
|
||||
initialItem: Rectangle {
|
||||
width: navigationStackView.width
|
||||
height: navigationStackView.height
|
||||
color: "transparent"
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
topPadding: 17
|
||||
spacing: 10
|
||||
FloatingButton {
|
||||
id: playAllBtn
|
||||
width: 28; height: 28
|
||||
icon.name: "headline_play_all"
|
||||
icon.width: 28
|
||||
icon.height: 28
|
||||
ToolTip {
|
||||
visible: playAllBtn.hovered
|
||||
text: qsTr("Play All")
|
||||
}
|
||||
onClicked: {
|
||||
Presenter.playPlaylist("musicResult");
|
||||
}
|
||||
}
|
||||
Label {
|
||||
id: buttonLable
|
||||
text: qsTr("Search Results")
|
||||
font: DTK.fontManager.t4
|
||||
}
|
||||
Label {
|
||||
font: DTK.fontManager.t8
|
||||
text: albumsModel.count !== 1 ? qsTr("%1 albums - %2 songs").arg(albumsModel.count).arg(songsModel.count) :
|
||||
(songsModel.count === 1 ? qsTr("1 album - 1 song") : qsTr("%1 album - %2 songs").arg(albumsModel.count).arg(songsModel.count))
|
||||
anchors.verticalCenter: buttonLable.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: headerLayout
|
||||
Layout.rightMargin: 40
|
||||
TabBar {
|
||||
id: tabArea
|
||||
Rectangle {
|
||||
id: headArea
|
||||
width: parent.width - 40
|
||||
height: parent.height - headArea.height
|
||||
height: 72
|
||||
Layout.leftMargin: 20
|
||||
Layout.rightMargin: 20
|
||||
currentIndex: 0
|
||||
color: "transparent"
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Music")
|
||||
width: 82
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Album")
|
||||
width: 82
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Artist")
|
||||
width: 82
|
||||
}
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
SortMenu {
|
||||
id: allMusicSortMenu
|
||||
visible: tabArea.currentIndex === 0
|
||||
sortPageHash: "musicResult"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
pageSortType: 0
|
||||
}
|
||||
SortMenu {
|
||||
id: albumMusicSortMenu
|
||||
visible: tabArea.currentIndex === 1
|
||||
sortPageHash: "albumResult"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
pageSortType: 0
|
||||
}
|
||||
SortMenu {
|
||||
id: artistMusicSortMenu
|
||||
visible: tabArea.currentIndex === 2
|
||||
sortPageHash: "artistResult"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
pageSortType: 0
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
var musicSortType = Presenter.playlistSortType("musicResult")
|
||||
var artistSortType = Presenter.playlistSortType("artistResult")
|
||||
var albumSortType = Presenter.playlistSortType("albumResult")
|
||||
|
||||
switch(musicSortType) {
|
||||
case 10:
|
||||
allMusicSortMenu.pageSortType = 0
|
||||
break
|
||||
case 11:
|
||||
allMusicSortMenu.pageSortType = 1
|
||||
break
|
||||
case 12:
|
||||
allMusicSortMenu.pageSortType = 2
|
||||
break
|
||||
case 13:
|
||||
allMusicSortMenu.pageSortType = 3
|
||||
break
|
||||
default:
|
||||
allMusicSortMenu.pageSortType = -1
|
||||
}
|
||||
|
||||
switch(albumSortType) {
|
||||
case 10:
|
||||
albumMusicSortMenu.pageSortType = 0
|
||||
break
|
||||
case 13:
|
||||
albumMusicSortMenu.pageSortType = 1
|
||||
break
|
||||
default:
|
||||
albumMusicSortMenu.pageSortType = -1
|
||||
}
|
||||
|
||||
switch(artistSortType) {
|
||||
case 10:
|
||||
artistMusicSortMenu.pageSortType = 0
|
||||
break
|
||||
case 12:
|
||||
artistMusicSortMenu.pageSortType = 2
|
||||
break
|
||||
default:
|
||||
artistMusicSortMenu.pageSortType = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: myStackView
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 20
|
||||
Layout.rightMargin: 20
|
||||
clip: true
|
||||
visible: curIndex < 0 ? false : true
|
||||
currentIndex: tabArea.currentIndex
|
||||
|
||||
AllMusicListView {
|
||||
id: allMusicList
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
mediaModel: songsModel
|
||||
viewListHash: "musicResult"
|
||||
}
|
||||
GridView {
|
||||
id: artistView
|
||||
width: Math.floor(parent.width / 196) * 196;
|
||||
height: parent.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top; anchors.topMargin: 34
|
||||
anchors.leftMargin: (parent.width - width) / 2
|
||||
anchors.rightMargin: (parent.width - width) / 2
|
||||
cellWidth: 196; cellHeight: 196
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
clip: true
|
||||
model: artistsModel
|
||||
delegate: ArtistGridDelegate{
|
||||
id: musicSingerGridItem
|
||||
onItemDoubleClicked: {
|
||||
searchRootRect.itemDoubleClicked(artistData);
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
topPadding: 17
|
||||
spacing: 10
|
||||
FloatingButton {
|
||||
id: playAllBtn
|
||||
width: 28; height: 28
|
||||
icon.name: "headline_play_all"
|
||||
icon.width: 28
|
||||
icon.height: 28
|
||||
ToolTip {
|
||||
visible: playAllBtn.hovered
|
||||
text: qsTr("Play All")
|
||||
}
|
||||
onClicked: {
|
||||
Presenter.playPlaylist("musicResult");
|
||||
}
|
||||
}
|
||||
Label {
|
||||
id: buttonLable
|
||||
text: qsTr("Search Results")
|
||||
font: DTK.fontManager.t4
|
||||
}
|
||||
Label {
|
||||
font: DTK.fontManager.t8
|
||||
text: albumsModel.count !== 1 ? qsTr("%1 albums - %2 songs").arg(albumsModel.count).arg(songsModel.count) :
|
||||
(songsModel.count === 1 ? qsTr("1 album - 1 song") : qsTr("%1 album - %2 songs").arg(albumsModel.count).arg(songsModel.count))
|
||||
anchors.verticalCenter: buttonLable.verticalCenter
|
||||
}
|
||||
}
|
||||
onWidthChanged: {
|
||||
var w = Math.floor(tabArea.width / 196) * 196;
|
||||
var m = (tabArea.width - w) / 2;
|
||||
anchors.leftMargin = m;
|
||||
anchors.rightMargin = m;
|
||||
}
|
||||
}
|
||||
GridView {
|
||||
id: albumGridView
|
||||
width: Math.floor(parent.width / 201) * 201;
|
||||
height: parent.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top; anchors.topMargin: 5
|
||||
anchors.leftMargin: (parent.width - width) / 2
|
||||
anchors.rightMargin: (parent.width - width) / 2
|
||||
cellWidth: 201; cellHeight: 228
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
clip: true
|
||||
model: albumsModel
|
||||
delegate: AlbumGridDelegate{
|
||||
id: itemDelegate
|
||||
playing: (globalVariant.curPlayingStatus === DmGlobal.Playing) ? true : false
|
||||
onItemDoubleClicked: {
|
||||
console.log("onItemDoubleClicked: " + albumData);
|
||||
searchRootRect.itemDoubleClicked(albumData);
|
||||
|
||||
RowLayout {
|
||||
id: headerLayout
|
||||
Layout.rightMargin: 40
|
||||
TabBar {
|
||||
id: tabArea
|
||||
width: parent.width - 40
|
||||
height: parent.height - headArea.height
|
||||
Layout.leftMargin: 20
|
||||
Layout.rightMargin: 20
|
||||
currentIndex: 0
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Music")
|
||||
width: 82
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Album")
|
||||
width: 82
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Artist")
|
||||
width: 82
|
||||
}
|
||||
}
|
||||
onWidthChanged: {
|
||||
var w = Math.floor(tabArea.width / 201) * 201;
|
||||
var m = (tabArea.width - w) / 2;
|
||||
anchors.leftMargin = m;
|
||||
anchors.rightMargin = m;
|
||||
Item { Layout.fillWidth: true }
|
||||
SortMenu {
|
||||
id: allMusicSortMenu
|
||||
visible: tabArea.currentIndex === 0
|
||||
sortPageHash: "musicResult"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
pageSortType: 0
|
||||
}
|
||||
SortMenu {
|
||||
id: albumMusicSortMenu
|
||||
visible: tabArea.currentIndex === 1
|
||||
sortPageHash: "albumResult"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
pageSortType: 0
|
||||
}
|
||||
SortMenu {
|
||||
id: artistMusicSortMenu
|
||||
visible: tabArea.currentIndex === 2
|
||||
sortPageHash: "artistResult"
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
pageSortType: 0
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
var musicSortType = Presenter.playlistSortType("musicResult")
|
||||
var artistSortType = Presenter.playlistSortType("artistResult")
|
||||
var albumSortType = Presenter.playlistSortType("albumResult")
|
||||
|
||||
switch(musicSortType) {
|
||||
case 10:
|
||||
allMusicSortMenu.pageSortType = 0
|
||||
break
|
||||
case 11:
|
||||
allMusicSortMenu.pageSortType = 1
|
||||
break
|
||||
case 12:
|
||||
allMusicSortMenu.pageSortType = 2
|
||||
break
|
||||
case 13:
|
||||
allMusicSortMenu.pageSortType = 3
|
||||
break
|
||||
default:
|
||||
allMusicSortMenu.pageSortType = -1
|
||||
}
|
||||
|
||||
switch(albumSortType) {
|
||||
case 10:
|
||||
albumMusicSortMenu.pageSortType = 0
|
||||
break
|
||||
case 13:
|
||||
albumMusicSortMenu.pageSortType = 1
|
||||
break
|
||||
default:
|
||||
albumMusicSortMenu.pageSortType = -1
|
||||
}
|
||||
|
||||
switch(artistSortType) {
|
||||
case 10:
|
||||
artistMusicSortMenu.pageSortType = 0
|
||||
break
|
||||
case 12:
|
||||
artistMusicSortMenu.pageSortType = 2
|
||||
break
|
||||
default:
|
||||
artistMusicSortMenu.pageSortType = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: myStackView
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
clip: true
|
||||
visible: curIndex < 0 ? false : true
|
||||
currentIndex: tabArea.currentIndex
|
||||
|
||||
AllMusicListView {
|
||||
id: allMusicList
|
||||
mediaModel: songsModel
|
||||
viewListHash: "musicResult"
|
||||
}
|
||||
Item {
|
||||
GridView {
|
||||
id: artistView
|
||||
width: Math.floor(parent.width / 208) * 208
|
||||
height: parent.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
cellWidth: 208
|
||||
cellHeight: 230
|
||||
header: Item { width: 1; height: 10 }
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
clip: true
|
||||
model: artistsModel
|
||||
delegate: ArtistGridDelegate{
|
||||
id: musicSingerGridItem
|
||||
onItemDoubleClicked: {
|
||||
searchRootRect.itemDoubleClicked(artistData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
GridView {
|
||||
id: albumGridView
|
||||
width: Math.floor(parent.width / 208) * 208
|
||||
height: parent.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 5
|
||||
cellWidth: 208
|
||||
cellHeight: 242
|
||||
header: Item { width: 1; height: 10 }
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
clip: true
|
||||
model: albumsModel
|
||||
delegate: AlbumGridDelegate{
|
||||
id: itemDelegate
|
||||
playing: (globalVariant.curPlayingStatus === DmGlobal.Playing) ? true : false
|
||||
onItemDoubleClicked: {
|
||||
searchRootRect.itemDoubleClicked(albumData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
popEnter: Transition {
|
||||
NumberAnimation { property: "scale"; from: 0.8; to: 1; duration: 300; easing.type: Easing.InOutQuad }
|
||||
NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 300; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
popExit: Transition {
|
||||
NumberAnimation { property: "scale"; from: 1; to: 0.8; duration: 300; easing.type: Easing.InOutQuad }
|
||||
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200; easing.type: Easing.OutExpo }
|
||||
}
|
||||
|
||||
pushEnter: Transition {
|
||||
NumberAnimation { property: "scale"; from: 1.2; to: 1; duration: 300; easing.type: Easing.InOutQuad }
|
||||
NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 300; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
pushExit: Transition {
|
||||
NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 200; easing.type: Easing.OutExpo }
|
||||
}
|
||||
}
|
||||
|
||||
onItemDoubleClicked: {
|
||||
searchRootRect.artistData = artistData
|
||||
onItemDoubleClicked: function(data) {
|
||||
searchRootRect.artistData = data
|
||||
if (data.name !== undefined) {
|
||||
selectedArtistName = data.name
|
||||
selectedAlbumName = data.name
|
||||
}
|
||||
globalVariant.globalSwitchButtonStatus = 2;
|
||||
}
|
||||
|
||||
onSwitchTypeChanged: {
|
||||
if (switchType === 1) {
|
||||
navigationStackView.pop(navigationStackView.initialItem);
|
||||
} else if (switchType === 2) {
|
||||
if (tabArea.currentIndex === 2) {
|
||||
var artistItem = navigationStackView.find(function(item) { return item.objectName === "artistSublist" })
|
||||
if (artistItem !== null) {
|
||||
navigationStackView.pop(artistItem);
|
||||
return;
|
||||
}
|
||||
navigationStackView.push(artistSublistView);
|
||||
} else if (tabArea.currentIndex === 1) {
|
||||
var albumItem = navigationStackView.find(function(item) { return item.objectName === "albumSublist" })
|
||||
if (albumItem !== null) {
|
||||
navigationStackView.pop(albumItem);
|
||||
return;
|
||||
}
|
||||
navigationStackView.push(albumSublistView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function returnUpperlevelView() {
|
||||
globalVariant.globalSwitchButtonStatus = 0;
|
||||
navigationStackView.pop(navigationStackView.initialItem);
|
||||
}
|
||||
|
||||
function updateSearchResultInfo(text, type) {
|
||||
songsModel.clear()
|
||||
albumsModel.clear()
|
||||
@@ -406,11 +453,21 @@ Rectangle {
|
||||
|
||||
Connections {
|
||||
target: artistMoreMenu
|
||||
onViewArtistDatails: { itemDoubleClicked(artistData);}
|
||||
function onViewArtistDatails(artistData) {
|
||||
searchRootRect.itemDoubleClicked(artistData);
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: albumMoreMenu
|
||||
onViewAlbumDatails: { itemDoubleClicked(artistData);}
|
||||
function onViewAlbumDatails(albumData) {
|
||||
searchRootRect.itemDoubleClicked(albumData);
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: globalVariant
|
||||
function onReturnUpperlevelView() {
|
||||
searchRootRect.returnUpperlevelView();
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
updateSearchResultInfo(pattern, curIndex)
|
||||
|
||||
@@ -219,7 +219,6 @@ ColumnLayout {
|
||||
Connections {
|
||||
target: musicBaseScrollView.contentItem
|
||||
function onContentYChanged() {
|
||||
// console.log("Connections........onContentYChanged ", musicBaseScrollView.contentItem.contentY)
|
||||
if (control.type === "playlists")
|
||||
dropArea.updateHoverIndex()
|
||||
}
|
||||
@@ -307,14 +306,5 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
globalVariant.curListPageChanged.connect(function(){
|
||||
if (globalVariant !== undefined && globalVariant.curListPage === "search") {
|
||||
sideListView.currentItem.checked = false
|
||||
}
|
||||
})
|
||||
|
||||
// musicBaseScrollView.contentItem.contentYChanged.connect(dropArea.updateHoverIndex())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user