Extract CursorPill, consolidate panel-cursor pill bases
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
// PillButton that participates in a panel's single-cursor model. Use
|
||||||
|
// inside a row of pills (DNS providers, bluetooth header actions, choice
|
||||||
|
// chips) where mouse hover and keyboard cursor should land in the same
|
||||||
|
// place.
|
||||||
|
//
|
||||||
|
// Caller binds `hasCursor` to the panel's cursor state and listens to
|
||||||
|
// `hovered(bool)` to update that state when the mouse enters or leaves.
|
||||||
|
// This is structurally a wrapper around PillButton with one extra
|
||||||
|
// HoverHandler — but extracting it lets every panel use the same wiring
|
||||||
|
// idiom and lets plugin authors drop into the same cursor model without
|
||||||
|
// touching internals.
|
||||||
|
//
|
||||||
|
// Why HoverHandler instead of a MouseArea overlay: HoverHandler doesn't
|
||||||
|
// steal pointer events from PillButton's internal click MouseArea, so
|
||||||
|
// clicks still reach the underlying button. An overlay MouseArea with
|
||||||
|
// acceptedButtons: Qt.NoButton works but is fragile around tooltip
|
||||||
|
// timing and event propagation.
|
||||||
|
PillButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
signal hovered(bool isHovered)
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: root.hovered(hovered)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
module qs.Ui
|
module qs.Ui
|
||||||
|
|
||||||
ChoiceButton 1.0 ChoiceButton.qml
|
ChoiceButton 1.0 ChoiceButton.qml
|
||||||
|
CursorPill 1.0 CursorPill.qml
|
||||||
CursorSurface 1.0 CursorSurface.qml
|
CursorSurface 1.0 CursorSurface.qml
|
||||||
KeyboardPanel 1.0 KeyboardPanel.qml
|
KeyboardPanel 1.0 KeyboardPanel.qml
|
||||||
PanelActionButton 1.0 PanelActionButton.qml
|
PanelActionButton 1.0 PanelActionButton.qml
|
||||||
|
|||||||
@@ -465,11 +465,11 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header pill — wraps PillButton with cursor-state binding so it
|
// Header pill: a CursorPill bound into the panel's "header" cursor
|
||||||
// participates in the same single-cursor model as device rows. We don't
|
// section. CursorPill collapses what used to be a PillButton subclass +
|
||||||
// use CursorSurface here because the pill already provides its
|
// overlay MouseArea into one component; we keep the pillIndex / activated
|
||||||
// own active/hover visuals and we want them to layer correctly.
|
// shim here so the three header pill instantiations stay readable.
|
||||||
component HeaderPill: PillButton {
|
component HeaderPill: CursorPill {
|
||||||
id: pill
|
id: pill
|
||||||
required property int pillIndex
|
required property int pillIndex
|
||||||
property bool pillEnabled: true
|
property bool pillEnabled: true
|
||||||
@@ -485,23 +485,13 @@ Item {
|
|||||||
enabled: pillEnabled
|
enabled: pillEnabled
|
||||||
opacity: pillEnabled ? 1 : 0.4
|
opacity: pillEnabled ? 1 : 0.4
|
||||||
|
|
||||||
// Hand off to PillButton's built-in cursor visuals so keyboard cursor and
|
|
||||||
// mouse hover render identically (fill + 1px border).
|
|
||||||
hasCursor: root.focusSection === "header" && root.selectedIndex === pillIndex
|
hasCursor: root.focusSection === "header" && root.selectedIndex === pillIndex
|
||||||
|
|
||||||
onClicked: pill.activated()
|
onClicked: pill.activated()
|
||||||
|
onHovered: function(isHovered) {
|
||||||
// Mouse hover updates root cursor state so keyboard + mouse share one
|
if (!isHovered) return
|
||||||
// selection model.
|
root.focusSection = "header"
|
||||||
MouseArea {
|
root.selectedIndex = pill.pillIndex
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
propagateComposedEvents: true
|
|
||||||
onContainsMouseChanged: if (containsMouse) {
|
|
||||||
root.focusSection = "header"
|
|
||||||
root.selectedIndex = pill.pillIndex
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -862,51 +862,29 @@ iwctl station "$station" get-networks rssi-dbms 2>/dev/null \\
|
|||||||
// One DNS provider pill. The cursor + current visuals come entirely from
|
// One DNS provider pill. The cursor + current visuals come entirely from
|
||||||
// CursorSurface; this component just binds them to the panel's cursor
|
// CursorSurface; this component just binds them to the panel's cursor
|
||||||
// state and renders the label/tooltip/click target.
|
// state and renders the label/tooltip/click target.
|
||||||
component DnsProviderPill: CursorSurface {
|
component DnsProviderPill: CursorPill {
|
||||||
id: pill
|
id: pill
|
||||||
required property string provider
|
required property string provider
|
||||||
required property int index
|
required property int index
|
||||||
property string tooltipText: ""
|
|
||||||
|
|
||||||
signal clicked()
|
text: provider
|
||||||
|
|
||||||
hasCursor: root.focusSection === "dns" && root.dnsIndex === index
|
|
||||||
current: root.dnsProvider === provider
|
|
||||||
foreground: root.bar.foreground
|
foreground: root.bar.foreground
|
||||||
fill: root.activeFill
|
tooltipBackground: root.bar.background
|
||||||
|
tooltipForeground: root.bar.foreground
|
||||||
|
fontFamily: root.bar.fontFamily
|
||||||
|
horizontalPadding: 10
|
||||||
|
verticalPadding: 6
|
||||||
|
|
||||||
implicitWidth: pillLabel.implicitWidth + 20
|
// Map the panel's domain semantics onto CursorPill's structural props:
|
||||||
implicitHeight: pillLabel.implicitHeight + 12
|
// `current DNS` is the pill's `active` fill; the keyboard cursor lights
|
||||||
|
// up `hasCursor`.
|
||||||
|
active: root.dnsProvider === provider
|
||||||
|
hasCursor: root.focusSection === "dns" && root.dnsIndex === index
|
||||||
|
|
||||||
Text {
|
onHovered: function(isHovered) {
|
||||||
id: pillLabel
|
if (!isHovered) return
|
||||||
anchors.centerIn: parent
|
root.focusSection = "dns"
|
||||||
text: pill.provider
|
root.dnsIndex = pill.index
|
||||||
color: root.bar.foreground
|
|
||||||
font.family: root.bar.fontFamily
|
|
||||||
font.pixelSize: 12
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: pillMouse
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
|
|
||||||
onContainsMouseChanged: if (containsMouse) {
|
|
||||||
root.focusSection = "dns"
|
|
||||||
root.dnsIndex = pill.index
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: pill.clicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
PanelToolTip {
|
|
||||||
visible: pill.tooltipText !== "" && pillMouse.containsMouse
|
|
||||||
text: pill.tooltipText
|
|
||||||
panelForeground: root.bar.foreground
|
|
||||||
panelBackground: root.bar.background
|
|
||||||
fontFamily: root.bar.fontFamily
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user