NPill: Restored the old horizontal NPill

This commit is contained in:
LemmyCook 2025-09-14 18:07:43 -04:00
parent 19312d94c3
commit 7e965262f5
8 changed files with 58 additions and 87 deletions

View file

@ -29,7 +29,7 @@ Item {
return {} return {}
} }
// Resolve settings: try user settings or defaults from BarWidgetRegistry readonly property bool isBarVertical: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
readonly property string displayMode: widgetSettings.displayMode !== undefined ? widgetSettings.displayMode : widgetMetadata.displayMode readonly property string displayMode: widgetSettings.displayMode !== undefined ? widgetSettings.displayMode : widgetMetadata.displayMode
readonly property real warningThreshold: widgetSettings.warningThreshold !== undefined ? widgetSettings.warningThreshold : widgetMetadata.warningThreshold readonly property real warningThreshold: widgetSettings.warningThreshold !== undefined ? widgetSettings.warningThreshold : widgetMetadata.warningThreshold
@ -87,6 +87,7 @@ Item {
rightOpen: BarWidgetRegistry.getNPillDirection(root) rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady) icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady)
text: (isReady || testMode) ? Math.round(percent) : "-" text: (isReady || testMode) ? Math.round(percent) : "-"
suffix: "%"
autoHide: false autoHide: false
forceOpen: isReady && (testMode || battery.isLaptopBattery) && displayMode === "alwaysShow" forceOpen: isReady && (testMode || battery.isLaptopBattery) && displayMode === "alwaysShow"
forceClose: displayMode === "alwaysHide" forceClose: displayMode === "alwaysHide"

View file

