diff --git a/:w b/:w new file mode 100644 index 0000000..422c0ce --- /dev/null +++ b/:w @@ -0,0 +1,15 @@ +import QtQuick +import "../settings/" +import "../" + +Text { + property real fill + font.family: "Material Symbols Rounded" + color: Colors.foreground + font.pixelSize: Settings.config.fontSize + 2 + font.variableAxes: { + wght: 700, + + } + +} diff --git a/Colors.qml b/Colors.qml index 42dff64..c1ba3b8 100644 --- a/Colors.qml +++ b/Colors.qml @@ -5,25 +5,25 @@ import Quickshell Singleton { id: customColors // Core Backgrounds - readonly property color background: "#1D2021" - readonly property color foreground: "#D5C4A1" - readonly property color cursor: "#D5C4A1" + readonly property color background: "#161616" + readonly property color foreground: "#FFFFFF" + readonly property color cursor: "#6F6F6F" // The 16 Colors of the Apocalypse - readonly property color color0: "#1D2021" - readonly property color color1: "#FB4934" - readonly property color color2: "#B8BB26" - readonly property color color3: "#FABD2F" - readonly property color color4: "#83A598" - readonly property color color5: "#D3869B" - readonly property color color6: "#8EC07C" - readonly property color color7: "#D5C4A1" - readonly property color color8: "#665C54" - readonly property color color9: "#FB4934" - readonly property color color10: "#B8BB26" - readonly property color color11: "#FABD2F" - readonly property color color12: "#83A598" - readonly property color color13: "#D3869B" - readonly property color color14: "#8EC07C" - readonly property color color15: "#FBF1C7" + readonly property color color0: "#262626" + readonly property color color1: "#EE5396" + readonly property color color2: "#42BE65" + readonly property color color3: "#FFE97B" + readonly property color color4: "#33B1FF" + readonly property color color5: "#FF7EB6" + readonly property color color6: "#3DDBD9" + readonly property color color7: "#DDE1E6" + readonly property color color8: "#393939" + readonly property color color9: "#EE5396" + readonly property color color10: "#42BE65" + readonly property color color11: "#FFE97B" + readonly property color color12: "#33B1FF" + readonly property color color13: "#FF7EB6" + readonly property color color14: "#3DDBD9" + readonly property color color15: "#FFFFFF" } diff --git a/modules/Bar/Bar.qml b/modules/Bar/Bar.qml index 113b20b..d5fef64 100644 --- a/modules/Bar/Bar.qml +++ b/modules/Bar/Bar.qml @@ -18,33 +18,36 @@ Variants { left: true right: true } + margins { + left: 10 + right: 10 + } implicitHeight: Settings.config.barHeight - Row { + RowLayout { id: leftStuff - spacing: 10 + spacing: 20 anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter Workspaces { - property var screen: modelData - } - Title { - anchors.verticalCenter: parent.verticalCenter + property var screen: root.modelData } + Title {} } Row { id: centerStuff anchors.centerIn: parent + Clock {} } - Row { + RowLayout { id: rightStuff - spacing: 10 + spacing: 20 anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - Clock {} Volume {} Battery {} + SystemTray {} } } } diff --git a/modules/Bar/Battery.qml b/modules/Bar/Battery.qml index 6e196e5..b3a22aa 100644 --- a/modules/Bar/Battery.qml +++ b/modules/Bar/Battery.qml @@ -12,28 +12,52 @@ Loader { sourceComponent: Item { id: root - implicitWidth: batRow.implicitWidth + + property bool frame1: UPower.displayDevice.percentage <= 0.16 + property bool frame2: UPower.displayDevice.percentage < 0.32 + property bool frame3: UPower.displayDevice.percentage < 0.48 + property bool frame4: UPower.displayDevice.percentage < 0.74 + property bool frame5: UPower.displayDevice.percentage < 0.90 + property bool frame6: UPower.displayDevice.percentage <= 1 + + function getBatteryIcon() { + if (UPower.displayDevice.state == UPowerDeviceState.Charging) { + return "battery_android_frame_bolt"; + } + if (frame1) { + return "battery_android_frame_1"; + } + if (frame2) { + return "battery_android_frame_2"; + } + if (frame3) { + return "battery_android_frame_3"; + } + if (frame4) { + return "battery_android_frame_4"; + } + if (frame5) { + return "battery_android_frame_5"; + } + if (frame6) { + return "battery_android_frame_full"; + } + } + + implicitWidth: batRow.width implicitHeight: Settings.config.barHeight - Rectangle { + + Row { id: batRow - implicitWidth: batText.implicitWidth + batIcon.implicitWidth + 10 - color: "transparent" - - implicitHeight: Settings.config.barHeight - Row { - anchors.centerIn: batRow - anchors.verticalCenter: batRow.verticalCenter - CustomText { - id: batText - text: Math.round(UPower.displayDevice.percentage * 100) + "%" - } - - IconImage { - id: batIcon - anchors.verticalCenter: batRow.verticalCenter - source: Quickshell.iconPath(UPower.displayDevice.iconName) - implicitSize: 14 - } + anchors.verticalCenter: parent.verticalCenter + spacing: 5 + CustomText { + id: batText + text: Math.round(UPower.displayDevice.percentage * 100) + "%" + } + CustomIcon { + id: batIcon + text: root.getBatteryIcon() } } } diff --git a/modules/Bar/SystemTray.qml b/modules/Bar/SystemTray.qml index e69de29..574ecec 100644 --- a/modules/Bar/SystemTray.qml +++ b/modules/Bar/SystemTray.qml @@ -0,0 +1,21 @@ +import Quickshell.Services.SystemTray +import QtQuick +import "." +import "../../settings/" + +Item { + id: root + implicitWidth: trayRow.implicitWidth + implicitHeight: Settings.config.barHeight + visible: trayRepeater.count > 0 + + Row { + id: trayRow + anchors.verticalCenter: parent.verticalCenter + Repeater { + id: trayRepeater + model: SystemTray.items + delegate: TrayItem {} + } + } +} diff --git a/modules/Bar/Title.qml b/modules/Bar/Title.qml index 94db03f..d5a032e 100644 --- a/modules/Bar/Title.qml +++ b/modules/Bar/Title.qml @@ -1,18 +1,17 @@ -import Quickshell import QtQuick import "../../reusables/" import "../../settings/" -import "../../" import Quickshell.Hyprland Item { - id: textContainer + id: root + readonly property var activeWindow: Hyprland.activeToplevel implicitWidth: text.implicitWidth implicitHeight: Settings.config.barHeight CustomText { id: text anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - text: Hyprland.activeToplevel ? Hyprland.activeToplevel.title : "Desktop" + text: root.activeWindow ? Hyprland.activeToplevel.title : "Desktop" } } diff --git a/modules/Bar/TrayItem.qml b/modules/Bar/TrayItem.qml index e69de29..94cdd38 100644 --- a/modules/Bar/TrayItem.qml +++ b/modules/Bar/TrayItem.qml @@ -0,0 +1,36 @@ +import QtQuick +import Quickshell +import Quickshell.Services.SystemTray +import Quickshell.Widgets + +MouseArea { + id: root + property var bar: root.QsWindow.window + required property SystemTrayItem modelData + + acceptedButtons: Qt.LeftButton | Qt.RightButton + implicitWidth: 16 + implicitHeight: 16 + + onClicked: event => { + if (event.button === Qt.LeftButton) { + modelData.activate(); + } else if (modelData.hasMenu) { + menu.open(); + } + } + + QsMenuAnchor { + id: menu + menu: root.modelData.hasMenu ? root.modelData.menu : null + anchor.item: root + } + + IconImage { + id: trayIcon + width: parent.implicitWidth + height: parent.implicitHeight + source: root.modelData.icon + anchors.centerIn: parent + } +} diff --git a/modules/Bar/Volume.qml b/modules/Bar/Volume.qml index a11df03..759ecc6 100644 --- a/modules/Bar/Volume.qml +++ b/modules/Bar/Volume.qml @@ -7,14 +7,47 @@ import "../../" Item { id: root - implicitWidth: volumeText.implicitWidth + 10 + implicitWidth: textRow.width implicitHeight: Settings.config.barHeight - CustomText { - id: volumeText - anchors.centerIn: parent - PwObjectTracker { - objects: Pipewire.ready ? Pipewire.defaultAudioSink : [] + property var sink: Pipewire.defaultAudioSink + function getVolumeIcon() { + // Safety check: if Pipewire is dead or sink is missing + if (!sink) + return "volume_off"; + + // If muted, show the hush icon + if (sink.audio.muted) + return "volume_off"; + + // Volume is usually 0.0 to 1.0 (0% to 100%) + const vol = sink.audio.volume; + + if (vol <= 0.25) + return "volume_mute"; + if (vol < 0.75) + return "volume_down"; + if (vol <= 1.00) + return "volume_up"; + + // If it's loud, prepare the ears! + return "volume_up"; + } + Row { + id: textRow + anchors.verticalCenter: parent.verticalCenter + spacing: 5 + CustomText { + id: volumeText + PwObjectTracker { + objects: Pipewire.ready ? Pipewire.defaultAudioSink : [] + } + text: Pipewire.ready ? Math.round(root.sink.audio.volume * 100) + "%" : "failure" + opacity: Pipewire.ready ? root.sink.audio.muted ? 0.5 : 1 : 0 + } + CustomIcon { + id: volumeIcon + opacity: Pipewire.ready ? root.sink.audio.muted ? 0.5 : 1 : 0 + text: Pipewire.ready ? root.getVolumeIcon() : null } - text: Pipewire.ready ? Pipewire.defaultAudioSink.audio.muted ? "mut: " + Math.round(Pipewire.defaultAudioSink.audio.volume * 100) + "%" : "vol: " + Math.round(Pipewire.defaultAudioSink.audio.volume * 100) + "%" : "failure" } } diff --git a/modules/Bar/Workspaces.qml b/modules/Bar/Workspaces.qml index 4363353..e61fcc6 100644 --- a/modules/Bar/Workspaces.qml +++ b/modules/Bar/Workspaces.qml @@ -13,7 +13,7 @@ Item { Row { id: workspaceRow anchors.centerIn: parent - spacing: 0 // Slightly increase spacing between workspace buttons + spacing: 10 // Slightly increase spacing between workspace buttons Repeater { id: wsRepeater @@ -21,6 +21,7 @@ Item { anchors.centerIn: parent Rectangle { id: workspaceNumber + radius: 20 property bool isOnMon: { if (!modelData) return false; @@ -34,14 +35,15 @@ Item { } required property var modelData - width: isOnMon ? Settings.config.barHeight + 10 : 0 - height: isOnMon ? Settings.config.barHeight : 0 - color: modelData.active ? Colors.foreground : "transparent" + width: isOnMon ? Settings.config.barHeight - Settings.config.barHeight / 2 : 0 + height: isOnMon ? Settings.config.barHeight - Settings.config.barHeight / 2 : 0 + color: "transparent" CustomText { anchors.centerIn: workspaceNumber text: parent.modelData.id - color: parent.modelData.active ? Colors.background : Colors.foreground // Set contrasting color for workspace number + color: Colors.foreground // Set contrasting color for workspace number + opacity: workspaceNumber.modelData.focused ? 1 : 0.5 } MouseArea { anchors.fill: parent diff --git a/reusables/CustomIcon.qml b/reusables/CustomIcon.qml new file mode 100644 index 0000000..f8ddafe --- /dev/null +++ b/reusables/CustomIcon.qml @@ -0,0 +1,13 @@ +import QtQuick +import "../settings/" +import "../" + +Text { + font.family: "Material Symbols Rounded" + color: Colors.foreground + font.pixelSize: Settings.config.fontSize + 1 + font.variableAxes: ({ + GRAD: 200, + wght: 400 + }) +} diff --git a/reusables/CustomText.qml b/reusables/CustomText.qml index 196d4d0..1c54b5e 100644 --- a/reusables/CustomText.qml +++ b/reusables/CustomText.qml @@ -6,4 +6,8 @@ Text { color: Colors.foreground font.family: Settings.config.font font.pixelSize: Settings.config.fontSize + font.variableAxes: ({ + GRAD: 200, + wght: 400 + }) } diff --git a/settings/Settings.qml b/settings/Settings.qml index 0a7e202..02dd731 100644 --- a/settings/Settings.qml +++ b/settings/Settings.qml @@ -21,10 +21,10 @@ Singleton { adapter: JsonAdapter { id: settingsAdapter - property var currentWall: "/home/lucy/.walls/faris.jpg" - property var barHeight: 18 - property var font: "JetBrainsMono Nerd Font" - property var fontSize: 12 + property var currentWall: "/home/lucy/.walls/frierensuff.png" + property var barHeight: 28 + property var font: "Google Sans Code" + property var fontSize: 14 property var rounding: 10 property var wallDir: "/home/lucy/.walls" property bool floating: true diff --git a/settings/config.json b/settings/config.json index 03a50c7..e4c5765 100644 --- a/settings/config.json +++ b/settings/config.json @@ -1,9 +1,9 @@ { - "barHeight": 18, - "currentWall": "/home/lucy/.walls/faris.jpg", + "barHeight": 28, + "currentWall": "/home/lucy/.walls/frierensuff.png", "floating": true, - "font": "JetBrainsMono Nerd Font", - "fontSize": 12, + "font": "Google Sans Code", + "fontSize": 14, "paddingSides": 10, "paddingTop": 10, "rounding": 10, diff --git a/shell.qml b/shell.qml index 1d1ac4d..79d7067 100644 --- a/shell.qml +++ b/shell.qml @@ -1,3 +1,4 @@ +//@ pragma UseQApplication import Quickshell import QtQuick import "./settings/"