mirror of
https://github.com/linuxdeepin/deepin-music.git
synced 2026-10-16 21:20:47 +08:00
fix: add keyboard navigation for search dropdown
1. Root cause: SearchResultDialog.qml had no keyboard navigation; SearchEdit only handled Return key, arrow keys were consumed by TextField default cursor movement 2. Fix: add selectedIndex tracking, moveSelection/activateSelection methods and highlight in SearchResultDialog; add Keys.onDownPressed /onUpPressed and extend onReturnPressed in WindowTitlebar SearchEdit 3. Impact: users can now navigate search results with arrow keys and confirm with Enter; mouse interaction unchanged Log: Search results now support keyboard navigation with arrow keys Influence: 1. Test arrow key navigation in search result dropdown 2. Test Enter key to activate selected search result 3. Verify mouse hover and click still work as before fix: 搜索结果下拉列表添加键盘导航 1. 根因:SearchResultDialog.qml 无键盘导航机制,SearchEdit 仅处理 回车键,方向键被 TextField 默认光标移动行为消费 2. 方案:在 SearchResultDialog 添加 selectedIndex 追踪、 moveSelection/activateSelection 方法和高亮显示;在 WindowTitlebar 的 SearchEdit 添加方向键处理并扩展回车键逻辑 3. 影响:用户可通过方向键导航搜索结果并回车确认,鼠标交互不受影响 Log: 搜索结果支持方向键导航和回车选择 Influence: 1. 测试搜索结果下拉列表中方向键导航 2. 测试回车键激活选中的搜索结果 3. 验证鼠标悬停和点击功能无回归 PMS: BUG-375953
This commit is contained in:
@@ -12,11 +12,48 @@ Popup {
|
|||||||
property string pattern: ""
|
property string pattern: ""
|
||||||
|
|
||||||
property int itemHeight: 40
|
property int itemHeight: 40
|
||||||
|
property int selectedIndex: -1
|
||||||
|
property int resultCount: (songList == null ? 0 : songList.length) + artistModel.count + albumModel.count
|
||||||
|
|
||||||
signal searchItemTriggered(string value, int type)
|
signal searchItemTriggered(string value, int type)
|
||||||
|
|
||||||
id: searchResultRect
|
id: searchResultRect
|
||||||
width: 360
|
width: 360
|
||||||
|
|
||||||
|
// Moves the keyboard selection by offset, wrapping around available results.
|
||||||
|
function moveSelection(offset) {
|
||||||
|
if (resultCount <= 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (selectedIndex < 0) {
|
||||||
|
selectedIndex = offset > 0 ? 0 : resultCount - 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedIndex = (selectedIndex + offset + resultCount) % resultCount
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activates the currently selected result and returns whether activation succeeded.
|
||||||
|
function activateSelection() {
|
||||||
|
if (selectedIndex < 0 || selectedIndex >= resultCount)
|
||||||
|
return false
|
||||||
|
|
||||||
|
var songCount = songList == null ? 0 : songList.length
|
||||||
|
if (selectedIndex < songCount) {
|
||||||
|
searchItemTriggered(songList[selectedIndex], 0)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var artistIndex = selectedIndex - songCount
|
||||||
|
if (artistIndex < artistModel.count) {
|
||||||
|
searchItemTriggered(artistModel.get(artistIndex).name, 1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
searchItemTriggered(albumModel.get(artistIndex - artistModel.count).name, 2)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
height: (songList == null ? 0 : songList.length + artistModel.count + albumModel.count) * itemHeight + 110
|
height: (songList == null ? 0 : songList.length + artistModel.count + albumModel.count) * itemHeight + 110
|
||||||
leftPadding: 8
|
leftPadding: 8
|
||||||
rightPadding: 8
|
rightPadding: 8
|
||||||
@@ -66,10 +103,17 @@ Popup {
|
|||||||
id: resultItemTextDelegate
|
id: resultItemTextDelegate
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: itemRect
|
id: itemRect
|
||||||
|
property int resultIndex: index
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: itemHeight
|
height: itemHeight
|
||||||
radius: 6
|
radius: 6
|
||||||
color: "#00000000"
|
color: "#00000000"
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.radius
|
||||||
|
color: palette.highlight
|
||||||
|
visible: searchResultRect.selectedIndex === itemRect.resultIndex
|
||||||
|
}
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -104,10 +148,20 @@ Popup {
|
|||||||
id: resultItemImgDelegate
|
id: resultItemImgDelegate
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: itemRect
|
id: itemRect
|
||||||
|
property int resultIndex: (model.type === "album"
|
||||||
|
? (searchResultRect.songList == null ? 0 : searchResultRect.songList.length)
|
||||||
|
+ searchResultRect.artistModel.count
|
||||||
|
: (searchResultRect.songList == null ? 0 : searchResultRect.songList.length)) + index
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: itemHeight
|
height: itemHeight
|
||||||
radius: 6
|
radius: 6
|
||||||
color: "#00000000"
|
color: "#00000000"
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.radius
|
||||||
|
color: palette.highlight
|
||||||
|
visible: searchResultRect.selectedIndex === itemRect.resultIndex
|
||||||
|
}
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|||||||
@@ -272,12 +272,29 @@ TitleBar {
|
|||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
placeholder: qsTr("Search")
|
placeholder: qsTr("Search")
|
||||||
enabled: Presenter.isExistMeta()
|
enabled: Presenter.isExistMeta()
|
||||||
|
Keys.onDownPressed: function(event) {
|
||||||
|
var searchResDlg = searchResultLoader.item
|
||||||
|
if (!searchResDlg || !searchResDlg.visible)
|
||||||
|
return
|
||||||
|
searchResDlg.moveSelection(1)
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
Keys.onUpPressed: function(event) {
|
||||||
|
var searchResDlg = searchResultLoader.item
|
||||||
|
if (!searchResDlg || !searchResDlg.visible)
|
||||||
|
return
|
||||||
|
searchResDlg.moveSelection(-1)
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
//console.log("SearchEdit: Keys.onEnterPressed....")
|
//console.log("SearchEdit: Keys.onEnterPressed....")
|
||||||
var searchResDlg = searchResultLoader.item
|
var searchResDlg = searchResultLoader.item
|
||||||
if (text.length <= 0 || !searchResDlg || searchResDlg.songList == null)
|
if (text.length <= 0 || !searchResDlg || searchResDlg.songList == null)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if (searchResDlg.visible && searchResDlg.activateSelection())
|
||||||
|
return
|
||||||
|
|
||||||
var type = -1
|
var type = -1
|
||||||
if (searchResDlg.songList.length > 0)
|
if (searchResDlg.songList.length > 0)
|
||||||
type = 0
|
type = 0
|
||||||
@@ -372,6 +389,7 @@ TitleBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var searchResDlg = searchResultLoader.item
|
var searchResDlg = searchResultLoader.item
|
||||||
|
searchResDlg.selectedIndex = -1
|
||||||
searchResDlg.songList = []
|
searchResDlg.songList = []
|
||||||
searchResDlg.artistModel.clear()
|
searchResDlg.artistModel.clear()
|
||||||
searchResDlg.albumModel.clear()
|
searchResDlg.albumModel.clear()
|
||||||
|
|||||||
Reference in New Issue
Block a user