diff --git a/Modules/Bar/Widgets/Battery.qml b/Modules/Bar/Widgets/Battery.qml index 6c87416..5509345 100644 --- a/Modules/Bar/Widgets/Battery.qml +++ b/Modules/Bar/Widgets/Battery.qml @@ -30,12 +30,12 @@ Item { } // Resolve settings: try user settings or defaults from BarWidgetRegistry - readonly property bool alwaysShowPercentage: widgetSettings.alwaysShowPercentage !== undefined ? widgetSettings.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + readonly property string displayMode: widgetSettings.displayMode !== undefined ? widgetSettings.displayMode : widgetMetadata.displayMode readonly property real warningThreshold: widgetSettings.warningThreshold !== undefined ? widgetSettings.warningThreshold : widgetMetadata.warningThreshold // Test mode - readonly property bool testMode: false - readonly property int testPercent: 90 + readonly property bool testMode: true + readonly property int testPercent: 100 readonly property bool testCharging: false // Main properties @@ -86,9 +86,10 @@ Item { rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady) - text: (isReady || testMode) ? Math.round(percent) + "%" : "-" + text: (isReady || testMode) ? Math.round(percent) : "-" autoHide: false - forceOpen: isReady && (testMode || battery.isLaptopBattery) && alwaysShowPercentage + forceOpen: isReady && (testMode || battery.isLaptopBattery) && displayMode === "alwaysShow" + forceClosed: displayMode === "alwaysHide" disableOpen: (!isReady || (!testMode && !battery.isLaptopBattery)) tooltipText: { let lines = [] diff --git a/Modules/Bar/Widgets/Brightness.qml b/Modules/Bar/Widgets/Brightness.qml index 832412d..efcbe8d 100644 --- a/Modules/Bar/Widgets/Brightness.qml +++ b/Modules/Bar/Widgets/Brightness.qml @@ -28,7 +28,7 @@ Item { return {} } - readonly property bool userAlwaysShowPercentage: (widgetSettings.alwaysShowPercentage !== undefined) ? widgetSettings.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode // Used to avoid opening the pill on Quickshell startup property bool firstBrightnessReceived: false @@ -80,9 +80,10 @@ Item { autoHide: false // Important to be false so we can hover as long as we want text: { var monitor = getMonitor() - return monitor ? (Math.round(monitor.brightness * 100) + "%") : "" + return monitor ? Math.round(monitor.brightness * 100) : "" } - forceOpen: userAlwaysShowPercentage + forceOpen: displayMode === "alwaysShow" + forceClosed: displayMode === "alwaysHide" tooltipText: { var monitor = getMonitor() if (!monitor) diff --git a/Modules/Bar/Widgets/KeyboardLayout.qml b/Modules/Bar/Widgets/KeyboardLayout.qml index aff5cdc..444df7d 100644 --- a/Modules/Bar/Widgets/KeyboardLayout.qml +++ b/Modules/Bar/Widgets/KeyboardLayout.qml @@ -30,7 +30,7 @@ Item { return {} } - readonly property bool forceOpen: (widgetSettings.forceOpen !== undefined) ? widgetSettings.forceOpen : widgetMetadata.forceOpen + readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode // Use the shared service for keyboard layout property string currentLayout: KeyboardLayoutService.currentLayout @@ -47,7 +47,8 @@ Item { autoHide: false // Important to be false so we can hover as long as we want text: currentLayout.toUpperCase() tooltipText: "Keyboard layout: " + currentLayout.toUpperCase() - forceOpen: root.forceOpen + forceOpen: root.displayMode === "forceOpen" + forceClosed: root.displayMode === "alwaysHide" fontSize: Style.fontSizeS // Use larger font size onClicked: { diff --git a/Modules/Bar/Widgets/Microphone.qml b/Modules/Bar/Widgets/Microphone.qml index c935df7..29844e9 100644 --- a/Modules/Bar/Widgets/Microphone.qml +++ b/Modules/Bar/Widgets/Microphone.qml @@ -30,7 +30,7 @@ Item { return {} } - readonly property bool alwaysShowPercentage: (widgetSettings.alwaysShowPercentage !== undefined) ? widgetSettings.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode // Used to avoid opening the pill on Quickshell startup property bool firstInputVolumeReceived: false @@ -91,8 +91,9 @@ Item { rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: getIcon() autoHide: false // Important to be false so we can hover as long as we want - text: Math.floor(AudioService.inputVolume * 100) + "%" - forceOpen: alwaysShowPercentage + text: Math.floor(AudioService.inputVolume * 100) + forceOpen: displayMode === "alwaysShow" + forceClosed: displayMode === "alwaysHide" tooltipText: "Microphone: " + Math.round(AudioService.inputVolume * 100) + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute." onWheel: function (delta) { diff --git a/Modules/Bar/Widgets/Volume.qml b/Modules/Bar/Widgets/Volume.qml index ba1a5dd..c87a510 100644 --- a/Modules/Bar/Widgets/Volume.qml +++ b/Modules/Bar/Widgets/Volume.qml @@ -30,7 +30,7 @@ Item { return {} } - readonly property bool alwaysShowPercentage: (widgetSettings.alwaysShowPercentage !== undefined) ? widgetSettings.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode // Used to avoid opening the pill on Quickshell startup property bool firstVolumeReceived: false @@ -76,8 +76,9 @@ Item { rightOpen: BarWidgetRegistry.getNPillDirection(root) icon: getIcon() autoHide: false // Important to be false so we can hover as long as we want - text: Math.floor(AudioService.volume * 100) + "%" - forceOpen: alwaysShowPercentage + text: Math.floor(AudioService.volume * 100) + forceOpen: displayMode === "alwaysShow" + forceClosed: displayMode === "alwaysHide" tooltipText: "Volume: " + Math.round(AudioService.volume * 100) + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute." onWheel: function (delta) { diff --git a/Modules/SettingsPanel/Bar/WidgetSettings/BatterySettings.qml b/Modules/SettingsPanel/Bar/WidgetSettings/BatterySettings.qml index df40081..17df1ca 100644 --- a/Modules/SettingsPanel/Bar/WidgetSettings/BatterySettings.qml +++ b/Modules/SettingsPanel/Bar/WidgetSettings/BatterySettings.qml @@ -14,20 +14,36 @@ ColumnLayout { property var widgetMetadata: null // Local state - property bool valueAlwaysShowPercentage: widgetData.alwaysShowPercentage !== undefined ? widgetData.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + property string valueDisplayMode: widgetData.displayMode !== undefined ? widgetData.displayMode : widgetMetadata.displayMode property int valueWarningThreshold: widgetData.warningThreshold !== undefined ? widgetData.warningThreshold : widgetMetadata.warningThreshold function saveSettings() { var settings = Object.assign({}, widgetData || {}) - settings.alwaysShowPercentage = valueAlwaysShowPercentage + settings.displayMode = valueDisplayMode settings.warningThreshold = valueWarningThreshold return settings } - NToggle { - label: "Always show percentage" - checked: root.valueAlwaysShowPercentage - onToggled: checked => root.valueAlwaysShowPercentage = checked + NComboBox { + label: "Display mode" + description: "Choose how the percentage is displayed." + minimumWidth: 134 * scaling + model: ListModel { + ListElement { + key: "normal" + name: "Normal" + } + ListElement { + key: "alwaysShow" + name: "Always Show" + } + ListElement { + key: "alwaysHide" + name: "Always Hide" + } + } + currentKey: root.valueDisplayMode + onSelected: key => root.valueDisplayMode = key } NSpinBox { diff --git a/Modules/SettingsPanel/Bar/WidgetSettings/BrightnessSettings.qml b/Modules/SettingsPanel/Bar/WidgetSettings/BrightnessSettings.qml index 551e277..2da8fce 100644 --- a/Modules/SettingsPanel/Bar/WidgetSettings/BrightnessSettings.qml +++ b/Modules/SettingsPanel/Bar/WidgetSettings/BrightnessSettings.qml @@ -14,17 +14,33 @@ ColumnLayout { property var widgetMetadata: null // Local state - property bool valueAlwaysShowPercentage: widgetData.alwaysShowPercentage !== undefined ? widgetData.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + property string valueDisplayMode: widgetData.displayMode !== undefined ? widgetData.displayMode : widgetMetadata.displayMode function saveSettings() { var settings = Object.assign({}, widgetData || {}) - settings.alwaysShowPercentage = valueAlwaysShowPercentage + settings.displayMode = valueDisplayMode return settings } - NToggle { - label: "Always show percentage" - checked: valueAlwaysShowPercentage - onToggled: checked => valueAlwaysShowPercentage = checked + NComboBox { + label: "Display mode" + description: "Choose how the percentage is displayed." + minimumWidth: 134 * scaling + model: ListModel { + ListElement { + key: "normal" + name: "Normal" + } + ListElement { + key: "alwaysShow" + name: "Always Show" + } + ListElement { + key: "alwaysHide" + name: "Always Hide" + } + } + currentKey: valueDisplayMode + onSelected: key => valueDisplayMode = key } } diff --git a/Modules/SettingsPanel/Bar/WidgetSettings/KeyboardLayoutSettings.qml b/Modules/SettingsPanel/Bar/WidgetSettings/KeyboardLayoutSettings.qml index c97e782..17cda8c 100644 --- a/Modules/SettingsPanel/Bar/WidgetSettings/KeyboardLayoutSettings.qml +++ b/Modules/SettingsPanel/Bar/WidgetSettings/KeyboardLayoutSettings.qml @@ -14,18 +14,33 @@ ColumnLayout { property var widgetMetadata: null // Local state - property bool valueForceOpen: widgetData.forceOpen !== undefined ? widgetData.forceOpen : widgetMetadata.forceOpen + property string valueDisplayMode: widgetData.displayMode !== undefined ? widgetData.displayMode : widgetMetadata.displayMode function saveSettings() { var settings = Object.assign({}, widgetData || {}) - settings.forceOpen = valueForceOpen + settings.displayMode = valueDisplayMode return settings } - NToggle { - label: "Force open" - description: "Keep the keyboard layout widget always expanded." - checked: valueForceOpen - onToggled: checked => valueForceOpen = checked + NComboBox { + label: "Display mode" + description: "Choose how the keyboard layout is displayed." + minimumWidth: 134 * scaling + model: ListModel { + ListElement { + key: "normal" + name: "Normal" + } + ListElement { + key: "forceOpen" + name: "Force Open" + } + ListElement { + key: "alwaysHide" + name: "Always Hide" + } + } + currentKey: valueDisplayMode + onSelected: key => valueDisplayMode = key } } diff --git a/Modules/SettingsPanel/Bar/WidgetSettings/MicrophoneSettings.qml b/Modules/SettingsPanel/Bar/WidgetSettings/MicrophoneSettings.qml index 551e277..2da8fce 100644 --- a/Modules/SettingsPanel/Bar/WidgetSettings/MicrophoneSettings.qml +++ b/Modules/SettingsPanel/Bar/WidgetSettings/MicrophoneSettings.qml @@ -14,17 +14,33 @@ ColumnLayout { property var widgetMetadata: null // Local state - property bool valueAlwaysShowPercentage: widgetData.alwaysShowPercentage !== undefined ? widgetData.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + property string valueDisplayMode: widgetData.displayMode !== undefined ? widgetData.displayMode : widgetMetadata.displayMode function saveSettings() { var settings = Object.assign({}, widgetData || {}) - settings.alwaysShowPercentage = valueAlwaysShowPercentage + settings.displayMode = valueDisplayMode return settings } - NToggle { - label: "Always show percentage" - checked: valueAlwaysShowPercentage - onToggled: checked => valueAlwaysShowPercentage = checked + NComboBox { + label: "Display mode" + description: "Choose how the percentage is displayed." + minimumWidth: 134 * scaling + model: ListModel { + ListElement { + key: "normal" + name: "Normal" + } + ListElement { + key: "alwaysShow" + name: "Always Show" + } + ListElement { + key: "alwaysHide" + name: "Always Hide" + } + } + currentKey: valueDisplayMode + onSelected: key => valueDisplayMode = key } } diff --git a/Modules/SettingsPanel/Bar/WidgetSettings/VolumeSettings.qml b/Modules/SettingsPanel/Bar/WidgetSettings/VolumeSettings.qml index 551e277..2da8fce 100644 --- a/Modules/SettingsPanel/Bar/WidgetSettings/VolumeSettings.qml +++ b/Modules/SettingsPanel/Bar/WidgetSettings/VolumeSettings.qml @@ -14,17 +14,33 @@ ColumnLayout { property var widgetMetadata: null // Local state - property bool valueAlwaysShowPercentage: widgetData.alwaysShowPercentage !== undefined ? widgetData.alwaysShowPercentage : widgetMetadata.alwaysShowPercentage + property string valueDisplayMode: widgetData.displayMode !== undefined ? widgetData.displayMode : widgetMetadata.displayMode function saveSettings() { var settings = Object.assign({}, widgetData || {}) - settings.alwaysShowPercentage = valueAlwaysShowPercentage + settings.displayMode = valueDisplayMode return settings } - NToggle { - label: "Always show percentage" - checked: valueAlwaysShowPercentage - onToggled: checked => valueAlwaysShowPercentage = checked + NComboBox { + label: "Display mode" + description: "Choose how the percentage is displayed." + minimumWidth: 134 * scaling + model: ListModel { + ListElement { + key: "normal" + name: "Normal" + } + ListElement { + key: "alwaysShow" + name: "Always Show" + } + ListElement { + key: "alwaysHide" + name: "Always Hide" + } + } + currentKey: valueDisplayMode + onSelected: key => valueDisplayMode = key } } diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index aef36b8..1bdbcd6 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -43,12 +43,12 @@ Singleton { }, "Battery": { "allowUserSettings": true, - "alwaysShowPercentage": false, + "displayMode": "normal", "warningThreshold": 30 }, "Brightness": { "allowUserSettings": true, - "alwaysShowPercentage": false + "displayMode": "normal" }, "Clock": { "allowUserSettings": true, @@ -65,7 +65,7 @@ Singleton { }, "Microphone": { "allowUserSettings": true, - "alwaysShowPercentage": false + "displayMode": "normal" }, "NotificationHistory": { "allowUserSettings": true, @@ -102,11 +102,11 @@ Singleton { }, "Volume": { "allowUserSettings": true, - "alwaysShowPercentage": false + "displayMode": "normal" }, "KeyboardLayout": { "allowUserSettings": true, - "forceOpen": false + "displayMode": "normal" } }) diff --git a/Widgets/NPill.qml b/Widgets/NPill.qml index d417203..08617d3 100644 --- a/Widgets/NPill.qml +++ b/Widgets/NPill.qml @@ -12,6 +12,7 @@ Item { property real sizeRatio: 0.8 property bool autoHide: false property bool forceOpen: false + property bool forceClosed: false property bool disableOpen: false property bool rightOpen: false property bool hovered: false @@ -47,6 +48,7 @@ Item { sizeRatio: root.sizeRatio autoHide: root.autoHide forceOpen: root.forceOpen + forceClosed: root.forceClosed disableOpen: root.disableOpen rightOpen: root.rightOpen hovered: root.hovered @@ -72,6 +74,7 @@ Item { sizeRatio: root.sizeRatio autoHide: root.autoHide forceOpen: root.forceOpen + forceClosed: root.forceClosed disableOpen: root.disableOpen rightOpen: root.rightOpen hovered: root.hovered diff --git a/Widgets/NPillHorizontal.qml b/Widgets/NPillHorizontal.qml index 78d02d3..9ba6b3c 100644 --- a/Widgets/NPillHorizontal.qml +++ b/Widgets/NPillHorizontal.qml @@ -12,6 +12,7 @@ Item { property real sizeRatio: 0.8 property bool autoHide: false property bool forceOpen: false + property bool forceClosed: false property bool disableOpen: false property bool rightOpen: false property bool hovered: false @@ -25,8 +26,8 @@ Item { readonly property bool openRightward: rightOpen readonly property bool openLeftward: !rightOpen - // Effective shown state (true if animated open or forced) - readonly property bool revealed: forceOpen || showPill + // Effective shown state (true if animated open or forced, but not if force closed) + readonly property bool revealed: !forceClosed && (forceOpen || showPill) signal shown signal hidden @@ -80,7 +81,7 @@ Item { id: textItem anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenterOffset: 0 // Center the text properly in the pill + anchors.horizontalCenterOffset: -pillPaddingHorizontal * 0.5 // Position text slightly left in the pill text: root.text font.family: Settings.data.ui.fontFixed font.pointSize: Style.fontSizeXXS * scaling @@ -253,7 +254,7 @@ Item { hovered = true root.entered() tooltip.show() - if (disableOpen) { + if (disableOpen || forceClosed) { return } if (!forceOpen) { @@ -263,7 +264,7 @@ Item { onExited: { hovered = false root.exited() - if (!forceOpen) { + if (!forceOpen && !forceClosed) { hide() } tooltip.hide() diff --git a/Widgets/NPillVertical.qml b/Widgets/NPillVertical.qml index 054c287..9c4fbb3 100644 --- a/Widgets/NPillVertical.qml +++ b/Widgets/NPillVertical.qml @@ -12,6 +12,7 @@ Item { property real sizeRatio: 0.8 property bool autoHide: false property bool forceOpen: false + property bool forceClosed: false property bool disableOpen: false property bool rightOpen: false property bool hovered: false @@ -25,8 +26,8 @@ Item { readonly property bool openDownward: rightOpen readonly property bool openUpward: !rightOpen - // Effective shown state (true if animated open or forced) - readonly property bool revealed: forceOpen || showPill + // Effective shown state (true if animated open or forced, but not if force closed) + readonly property bool revealed: !forceClosed && (forceOpen || showPill) signal shown signal hidden @@ -48,7 +49,7 @@ Item { readonly property int pillPaddingVertical: Style.marginS * scaling readonly property int pillOverlap: iconSize * 0.5 readonly property int maxPillWidth: iconSize - readonly property int maxPillHeight: Math.max(1, textItem.implicitHeight + pillPaddingVertical * 3) + readonly property int maxPillHeight: Math.max(1, textItem.implicitHeight + pillPaddingVertical * 4) // For vertical bars: width is just icon size, height includes pill space width: iconSize @@ -76,14 +77,17 @@ Item { anchors.horizontalCenter: parent.horizontalCenter - NTextVertical { + NText { id: textItem anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: 0 // Center the text properly in the pill + anchors.verticalCenterOffset: -pillPaddingVertical * 0.5 // Position text slightly higher in the pill text: root.text - fontSize: Style.fontSizeXXS * scaling - fontWeight: Style.fontWeightBold + font.family: Settings.data.ui.fontFixed + font.pointSize: Style.fontSizeXXS * scaling + font.weight: Style.fontWeightMedium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter color: Color.mOnSurface visible: revealed } @@ -252,7 +256,7 @@ Item { hovered = true root.entered() tooltip.show() - if (disableOpen) { + if (disableOpen || forceClosed) { return } if (!forceOpen) { @@ -262,7 +266,7 @@ Item { onExited: { hovered = false root.exited() - if (!forceOpen) { + if (!forceOpen && !forceClosed) { hide() } tooltip.hide()