Compare commits

...

8 Commits

10 changed files with 280 additions and 209 deletions

20
Bar.qml
View File

@@ -1,9 +1,12 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import Quickshell
import Quickshell.Hyprland
import Quickshell.Wayland
import "./Bar"
import "./Services/"
import "Color.js" as Colors
Scope {
@@ -25,6 +28,8 @@ Scope {
required property var modelData
property HyprlandMonitor monitor: Hyprland.monitorFor(modelData)
WlrLayershell.keyboardFocus: monitor.focused == true ? IpcManager.focusState :
WlrKeyboardFocus.None
color: "transparent"
exclusionMode: ExclusionMode.Normal
exclusiveZone: barExclusionZone
@@ -32,6 +37,21 @@ Scope {
mask: maskRegion
screen: modelData
Rectangle {
id: blurOverlay
color: Colors.base
implicitHeight: win.modelData.height
implicitWidth: win.modelData.width
opacity: IpcManager.logoutMenuOpen == true ? 0.8 : 0
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
}
Region {
id: maskRegion

View File

@@ -18,61 +18,16 @@ Container {
animOffset: 150
boxColor: Colors.green
boxHeight: 25
boxHeightOpened: root.batteryDisplayHeight
boxRadius: radius
boxWidth: 60
boxWidthOpened: 410
defaultItem: icon
exclusiveMonitor: root.monitor
exclusiveToScreen: true
forceHidden: !BatteryManager.hasLaptopBattery
states: [
State {
name: "closed"
when: root.hovered == false && root.opened == false
PropertyChanges {
root.boxHeight: 25
root.boxRadius: root.radius
root.boxWidth: 60
}
},
State {
name: "hovered"
when: root.hovered == true && root.opened == false
PropertyChanges {
root.boxHeight: 28
root.boxWidth: 64
}
},
State {
name: "opened"
when: root.opened == true && root.hovered == true
PropertyChanges {
root.boxHeight: root.batteryDisplayHeight
root.boxRadius: 12
root.boxWidth: 450
}
StateChangeScript {
script: {
stack.replace(batteryDisplay);
}
}
}
]
hover.onHoveredChanged: {
if (hover.hovered == false) {
root.opened = false;
if (root.state != "icon") {
root.stack.replace(icon);
}
}
}
tap.onTapped: {
root.opened = true;
}
openedItem: batteryDisplay
Component {
id: icon

View File

@@ -14,67 +14,19 @@ Container {
property double devicePlaqueHeight: 60
property double devicePlaqueSpacing: 4
required property HyprlandMonitor monitor
property bool opened: false
animOffset: 200
boxColor: Colors.peach
boxHeight: 25
boxHeightOpened: (root.devicePlaqueHeight * BluetoothManager.getConnectedDevicesList().length) + (
root.devicePlaqueSpacing * (BluetoothManager.getConnectedDevicesList().length + 1)) + 2
boxWidth: 33
boxWidthOpened: 350
defaultItem: icon
exclusiveMonitor: root.monitor
exclusiveToScreen: true
forceHidden: !BluetoothManager.anyConnected
states: [
State {
name: "closed"
when: root.hovered == false && root.opened == false
PropertyChanges {
root.boxHeight: 25
root.boxRadius: 9
root.boxWidth: 33
}
},
State {
name: "hovered"
when: root.hovered == true && root.opened == false
PropertyChanges {
root.boxHeight: 28
root.boxWidth: 35
}
},
State {
name: "opened"
when: root.opened == true && root.hovered == true
PropertyChanges {
root.boxHeight: (root.devicePlaqueHeight * BluetoothManager.getConnectedDevicesList().length) + (
root.devicePlaqueSpacing * (BluetoothManager.getConnectedDevicesList().length + 1)) + 2
root.boxRadius: 12
root.boxWidth: 350
}
StateChangeScript {
script: {
stack.replace(deviceList);
}
}
}
]
hover.onHoveredChanged: {
if (hover.hovered == false) {
root.opened = false;
if (root.state != "icon") {
root.stack.replace(icon);
}
}
}
tap.onTapped: {
root.opened = true;
}
openedItem: deviceList
Component {
id: icon

View File

@@ -13,66 +13,18 @@ Container {
required property HyprlandMonitor monitor
property double networkDisplayHeight: 80
property bool opened: false
animOffset: 250
boxColor: Colors.red
boxHeight: 25
boxHeightOpened: root.networkDisplayHeight
boxWidth: 33
boxWidthOpened: 350
defaultItem: icon
exclusiveMonitor: root.monitor
exclusiveToScreen: true
forceHidden: !NetworkManager.connectedWifi
states: [
State {
name: "closed"
when: root.hovered == false && root.opened == false
PropertyChanges {
root.boxHeight: 25
root.boxRadius: 9
root.boxWidth: 33
}
},
State {
name: "hovered"
when: root.hovered == true && root.opened == false
PropertyChanges {
root.boxHeight: 28
root.boxWidth: 35
}
},
State {
name: "opened"
when: root.opened == true && root.hovered == true
PropertyChanges {
root.boxHeight: root.networkDisplayHeight
root.boxRadius: 12
root.boxWidth: 350
}
StateChangeScript {
script: {
stack.replace(wifiInfo);
}
}
}
]
hover.onHoveredChanged: {
if (hover.hovered == false) {
root.opened = false;
if (root.state != "icon") {
root.stack.replace(icon);
}
}
}
tap.onTapped: {
root.opened = true;
}
openedItem: networkDisplay
Component {
id: icon
@@ -86,7 +38,7 @@ Container {
}
Component {
id: wifiInfo
id: networkDisplay
Item {
id: networkDisplayRoot

View File

@@ -15,6 +15,10 @@ Container {
id: root
property Notification latestNotif
property bool logout: false
property double logoutHeight: 100
property double logoutMargin: 7
property double logoutSpacing: 5
required property HyprlandMonitor monitor
property bool mpris: false
property double mprisHeight: 60
@@ -22,7 +26,6 @@ Container {
property double notificationHeight: 100
property double notificationWidth: 350
property bool notified: false
property bool overriden: false
boxColor: Colors.mauve
defaultItem: time
@@ -30,43 +33,6 @@ Container {
exclusiveToScreen: true
states: [
State {
name: "closed"
when: root.hovered == false && root.overriden == false
PropertyChanges {
root.boxHeight: 28
root.boxRadius: 9
root.boxWidth: 100
}
StateChangeScript {
script: {
if (!root.stack.currentItem) {
return;
}
if (root.stack.currentItem.component != "time") {
root.stack.replace(time);
}
}
}
},
State {
name: "hovered"
when: root.hovered == true && root.overriden == false
PropertyChanges {
root.boxHeight: MprisManager.getPlaying() == false ? 32 : root.mprisHeight
root.boxRadius: 12
root.boxWidth: MprisManager.getPlaying() == false ? 107 : root.mprisWidth
}
StateChangeScript {
script: {
root.stack.replace(MprisManager.getPlaying() == true ? mprisToast : time);
}
}
},
State {
name: "notified"
when: root.notified == true
@@ -93,7 +59,7 @@ Container {
root.boxHeight: root.mprisHeight
root.boxRadius: 12
root.boxWidth: root.mprisWidth
root.visibleTopMargin: 5
root.visibleTopMargin: root.hovered == true ? 0 : 5
}
StateChangeScript {
@@ -102,9 +68,51 @@ Container {
mprisTimer.restart();
}
}
},
State {
name: "logout"
when: root.logout == true
PropertyChanges {
root.boxHeight: root.logoutHeight
root.boxRadius: 13
root.boxWidth: ((root.logoutHeight - (root.logoutMargin * 2)) * 5) + (root.logoutMargin * 2) + (
root.logoutSpacing * 4)
root.visibleTopMargin: 10
}
StateChangeScript {
script: {
root.stack.replace(logoutMenu);
}
}
}
]
onHoveredChanged: {
if (root.hovered == true && MprisManager.getPlaying() == true) {
root.overriden = true;
root.mpris = true;
} else {
root.overriden = false;
root.mpris = true;
}
}
Connections {
function onCloseLogoutMenu() {
root.overriden = false;
root.logout = false;
}
function onLogoutMenu() {
root.overriden = true;
root.logout = true;
}
target: IpcManager
}
Connections {
function onNewNotification() {
notification => {
@@ -155,6 +163,98 @@ Container {
}
}
Component {
id: logoutMenu
Item {
id: logoutMenuRoot
property var logoutModel: [
{
color: Colors.red,
text: "s",
key: Qt.Key_S
},
{
color: Colors.peach,
text: "e",
key: Qt.Key_E
},
{
color: Colors.yellow,
text: "r",
key: Qt.Key_R
},
{
color: Colors.green,
text: "l",
key: Qt.Key_L
},
{
color: Colors.sky,
text: "u",
key: Qt.Key_U
},
]
Component.onCompleted: {
forceActiveFocus();
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Escape) {
IpcManager.closeLogoutMenu();
} else {
for (let button of logoutMenuRoot.logoutModel) {
if (button.key == event.key) {
event.accepted = true;
}
}
}
}
RowLayout {
spacing: root.logoutSpacing
anchors {
fill: parent
margins: root.logoutMargin
}
Repeater {
delegate: logoutButton
model: logoutMenuRoot.logoutModel
}
Component {
id: logoutButton
Item {
id: logoutButtonRoot
// Key yen isn't on my keyboard, acts as an errorless analog for no bind
required property var modelData
Layout.fillHeight: true
Layout.fillWidth: true
Rectangle {
anchors.fill: parent
color: logoutButtonRoot.modelData.color
radius: 7
StyledText {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
text: logoutButtonRoot.modelData.text
verticalAlignment: Qt.AlignVCenter
}
}
}
}
}
}
}
Component {
id: time
@@ -162,7 +262,7 @@ Container {
property string component: "time"
horizontalAlignment: Qt.AlignCenter
text: Time.time
text: TimeManager.time
verticalAlignment: Qt.AlignVCenter
}
}

View File

@@ -25,18 +25,6 @@ Container {
defaultItem: placeholder
exclusiveMonitor: monitor
states: [
State {
name: "hovered"
when: root.hovered
PropertyChanges {
root.barHeight: 30
root.workspaceWidth: 20
}
}
]
Component {
id: placeholder

View File

@@ -14,8 +14,12 @@ Item {
property double animOffset: 0
property color boxColor: Colors.surface0
property double boxHeight: 28
property double boxHeightOpened: 150
property bool boxOpened: false
property double boxRadius: 9
property double boxRadiusOpened: 12
property double boxWidth: 100
property double boxWidthOpened: 200
readonly property double calculatedTopMargin: {
if (!root.exclusiveToScreen) {
return visibleTopMargin;
@@ -38,6 +42,8 @@ Item {
property alias hover: hoverHandler
property bool hoverableWhenHidden: false
property bool hovered: false
property Component openedItem
property bool overriden: false
property alias rect: container
property alias stack: containerContent
property alias tap: tapHandler
@@ -50,13 +56,13 @@ Item {
Behavior on anchors.topMargin {
animation: defaultCurve
}
Behavior on boxHeight {
Behavior on boxRadius {
SpringAnimation {
damping: 0.3
spring: 4
}
}
Behavior on boxRadius {
Behavior on implicitHeight {
SpringAnimation {
damping: 0.3
spring: 4
@@ -68,6 +74,56 @@ Item {
spring: 4
}
}
states: [
State {
name: "closed"
when: root.hovered == false && root.boxOpened == false && root.overriden == false
PropertyChanges {
container.radius: root.boxRadius
root.implicitHeight: root.boxHeight
root.implicitWidth: root.boxWidth
}
StateChangeScript {
script: {
stack.replace(root.defaultItem);
}
}
},
State {
name: "hovered"
when: root.hovered == true && root.boxOpened == false && root.overriden == false
PropertyChanges {
container.radius: root.boxRadius + 3
root.implicitHeight: root.boxHeight + 2
root.implicitWidth: root.boxWidth + 2
}
StateChangeScript {
script: {
stack.replace(root.defaultItem);
}
}
},
State {
name: "opened"
when: root.boxOpened == true && root.hovered == true && root.overriden == false
PropertyChanges {
container.radius: root.boxRadiusOpened
root.implicitHeight: root.boxHeightOpened
root.implicitWidth: root.boxWidthOpened
}
StateChangeScript {
script: {
stack.replace(root.openedItem);
}
}
}
]
onForceHiddenChanged: {
if (root.forceHidden == true) {
@@ -125,12 +181,22 @@ Item {
root.hovered = true;
} else {
root.hovered = false;
root.boxOpened = false;
if (root.state == "closed") {
root.stack.replace(root.defaultItem);
}
}
}
}
TapHandler {
id: tapHandler
onTapped: {
if (root.openedItem) {
root.boxOpened = true;
}
}
}
Rectangle {
@@ -141,6 +207,12 @@ Item {
color: root.boxColor
radius: root.boxRadius
Behavior on radius {
NumberAnimation {
duration: 300
}
}
StackView {
id: containerContent

31
Services/IpcManager.qml Normal file
View File

@@ -0,0 +1,31 @@
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
Singleton {
id: root
property var focusState: WlrKeyboardFocus.None
property bool logoutMenuOpen: false
signal closeLogoutMenu
signal logoutMenu
onCloseLogoutMenu: {
root.focusState = WlrKeyboardFocus.None;
root.logoutMenuOpen = false;
}
IpcHandler {
function openLogoutMenu(): void {
root.logoutMenu();
root.focusState = WlrKeyboardFocus.Exclusive;
root.logoutMenuOpen = true;
}
target: "root"
}
}

View File

@@ -1,8 +1,9 @@
module Services
singleton Time 1.0 Time.qml
singleton TimeManager 1.0 TimeManager.qml
singleton NotificationManager 1.0 NotificationManager.qml
singleton WorkspaceManager 1.0 WorkspaceManager.qml
singleton BluetoothManager 1.0 BluetoothManager.qml
singleton MprisManager 1.0 MprisManager.qml
singleton BatteryManager 1.0 BatteryManager.qml
singleton NetworkManager 1.0 NetworkManager.qml
singleton IpcManager 1.0 IpcManager.qml