diff --git a/Modules/Bar/Battery/BatteryPanel.qml b/Modules/Bar/Battery/BatteryPanel.qml index a6f41829..db0e7693 100644 --- a/Modules/Bar/Battery/BatteryPanel.qml +++ b/Modules/Bar/Battery/BatteryPanel.qml @@ -34,59 +34,62 @@ NPanel { updateOptionsModel() } - panelContent: Rectangle { - color: Color.transparent + panelContent: Item { + anchors.fill: parent ColumnLayout { anchors.fill: parent - anchors.margins: Style.marginL + anchors.margins: Style.marginM spacing: Style.marginM // HEADER - RowLayout { + NBox { Layout.fillWidth: true - spacing: Style.marginM + Layout.preferredHeight: header.implicitHeight + Style.marginM * 2 - NText { - text: I18n.tr("battery.panel.title") - pointSize: Style.fontSizeL - font.weight: Style.fontWeightBold - color: Color.mOnSurface - Layout.fillWidth: true - } + RowLayout { + id: header + anchors.fill: parent + anchors.margins: Style.marginM + spacing: Style.marginM - NToggle { - id: batteryManagerSwitch - checked: BatteryService.chargingMode !== BatteryService.ChargingMode.Disabled - onToggled: checked => BatteryService.toggleEnabled(checked) - baseSize: Style.baseWidgetSize * 0.65 - } + NText { + text: I18n.tr("battery.panel.title") + pointSize: Style.fontSizeL + font.weight: Style.fontWeightBold + color: Color.mOnSurface + Layout.fillWidth: true + } - NIconButton { - icon: "close" - tooltipText: I18n.tr("tooltips.close") - baseSize: Style.baseWidgetSize * 0.8 - onClicked: { - root.close() + NToggle { + id: batteryManagerSwitch + checked: BatteryService.chargingMode !== BatteryService.ChargingMode.Disabled + onToggled: checked => BatteryService.toggleEnabled(checked) + baseSize: Style.baseWidgetSize * 0.65 + } + + NIconButton { + icon: "close" + tooltipText: I18n.tr("tooltips.close") + baseSize: Style.baseWidgetSize * 0.8 + onClicked: { + root.close() + } } } } - NDivider { - Layout.fillWidth: true - } - ButtonGroup { id: batteryGroup } - Rectangle { + NBox { Layout.fillWidth: true Layout.fillHeight: true - color: Color.transparent ColumnLayout { anchors.fill: parent + anchors.margins: Style.marginM spacing: Style.marginM Repeater { diff --git a/Modules/Bar/Bluetooth/BluetoothDevicesList.qml b/Modules/Bar/Bluetooth/BluetoothDevicesList.qml index 7c9703e6..f2721e6a 100644 --- a/Modules/Bar/Bluetooth/BluetoothDevicesList.qml +++ b/Modules/Bar/Bluetooth/BluetoothDevicesList.qml @@ -8,7 +8,7 @@ import qs.Commons import qs.Services import qs.Widgets -ColumnLayout { +NBox { id: root property string label: "" @@ -18,161 +18,170 @@ ColumnLayout { } Layout.fillWidth: true - spacing: Style.marginM + Layout.preferredHeight: column.implicitHeight + Style.marginM * 2 - NText { - text: root.label - pointSize: Style.fontSizeL - color: Color.mSecondary - font.weight: Style.fontWeightMedium - Layout.fillWidth: true - visible: root.model.length > 0 - } + ColumnLayout { + id: column + anchors.fill: parent + anchors.margins: Style.marginM - Repeater { - id: deviceList - Layout.fillWidth: true - model: root.model - visible: BluetoothService.adapter && BluetoothService.adapter.enabled - - Rectangle { - id: device - - 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 defaultColor - } + spacing: Style.marginM + NText { + text: root.label + pointSize: Style.fontSizeL + color: Color.mSecondary + font.weight: Style.fontWeightMedium + visible: root.model.length > 0 Layout.fillWidth: true - Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * 2) - radius: Style.radiusM - color: Color.mSurface - border.width: Style.borderS - border.color: getContentColor(Color.mOutline) + Layout.leftMargin: Style.marginM + } - RowLayout { - id: deviceLayout - anchors.fill: parent - anchors.margins: Style.marginM - spacing: Style.marginM - Layout.alignment: Qt.AlignVCenter + Repeater { + id: deviceList + Layout.fillWidth: true + model: root.model + visible: BluetoothService.adapter && BluetoothService.adapter.enabled - // One device BT icon - NIcon { - icon: BluetoothService.getDeviceIcon(modelData) - pointSize: Style.fontSizeXXL - color: getContentColor(Color.mOnSurface) - Layout.alignment: Qt.AlignVCenter + Rectangle { + id: device + + 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 defaultColor } - ColumnLayout { - Layout.fillWidth: true - spacing: Style.marginXXS + Layout.fillWidth: true + Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * 2) + radius: Style.radiusM + color: Color.mSurface + border.width: Style.borderS + border.color: getContentColor(Color.mOutline) - // Device name - NText { - text: modelData.name || modelData.deviceName - pointSize: Style.fontSizeM - font.weight: Style.fontWeightMedium - elide: Text.ElideRight + RowLayout { + id: deviceLayout + anchors.fill: parent + anchors.margins: Style.marginM + spacing: Style.marginM + Layout.alignment: Qt.AlignVCenter + + // One device BT icon + NIcon { + icon: BluetoothService.getDeviceIcon(modelData) + pointSize: Style.fontSizeXXL color: getContentColor(Color.mOnSurface) - Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter } - // Status - NText { - text: BluetoothService.getStatusString(modelData) - visible: text !== "" - pointSize: Style.fontSizeXS - color: getContentColor(Color.mOnSurfaceVariant) - } - - // Signal Strength - RowLayout { - visible: modelData.signalStrength !== undefined + ColumnLayout { Layout.fillWidth: true - spacing: Style.marginXS + spacing: Style.marginXXS - // Device signal strength - "Unknown" when not connected + // Device name NText { - text: BluetoothService.getSignalStrength(modelData) + text: modelData.name || modelData.deviceName + pointSize: Style.fontSizeM + font.weight: Style.fontWeightMedium + elide: Text.ElideRight + color: getContentColor(Color.mOnSurface) + Layout.fillWidth: true + } + + // Status + NText { + text: BluetoothService.getStatusString(modelData) + visible: text !== "" pointSize: Style.fontSizeXS color: getContentColor(Color.mOnSurfaceVariant) } - NIcon { - visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked - icon: BluetoothService.getSignalIcon(modelData) - pointSize: Style.fontSizeXS - color: getContentColor(Color.mOnSurface) + // Signal Strength + RowLayout { + visible: modelData.signalStrength !== undefined + Layout.fillWidth: true + spacing: Style.marginXS + + // Device signal strength - "Unknown" when not connected + NText { + text: BluetoothService.getSignalStrength(modelData) + pointSize: Style.fontSizeXS + color: getContentColor(Color.mOnSurfaceVariant) + } + + NIcon { + visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked + icon: BluetoothService.getSignalIcon(modelData) + pointSize: Style.fontSizeXS + color: getContentColor(Color.mOnSurface) + } + + NText { + visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked + text: (modelData.signalStrength !== undefined && modelData.signalStrength > 0) ? modelData.signalStrength + "%" : "" + pointSize: Style.fontSizeXS + color: getContentColor(Color.mOnSurface) + } } + // Battery NText { - visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked - text: (modelData.signalStrength !== undefined && modelData.signalStrength > 0) ? modelData.signalStrength + "%" : "" + visible: modelData.batteryAvailable + text: BluetoothService.getBattery(modelData) pointSize: Style.fontSizeXS - color: getContentColor(Color.mOnSurface) + color: getContentColor(Color.mOnSurfaceVariant) } } - // Battery - NText { - visible: modelData.batteryAvailable - text: BluetoothService.getBattery(modelData) - pointSize: Style.fontSizeXS - color: getContentColor(Color.mOnSurfaceVariant) + // Spacer to push connect button to the right + Item { + Layout.fillWidth: true } - } - // Spacer to push connect button to the right - Item { - Layout.fillWidth: true - } - - // Call to action - NButton { - id: button - visible: (modelData.state !== BluetoothDeviceState.Connecting) - enabled: (canConnect || canDisconnect) && !isBusy - outlined: !button.hovered - fontSize: Style.fontSizeXS - fontWeight: Style.fontWeightMedium - backgroundColor: { - if (device.canDisconnect && !isBusy) { - return Color.mError + // Call to action + NButton { + id: button + visible: (modelData.state !== BluetoothDeviceState.Connecting) + enabled: (canConnect || canDisconnect) && !isBusy + outlined: !button.hovered + fontSize: Style.fontSizeXS + fontWeight: Style.fontWeightMedium + backgroundColor: { + if (device.canDisconnect && !isBusy) { + return Color.mError + } + return Color.mPrimary } - return Color.mPrimary - } - tooltipText: root.tooltipText - text: { - if (modelData.pairing) { - return "Pairing..." + tooltipText: root.tooltipText + text: { + if (modelData.pairing) { + return "Pairing..." + } + if (modelData.blocked) { + return "Blocked" + } + if (modelData.connected) { + return "Disconnect" + } + return "Connect" } - if (modelData.blocked) { - return "Blocked" + icon: (isBusy ? "busy" : null) + onClicked: { + if (modelData.connected) { + BluetoothService.disconnectDevice(modelData) + } else { + BluetoothService.connectDeviceWithTrust(modelData) + } } - if (modelData.connected) { - return "Disconnect" + onRightClicked: { + BluetoothService.forgetDevice(modelData) } - return "Connect" - } - icon: (isBusy ? "busy" : null) - onClicked: { - if (modelData.connected) { - BluetoothService.disconnectDevice(modelData) - } else { - BluetoothService.connectDeviceWithTrust(modelData) - } - } - onRightClicked: { - BluetoothService.forgetDevice(modelData) } } } diff --git a/Modules/Bar/Bluetooth/BluetoothPanel.qml b/Modules/Bar/Bluetooth/BluetoothPanel.qml index 7e08efef..18563c0d 100644 --- a/Modules/Bar/Bluetooth/BluetoothPanel.qml +++ b/Modules/Bar/Bluetooth/BluetoothPanel.qml @@ -11,7 +11,7 @@ import qs.Widgets NPanel { id: root - preferredWidth: 380 * Style.uiScaleRatio + preferredWidth: 420 * Style.uiScaleRatio preferredHeight: 500 * Style.uiScaleRatio panelKeyboardFocus: true @@ -23,63 +23,67 @@ NPanel { anchors.margins: Style.marginL spacing: Style.marginM - // HEADER - RowLayout { + // Header + NBox { Layout.fillWidth: true - spacing: Style.marginM + implicitHeight: headerRow.implicitHeight + (Style.marginM * 2) - NIcon { - icon: "bluetooth" - pointSize: Style.fontSizeXXL - color: Color.mPrimary - } + RowLayout { + id: headerRow + anchors.fill: parent + anchors.leftMargin: Style.marginM + anchors.rightMargin: Style.marginM + spacing: Style.marginM - NText { - text: I18n.tr("bluetooth.panel.title") - pointSize: Style.fontSizeL - font.weight: Style.fontWeightBold - color: Color.mOnSurface - Layout.fillWidth: true - } + NIcon { + icon: "bluetooth" + pointSize: Style.fontSizeXXL + color: Color.mPrimary + } - NToggle { - id: bluetoothSwitch - checked: BluetoothService.enabled - onToggled: checked => BluetoothService.setBluetoothEnabled(checked) - baseSize: Style.baseWidgetSize * 0.65 - } + NText { + text: I18n.tr("bluetooth.panel.title") + pointSize: Style.fontSizeL + font.weight: Style.fontWeightBold + color: Color.mOnSurface + Layout.fillWidth: true + } - NIconButton { - enabled: BluetoothService.enabled - icon: BluetoothService.adapter && BluetoothService.adapter.discovering ? "stop" : "refresh" - tooltipText: I18n.tr("tooltips.refresh-devices") - baseSize: Style.baseWidgetSize * 0.8 - onClicked: { - if (BluetoothService.adapter) { - BluetoothService.adapter.discovering = !BluetoothService.adapter.discovering + NToggle { + id: bluetoothSwitch + checked: BluetoothService.enabled + onToggled: checked => BluetoothService.setBluetoothEnabled(checked) + baseSize: Style.baseWidgetSize * 0.65 + } + + NIconButton { + enabled: BluetoothService.enabled + icon: BluetoothService.adapter && BluetoothService.adapter.discovering ? "stop" : "refresh" + tooltipText: I18n.tr("tooltips.refresh-devices") + baseSize: Style.baseWidgetSize * 0.8 + onClicked: { + if (BluetoothService.adapter) { + BluetoothService.adapter.discovering = !BluetoothService.adapter.discovering + } + } + } + + NIconButton { + icon: "close" + tooltipText: I18n.tr("tooltips.close") + baseSize: Style.baseWidgetSize * 0.8 + onClicked: { + root.close() } } } - - NIconButton { - icon: "close" - tooltipText: I18n.tr("tooltips.close") - baseSize: Style.baseWidgetSize * 0.8 - onClicked: { - root.close() - } - } } - NDivider { - Layout.fillWidth: true - } - - Rectangle { + // Adapter not available of disabled + NBox { visible: !(BluetoothService.adapter && BluetoothService.adapter.enabled) Layout.fillWidth: true Layout.fillHeight: true - color: Color.transparent // Center the content within this rectangle ColumnLayout { @@ -166,9 +170,9 @@ NPanel { } // Fallback - No devices, scanning - ColumnLayout { - Layout.alignment: Qt.AlignHCenter - spacing: Style.marginM + NBox { + Layout.fillWidth: true + Layout.preferredHeight: columnScanning.implicitHeight + Style.marginM * 2 visible: { if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices) { return false @@ -180,37 +184,45 @@ NPanel { return (availableCount === 0) } - RowLayout { - Layout.alignment: Qt.AlignHCenter - spacing: Style.marginXS + ColumnLayout { + id: columnScanning + anchors.fill: parent + anchors.margins: Style.marginM - NIcon { - icon: "refresh" - pointSize: Style.fontSizeXXL * 1.5 - color: Color.mPrimary + spacing: Style.marginM - RotationAnimation on rotation { - running: true - loops: Animation.Infinite - from: 0 - to: 360 - duration: Style.animationSlow * 4 + RowLayout { + Layout.alignment: Qt.AlignHCenter + spacing: Style.marginXS + + NIcon { + icon: "refresh" + pointSize: Style.fontSizeXXL * 1.5 + color: Color.mPrimary + + RotationAnimation on rotation { + running: true + loops: Animation.Infinite + from: 0 + to: 360 + duration: Style.animationSlow * 4 + } + } + + NText { + text: I18n.tr("bluetooth.panel.scanning") + pointSize: Style.fontSizeL + color: Color.mOnSurface } } NText { - text: I18n.tr("bluetooth.panel.scanning") - pointSize: Style.fontSizeL - color: Color.mOnSurface + text: I18n.tr("bluetooth.panel.pairing-mode") + pointSize: Style.fontSizeM + color: Color.mOnSurfaceVariant + Layout.alignment: Qt.AlignHCenter } } - - NText { - text: I18n.tr("bluetooth.panel.pairing-mode") - pointSize: Style.fontSizeM - color: Color.mOnSurfaceVariant - Layout.alignment: Qt.AlignHCenter - } } Item { diff --git a/Modules/Bar/WiFi/WiFiPanel.qml b/Modules/Bar/WiFi/WiFiPanel.qml index 90e40b43..281ace59 100644 --- a/Modules/Bar/WiFi/WiFiPanel.qml +++ b/Modules/Bar/WiFi/WiFiPanel.qml @@ -10,7 +10,7 @@ import qs.Widgets NPanel { id: root - preferredWidth: 400 * Style.uiScaleRatio + preferredWidth: 420 * Style.uiScaleRatio preferredHeight: 500 * Style.uiScaleRatio panelKeyboardFocus: true @@ -29,51 +29,53 @@ NPanel { spacing: Style.marginM // Header - RowLayout { + NBox { Layout.fillWidth: true - spacing: Style.marginM + Layout.preferredHeight: headerRow.implicitHeight + Style.marginM * 2 - NIcon { - icon: Settings.data.network.wifiEnabled ? "wifi" : "wifi-off" - pointSize: Style.fontSizeXXL - color: Settings.data.network.wifiEnabled ? Color.mPrimary : Color.mOnSurfaceVariant - } + RowLayout { + id: headerRow + anchors.fill: parent + anchors.margins: Style.marginM + spacing: Style.marginM - NText { - text: I18n.tr("wifi.panel.title") - pointSize: Style.fontSizeL - font.weight: Style.fontWeightBold - color: Color.mOnSurface - Layout.fillWidth: true - } + NIcon { + icon: Settings.data.network.wifiEnabled ? "wifi" : "wifi-off" + pointSize: Style.fontSizeXXL + color: Settings.data.network.wifiEnabled ? Color.mPrimary : Color.mOnSurfaceVariant + } - NToggle { - id: wifiSwitch - checked: Settings.data.network.wifiEnabled - onToggled: checked => NetworkService.setWifiEnabled(checked) - baseSize: Style.baseWidgetSize * 0.65 - } + NText { + text: I18n.tr("wifi.panel.title") + pointSize: Style.fontSizeL + font.weight: Style.fontWeightBold + color: Color.mOnSurface + Layout.fillWidth: true + } - NIconButton { - icon: "refresh" - tooltipText: I18n.tr("tooltips.refresh") - baseSize: Style.baseWidgetSize * 0.8 - enabled: Settings.data.network.wifiEnabled && !NetworkService.scanning - onClicked: NetworkService.scan() - } + NToggle { + id: wifiSwitch + checked: Settings.data.network.wifiEnabled + onToggled: checked => NetworkService.setWifiEnabled(checked) + baseSize: Style.baseWidgetSize * 0.65 + } - NIconButton { - icon: "close" - tooltipText: I18n.tr("tooltips.close") - baseSize: Style.baseWidgetSize * 0.8 - onClicked: root.close() + NIconButton { + icon: "refresh" + tooltipText: I18n.tr("tooltips.refresh") + baseSize: Style.baseWidgetSize * 0.8 + enabled: Settings.data.network.wifiEnabled && !NetworkService.scanning + onClicked: NetworkService.scan() + } + + NIconButton { + icon: "close" + tooltipText: I18n.tr("tooltips.close") + baseSize: Style.baseWidgetSize * 0.8 + onClicked: root.close() + } } } - - NDivider { - Layout.fillWidth: true - } - // Error message Rectangle { visible: NetworkService.lastError.length > 0 @@ -113,16 +115,15 @@ NPanel { } // Main content area - Rectangle { + NBox { Layout.fillWidth: true Layout.fillHeight: true - color: Color.transparent // WiFi disabled state ColumnLayout { visible: !Settings.data.network.wifiEnabled anchors.fill: parent - spacing: Style.marginM + anchors.margins: Style.marginM Item { Layout.fillHeight: true @@ -158,6 +159,7 @@ NPanel { ColumnLayout { visible: Settings.data.network.wifiEnabled && NetworkService.scanning && Object.keys(NetworkService.networks).length === 0 anchors.fill: parent + anchors.margins: Style.marginM spacing: Style.marginL Item { @@ -187,6 +189,7 @@ NPanel { NScrollView { visible: Settings.data.network.wifiEnabled && (!NetworkService.scanning || Object.keys(NetworkService.networks).length > 0) anchors.fill: parent + anchors.margins: Style.marginM horizontalPolicy: ScrollBar.AlwaysOff verticalPolicy: ScrollBar.AsNeeded clip: true diff --git a/Services/MediaService.qml b/Services/MediaService.qml index aa6a6648..505a945b 100644 --- a/Services/MediaService.qml +++ b/Services/MediaService.qml @@ -305,7 +305,8 @@ Singleton { running: true onTriggered: { Logger.d("MediaService", "playerStateMonitor triggered. autoSwitchingPaused: " + root.autoSwitchingPaused) - if (autoSwitchingPaused) return + if (autoSwitchingPaused) + return // Only update if we don't have a playing player or if current player is paused if (!currentPlayer || !currentPlayer.isPlaying || currentPlayer.playbackState !== MprisPlaybackState.Playing) { updateCurrentPlayer()