@ -28,6 +28,7 @@ Item {
return {} return {}
} }
readonly property bool isBarVertical: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode
// Used to avoid opening the pill on Quickshell startup // Used to avoid opening the pill on Quickshell startup
@ -79,9 +80,11 @@ Item {
icon: getIcon() icon: getIcon()
autoHide: false // Important to be false so we can hover as long as we want autoHide: false // Important to be false so we can hover as long as we want
text: { text: {
return ""
var monitor = getMonitor() var monitor = getMonitor()
return monitor ? Math.round(monitor.brightness * 100) : "" return monitor ? Math.round(monitor.brightness * 100) : ""
} }
suffix: text.length > 0 ? "%" : "-"
forceOpen: displayMode === "alwaysShow" forceOpen: displayMode === "alwaysShow"
forceClose: displayMode === "alwaysHide" forceClose: displayMode === "alwaysHide"
tooltipText: { tooltipText: {

View file

@ -49,10 +49,7 @@ Item {
tooltipText: "Keyboard layout: " + currentLayout.toUpperCase() tooltipText: "Keyboard layout: " + currentLayout.toUpperCase()
forceOpen: root.displayMode === "forceOpen" forceOpen: root.displayMode === "forceOpen"
forceClose: root.displayMode === "alwaysHide" forceClose: root.displayMode === "alwaysHide"
fontSize: Style.fontSizeS // Use larger font size
onClicked: { onClicked: {
// You could open keyboard settings here if needed // You could open keyboard settings here if needed
// For now, just show the current layout // For now, just show the current layout
} }

View file

@ -30,6 +30,7 @@ Item {
return {} return {}
} }
readonly property bool isBarVertical: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode
// Used to avoid opening the pill on Quickshell startup // Used to avoid opening the pill on Quickshell startup
@ -87,11 +88,11 @@ Item {
NPill { NPill {
id: pill id: pill
rightOpen: BarWidgetRegistry.getNPillDirection(root) rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: getIcon() icon: getIcon()
autoHide: false // Important to be false so we can hover as long as we want autoHide: false // Important to be false so we can hover as long as we want
text: Math.floor(AudioService.inputVolume * 100) text: Math.floor(AudioService.inputVolume * 100)
suffix: "%"
forceOpen: displayMode === "alwaysShow" forceOpen: displayMode === "alwaysShow"
forceClose: displayMode === "alwaysHide" forceClose: 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." tooltipText: "Microphone: " + Math.round(AudioService.inputVolume * 100) + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute."

View file

@ -30,7 +30,7 @@ Item {
return {} return {}
} }
readonly property bool isVertical: Settings.data.bar.position === "left" || Settings.data.bar.position === "right" readonly property bool isBarVertical: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode readonly property string displayMode: (widgetSettings.displayMode !== undefined) ? widgetSettings.displayMode : widgetMetadata.displayMode
// Used to avoid opening the pill on Quickshell startup // Used to avoid opening the pill on Quickshell startup
@ -77,7 +77,8 @@ Item {
rightOpen: BarWidgetRegistry.getNPillDirection(root) rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: getIcon() icon: getIcon()
autoHide: false // Important to be false so we can hover as long as we want autoHide: false // Important to be false so we can hover as long as we want
text: `${Math.floor(AudioService.volume * 100)}${isVertical ? "" : "%"}` text: Math.floor(AudioService.volume * 100)
suffix: "%"
forceOpen: displayMode === "alwaysShow" forceOpen: displayMode === "alwaysShow"
forceClose: displayMode === "alwaysHide" forceClose: 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." tooltipText: "Volume: " + Math.round(AudioService.volume * 100) + "%\nLeft click for advanced settings.\nScroll up/down to change volume.\nRight click to toggle mute."

View file

@ -8,6 +8,7 @@ Item {
property string icon: "" property string icon: ""
property string text: "" property string text: ""
property string suffix: ""
property string tooltipText: "" property string tooltipText: ""
property real sizeRatio: 0.8 property real sizeRatio: 0.8
property bool autoHide: false property bool autoHide: false
@ -16,7 +17,6 @@ Item {
property bool disableOpen: false property bool disableOpen: false
property bool rightOpen: false property bool rightOpen: false
property bool hovered: false property bool hovered: false
property real fontSize: Style.fontSizeXS
readonly property string barPosition: Settings.data.bar.position readonly property string barPosition: Settings.data.bar.position
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right" readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
@ -44,6 +44,7 @@ Item {
NPillVertical { NPillVertical {
icon: root.icon icon: root.icon
text: root.text text: root.text
suffix: root.suffix
tooltipText: root.tooltipText tooltipText: root.tooltipText
sizeRatio: root.sizeRatio sizeRatio: root.sizeRatio
autoHide: root.autoHide autoHide: root.autoHide
@ -52,8 +53,6 @@ Item {
disableOpen: root.disableOpen disableOpen: root.disableOpen
rightOpen: root.rightOpen rightOpen: root.rightOpen
hovered: root.hovered hovered: root.hovered
fontSize: root.fontSize
onShown: root.shown() onShown: root.shown()
onHidden: root.hidden() onHidden: root.hidden()
onEntered: root.entered() onEntered: root.entered()
@ -70,6 +69,7 @@ Item {
NPillHorizontal { NPillHorizontal {
icon: root.icon icon: root.icon
text: root.text text: root.text
suffix: root.suffix
tooltipText: root.tooltipText tooltipText: root.tooltipText
sizeRatio: root.sizeRatio sizeRatio: root.sizeRatio
autoHide: root.autoHide autoHide: root.autoHide
@ -78,8 +78,6 @@ Item {
disableOpen: root.disableOpen disableOpen: root.disableOpen
rightOpen: root.rightOpen rightOpen: root.rightOpen
hovered: root.hovered hovered: root.hovered
fontSize: root.fontSize
onShown: root.shown() onShown: root.shown()
onHidden: root.hidden() onHidden: root.hidden()
onEntered: root.entered() onEntered: root.entered()

View file

@ -8,6 +8,7 @@ Item {
property string icon: "" property string icon: ""
property string text: "" property string text: ""
property string suffix: ""
property string tooltipText: "" property string tooltipText: ""
property real sizeRatio: 0.8 property real sizeRatio: 0.8
property bool autoHide: false property bool autoHide: false
@ -16,18 +17,9 @@ Item {
property bool disableOpen: false property bool disableOpen: false
property bool rightOpen: false property bool rightOpen: false
property bool hovered: false property bool hovered: false
property real fontSize: Style.fontSizeXS
// Bar position detection for pill direction // Effective shown state (true if hovered/animated open or forced)
readonly property string barPosition: Settings.data.bar.position readonly property bool revealed: forceOpen || showPill
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
// Determine pill direction based on section position
readonly property bool openRightward: rightOpen
readonly property bool openLeftward: !rightOpen
// Effective shown state (true if animated open or forced, but not if force closed)
readonly property bool revealed: !forceClose && (forceOpen || showPill)
signal shown signal shown
signal hidden signal hidden
@ -42,51 +34,51 @@ Item {
property bool showPill: false property bool showPill: false
property bool shouldAnimateHide: false property bool shouldAnimateHide: false
// Sizing logic for horizontal bars // Exposed width logic
readonly property int iconSize: Math.round(Style.baseWidgetSize * sizeRatio * scaling) readonly property int iconSize: Math.round(Style.baseWidgetSize * sizeRatio * scaling)
readonly property int pillWidth: iconSize readonly property int pillHeight: iconSize
readonly property int pillPaddingHorizontal: Style.marginS * scaling readonly property int pillPaddingHorizontal: Style.marginS * scaling
readonly property int pillPaddingVertical: Style.marginS * scaling
readonly property int pillOverlap: iconSize * 0.5 readonly property int pillOverlap: iconSize * 0.5
readonly property int maxPillWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 4) readonly property int maxPillWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap)
readonly property int maxPillHeight: iconSize
// For horizontal bars: height is just icon size, width includes pill space width: iconSize + Math.max(0, pill.width - pillOverlap)
width: revealed ? (openRightward ? (iconSize + maxPillWidth - pillOverlap) : (iconSize + maxPillWidth - pillOverlap)) : iconSize height: pillHeight
height: iconSize
Rectangle { Rectangle {
id: pill id: pill
width: revealed ? maxPillWidth : 1 width: revealed ? maxPillWidth : 1
height: revealed ? maxPillHeight : 1 height: pillHeight
// Position based on direction - center the pill relative to the icon x: rightOpen ? (iconCircle.x + iconCircle.width / 2) : // Opens right
x: openLeftward ? (iconCircle.x + iconCircle.width / 2 - width) : (iconCircle.x + iconCircle.width / 2 - pillOverlap) (iconCircle.x + iconCircle.width / 2) - width // Opens left
y: 0
opacity: revealed ? Style.opacityFull : Style.opacityNone opacity: revealed ? Style.opacityFull : Style.opacityNone
color: Color.mSurfaceVariant color: Color.mSurfaceVariant
border.color: Color.mOutline
border.width: Math.max(1, Style.borderS * scaling)
// Radius logic for horizontal expansion - rounded on the side that connects to icon
topLeftRadius: openLeftward ? iconSize * 0.5 : 0
bottomLeftRadius: openLeftward ? iconSize * 0.5 : 0
topRightRadius: openRightward ? iconSize * 0.5 : 0
bottomRightRadius: openRightward ? iconSize * 0.5 : 0
topLeftRadius: rightOpen ? 0 : pillHeight * 0.5
bottomLeftRadius: rightOpen ? 0 : pillHeight * 0.5
topRightRadius: rightOpen ? pillHeight * 0.5 : 0
bottomRightRadius: rightOpen ? pillHeight * 0.5 : 0
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
NText { NText {
id: textItem id: textItem
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenterOffset: -pillPaddingHorizontal * 0.5 // Position text slightly left in the pill x: {
text: root.text // Better text horizontal centering
var centerX = (parent.width - width) / 2
var offset = rightOpen ? Style.marginXS * scaling : -Style.marginXS * scaling
if (forceOpen) {
// If its force open, the icon disc background is the same color as the bg pill move text slightly
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXS * scaling
}
return centerX + offset
}
text: root.text + root.suffix
font.family: Settings.data.ui.fontFixed font.family: Settings.data.ui.fontFixed
font.pointSize: Style.fontSizeXXS * scaling font.pointSize: Style.fontSizeXS * scaling
font.weight: Style.fontWeightBold font.weight: Style.fontWeightBold
color: Color.mOnSurface color: Color.mPrimary
visible: revealed visible: revealed
} }
@ -97,13 +89,6 @@ Item {
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
} }
Behavior on height {
enabled: showAnim.running || hideAnim.running
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutCubic
}
}
Behavior on opacity { Behavior on opacity {
enabled: showAnim.running || hideAnim.running enabled: showAnim.running || hideAnim.running
NumberAnimation { NumberAnimation {
@ -119,12 +104,10 @@ Item {
height: iconSize height: iconSize
radius: width * 0.5 radius: width * 0.5
color: hovered && !forceOpen ? Color.mTertiary : Color.mSurfaceVariant color: hovered && !forceOpen ? Color.mTertiary : Color.mSurfaceVariant
// Icon positioning based on direction
x: openLeftward ? (parent.width - width) : 0
y: 0
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
x: rightOpen ? 0 : (parent.width - width)
Behavior on color { Behavior on color {
ColorAnimation { ColorAnimation {
duration: Style.animationNormal duration: Style.animationNormal
@ -154,14 +137,6 @@ Item {
duration: Style.animationNormal duration: Style.animationNormal
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
NumberAnimation {
target: pill
property: "height"
from: 1
to: maxPillHeight
duration: Style.animationNormal
easing.type: Easing.OutCubic
}
NumberAnimation { NumberAnimation {
target: pill target: pill
property: "opacity" property: "opacity"
@ -203,14 +178,6 @@ Item {
duration: Style.animationNormal duration: Style.animationNormal
easing.type: Easing.InCubic easing.type: Easing.InCubic
} }
NumberAnimation {
target: pill
property: "height"
from: maxPillHeight
to: 1
duration: Style.animationNormal
easing.type: Easing.InCubic
}
NumberAnimation { NumberAnimation {
target: pill target: pill
property: "opacity" property: "opacity"
@ -228,12 +195,10 @@ Item {
NTooltip { NTooltip {
id: tooltip id: tooltip
target: pill
text: root.tooltipText
positionLeft: barPosition === "right"
positionRight: barPosition === "left"
positionAbove: Settings.data.bar.position === "bottom" positionAbove: Settings.data.bar.position === "bottom"
target: pill
delay: Style.tooltipDelayLong delay: Style.tooltipDelayLong
text: root.tooltipText
} }
Timer { Timer {
@ -254,7 +219,7 @@ Item {
hovered = true hovered = true
root.entered() root.entered()
tooltip.show() tooltip.show()
if (disableOpen || forceClose) { if (disableOpen) {
return return
} }
if (!forceOpen) { if (!forceOpen) {
@ -264,7 +229,7 @@ Item {
onExited: { onExited: {
hovered = false hovered = false
root.exited() root.exited()
if (!forceOpen && !forceClose) { if (!forceOpen) {
hide() hide()
} }
tooltip.hide() tooltip.hide()

View file

@ -8,6 +8,7 @@ Item {
property string icon: "" property string icon: ""
property string text: "" property string text: ""
property string suffix: ""
property string tooltipText: "" property string tooltipText: ""
property real sizeRatio: 0.8 property real sizeRatio: 0.8
property bool autoHide: false property bool autoHide: false
@ -16,7 +17,6 @@ Item {
property bool disableOpen: false property bool disableOpen: false
property bool rightOpen: false property bool rightOpen: false
property bool hovered: false property bool hovered: false
property real fontSize: Style.fontSizeXS
// Bar position detection for pill direction // Bar position detection for pill direction
readonly property string barPosition: Settings.data.bar.position readonly property string barPosition: Settings.data.bar.position
@ -66,8 +66,6 @@ Item {
opacity: revealed ? Style.opacityFull : Style.opacityNone opacity: revealed ? Style.opacityFull : Style.opacityNone
color: Color.mSurfaceVariant color: Color.mSurfaceVariant
border.color: Color.mOutline
border.width: Math.max(1, Style.borderS * scaling)
// Radius logic for vertical expansion - rounded on the side that connects to icon // Radius logic for vertical expansion - rounded on the side that connects to icon
topLeftRadius: openUpward ? iconSize * 0.5 : 0 topLeftRadius: openUpward ? iconSize * 0.5 : 0
@ -81,14 +79,21 @@ Item {
id: textItem id: textItem
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -pillPaddingVertical * 0.5 // Position text slightly higher in the pill anchors.verticalCenterOffset: {
text: root.text var offset = openDownward ? pillPaddingVertical * 0.75 : -pillPaddingVertical * 0.75
if (forceOpen) {
// If its force open, the icon disc background is the same color as the bg pill move text slightly
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXS * scaling
}
return offset
}
text: root.text + root.suffix
font.family: Settings.data.ui.fontFixed font.family: Settings.data.ui.fontFixed
font.pointSize: Style.fontSizeXXS * scaling font.pointSize: Style.fontSizeXXS * scaling
font.weight: Style.fontWeightMedium font.weight: Style.fontWeightMedium
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
color: Color.mOnSurface color: Color.mPrimary
visible: revealed visible: revealed
} }