Refine Bluetooth panel device actions
This commit is contained in:
@@ -115,6 +115,7 @@ Panel {
|
|||||||
// guaranteeing one highlight on screen.
|
// guaranteeing one highlight on screen.
|
||||||
property string focusSection: "connected"
|
property string focusSection: "connected"
|
||||||
property int selectedIndex: 0
|
property int selectedIndex: 0
|
||||||
|
property bool actionFocused: false
|
||||||
property bool cursorActive: false
|
property bool cursorActive: false
|
||||||
|
|
||||||
// Stable identity for the focused device. Devices move between sections as
|
// Stable identity for the focused device. Devices move between sections as
|
||||||
@@ -246,24 +247,43 @@ Panel {
|
|||||||
var sections = visibleSections
|
var sections = visibleSections
|
||||||
if (!sections || sections.length === 0) return
|
if (!sections || sections.length === 0) return
|
||||||
var sIdx = sections.indexOf(focusSection)
|
var sIdx = sections.indexOf(focusSection)
|
||||||
if (sIdx < 0) { focusSection = sections[0]; selectedIndex = 0; return }
|
if (sIdx < 0) { focusSection = sections[0]; selectedIndex = 0; actionFocused = false; return }
|
||||||
|
|
||||||
var idx = selectedIndex
|
var idx = selectedIndex
|
||||||
var max = sectionCount(focusSection) - 1
|
var max = sectionCount(focusSection) - 1
|
||||||
|
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
if (idx < max) { selectedIndex = idx + 1; return }
|
if (idx < max) { selectedIndex = idx + 1; actionFocused = false; return }
|
||||||
if (sIdx < sections.length - 1) {
|
if (sIdx < sections.length - 1) {
|
||||||
focusSection = sections[sIdx + 1]
|
focusSection = sections[sIdx + 1]
|
||||||
selectedIndex = 0
|
selectedIndex = 0
|
||||||
|
actionFocused = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx > 0) { selectedIndex = idx - 1; return }
|
if (idx > 0) { selectedIndex = idx - 1; actionFocused = false; return }
|
||||||
if (sIdx > 0) { focusSection = sections[sIdx - 1]; selectedIndex = sectionCount(focusSection) - 1 }
|
if (sIdx > 0) {
|
||||||
|
focusSection = sections[sIdx - 1]
|
||||||
|
selectedIndex = sectionCount(focusSection) - 1
|
||||||
|
actionFocused = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function moveCursorH(delta) {
|
||||||
|
if (!cursorActive) { cursorActive = true; return }
|
||||||
|
if (focusSection !== "known") return
|
||||||
|
var dev = deviceAt(focusSection, selectedIndex)
|
||||||
|
if (!dev || dev.connected) return
|
||||||
|
if (delta > 0) actionFocused = true
|
||||||
|
else if (delta < 0) actionFocused = false
|
||||||
|
}
|
||||||
|
|
||||||
function activateCursor() {
|
function activateCursor() {
|
||||||
|
if (actionFocused) {
|
||||||
|
deleteSelected()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (focusSection === "connected" || focusSection === "known") {
|
if (focusSection === "connected" || focusSection === "known") {
|
||||||
var dev = deviceAt(focusSection, selectedIndex)
|
var dev = deviceAt(focusSection, selectedIndex)
|
||||||
if (!dev) return
|
if (!dev) return
|
||||||
@@ -278,17 +298,14 @@ Panel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'x' on a known row mirrors the row's X button: connected device
|
// 'x' forgets remembered devices. Connected rows toggle connection via
|
||||||
// disconnects, everything else forgets the pairing. Mismatching this
|
// Enter/click, so the destructive forget action is intentionally unavailable
|
||||||
// (e.g. forgetting a connected device) is destructive — the X button
|
// while connected.
|
||||||
// tooltip says "Disconnect" for connected rows, and the keybind has
|
|
||||||
// to agree.
|
|
||||||
function deleteSelected() {
|
function deleteSelected() {
|
||||||
if (focusSection !== "connected" && focusSection !== "known") return
|
if (focusSection !== "known") return
|
||||||
var dev = deviceAt(focusSection, selectedIndex)
|
var dev = deviceAt(focusSection, selectedIndex)
|
||||||
if (!dev) return
|
if (!dev) return
|
||||||
if (dev.connected) disconnectDevice(dev)
|
forgetDevice(dev)
|
||||||
else forgetDevice(dev)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenedChanged: {
|
onOpenedChanged: {
|
||||||
@@ -297,6 +314,7 @@ Panel {
|
|||||||
if (connectedDevices.length > 0) { focusSection = "connected"; selectedIndex = 0 }
|
if (connectedDevices.length > 0) { focusSection = "connected"; selectedIndex = 0 }
|
||||||
else if (knownDevices.length > 0) { focusSection = "known"; selectedIndex = 0 }
|
else if (knownDevices.length > 0) { focusSection = "known"; selectedIndex = 0 }
|
||||||
else if (discoveredDevices.length > 0) { focusSection = "discovered"; selectedIndex = 0 }
|
else if (discoveredDevices.length > 0) { focusSection = "discovered"; selectedIndex = 0 }
|
||||||
|
actionFocused = false
|
||||||
cursorActive = false
|
cursorActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,6 +482,7 @@ Panel {
|
|||||||
onMoveRequested: function(dx, dy) {
|
onMoveRequested: function(dx, dy) {
|
||||||
if (!root.cursorActive) { root.cursorActive = true; return }
|
if (!root.cursorActive) { root.cursorActive = true; return }
|
||||||
if (dy !== 0) root.moveCursor(dy)
|
if (dy !== 0) root.moveCursor(dy)
|
||||||
|
else if (dx !== 0) root.moveCursorH(dx)
|
||||||
}
|
}
|
||||||
onActivateRequested: if (root.cursorActive) root.activateCursor()
|
onActivateRequested: if (root.cursorActive) root.activateCursor()
|
||||||
onCloseRequested: root.close()
|
onCloseRequested: root.close()
|
||||||
@@ -650,8 +669,18 @@ Panel {
|
|||||||
readonly property bool isConnected: dev && dev.connected
|
readonly property bool isConnected: dev && dev.connected
|
||||||
readonly property int devState: dev && dev.state !== undefined ? dev.state : -1
|
readonly property int devState: dev && dev.state !== undefined ? dev.state : -1
|
||||||
readonly property string action: root.pendingAction(dev ? dev.address : "")
|
readonly property string action: root.pendingAction(dev ? dev.address : "")
|
||||||
|
readonly property string actionTooltip: {
|
||||||
|
if (!dev) return ""
|
||||||
|
if (isConnected) return "Disconnect"
|
||||||
|
if (isDiscovered) return "Pair"
|
||||||
|
return "Connect"
|
||||||
|
}
|
||||||
|
|
||||||
hasCursor: root.cursorActive && root.focusSection === sectionName && root.selectedIndex === rowIndex
|
readonly property bool rowSelected: root.cursorActive && root.focusSection === sectionName && root.selectedIndex === rowIndex
|
||||||
|
readonly property bool forgetAvailable: sectionName === "known" && !isConnected && !isDiscovered
|
||||||
|
readonly property bool showForgetButton: forgetAvailable && (rowMouse.containsMouse || rowSelected)
|
||||||
|
|
||||||
|
hasCursor: rowSelected && !root.actionFocused
|
||||||
onHasCursorChanged: if (hasCursor) root.ensureCursorVisible(row)
|
onHasCursorChanged: if (hasCursor) root.ensureCursorVisible(row)
|
||||||
current: isConnected
|
current: isConnected
|
||||||
foreground: root.bar.foreground
|
foreground: root.bar.foreground
|
||||||
@@ -690,6 +719,7 @@ Panel {
|
|||||||
root.cursorActive = true
|
root.cursorActive = true
|
||||||
root.focusSection = row.sectionName
|
root.focusSection = row.sectionName
|
||||||
root.selectedIndex = row.rowIndex
|
root.selectedIndex = row.rowIndex
|
||||||
|
root.actionFocused = false
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: function(mouse) {
|
onClicked: function(mouse) {
|
||||||
@@ -699,11 +729,17 @@ Panel {
|
|||||||
else if (!row.isDiscovered) root.forgetDevice(row.dev)
|
else if (!row.isDiscovered) root.forgetDevice(row.dev)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (row.isConnected) return // use the X button to disconnect
|
if (row.isConnected) root.disconnectDevice(row.dev)
|
||||||
root.connectDevice(row.dev)
|
else root.connectDevice(row.dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PanelToolTip {
|
||||||
|
visible: row.actionTooltip !== "" && rowMouse.containsMouse && !root.actionFocused
|
||||||
|
text: row.actionTooltip
|
||||||
|
fontFamily: root.bar.fontFamily
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: rowContent
|
id: rowContent
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -711,7 +747,7 @@ Panel {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: Style.space(10)
|
anchors.leftMargin: Style.space(10)
|
||||||
anchors.rightMargin: Style.space(10)
|
anchors.rightMargin: Style.space(10)
|
||||||
implicitHeight: Math.max(deviceIcon.implicitHeight, info.implicitHeight, disconnectBtn.implicitHeight)
|
implicitHeight: Math.max(deviceIcon.implicitHeight, info.implicitHeight, forgetBtn.implicitHeight)
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: deviceIcon
|
id: deviceIcon
|
||||||
@@ -723,32 +759,13 @@ Panel {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit close button on any known device. Action depends on state:
|
|
||||||
// connected -> disconnect, otherwise -> forget the pairing entirely.
|
|
||||||
PanelActionButton {
|
|
||||||
id: disconnectBtn
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !row.isDiscovered
|
|
||||||
iconText: ""
|
|
||||||
tooltipText: row.isConnected ? "Disconnect" : "Forget"
|
|
||||||
foreground: root.bar.foreground
|
|
||||||
hoverColor: root.bar.urgent
|
|
||||||
fontFamily: root.bar.fontFamily
|
|
||||||
onClicked: {
|
|
||||||
if (!row.dev) return
|
|
||||||
if (row.isConnected) root.disconnectDevice(row.dev)
|
|
||||||
else root.forgetDevice(row.dev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: info
|
id: info
|
||||||
spacing: Style.space(1)
|
spacing: Style.space(1)
|
||||||
anchors.left: deviceIcon.right
|
anchors.left: deviceIcon.right
|
||||||
anchors.leftMargin: Style.space(10)
|
anchors.leftMargin: Style.space(10)
|
||||||
anchors.right: disconnectBtn.visible ? disconnectBtn.left : parent.right
|
anchors.right: forgetBtn.visible ? forgetBtn.left : parent.right
|
||||||
anchors.rightMargin: disconnectBtn.visible ? Style.space(8) : 0
|
anchors.rightMargin: forgetBtn.visible ? Style.space(8) : 0
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
@@ -769,6 +786,33 @@ Panel {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PanelActionButton {
|
||||||
|
id: forgetBtn
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: row.showForgetButton
|
||||||
|
iconText: ""
|
||||||
|
tooltipText: "Forget"
|
||||||
|
foreground: root.bar.foreground
|
||||||
|
hoverColor: root.bar.foreground
|
||||||
|
fontFamily: root.bar.fontFamily
|
||||||
|
hasCursor: row.rowSelected && root.actionFocused
|
||||||
|
onHovered: function(isHovered) {
|
||||||
|
if (!isHovered) {
|
||||||
|
if (rowMouse.containsMouse) root.actionFocused = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
root.cursorActive = true
|
||||||
|
root.focusSection = row.sectionName
|
||||||
|
root.selectedIndex = row.rowIndex
|
||||||
|
root.actionFocused = true
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
if (!row.dev) return
|
||||||
|
root.forgetDevice(row.dev)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user