feat(qt): the sidebar's playlist and My QBZ filters follow the search-box contract

Both inline fields were bare TextInputs: no clear cross, no Escape.
They are QbzSearchField now — Escape empties the filter, hands the
keyboard back and folds the field into its title; the cross empties it
and keeps the caret. The control grew what a 22px header row needs: an
optional leading glyph (the toggle already shows one), a cross sized to
the field, and an `escaped` signal for hosts that fold the field away.

cc
This commit is contained in:
vicrodh committed 2026-09-14 00:49:54 -06:00
1 parent a564ed936b
commit 3d4d3bc6ed
2 files changed
+47 -67

No files matched your search

+17 -7
View File
@@ -22,6 +22,14 @@ Rectangle {
property alias text: input.text property alias text: input.text
property string placeholder: "" property string placeholder: ""
/// The leading magnifier; off for hosts whose own toggle already shows one
/// (the sidebar's inline filters).
property bool showGlyph: true
/// Escape emptied the field and handed the keyboard back; a host that
/// folds the field away listens here.
signal escaped()
/// The clear cross scales with a short field (the sidebar's 22px rows).
readonly property int clearSize: Math.min(22, Math.max(16, height - 2))
property int glyphSize: 14 property int glyphSize: 14
property int fontPx: 13 property int fontPx: 13
property int sidePadding: 10 property int sidePadding: 10
@@ -80,6 +88,7 @@ Rectangle {
} }
QbzIcon { QbzIcon {
visible: root.showGlyph
name: "search" name: "search"
width: root.glyphSize width: root.glyphSize
height: root.glyphSize height: root.glyphSize
@@ -92,7 +101,7 @@ Rectangle {
QbzTextEditMenu { } QbzTextEditMenu { }
anchors.left: parent.left anchors.left: parent.left
anchors.right: clearSlot.left anchors.right: clearSlot.left
anchors.leftMargin: root.sidePadding + root.glyphSize + 7 anchors.leftMargin: root.sidePadding + (root.showGlyph ? root.glyphSize + 7 : 0)
anchors.rightMargin: 4 anchors.rightMargin: 4
height: parent.height height: parent.height
color: theme.textPrimary color: theme.textPrimary
@@ -106,6 +115,7 @@ Rectangle {
} }
Keys.onEscapePressed: function (event) { Keys.onEscapePressed: function (event) {
root.clearAndBlur() root.clearAndBlur()
root.escaped()
event.accepted = true event.accepted = true
} }
Text { Text {
@@ -124,19 +134,19 @@ Rectangle {
id: clearSlot id: clearSlot
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 5 anchors.rightMargin: 5
width: input.text !== "" ? 22 : 0 width: input.text !== "" ? root.clearSize : 0
height: parent.height height: parent.height
visible: input.text !== "" visible: input.text !== ""
Rectangle { Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
width: 22 width: root.clearSize
height: 22 height: root.clearSize
radius: 11 radius: root.clearSize / 2
color: clearArea.containsMouse ? theme.surfaceHover : "transparent" color: clearArea.containsMouse ? theme.surfaceHover : "transparent"
QbzIcon { QbzIcon {
name: "x" name: "x"
width: 12 width: Math.round(root.clearSize * 0.55)
height: 12 height: Math.round(root.clearSize * 0.55)
anchors.centerIn: parent anchors.centerIn: parent
tintName: clearArea.containsMouse ? "textPrimary" : "muted" tintName: clearArea.containsMouse ? "textPrimary" : "muted"
} }
+30 -60
View File
@@ -903,12 +903,10 @@ Rectangle {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
root.myqbzSearchOpen = !root.myqbzSearchOpen root.myqbzSearchOpen = !root.myqbzSearchOpen
if (!root.myqbzSearchOpen) { if (!root.myqbzSearchOpen)
myqbzSearchEdit.text = "" myqbzSearchEdit.clear()
root.myqbzSearch = "" else
} else { myqbzSearchEdit.focusField()
myqbzSearchEdit.forceActiveFocus()
}
} }
} }
} }
@@ -999,8 +997,11 @@ Rectangle {
onClicked: QbzShell.navigateTo("collections") onClicked: QbzShell.navigateTo("collections")
} }
} }
// Inline search field (filters the tree client-side). // Inline search field (filters the tree client-side). The
Rectangle { // shared search box: Escape empties it AND folds it away,
// the cross empties it and keeps the caret.
QbzSearchField {
id: myqbzSearchEdit
visible: root.myqbzSearchOpen visible: root.myqbzSearchOpen
anchors.left: myqbzBrandIcon.right anchors.left: myqbzBrandIcon.right
anchors.leftMargin: 8 anchors.leftMargin: 8
@@ -1009,28 +1010,12 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
height: 22 height: 22
radius: 4 radius: 4
color: (theme.ambientOn ? theme.surfaceElevatedA50 : theme.surfaceElevated) showGlyph: false
border.width: 1 sidePadding: 6
border.color: theme.borderSubtle fontPx: 12
TextInput { placeholder: QbzSession.tr("Search My QBZ", QbzSession.trRev)
QbzTextEditMenu { } onEdited: function (text) { root.myqbzSearch = text }
id: myqbzSearchEdit onEscaped: root.myqbzSearchOpen = false
anchors.fill: parent
anchors.leftMargin: 6
color: theme.textPrimary
font.pixelSize: 12
verticalAlignment: Text.AlignVCenter
clip: true
onTextEdited: root.myqbzSearch = text
Text {
visible: myqbzSearchEdit.text === ""
anchors.fill: parent
text: QbzSession.tr("Search My QBZ", QbzSession.trRev)
color: theme.textMuted
font.pixelSize: 12
verticalAlignment: Text.AlignVCenter
}
}
} }
} }
@@ -1280,34 +1265,21 @@ Rectangle {
font.letterSpacing: 1 font.letterSpacing: 1
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
// Inline search input (filters entries, recursive). // Inline search input (filters entries, recursive). The shared
Rectangle { // search box: Escape empties it AND folds it back into the title,
// the cross empties it and keeps the caret.
QbzSearchField {
id: searchEdit
visible: root.searchOpen visible: root.searchOpen
width: parent.width - 4 * 26 width: parent.width - 4 * 26
height: 22 height: 22
radius: 4 radius: 4
color: (theme.ambientOn ? theme.surfaceElevatedA50 : theme.surfaceElevated) showGlyph: false
border.width: 1 sidePadding: 6
border.color: theme.borderSubtle fontPx: 12
TextInput { placeholder: QbzSession.tr("Search playlists", QbzSession.trRev)
QbzTextEditMenu { } onEdited: function (text) { QbzShell.sidebarSearch(text) }
id: searchEdit onEscaped: root.searchOpen = false
anchors.fill: parent
anchors.leftMargin: 6
color: theme.textPrimary
font.pixelSize: 12
verticalAlignment: Text.AlignVCenter
clip: true
onTextEdited: QbzShell.sidebarSearch(text)
Text {
visible: searchEdit.text === ""
anchors.fill: parent
text: QbzSession.tr("Search playlists", QbzSession.trRev)
color: theme.textMuted
font.pixelSize: 12
verticalAlignment: Text.AlignVCenter
}
}
} }
// Search toggle. // Search toggle.
@@ -1330,12 +1302,10 @@ Rectangle {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
root.searchOpen = !root.searchOpen root.searchOpen = !root.searchOpen
if (!root.searchOpen) { if (!root.searchOpen)
searchEdit.text = "" searchEdit.clear()
QbzShell.sidebarSearch("") else
} else { searchEdit.focusField()
searchEdit.forceActiveFocus()
}
} }
} }
} }