NPill: allow to open left or right depending on

This commit is contained in:
LemmyCook 2025-08-31 15:45:10 -04:00
parent 2498f0273d
commit 3683d3c29b
7 changed files with 73 additions and 11 deletions

View file

@ -65,7 +65,10 @@ Variants {
delegate: NWidgetLoader { delegate: NWidgetLoader {
widgetName: modelData widgetName: modelData
widgetProps: { widgetProps: {
"screen": root.modelData || null "screen": root.modelData || null,
"barSection": parent.objectName,
"sectionWidgetIndex": index,
"sectionWidgetsCount": Settings.data.bar.widgets.left.length
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -87,7 +90,10 @@ Variants {
delegate: NWidgetLoader { delegate: NWidgetLoader {
widgetName: modelData widgetName: modelData
widgetProps: { widgetProps: {
"screen": root.modelData || null "screen": root.modelData || null,
"barSection": parent.objectName,
"sectionWidgetIndex": index,
"sectionWidgetsCount": Settings.data.bar.widgets.center.length
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -110,7 +116,10 @@ Variants {
delegate: NWidgetLoader { delegate: NWidgetLoader {
widgetName: modelData widgetName: modelData
widgetProps: { widgetProps: {
"screen": root.modelData || null "screen": root.modelData || null,
"barSection": parent.objectName,
"sectionWidgetIndex": index,
"sectionWidgetsCount": Settings.data.bar.widgets.right.length
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }

View file

@ -8,14 +8,20 @@ import qs.Widgets
Item { Item {
id: root id: root
property ShellScreen screen property ShellScreen screen
property real scaling: ScalingService.scale(screen) property real scaling: ScalingService.scale(screen)
implicitWidth: pill.width property string barSection: ""
implicitHeight: pill.height property int sectionWidgetIndex: 0
property int sectionWidgetsCount: 0
// Track if we've already notified to avoid spam // Track if we've already notified to avoid spam
property bool hasNotifiedLowBattery: false property bool hasNotifiedLowBattery: false
implicitWidth: pill.width
implicitHeight: pill.height
// Helper to evaluate and possibly notify // Helper to evaluate and possibly notify
function maybeNotify(percent, charging) { function maybeNotify(percent, charging) {
const p = Math.round(percent) const p = Math.round(percent)
@ -57,8 +63,9 @@ Item {
NPill { NPill {
id: pill id: pill
// Test mode // Test mode
property bool testMode: false property bool testMode: true
property int testPercent: 20 property int testPercent: 20
property bool testCharging: false property bool testCharging: false
property var battery: UPower.displayDevice property var battery: UPower.displayDevice
@ -91,8 +98,9 @@ Item {
return "battery_android_0" return "battery_android_0"
} }
rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: batteryIcon() icon: batteryIcon()
text: (isReady && battery.isLaptopBattery) ? Math.round(percent) + "%" : "-" text: ((isReady && battery.isLaptopBattery) || testMode) ? Math.round(percent) + "%" : "-"
textColor: charging ? Color.mPrimary : Color.mOnSurface textColor: charging ? Color.mPrimary : Color.mOnSurface
iconCircleColor: Color.mPrimary iconCircleColor: Color.mPrimary
collapsedIconColor: Color.mOnSurface collapsedIconColor: Color.mOnSurface

View file

@ -10,6 +10,9 @@ Item {
property ShellScreen screen property ShellScreen screen
property real scaling: ScalingService.scale(screen) property real scaling: ScalingService.scale(screen)
property string barSection: ""
property int sectionWidgetIndex: 0
property int sectionWidgetsCount: 0
// Used to avoid opening the pill on Quickshell startup // Used to avoid opening the pill on Quickshell startup
property bool firstBrightnessReceived: false property bool firstBrightnessReceived: false
@ -58,6 +61,8 @@ Item {
NPill { NPill {
id: pill id: pill
rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: getIcon() icon: getIcon()
iconCircleColor: Color.mPrimary iconCircleColor: Color.mPrimary
collapsedIconColor: Color.mOnSurface collapsedIconColor: Color.mOnSurface

View file

@ -11,6 +11,9 @@ Row {
property ShellScreen screen property ShellScreen screen
property real scaling: ScalingService.scale(screen) property real scaling: ScalingService.scale(screen)
property string barSection: ""
property int sectionWidgetIndex: 0
property int sectionWidgetsCount: 0
// Use the shared service for keyboard layout // Use the shared service for keyboard layout
property string currentLayout: KeyboardLayoutService.currentLayout property string currentLayout: KeyboardLayoutService.currentLayout
@ -20,6 +23,8 @@ Row {
NPill { NPill {
id: pill id: pill
rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: "keyboard_alt" icon: "keyboard_alt"
iconCircleColor: Color.mPrimary iconCircleColor: Color.mPrimary
collapsedIconColor: Color.mOnSurface collapsedIconColor: Color.mOnSurface

View file

@ -12,6 +12,9 @@ Item {
property ShellScreen screen property ShellScreen screen
property real scaling: ScalingService.scale(screen) property real scaling: ScalingService.scale(screen)
property string barSection: ""
property int sectionWidgetIndex: 0
property int sectionWidgetsCount: 0
// Used to avoid opening the pill on Quickshell startup // Used to avoid opening the pill on Quickshell startup
property bool firstVolumeReceived: false property bool firstVolumeReceived: false
@ -53,6 +56,8 @@ Item {
NPill { NPill {
id: pill id: pill
rightOpen: BarWidgetRegistry.getNPillDirection(root)
icon: getIcon() icon: getIcon()
iconCircleColor: Color.mPrimary iconCircleColor: Color.mPrimary
collapsedIconColor: Color.mOnSurface collapsedIconColor: Color.mOnSurface

View file

@ -2,6 +2,7 @@ pragma Singleton
import QtQuick import QtQuick
import Quickshell import Quickshell
import qs.Commons
import qs.Modules.Bar.Widgets import qs.Modules.Bar.Widgets
Singleton { Singleton {
@ -104,4 +105,24 @@ Singleton {
function getAvailableWidgets() { function getAvailableWidgets() {
return Object.keys(widgets) return Object.keys(widgets)
} }
function getNPillDirection(widget) {
try {
if (widget.barSection === "leftSection") {
return true
} else if (widget.barSection === "rightSection") {
return false
} else {
// middle section
if (widget.sectionWidgetIndex < widget.sectionWidgetsCount / 2) {
return false
} else {
return true
}
}
} catch (e) {
Logger.error(e)
}
return false
}
} }

View file

@ -18,6 +18,7 @@ Item {
property bool autoHide: false property bool autoHide: false
property bool forceOpen: false property bool forceOpen: false
property bool disableOpen: false property bool disableOpen: false
property bool rightOpen: false
// Effective shown state (true if hovered/animated open or forced) // Effective shown state (true if hovered/animated open or forced)
readonly property bool effectiveShown: forceOpen || showPill readonly property bool effectiveShown: forceOpen || showPill
@ -48,11 +49,17 @@ Item {
id: pill id: pill
width: effectiveShown ? maxPillWidth : 1 width: effectiveShown ? maxPillWidth : 1
height: pillHeight height: pillHeight
x: (iconCircle.x + iconCircle.width / 2) - width
x: rightOpen ? (iconCircle.x + iconCircle.width / 2) : // Opens right
(iconCircle.x + iconCircle.width / 2) - width // Opens left
opacity: effectiveShown ? Style.opacityFull : Style.opacityNone opacity: effectiveShown ? Style.opacityFull : Style.opacityNone
color: pillColor color: pillColor
topLeftRadius: pillHeight * 0.5
bottomLeftRadius: pillHeight * 0.5 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 {
@ -89,7 +96,9 @@ Item {
// When forced shown, match pill background; otherwise use accent when hovered // When forced shown, match pill background; otherwise use accent when hovered
color: forceOpen ? pillColor : (showPill ? iconCircleColor : Color.mSurfaceVariant) color: forceOpen ? pillColor : (showPill ? iconCircleColor : Color.mSurfaceVariant)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.left: rightOpen ? parent.left : undefined
anchors.right: rightOpen ? undefined : parent.right
Behavior on color { Behavior on color {
ColorAnimation { ColorAnimation {