diff --git a/Modules/Bar/Widgets/Bluetooth.qml b/Modules/Bar/Widgets/Bluetooth.qml index 4036743..760745c 100644 --- a/Modules/Bar/Widgets/Bluetooth.qml +++ b/Modules/Bar/Widgets/Bluetooth.qml @@ -21,6 +21,6 @@ NIconButton { colorBorderHover: Color.transparent icon: "bluetooth" - tooltipText: "Bluetooth devices" + tooltipText: "Bluetooth" onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(screen, this) } diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 987624d..6c53e65 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -132,7 +132,6 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - } Row { diff --git a/Modules/BluetoothPanel/BluetoothDevicesList.qml b/Modules/BluetoothPanel/BluetoothDevicesList.qml index 43c34f8..8780d95 100644 --- a/Modules/BluetoothPanel/BluetoothDevicesList.qml +++ b/Modules/BluetoothPanel/BluetoothDevicesList.qml @@ -36,65 +36,39 @@ ColumnLayout { visible: BluetoothService.adapter && BluetoothService.adapter.enabled Rectangle { - id: bluetoothDeviceRectangle - property bool canConnect: BluetoothService.canConnect(modelData) - property bool canDisconnect: BluetoothService.canDisconnect(modelData) - property bool isBusy: BluetoothService.isDeviceBusy(modelData) + id: device - Layout.fillWidth: true - Layout.preferredHeight: 64 * scaling + (10 * scaling * modelData.batteryAvailable) - radius: Style.radiusM * scaling - - color: { - if (availableDeviceArea.containsMouse) { - if (canDisconnect && !isBusy) - return Color.mError - - if (!isBusy) - return Color.mTertiary - return Color.mPrimary - } + readonly property bool canConnect: BluetoothService.canConnect(modelData) + readonly property bool canDisconnect: BluetoothService.canDisconnect(modelData) + readonly property bool isBusy: BluetoothService.isDeviceBusy(modelData) + function getContentColor(defaultColor = Color.mOnSurface) { if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) return Color.mPrimary - if (modelData.blocked) return Color.mError - - return Color.mSurfaceVariant + return defaultColor } - border.color: Color.mOutline + + Layout.fillWidth: true + Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * scaling * 2) + radius: Style.radiusM * scaling + color: Color.mSurface border.width: Math.max(1, Style.borderS * scaling) - - NTooltip { - id: tooltip - target: bluetoothDeviceRectangle - positionAbove: Settings.data.bar.position === "bottom" - text: root.tooltipText - } + border.color: getContentColor(Color.mOutline) RowLayout { + id: deviceLayout anchors.fill: parent anchors.margins: Style.marginM * scaling - spacing: Style.marginS * scaling + spacing: Style.marginM * scaling Layout.alignment: Qt.AlignVCenter // One device BT icon NIcon { text: BluetoothService.getDeviceIcon(modelData) font.pointSize: Style.fontSizeXXL * scaling - color: { - if (availableDeviceArea.containsMouse) - return Color.mOnTertiary - - if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) - return Color.mOnPrimary - - if (modelData.blocked) - return Color.mOnError - - return Color.mOnSurface - } + color: getContentColor(Color.mOnSurface) Layout.alignment: Qt.AlignVCenter } @@ -106,25 +80,23 @@ ColumnLayout { NText { text: modelData.name || modelData.deviceName font.pointSize: Style.fontSizeM * scaling - elide: Text.ElideRight - color: { - if (availableDeviceArea.containsMouse) - return Color.mOnTertiary - - if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) - return Color.mOnPrimary - - if (modelData.blocked) - return Color.mOnError - - return Color.mOnSurface - } font.weight: Style.fontWeightMedium + elide: Text.ElideRight + color: getContentColor(Color.mOnSurface) Layout.fillWidth: true } + // Status + NText { + text: BluetoothService.getStatusString(modelData) + visible: text !== "" + font.pointSize: Style.fontSizeXS * scaling + color: getContentColor(Color.mOnSurfaceVariant) + } + // Signal Strength RowLayout { + visible: modelData.signalStrength !== undefined Layout.fillWidth: true spacing: Style.marginXS * scaling @@ -132,76 +104,32 @@ ColumnLayout { NText { text: BluetoothService.getSignalStrength(modelData) font.pointSize: Style.fontSizeXS * scaling - color: { - if (availableDeviceArea.containsMouse) - return Color.mOnTertiary - - if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) - return Color.mOnPrimary - - if (modelData.blocked) - return Color.mOnError - - return Color.mOnSurfaceVariant - } + color: getContentColor(Color.mOnSurfaceVariant) } NIcon { + visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked text: BluetoothService.getSignalIcon(modelData) font.pointSize: Style.fontSizeXS * scaling - color: { - if (availableDeviceArea.containsMouse) - return Color.mOnTertiary - - if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) - return Color.mOnPrimary - - if (modelData.blocked) - return Color.mOnError - - return Color.mOnSurface - } - visible: modelData.signalStrength !== undefined && modelData.signalStrength > 0 && !modelData.pairing - && !modelData.blocked + color: getContentColor(Color.mOnSurface) } NText { + visible: modelData.signalStrength > 0 && !modelData.pairing + && !modelData.blocked text: (modelData.signalStrength !== undefined && modelData.signalStrength > 0) ? modelData.signalStrength + "%" : "" font.pointSize: Style.fontSizeXS * scaling - color: { - if (availableDeviceArea.containsMouse) - return Color.mOnTertiary - - if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) - return Color.mOnPrimary - - if (modelData.blocked) - return Color.mOnError - - return Color.mOnSurface - } - visible: modelData.signalStrength !== undefined && modelData.signalStrength > 0 && !modelData.pairing - && !modelData.blocked + color: getContentColor(Color.mOnSurface) } } + // Battery NText { visible: modelData.batteryAvailable text: BluetoothService.getBattery(modelData) font.pointSize: Style.fontSizeXS * scaling - color: { - if (availableDeviceArea.containsMouse) - return Color.mOnTertiary - - if (modelData.pairing || modelData.state === BluetoothDeviceState.Connecting) - return Color.mOnPrimary - - if (modelData.blocked) - return Color.mOnError - - return Color.mOnSurfaceVariant - } + color: getContentColor(Color.mOnSurfaceVariant) } } @@ -211,96 +139,86 @@ ColumnLayout { } // Call to action - Rectangle { - Layout.preferredWidth: 80 * scaling - Layout.preferredHeight: 28 * scaling - radius: Style.radiusM * scaling + NButton { + id: button visible: (modelData.state !== BluetoothDeviceState.Connecting) - color: Color.transparent - - border.color: { - if (availableDeviceArea.containsMouse) { - return Color.mOnTertiary - } - if (bluetoothDeviceRectangle.canDisconnect && !isBusy) { + enabled: (canConnect || canDisconnect) && !isBusy + outlined: !button.hovered + fontSize: Style.fontSizeXS * scaling + fontWeight: Style.fontWeightMedium + backgroundColor: { + if (device.canDisconnect && !isBusy) { return Color.mError } return Color.mPrimary } - border.width: Math.max(1, Style.borderS * scaling) - opacity: canConnect || isBusy || canDisconnect ? 1 : 0.5 - - NText { - anchors.centerIn: parent - text: { - if (modelData.pairing) { - return "Pairing..." - } - if (modelData.blocked) { - return "Blocked" - } - if (modelData.connected) { - return "Disconnect" - } - return "Connect" + tooltipText: root.tooltipText + text: { + if (modelData.pairing) { + return "Pairing..." } - font.pointSize: Style.fontSizeXS * scaling - font.weight: Style.fontWeightMedium - color: { - - if (availableDeviceArea.containsMouse) { - return Color.mOnTertiary - } - - if (bluetoothDeviceRectangle.canDisconnect && !isBusy) { - return Color.mError - } else { - return Color.mPrimary - } + if (modelData.blocked) { + return "Blocked" } + if (modelData.connected) { + return "Disconnect" + } + return "Connect" } - } - } - - MouseArea { - - id: availableDeviceArea - acceptedButtons: Qt.LeftButton | Qt.RightButton - anchors.fill: parent - hoverEnabled: true - cursorShape: (canConnect || canDisconnect) - && !isBusy ? Qt.PointingHandCursor : (isBusy ? Qt.BusyCursor : Qt.ArrowCursor) - onEntered: { - if (root.tooltipText && !isBusy) { - tooltip.show() - } - } - onExited: { - if (root.tooltipText && !isBusy) { - tooltip.hide() - } - } - onClicked: function (mouse) { - - if (!modelData || modelData.pairing) { - return - } - - if (root.tooltipText && !isBusy) { - tooltip.hide() - } - - if (mouse.button === Qt.LeftButton) { + icon: (isBusy ? "hourglass_full" : null) + onClicked: { if (modelData.connected) { BluetoothService.disconnectDevice(modelData) } else { BluetoothService.connectDeviceWithTrust(modelData) - } - } else if (mouse.button === Qt.RightButton) { + } + } + onRightClicked: + { BluetoothService.forgetDevice(modelData) } } } + + // MouseArea { + + // id: availableDeviceArea + // acceptedButtons: Qt.LeftButton | Qt.RightButton + // anchors.fill: parent + // hoverEnabled: true + // cursorShape: (canConnect || canDisconnect) + // && !isBusy ? Qt.PointingHandCursor : (isBusy ? Qt.BusyCursor : Qt.ArrowCursor) + // onEntered: { + // if (root.tooltipText && !isBusy) { + // tooltip.show() + // } + // } + // onExited: { + // if (root.tooltipText && !isBusy) { + // tooltip.hide() + // } + // } + // onClicked: function (mouse) { + + // if (!modelData || modelData.pairing) { + // return + // } + + // if (root.tooltipText && !isBusy) { + // tooltip.hide() + // } + + // if (mouse.button === Qt.LeftButton) { + // if (modelData.connected) { + // BluetoothService.disconnectDevice(modelData) + // } else { + // BluetoothService.connectDeviceWithTrust(modelData) + // } + // } else if (mouse.button === Qt.RightButton) { + // BluetoothService.forgetDevice(modelData) + // } + // } + // } } } } diff --git a/Services/BluetoothService.qml b/Services/BluetoothService.qml index 6283981..d6de5b5 100644 --- a/Services/BluetoothService.qml +++ b/Services/BluetoothService.qml @@ -107,13 +107,21 @@ Singleton { return device.connected && !device.pairing && !device.blocked } - function getSignalStrength(device) { + function getStatusString(device) { + if (device.state === BluetoothDeviceState.Connecting) { + return "Connecting..." + } if (device.pairing) { return "Pairing..." } if (device.blocked) { return "Blocked" } + return "" + } + + + function getSignalStrength(device) { if (!device || device.signalStrength === undefined || device.signalStrength <= 0) { return "Signal: Unknown" } diff --git a/Widgets/NButton.qml b/Widgets/NButton.qml index 1d090fd..5648c46 100644 --- a/Widgets/NButton.qml +++ b/Widgets/NButton.qml @@ -9,13 +9,15 @@ Rectangle { // Public properties property string text: "" property string icon: "" + property string tooltipText property color backgroundColor: Color.mPrimary property color textColor: Color.mOnPrimary property color hoverColor: Color.mTertiary property color pressColor: Color.mSecondary property bool enabled: true - property int fontSize: Style.fontSizeM * scaling - property int iconSize: Style.fontSizeL * scaling + property real fontSize: Style.fontSizeM * scaling + property int fontWeight: Style.fontWeightBold + property real iconSize: Style.fontSizeL * scaling property bool outlined: false property real customWidth: -1 property real customHeight: -1 @@ -106,7 +108,7 @@ Rectangle { visible: root.text !== "" text: root.text font.pointSize: root.fontSize - font.weight: Style.fontWeightBold + font.weight: root.fontWeight color: { if (!root.enabled) return Color.mOnSurfaceVariant @@ -127,6 +129,13 @@ Rectangle { } } + NTooltip { + id: tooltip + target: root + positionAbove: Settings.data.bar.position === "bottom" + text: root.tooltipText + } + // Mouse interaction MouseArea { id: mouseArea @@ -136,16 +145,27 @@ Rectangle { acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor - onEntered: root.hovered = true + onEntered: { + root.hovered = true + if (tooltipText) { + tooltip.show() + } + } onExited: { root.hovered = false root.pressed = false + if (tooltipText) { + tooltip.hide() + } } onPressed: mouse => { root.pressed = true } onReleased: mouse => { root.pressed = false + if (tooltipText) { + tooltip.hide() + } if (!root.hovered) { return } @@ -161,6 +181,9 @@ Rectangle { onCanceled: { root.pressed = false root.hovered = false + if (tooltipText) { + tooltip.hide() + } } } }