feat(settings): Add usage badges to widget selector

Adds a visual indicator to the "Add Widget" dropdown in the Bar
settings panel to show which widgets are already in use and where.

- A small text badge ("L", "C", "R") now appears next to any widget
  that is already on a panel.
- The badges are reactive and update automatically when widgets are
  added or removed.
- This helps prevent accidental duplicate additions and makes widget
  management easier.
This commit is contained in:
loner
2025-10-14 03:40:51 +08:00
parent 158d3a1e63
commit 679224e1d9
4 changed files with 112 additions and 40 deletions
+67 -30
View File
@@ -20,6 +20,7 @@ RowLayout {
property string currentKey: ""
property string placeholder: ""
property string searchPlaceholder: I18n.tr("placeholders.search")
property Component delegate: null
readonly property real preferredHeight: Style.baseWidgetSize * 1.1
@@ -187,43 +188,79 @@ RowLayout {
horizontalPolicy: ScrollBar.AlwaysOff
verticalPolicy: ScrollBar.AsNeeded
delegate: ItemDelegate {
width: listView.width
hoverEnabled: true
highlighted: ListView.view.currentIndex === index
delegate: root.delegate ? root.delegate : defaultDelegate
onHoveredChanged: {
if (hovered) {
ListView.view.currentIndex = index
Component {
id: defaultDelegate
ItemDelegate {
id: delegateRoot
width: listView.width
hoverEnabled: true
highlighted: ListView.view.currentIndex === index
onHoveredChanged: {
if (hovered) {
ListView.view.currentIndex = index
}
}
}
onClicked: {
root.selected(filteredModel.get(index).key)
combo.currentIndex = root.findIndexByKeyInFiltered(filteredModel.get(index).key)
combo.popup.close()
}
onClicked: {
root.selected(filteredModel.get(index).key)
combo.currentIndex = root.findIndexByKeyInFiltered(filteredModel.get(index).key)
combo.popup.close()
}
contentItem: NText {
text: name
pointSize: Style.fontSizeM
color: highlighted ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
Behavior on color {
ColorAnimation {
duration: Style.animationFast
contentItem: RowLayout {
width: parent.width
spacing: Style.marginM
NText {
text: name
pointSize: Style.fontSizeM
color: highlighted ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
Layout.fillWidth: true
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
RowLayout {
spacing: Style.marginS
Layout.alignment: Qt.AlignRight
Repeater {
model: badgeLocations
delegate: NBox {
width: Style.baseWidgetSize * 0.7
height: Style.baseWidgetSize * 0.7
color: "transparent"
radius: Style.radiusS
border.width: 0
NText {
anchors.centerIn: parent
text: modelData
pointSize: Style.fontSizeXXS
font.weight: Style.fontWeightBold
color: highlighted ? Color.mOnTertiary : Color.mOnSurface
}
}
}
}
}
background: Rectangle {
width: listView.width
color: highlighted ? Color.mTertiary : Color.transparent
radius: Style.radiusS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
background: Rectangle {
width: listView.width
color: highlighted ? Color.mTertiary : Color.transparent
radius: Style.radiusS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
}