Merge branch 'rewrite-again'
This commit is contained in:
65
Bar.qml
65
Bar.qml
@@ -3,14 +3,20 @@ import QtQuick.Effects
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import "Bar"
|
import "./Bar"
|
||||||
import "Color.js" as Colors
|
import "Color.js" as Colors
|
||||||
|
|
||||||
Scope {
|
Scope {
|
||||||
Variants {
|
Variants {
|
||||||
model: Quickshell.screens
|
id: panelDelegate
|
||||||
|
|
||||||
|
delegate: panelWindow
|
||||||
|
model: Quickshell.screens
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: panelWindow
|
||||||
|
|
||||||
delegate: Component {
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: win
|
id: win
|
||||||
|
|
||||||
@@ -23,9 +29,12 @@ Scope {
|
|||||||
exclusionMode: ExclusionMode.Normal
|
exclusionMode: ExclusionMode.Normal
|
||||||
exclusiveZone: barExclusionZone
|
exclusiveZone: barExclusionZone
|
||||||
implicitHeight: barMaxHeight
|
implicitHeight: barMaxHeight
|
||||||
|
mask: maskRegion
|
||||||
screen: modelData
|
screen: modelData
|
||||||
|
|
||||||
mask: Region {
|
Region {
|
||||||
|
id: maskRegion
|
||||||
|
|
||||||
Region {
|
Region {
|
||||||
item: left
|
item: left
|
||||||
}
|
}
|
||||||
@@ -45,23 +54,42 @@ Scope {
|
|||||||
top: true
|
top: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: rowContainer
|
||||||
|
shadowBlur: 1.5
|
||||||
|
shadowColor: Colors.mantle
|
||||||
|
shadowEnabled: true
|
||||||
|
shadowHorizontalOffset: 5
|
||||||
|
shadowOpacity: 1
|
||||||
|
shadowVerticalOffset: 3
|
||||||
|
source: rowContainer
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: rowContainer
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
topMargin: 3
|
topMargin: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 3
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: 3
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: left
|
id: left
|
||||||
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
leftMargin: 7
|
top: parent.top
|
||||||
}
|
}
|
||||||
|
|
||||||
Left {
|
WorkspaceSelector {
|
||||||
monitor: win.monitor
|
monitor: win.monitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,13 +97,12 @@ Scope {
|
|||||||
Row {
|
Row {
|
||||||
id: center
|
id: center
|
||||||
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
top: parent.top
|
||||||
}
|
}
|
||||||
|
|
||||||
Center {
|
Time {
|
||||||
monitor: win.monitor
|
monitor: win.monitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,14 +110,23 @@ Scope {
|
|||||||
Row {
|
Row {
|
||||||
id: right
|
id: right
|
||||||
|
|
||||||
height: childrenRect.height
|
Layout.alignment: Qt.AlignTop
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: 7
|
top: parent.top
|
||||||
}
|
}
|
||||||
|
|
||||||
Right {
|
Network {
|
||||||
|
monitor: win.monitor
|
||||||
|
}
|
||||||
|
|
||||||
|
Bluetooth {
|
||||||
|
monitor: win.monitor
|
||||||
|
}
|
||||||
|
|
||||||
|
Battery {
|
||||||
monitor: win.monitor
|
monitor: win.monitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,4 +134,3 @@ Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
189
Bar/Battery.qml
Normal file
189
Bar/Battery.qml
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
import "../Components/"
|
||||||
|
import "../Services/"
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property double batteryDisplayHeight: 100
|
||||||
|
required property HyprlandMonitor monitor
|
||||||
|
property bool opened: false
|
||||||
|
property double radius: 9
|
||||||
|
|
||||||
|
animOffset: 150
|
||||||
|
boxColor: Colors.green
|
||||||
|
boxRadius: radius
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
Item {
|
||||||
|
BatteryGradient {}
|
||||||
|
|
||||||
|
CenteredText {
|
||||||
|
property string component: "icon"
|
||||||
|
|
||||||
|
propo: true
|
||||||
|
text: BatteryManager.getBatteryText()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: batteryDisplay
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: batteryDisplayRoot
|
||||||
|
|
||||||
|
property double innerMargin: 5
|
||||||
|
property double outerMargin: 6
|
||||||
|
|
||||||
|
BatteryGradient {}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: batteryBackground
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: batteryDisplayRoot.outerMargin
|
||||||
|
color: Colors.surface1
|
||||||
|
radius: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: percentBox
|
||||||
|
|
||||||
|
property double percentBoxRadius: 5
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.margins: batteryDisplayRoot.innerMargin
|
||||||
|
color: Colors.text
|
||||||
|
implicitWidth: root.batteryDisplayHeight - (batteryDisplayRoot.innerMargin * 2) - (
|
||||||
|
batteryDisplayRoot.outerMargin * 2)
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: Colors.green
|
||||||
|
implicitHeight: (root.batteryDisplayHeight - (batteryDisplayRoot.innerMargin * 2) - (
|
||||||
|
batteryDisplayRoot.outerMargin * 2)) * BatteryManager.mainBattery.percentage
|
||||||
|
radius: percentBox.percentBoxRadius
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CenteredText {
|
||||||
|
fontSize: 15
|
||||||
|
text: BatteryManager.getBatteryPercentage(BatteryManager.mainBattery) + "%"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: batColumn
|
||||||
|
|
||||||
|
property var batInfo: BatteryManager.getMainBatteryInfo()
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.text
|
||||||
|
fontSize: 14
|
||||||
|
text: "Battery - " + batColumn.batInfo["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.subtext1
|
||||||
|
fontSize: 12
|
||||||
|
fontWeight: 5
|
||||||
|
text: batColumn.batInfo["energy"] + "/" + batColumn.batInfo["capacity"] + "Wh - "
|
||||||
|
+ BatteryManager.getChargingRateFormat()
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
property var timeInfo: batColumn.batInfo["time"]
|
||||||
|
|
||||||
|
color: Colors.subtext1
|
||||||
|
fontSize: 12
|
||||||
|
fontWeight: 5
|
||||||
|
text: BatteryManager.getTimeFormat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component BatteryGradient: MidpointGradient {
|
||||||
|
anchors.fill: parent
|
||||||
|
angle: -45
|
||||||
|
blur: 0.6
|
||||||
|
color: BatteryManager.getBatteryColor()
|
||||||
|
midpoint: 0.55
|
||||||
|
radius: radius
|
||||||
|
}
|
||||||
|
}
|
||||||
213
Bar/Bluetooth.qml
Normal file
213
Bar/Bluetooth.qml
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
import "../Components/"
|
||||||
|
import "../Services/"
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property double devicePlaqueHeight: 60
|
||||||
|
property double devicePlaqueSpacing: 4
|
||||||
|
required property HyprlandMonitor monitor
|
||||||
|
property bool opened: false
|
||||||
|
|
||||||
|
animOffset: 200
|
||||||
|
boxColor: Colors.peach
|
||||||
|
boxHeight: 25
|
||||||
|
boxWidth: 33
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
property string component: "icon"
|
||||||
|
|
||||||
|
horizontalAlignment: Qt.AlignCenter
|
||||||
|
propo: true
|
||||||
|
text: ""
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: deviceList
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: deviceListRoot
|
||||||
|
|
||||||
|
property string component: "deviceList"
|
||||||
|
property double plaqueHeight: root.devicePlaqueHeight
|
||||||
|
property double plaqueSpacing: root.devicePlaqueSpacing
|
||||||
|
|
||||||
|
spacing: plaqueSpacing
|
||||||
|
|
||||||
|
Item {
|
||||||
|
implicitHeight: 1
|
||||||
|
implicitWidth: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
delegate: devicePlaque
|
||||||
|
model: BluetoothManager.getConnectedDevicesList()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: devicePlaque
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: devicePlaqueRoot
|
||||||
|
|
||||||
|
readonly property variant deviceText: BluetoothManager.getDeviceText(modelData)
|
||||||
|
readonly property double margin: 5
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
color: Colors.surface1
|
||||||
|
implicitHeight: deviceListRoot.plaqueHeight
|
||||||
|
radius: 10
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: devicePlaqueRoot.margin
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: devicePlaqueRoot.margin
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: deviceInfoRow
|
||||||
|
|
||||||
|
property double margin: 7
|
||||||
|
|
||||||
|
spacing: margin * 2
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: margin
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: iconContainer
|
||||||
|
|
||||||
|
property double boxRadius: 4
|
||||||
|
|
||||||
|
color: Colors.text
|
||||||
|
implicitHeight: deviceListRoot.plaqueHeight - (deviceInfoRow.margin * 2)
|
||||||
|
implicitWidth: deviceListRoot.plaqueHeight - (deviceInfoRow.margin * 2)
|
||||||
|
radius: boxRadius
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: batteryIndicator
|
||||||
|
|
||||||
|
color: Colors.green
|
||||||
|
implicitHeight: (deviceListRoot.plaqueHeight - (deviceInfoRow.margin * 2))
|
||||||
|
* devicePlaqueRoot.deviceText["batteryRaw"]
|
||||||
|
radius: iconContainer.boxRadius
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
id: batteryHoverHandler
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (batteryHoverHandler.hovered == true) {
|
||||||
|
batteryText.text = devicePlaqueRoot.deviceText["battery"];
|
||||||
|
} else {
|
||||||
|
batteryText.text = devicePlaqueRoot.deviceText["icon"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CenteredText {
|
||||||
|
id: batteryText
|
||||||
|
|
||||||
|
fontSize: 17
|
||||||
|
text: devicePlaqueRoot.deviceText["icon"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.text
|
||||||
|
fontSize: 14
|
||||||
|
text: devicePlaqueRoot.deviceText["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.subtext1
|
||||||
|
fontSize: 10
|
||||||
|
text: devicePlaqueRoot.deviceText["mac"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
263
Bar/Center.qml
263
Bar/Center.qml
@@ -1,263 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Services.Mpris
|
|
||||||
import Quickshell.Services.Notifications
|
|
||||||
import "../Color.js" as Colors
|
|
||||||
import "../Components/"
|
|
||||||
import "../Services/"
|
|
||||||
import "./Center"
|
|
||||||
|
|
||||||
Container {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property Notification latestNotification: NotificationManager.getLatestNotification() || null
|
|
||||||
required property HyprlandMonitor monitor
|
|
||||||
property NotificationServer notifServer: NotificationManager.notif
|
|
||||||
property string previousState
|
|
||||||
|
|
||||||
boxColor: Colors.mauve
|
|
||||||
defaultItem: time
|
|
||||||
exclusiveMonitor: root.monitor
|
|
||||||
exclusiveToScreen: true
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 28
|
|
||||||
root.boxRadius: 9
|
|
||||||
root.boxWidth: 100
|
|
||||||
root.visibleTopMargin: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
if (root.previousState != "hovered") {
|
|
||||||
root.stack.replace(time);
|
|
||||||
}
|
|
||||||
root.previousState = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 35
|
|
||||||
root.boxRadius: 15
|
|
||||||
root.boxWidth: 110
|
|
||||||
root.visibleTopMargin: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
root.previousState = "hovered";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "mprisToast"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 35
|
|
||||||
root.boxRadius: 15
|
|
||||||
root.boxWidth: 350
|
|
||||||
root.visibleTopMargin: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
root.previousState = "mpris";
|
|
||||||
root.stack.replace(mpris);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "expanded"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 140
|
|
||||||
root.boxRadius: 30
|
|
||||||
root.boxWidth: 300
|
|
||||||
root.visibleTopMargin: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
if (root.state != "notifications") {
|
|
||||||
root.stack.replace(fullTime);
|
|
||||||
root.previousState = "expanded";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
extend: "expanded"
|
|
||||||
name: "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 320
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "notified"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 90
|
|
||||||
root.boxRadius: 30
|
|
||||||
root.boxWidth: 330
|
|
||||||
root.visibleTopMargin: 20
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
root.stack.replace(notification);
|
|
||||||
root.previousState = "notified";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
hover.onHoveredChanged: {
|
|
||||||
if (hover.hovered == true) {
|
|
||||||
if (root.state == "notified") {
|
|
||||||
root.state = "notified";
|
|
||||||
notificationViewTimer.stop();
|
|
||||||
} else if (MprisManager.getPlaying() == true) {
|
|
||||||
root.state = "mprisToast";
|
|
||||||
} else {
|
|
||||||
root.state = "hovered";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
root.state = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onLatestNotificationChanged: {
|
|
||||||
if (latestNotification != null && Hyprland.focusedMonitor == monitor) {
|
|
||||||
if (root.latestNotification.lastGeneration == false) {
|
|
||||||
root.state = "notified";
|
|
||||||
notificationViewTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tap.onTapped: {
|
|
||||||
root.state == "hovered" ? root.state = "expanded" : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onTrackChanged() {
|
|
||||||
if (Hyprland.focusedMonitor == root.monitor) {
|
|
||||||
musicToastTimer.restart();
|
|
||||||
if (root.state == "") {
|
|
||||||
root.state = "mprisToast";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target: MprisManager.defaultPlayer
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: notificationViewTimer
|
|
||||||
|
|
||||||
interval: 3000
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
root.state = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: musicToastTimer
|
|
||||||
|
|
||||||
interval: 3000
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if (!root.hover.hovered) {
|
|
||||||
root.state = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: time
|
|
||||||
|
|
||||||
Item {
|
|
||||||
CenteredText {
|
|
||||||
text: Time.time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: mpris
|
|
||||||
|
|
||||||
Mpris {
|
|
||||||
TapHandler {
|
|
||||||
onTapped: root.state = "expanded"
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
acceptedButtons: Qt.RightButton
|
|
||||||
|
|
||||||
onTapped: MprisManager.skip()
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
acceptedButtons: Qt.MiddleButton
|
|
||||||
|
|
||||||
onTapped: MprisManager.prev()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: fullTime
|
|
||||||
|
|
||||||
Expanded {
|
|
||||||
NotificationList {
|
|
||||||
id: notifList
|
|
||||||
|
|
||||||
animEnabled: false
|
|
||||||
radius: root.boxRadius
|
|
||||||
rootState: root.state
|
|
||||||
server: root.notifServer
|
|
||||||
state: ""
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: {
|
|
||||||
notifList.animEnabled = true;
|
|
||||||
root.state = "notifications";
|
|
||||||
Qt.callLater(() => {
|
|
||||||
notifList.animEnabled = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: notification
|
|
||||||
|
|
||||||
NotificationDisplay {
|
|
||||||
body: root.latestNotification.body
|
|
||||||
summary: root.latestNotification.summary
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: {
|
|
||||||
root.state = "notifications";
|
|
||||||
root.stack.replace(fullTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: fullTimeRoot
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: 30
|
|
||||||
|
|
||||||
gradient: MidpointGradient {
|
|
||||||
color: Colors.red
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: timeColumnContainer
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: timeColumn
|
|
||||||
|
|
||||||
spacing: 5
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
color: Colors.surface0
|
|
||||||
text: Time.time
|
|
||||||
|
|
||||||
font {
|
|
||||||
pointSize: 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
color: Colors.surface1
|
|
||||||
text: Time.date
|
|
||||||
|
|
||||||
font {
|
|
||||||
pointSize: 9
|
|
||||||
weight: 400
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell.Services.Mpris
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property MprisPlayer player: MprisManager.defaultPlayer
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: Colors.red
|
|
||||||
radius: 5
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 15
|
|
||||||
fill: parent
|
|
||||||
leftMargin: 10
|
|
||||||
rightMargin: parent.width - ((parent.width * MprisManager.pos) - 10)
|
|
||||||
topMargin: 15
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 2
|
|
||||||
fill: parent
|
|
||||||
leftMargin: 7
|
|
||||||
rightMargin: 7
|
|
||||||
topMargin: 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.fill: parent
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
source: MprisManager.defaultPlayer.trackArtUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
elide: Qt.ElideRight
|
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
|
||||||
text: MprisManager.defaultPlayer.trackArtist + " - " + MprisManager.defaultPlayer.trackTitle
|
|
||||||
verticalAlignment: Qt.AlignVCenter
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Services.Notifications
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property string body
|
|
||||||
required property string summary
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: 30
|
|
||||||
|
|
||||||
gradient: MidpointGradient {
|
|
||||||
color: Colors.green
|
|
||||||
midpoint: 0.7
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 5
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
font.pointSize: 11
|
|
||||||
text: root.summary
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
maximumLineCount: 2
|
|
||||||
text: root.body
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
width: root.width - 20
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
|
|
||||||
font {
|
|
||||||
pointSize: 10
|
|
||||||
weight: 500
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Effects
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Services.Notifications
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property bool animEnabled
|
|
||||||
required property double radius
|
|
||||||
required property string rootState
|
|
||||||
required property NotificationServer server
|
|
||||||
|
|
||||||
Behavior on anchors.topMargin {
|
|
||||||
enabled: root.animEnabled
|
|
||||||
|
|
||||||
SpringAnimation {
|
|
||||||
damping: 0.35
|
|
||||||
spring: 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: root.rootState != "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.anchors.topMargin: root.parent.height - 21
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "expanded"
|
|
||||||
when: root.rootState == "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.anchors.topMargin: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
topMargin: parent.height - 21
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: background
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Colors.surface0
|
|
||||||
radius: root.radius - 3
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: root.rootState != "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "expanded"
|
|
||||||
when: root.rootState == "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
background.anchors.bottomMargin: 5
|
|
||||||
background.anchors.leftMargin: 5
|
|
||||||
background.anchors.rightMargin: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 15
|
|
||||||
leftMargin: 20
|
|
||||||
rightMargin: 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: notifListContainer
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 5
|
|
||||||
leftMargin: 5
|
|
||||||
rightMargin: 5
|
|
||||||
topMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
color: Colors.overlay0
|
|
||||||
text: "No Notifications"
|
|
||||||
visible: root.server.trackedNotifications.values.length <= 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: notifScrollingList
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
|
||||||
height: Math.min(contentHeight, parent.height)
|
|
||||||
implicitHeight: background.height
|
|
||||||
model: root.server.trackedNotifications.values.length
|
|
||||||
spacing: 7
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
id: notifRoot
|
|
||||||
|
|
||||||
property Notification currentNotif: root.server.trackedNotifications.values[(notifRoot.notifLen
|
|
||||||
- 1) - index]
|
|
||||||
required property real index
|
|
||||||
property real notifLen: root.server.trackedNotifications.values.length
|
|
||||||
|
|
||||||
height: 50
|
|
||||||
width: ListView.view.width
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: notifHover.hovered == false
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
when: notifHover.hovered == false
|
|
||||||
|
|
||||||
PropertyChanges {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
HoverHandler {
|
|
||||||
id: notifHover
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: dismissButton
|
|
||||||
|
|
||||||
color: Colors.red
|
|
||||||
implicitWidth: 100
|
|
||||||
radius: 10
|
|
||||||
|
|
||||||
Behavior on anchors.rightMargin {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: notifHover.hovered == false
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
when: notifHover.hovered == true
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
dismissButton.anchors.rightMargin: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
color: Colors.surface0
|
|
||||||
font.pointSize: 15
|
|
||||||
horizontalAlignment: Qt.AlignRight
|
|
||||||
text: ""
|
|
||||||
verticalAlignment: Qt.AlignVCenter
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
rightMargin: 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: {
|
|
||||||
notifRoot.currentNotif.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
bottomMargin: 3
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: 10
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: textContainer
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
color: Colors.surface2
|
|
||||||
radius: 9
|
|
||||||
|
|
||||||
Behavior on anchors.rightMargin {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: notifHover.hovered == false
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
when: notifHover.hovered == true
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
textContainer.anchors.rightMargin: 40
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: textColumn
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
centerIn: parent
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
color: Colors.text
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: notifRoot.currentNotif.summary
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
width: notifRoot.width - 10
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
color: Colors.subtext1
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: notifRoot.currentNotif.body
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
width: notifRoot.width - 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 5
|
|
||||||
leftMargin: 10
|
|
||||||
rightMargin: 10
|
|
||||||
topMargin: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiEffect {
|
|
||||||
id: notifListClipper
|
|
||||||
|
|
||||||
anchors.fill: notifListContainer
|
|
||||||
maskEnabled: true
|
|
||||||
maskSource: clipsource
|
|
||||||
opacity: 0
|
|
||||||
source: notifListContainer
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: root.rootState != "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
notifListClipper.opacity: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "expanded"
|
|
||||||
when: root.rootState == "notifications"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
notifListClipper.opacity: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: clipsource
|
|
||||||
|
|
||||||
anchors.fill: background
|
|
||||||
color: "black"
|
|
||||||
layer.enabled: true
|
|
||||||
radius: background.radius
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
70
Bar/Left.qml
70
Bar/Left.qml
@@ -1,70 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Services.Notifications
|
|
||||||
import "../Color.js" as Colors
|
|
||||||
import "../Components/"
|
|
||||||
import "../Services/"
|
|
||||||
import "./Center"
|
|
||||||
import "./Left/"
|
|
||||||
|
|
||||||
Container {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property double extraHoveredWidth: 0
|
|
||||||
required property HyprlandMonitor monitor
|
|
||||||
property double rowLeftMargin: 4
|
|
||||||
property double rowSpacing: 3
|
|
||||||
property double rowYmargin: 3
|
|
||||||
property double selectorFocusedExtra: 15
|
|
||||||
property double selectorHeight: 20
|
|
||||||
property double selectorWidth: 20
|
|
||||||
property double spacing: 3
|
|
||||||
property double workspaceNumber: WorkspaceManager.getNumberOfWorkspaces(monitor)
|
|
||||||
|
|
||||||
boxHeight: 25
|
|
||||||
boxWidth: (selectorWidth * workspaceNumber) + ((2 * rowLeftMargin) + (rowSpacing * (
|
|
||||||
workspaceNumber - 1))) + extraHoveredWidth + (hoverHandler.hovered == true
|
|
||||||
? selectorFocusedExtra : 0)
|
|
||||||
exclusiveMonitor: monitor
|
|
||||||
|
|
||||||
defaultItem: WorkspaceContainer {
|
|
||||||
extraHoveredWidth: root.extraHoveredWidth
|
|
||||||
monitor: root.monitor
|
|
||||||
rowLeftMargin: root.rowLeftMargin
|
|
||||||
rowSpacing: root.rowSpacing
|
|
||||||
rowYmargin: root.rowYmargin
|
|
||||||
selectorFocusedExtra: root.selectorFocusedExtra
|
|
||||||
selectorHeight: root.selectorHeight
|
|
||||||
selectorWidth: root.selectorWidth
|
|
||||||
}
|
|
||||||
Behavior on rowYmargin {
|
|
||||||
SpringAnimation {
|
|
||||||
damping: 0.3
|
|
||||||
spring: 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: !hoverHandler.hovered
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
when: hoverHandler.hovered
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 40
|
|
||||||
root.extraHoveredWidth: 25
|
|
||||||
root.rowYmargin: 5
|
|
||||||
root.selectorWidth: 40
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
HoverHandler {
|
|
||||||
id: hoverHandler
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property double extraHoveredWidth
|
|
||||||
required property HyprlandMonitor monitor
|
|
||||||
required property double rowLeftMargin
|
|
||||||
required property double rowSpacing
|
|
||||||
required property double rowYmargin
|
|
||||||
required property double selectorFocusedExtra
|
|
||||||
required property double selectorHeight
|
|
||||||
required property double selectorWidth
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: newWorkspaceButton
|
|
||||||
|
|
||||||
implicitWidth: 20
|
|
||||||
opacity: root.extraHoveredWidth > 0 ? 1 : 0
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
id: tapHandler
|
|
||||||
|
|
||||||
onTapped: WorkspaceManager.activateNextFreeWorkspace()
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
bottomMargin: 5 + root.rowYmargin
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: 4
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 5 + root.rowYmargin
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Colors.green
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: "+"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: root.rowSpacing
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
bottomMargin: root.rowYmargin
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: root.rowLeftMargin
|
|
||||||
top: parent.top
|
|
||||||
topMargin: root.rowYmargin
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: WorkspaceManager.getWorkspacesForMonitor(root.monitor)
|
|
||||||
|
|
||||||
WorkspaceSelector {
|
|
||||||
required property HyprlandWorkspace modelData
|
|
||||||
|
|
||||||
extraHoveredWidth: root.extraHoveredWidth
|
|
||||||
selectorFocusedExtra: root.selectorFocusedExtra
|
|
||||||
selectorHeight: root.selectorHeight
|
|
||||||
selectorWidth: root.selectorWidth
|
|
||||||
workspace: modelData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property double extraHoveredWidth
|
|
||||||
property bool hovered: extraHoveredWidth > 0 ? true : false
|
|
||||||
property color selectorColor: Colors.surface2
|
|
||||||
required property double selectorFocusedExtra
|
|
||||||
required property double selectorHeight
|
|
||||||
required property double selectorWidth
|
|
||||||
required property HyprlandWorkspace workspace
|
|
||||||
property string workspaceState: WorkspaceManager.getWorkspaceState(workspace)
|
|
||||||
|
|
||||||
implicitWidth: selectorWidth + (root.hovered == true ? (root.workspaceState == "focused"
|
|
||||||
? selectorFocusedExtra : 0) : 0)
|
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
|
||||||
SpringAnimation {
|
|
||||||
damping: 0.3
|
|
||||||
spring: 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: root.workspaceState == "inactive"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.selectorColor: Colors.surface2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "active"
|
|
||||||
when: root.workspaceState == "active"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.selectorColor: Colors.overlay2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "focused"
|
|
||||||
when: root.workspaceState == "focused"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.selectorColor: Colors.lavender
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
id: tapHandler
|
|
||||||
|
|
||||||
onTapped: root.workspace.activate()
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
top: parent.top
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: root.selectorColor
|
|
||||||
radius: 6
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
font.pointSize: 10.5
|
|
||||||
text: root.workspace.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
161
Bar/Network.qml
Normal file
161
Bar/Network.qml
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
import "../Components/"
|
||||||
|
import "../Services/"
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property HyprlandMonitor monitor
|
||||||
|
property double networkDisplayHeight: 80
|
||||||
|
property bool opened: false
|
||||||
|
|
||||||
|
animOffset: 250
|
||||||
|
boxColor: Colors.red
|
||||||
|
boxHeight: 25
|
||||||
|
boxWidth: 33
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
horizontalAlignment: Qt.AlignCenter
|
||||||
|
propo: true
|
||||||
|
text: NetworkManager.getNetworkDetails(NetworkManager.defaultAdapter)["icon"] || ""
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: wifiInfo
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: networkDisplayRoot
|
||||||
|
|
||||||
|
property double innerMargin: 5
|
||||||
|
property double outerMargin: 6
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: networkDisplayBg
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: networkDisplayRoot.outerMargin
|
||||||
|
color: Colors.surface1
|
||||||
|
radius: 8
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: iconBox
|
||||||
|
|
||||||
|
property double iconBoxRadius: 5
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.margins: networkDisplayRoot.innerMargin
|
||||||
|
color: Colors.red
|
||||||
|
implicitWidth: root.networkDisplayHeight - (networkDisplayRoot.innerMargin * 2) - (
|
||||||
|
networkDisplayRoot.outerMargin * 2)
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
CenteredText {
|
||||||
|
fontSize: 23
|
||||||
|
propo: true
|
||||||
|
text: NetworkManager.getNetworkDetails(NetworkManager.defaultAdapter)["icon"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: networkColumn
|
||||||
|
|
||||||
|
property var networkInfo: NetworkManager.getNetworkDetails(NetworkManager.defaultAdapter)
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.text
|
||||||
|
fontSize: 14
|
||||||
|
text: networkColumn.networkInfo["networkName"]
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.subtext1
|
||||||
|
fontSize: 12
|
||||||
|
fontWeight: 5
|
||||||
|
text: "Connected on: " + networkColumn.networkInfo["adapterName"]
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
property var timeInfo: networkColumn.networkInfo["time"]
|
||||||
|
|
||||||
|
color: Colors.subtext1
|
||||||
|
fontSize: 12
|
||||||
|
fontWeight: 5
|
||||||
|
text: "Network Details " + (networkColumn.networkInfo["saved"] == true ? "Saved" : "Not Saved")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import Quickshell.Services.Notifications
|
|
||||||
import "../Color.js" as Colors
|
|
||||||
import "../Components/"
|
|
||||||
import "../Services/"
|
|
||||||
import "./Center"
|
|
||||||
import "./Right/"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property HyprlandMonitor monitor
|
|
||||||
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Battery {
|
|
||||||
exclusiveMonitor: root.monitor
|
|
||||||
}
|
|
||||||
|
|
||||||
Bluetooth {
|
|
||||||
exclusiveMonitor: root.monitor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Services.UPower
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
import "Bluetooth"
|
|
||||||
|
|
||||||
Container {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
animOffset: 160
|
|
||||||
boxColor: Colors.green
|
|
||||||
boxHeight: 25
|
|
||||||
boxWidth: 40
|
|
||||||
defaultItem: icon
|
|
||||||
exclusiveToScreen: true
|
|
||||||
forceHidden: BatteryManager.battery.isLaptopBattery
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
text: BatteryManager.batteryPercentage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
pragma ComponentBehavior: Bound
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Bluetooth
|
|
||||||
import "../../Color.js" as Colors
|
|
||||||
import "../../Components/"
|
|
||||||
import "../../Services/"
|
|
||||||
import "Bluetooth"
|
|
||||||
|
|
||||||
Container {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool shown: false
|
|
||||||
|
|
||||||
animOffset: 200
|
|
||||||
boxColor: Colors.peach
|
|
||||||
boxHeight: 25
|
|
||||||
boxWidth: 30
|
|
||||||
defaultItem: icon
|
|
||||||
exclusiveToScreen: true
|
|
||||||
forceHidden: !(root.shown || BluetoothManager.getConnected())
|
|
||||||
hoverableWhenHidden: true
|
|
||||||
state: ""
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 25
|
|
||||||
root.boxWidth: 30
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
root.stack.replace(icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "expanded"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
root.boxHeight: 250
|
|
||||||
root.boxRadius: 20
|
|
||||||
root.boxWidth: 350
|
|
||||||
}
|
|
||||||
|
|
||||||
StateChangeScript {
|
|
||||||
script: {
|
|
||||||
root.stack.replace(expanded);
|
|
||||||
root.shown = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
hover.onHoveredChanged: {
|
|
||||||
if (hover.hovered == false) {
|
|
||||||
root.state = "";
|
|
||||||
hoverIntervalTimer.start();
|
|
||||||
} else {
|
|
||||||
root.shown = true;
|
|
||||||
hoverIntervalTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tap.onTapped: state = "expanded"
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: hoverIntervalTimer
|
|
||||||
|
|
||||||
interval: 500
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if (root.hover.hovered == false) {
|
|
||||||
root.shown = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
Item {
|
|
||||||
CenteredText {
|
|
||||||
text: BluetoothManager.getConnected() == true ? "" : ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: expanded
|
|
||||||
|
|
||||||
Expanded {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,384 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell.Bluetooth
|
|
||||||
import "../../../Color.js" as Colors
|
|
||||||
import "../../../Components/"
|
|
||||||
import "../../../Services/"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property double topBarHeight: 35
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: Colors.surface0
|
|
||||||
radius: 17
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 5
|
|
||||||
fill: parent
|
|
||||||
leftMargin: 5
|
|
||||||
rightMargin: 5
|
|
||||||
topMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: topBar
|
|
||||||
|
|
||||||
property double topBarHeight: root.topBarHeight
|
|
||||||
|
|
||||||
color: Colors.peach
|
|
||||||
implicitHeight: topBarHeight
|
|
||||||
radius: 9
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: 5
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: 5
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: topBarRow
|
|
||||||
|
|
||||||
property double topBarRowPadding: 4
|
|
||||||
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: topBarRowPadding
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: topBarRowPadding
|
|
||||||
top: parent.top
|
|
||||||
topMargin: topBarRowPadding
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
// color: Qt.lighter(Colors.peach, 1.2)
|
|
||||||
color: Colors.surface1
|
|
||||||
implicitHeight: topBar.topBarHeight - (topBarRow.topBarRowPadding * 2)
|
|
||||||
radius: 6
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: Colors.text
|
|
||||||
horizontalAlignment: Qt.AlignLeft
|
|
||||||
text: " " + BluetoothManager.defaultAdapterName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: scanButton
|
|
||||||
|
|
||||||
color: Qt.lighter(Colors.peach, 1.15)
|
|
||||||
implicitHeight: topBar.topBarHeight - (topBarRow.topBarRowPadding * 2)
|
|
||||||
implicitWidth: topBar.topBarHeight - (topBarRow.topBarRowPadding * 2)
|
|
||||||
radius: 6
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "hovered"
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
scanButton.color: Colors.green
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
border {
|
|
||||||
color: Colors.surface0
|
|
||||||
width: 2
|
|
||||||
}
|
|
||||||
|
|
||||||
HoverHandler {
|
|
||||||
onHoveredChanged: hovered == true ? scanButton.state = "hovered" : scanButton.state = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: {
|
|
||||||
BluetoothManager.toggleDiscover();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
id: scanButtonText
|
|
||||||
|
|
||||||
text: ""
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
id: animateRotation
|
|
||||||
|
|
||||||
duration: 1000
|
|
||||||
from: 0
|
|
||||||
loops: Animation.Infinite
|
|
||||||
properties: "rotation"
|
|
||||||
running: BluetoothManager.defaultAdapter.discovering
|
|
||||||
target: scanButtonText
|
|
||||||
to: 360
|
|
||||||
|
|
||||||
onStopped: {
|
|
||||||
scanButton.rotation = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
|
||||||
clip: true
|
|
||||||
model: BluetoothManager.getDevicesList()
|
|
||||||
spacing: 5
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
id: deviceRoot
|
|
||||||
|
|
||||||
required property real index
|
|
||||||
required property BluetoothDevice modelData
|
|
||||||
|
|
||||||
height: 55
|
|
||||||
width: ListView.view.width
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: containerBox
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
clip: true
|
|
||||||
color: Colors.peach
|
|
||||||
radius: 7
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: Colors.green
|
|
||||||
implicitHeight: parent.height - 10
|
|
||||||
implicitWidth: parent.width * (deviceRoot.modelData.batteryAvailable == true
|
|
||||||
? deviceRoot.modelData.battery : 0) - 10
|
|
||||||
opacity: 0.7
|
|
||||||
radius: 7
|
|
||||||
visible: deviceRoot.modelData.batteryAvailable == true
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 4
|
|
||||||
fill: parent
|
|
||||||
leftMargin: 4
|
|
||||||
rightMargin: 4
|
|
||||||
topMargin: 4
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
color: deviceRoot.modelData.connected ? Colors.green : Qt.lighter(Colors.peach, 1.25)
|
|
||||||
radius: 5
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
color: Colors.surface0
|
|
||||||
font.pointSize: 30
|
|
||||||
text: BluetoothManager.getIcon(deviceRoot.modelData.icon)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: Qt.lighter(Colors.peach, 1.15)
|
|
||||||
radius: 4
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
elide: Qt.ElideRight
|
|
||||||
text: deviceRoot.modelData.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: Colors.surface2
|
|
||||||
font.weight: 300
|
|
||||||
text: deviceRoot.modelData.address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: itemEntry
|
|
||||||
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: Colors.red
|
|
||||||
radius: 3
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: deleteButtonLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: forgetButton
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: deviceRoot.modelData.connected == false
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
deleteButtonLoader.sourceComponent: forgetButton
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "connected"
|
|
||||||
when: deviceRoot.modelData.connected == true
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
deleteButtonLoader.sourceComponent: disconnectButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: disconnectButton
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: deviceRoot.modelData.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
text: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: forgetButton
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: deviceRoot.modelData.forget()
|
|
||||||
}
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
text: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: greenButton
|
|
||||||
|
|
||||||
property Component loadedItem: connectButton
|
|
||||||
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: Colors.green
|
|
||||||
radius: 3
|
|
||||||
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: ""
|
|
||||||
when: deviceRoot.modelData.paired == true
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
greenButton.color: Colors.green
|
|
||||||
greenButton.loadedItem: connectButton
|
|
||||||
}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "unpaired"
|
|
||||||
when: deviceRoot.modelData.paired == false
|
|
||||||
|
|
||||||
PropertyChanges {
|
|
||||||
greenButton.color: Colors.blue
|
|
||||||
greenButton.loadedItem: pairButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: greenButton.loadedItem
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: connectButton
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: deviceRoot.modelData.connect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: pairButton
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
CenteredText {
|
|
||||||
text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
TapHandler {
|
|
||||||
onTapped: {
|
|
||||||
deviceRoot.modelData.pair();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
bottomMargin: 5
|
|
||||||
fill: parent
|
|
||||||
leftMargin: 5
|
|
||||||
rightMargin: 5
|
|
||||||
topMargin: 10 + root.topBarHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
337
Bar/Time.qml
Normal file
337
Bar/Time.qml
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import Quickshell.Widgets
|
||||||
|
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
import "../Components/"
|
||||||
|
import "../Services/"
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property Notification latestNotif
|
||||||
|
required property HyprlandMonitor monitor
|
||||||
|
property bool mpris: false
|
||||||
|
property double mprisHeight: 60
|
||||||
|
property double mprisWidth: 350
|
||||||
|
property double notificationHeight: 100
|
||||||
|
property double notificationWidth: 350
|
||||||
|
property bool notified: false
|
||||||
|
property bool overriden: false
|
||||||
|
|
||||||
|
boxColor: Colors.mauve
|
||||||
|
defaultItem: time
|
||||||
|
exclusiveMonitor: root.monitor
|
||||||
|
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
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
root.boxHeight: root.notificationHeight
|
||||||
|
root.boxRadius: 12
|
||||||
|
root.boxWidth: root.notificationWidth
|
||||||
|
root.visibleTopMargin: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
StateChangeScript {
|
||||||
|
script: {
|
||||||
|
root.stack.replace(notification);
|
||||||
|
notificationTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "mpris"
|
||||||
|
when: root.mpris == true
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
root.boxHeight: root.mprisHeight
|
||||||
|
root.boxRadius: 12
|
||||||
|
root.boxWidth: root.mprisWidth
|
||||||
|
root.visibleTopMargin: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
StateChangeScript {
|
||||||
|
script: {
|
||||||
|
root.stack.replace(mprisToast);
|
||||||
|
mprisTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onNewNotification() {
|
||||||
|
notification => {
|
||||||
|
if (notification.lastGeneration == false) {
|
||||||
|
root.latestNotif = notification;
|
||||||
|
root.overriden = true;
|
||||||
|
root.notified = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
target: NotificationManager
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onTrackChanged() {
|
||||||
|
root.overriden = true;
|
||||||
|
root.mpris = true;
|
||||||
|
console.log("track changed");
|
||||||
|
}
|
||||||
|
|
||||||
|
target: MprisManager.defaultPlayer
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: notificationTimer
|
||||||
|
|
||||||
|
interval: 2000
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root.notified = false;
|
||||||
|
root.overriden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: mprisTimer
|
||||||
|
|
||||||
|
interval: 3000
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root.mpris = false;
|
||||||
|
root.overriden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: time
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
property string component: "time"
|
||||||
|
|
||||||
|
horizontalAlignment: Qt.AlignCenter
|
||||||
|
text: Time.time
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: notification
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: notificationRoot
|
||||||
|
|
||||||
|
property double innerMargin: 5
|
||||||
|
property double outerMargin: 6
|
||||||
|
|
||||||
|
function getInnerHeight() {
|
||||||
|
let fullHeight = root.notificationHeight;
|
||||||
|
let fullMargin = notificationRoot.innerMargin + notificationRoot.outerMargin;
|
||||||
|
|
||||||
|
return fullHeight - (fullMargin * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: Colors.surface1
|
||||||
|
radius: 9
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: notificationRoot.outerMargin
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Rectangle {
|
||||||
|
Layout.margins: notificationRoot.innerMargin
|
||||||
|
color: Colors.mauve
|
||||||
|
implicitHeight: notificationRoot.getInnerHeight()
|
||||||
|
implicitWidth: notificationRoot.getInnerHeight()
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
source: root.latestNotif.image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property double textMargin: 4
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 0
|
||||||
|
Layout.margins: notificationRoot.innerMargin + textMargin
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
color: Colors.text
|
||||||
|
fontSize: 14
|
||||||
|
text: root.latestNotif.summary
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.maximumWidth: root.notificationWidth - ((notificationRoot.outerMargin * 2) + (
|
||||||
|
notificationRoot.innerMargin * 3) + notificationRoot.getInnerHeight())
|
||||||
|
color: Colors.subtext0
|
||||||
|
elide: Qt.ElideRight
|
||||||
|
fontWeight: 5
|
||||||
|
maximumLineCount: 2
|
||||||
|
text: root.latestNotif.body
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: mprisToast
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: mprisToastRoot
|
||||||
|
|
||||||
|
property double innerMargin: 4
|
||||||
|
property double outerMargin: 4
|
||||||
|
property var trackInfo: MprisManager.getTrackInfo()
|
||||||
|
|
||||||
|
function getInnerHeight() {
|
||||||
|
let fullHeight = root.mprisHeight;
|
||||||
|
let fullMargin = mprisToastRoot.innerMargin + mprisToastRoot.outerMargin;
|
||||||
|
|
||||||
|
return fullHeight - (fullMargin * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: Colors.surface1
|
||||||
|
radius: 9
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: mprisToastRoot.outerMargin
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Rectangle {
|
||||||
|
Layout.margins: mprisToastRoot.innerMargin
|
||||||
|
color: Colors.mauve
|
||||||
|
implicitHeight: mprisToastRoot.getInnerHeight()
|
||||||
|
implicitWidth: mprisToastRoot.getInnerHeight()
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: mprisToastRoot.trackInfo["albumArt"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property double textMargin: 1
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 0
|
||||||
|
Layout.margins: mprisToastRoot.innerMargin + textMargin
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.maximumWidth: root.mprisWidth - ((mprisToastRoot.outerMargin * 2) + (
|
||||||
|
mprisToastRoot.innerMargin * 5) + mprisToastRoot.getInnerHeight())
|
||||||
|
color: Colors.text
|
||||||
|
fontSize: 14
|
||||||
|
text: mprisToastRoot.trackInfo["name"] + " - " + mprisToastRoot.trackInfo["artist"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: root.mprisWidth - ((mprisToastRoot.outerMargin * 2) + (
|
||||||
|
mprisToastRoot.innerMargin * 5) + mprisToastRoot.getInnerHeight())
|
||||||
|
Layout.preferredWidth: root.mprisWidth - ((mprisToastRoot.outerMargin * 2) + (
|
||||||
|
mprisToastRoot.innerMargin * 5) + mprisToastRoot.getInnerHeight())
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Colors.overlay0
|
||||||
|
radius: 100
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: Colors.mauve
|
||||||
|
implicitWidth: parent.width * mprisToastRoot.trackInfo["lengthPercent"]
|
||||||
|
radius: 100
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: MprisManager.getTimeString()
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
108
Bar/WorkspaceSelector.qml
Normal file
108
Bar/WorkspaceSelector.qml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
import "../Components/"
|
||||||
|
import "../Services/"
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property double barHeight: 25
|
||||||
|
required property HyprlandMonitor monitor
|
||||||
|
property double rowLeftMargin: 5
|
||||||
|
property double workspaceButtonSpacing: 4
|
||||||
|
property double workspaceCount: WorkspaceManager.getNumberOfWorkspaces(monitor)
|
||||||
|
property double workspaceWidth: 17
|
||||||
|
|
||||||
|
boxHeight: barHeight
|
||||||
|
boxRadius: 8
|
||||||
|
boxWidth: (2 * rowLeftMargin) + (workspaceCount * workspaceWidth) + ((workspaceCount - 1)
|
||||||
|
* workspaceButtonSpacing)
|
||||||
|
defaultItem: placeholder
|
||||||
|
exclusiveMonitor: monitor
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "hovered"
|
||||||
|
when: root.hovered
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
root.barHeight: 30
|
||||||
|
root.workspaceWidth: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: placeholder
|
||||||
|
|
||||||
|
Item {}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: root.workspaceButtonSpacing
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: root.rowLeftMargin
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
delegate: workspaceButton
|
||||||
|
delegateModelAccess: DelegateModel.ReadOnly
|
||||||
|
model: WorkspaceManager.getWorkspacesForMonitor(root.exclusiveMonitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: workspaceButton
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: buttonRoot
|
||||||
|
|
||||||
|
required property var modelData
|
||||||
|
property double stateInt: WorkspaceManager.getWorkspaceStateIndex(modelData)
|
||||||
|
property variant workspaceColors: [Colors.lavender, Colors.overlay2, Colors.surface2]
|
||||||
|
property string workspaceId: modelData.id
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
implicitHeight: root.barHeight - 7
|
||||||
|
implicitWidth: root.workspaceWidth
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
SpringAnimation {
|
||||||
|
damping: 0.3
|
||||||
|
spring: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
SpringAnimation {
|
||||||
|
damping: 0.3
|
||||||
|
spring: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
id: tapHandler
|
||||||
|
|
||||||
|
onTapped: WorkspaceManager.activateWorkspaceById(buttonRoot.modelData.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: buttonRoot.workspaceColors[buttonRoot.stateInt]
|
||||||
|
radius: 4
|
||||||
|
|
||||||
|
CenteredText {
|
||||||
|
text: buttonRoot.modelData.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ import "../Color.js" as Colors
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool _fullyHidden: false
|
||||||
|
property bool _widthCollapsed: false
|
||||||
property double animOffset: 0
|
property double animOffset: 0
|
||||||
property color boxColor: Colors.surface0
|
property color boxColor: Colors.surface0
|
||||||
property double boxHeight: 28
|
property double boxHeight: 28
|
||||||
@@ -35,13 +37,15 @@ Item {
|
|||||||
property bool forceHidden: false
|
property bool forceHidden: false
|
||||||
property alias hover: hoverHandler
|
property alias hover: hoverHandler
|
||||||
property bool hoverableWhenHidden: false
|
property bool hoverableWhenHidden: false
|
||||||
|
property bool hovered: false
|
||||||
property alias rect: container
|
property alias rect: container
|
||||||
property alias stack: containerContent
|
property alias stack: containerContent
|
||||||
property alias tap: tapHandler
|
property alias tap: tapHandler
|
||||||
property double visibleTopMargin: 0
|
property double visibleTopMargin: 0
|
||||||
|
|
||||||
implicitHeight: boxHeight
|
implicitHeight: boxHeight
|
||||||
implicitWidth: boxWidth
|
implicitWidth: root._widthCollapsed ? 0 : root.boxWidth
|
||||||
|
visible: !root._fullyHidden
|
||||||
|
|
||||||
Behavior on anchors.topMargin {
|
Behavior on anchors.topMargin {
|
||||||
animation: defaultCurve
|
animation: defaultCurve
|
||||||
@@ -58,13 +62,49 @@ Item {
|
|||||||
spring: 4
|
spring: 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Behavior on boxWidth {
|
Behavior on implicitWidth {
|
||||||
SpringAnimation {
|
SpringAnimation {
|
||||||
damping: 0.3
|
damping: 0.3
|
||||||
spring: 4
|
spring: 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onForceHiddenChanged: {
|
||||||
|
if (root.forceHidden == true) {
|
||||||
|
hideTimer.restart();
|
||||||
|
} else {
|
||||||
|
hideTimer.stop();
|
||||||
|
subHideTimer.stop();
|
||||||
|
root._fullyHidden = false;
|
||||||
|
root._widthCollapsed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: hideTimer
|
||||||
|
|
||||||
|
interval: 250
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root._widthCollapsed = true;
|
||||||
|
subHideTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: subHideTimer
|
||||||
|
|
||||||
|
interval: 200
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root._fullyHidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
topMargin: calculatedTopMargin
|
topMargin: calculatedTopMargin
|
||||||
@@ -79,22 +119,20 @@ Item {
|
|||||||
|
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
id: hoverHandler
|
id: hoverHandler
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hoverHandler.hovered == true) {
|
||||||
|
root.hovered = true;
|
||||||
|
} else {
|
||||||
|
root.hovered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
id: tapHandler
|
id: tapHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
RectangularShadow {
|
|
||||||
anchors.fill: container
|
|
||||||
blur: 30
|
|
||||||
color: Colors.mantle
|
|
||||||
offset.x: 7
|
|
||||||
offset.y: 3
|
|
||||||
radius: container.radius
|
|
||||||
spread: 10
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: container
|
id: container
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,62 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Shapes
|
||||||
|
|
||||||
Gradient {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property color color
|
property real angle: 0 // Degrees; 0 = transparent left, colour right
|
||||||
property double midpoint: 0.6
|
readonly property real angleRadians: angle * Math.PI / 180.0
|
||||||
|
property real blur: 0.0 // 0 = sharp, 1 = very soft
|
||||||
|
|
||||||
|
// Public API
|
||||||
|
property color color: "#4da3ffff"
|
||||||
|
|
||||||
|
// Half the diagonal ensures the gradient covers the entire item.
|
||||||
|
readonly property real gradientRadius: Math.sqrt(width * width + height * height) / 2.0
|
||||||
|
property real midpoint: 0.5 // 0..1
|
||||||
|
property double radius: 10
|
||||||
|
readonly property real safeBlur: Math.max(blur, 0.00001)
|
||||||
|
readonly property real safeMidpoint: clamp01(midpoint)
|
||||||
|
readonly property real transitionEnd: clamp01(safeMidpoint + safeBlur / 2.0)
|
||||||
|
readonly property real transitionStart: clamp01(safeMidpoint - safeBlur / 2.0)
|
||||||
|
readonly property color transparentColor: Qt.rgba(color.r, color.g, color.b, 0.0)
|
||||||
|
|
||||||
|
function clamp01(value) {
|
||||||
|
return Math.max(0.0, Math.min(1.0, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape {
|
||||||
|
anchors.fill: parent
|
||||||
|
preferredRendererType: Shape.CurveRenderer
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
strokeWidth: -1
|
||||||
|
|
||||||
|
fillGradient: LinearGradient {
|
||||||
|
x1: root.width / 2.0 - root.gradientRadius * Math.cos(root.angleRadians)
|
||||||
|
x2: root.width / 2.0 + root.gradientRadius * Math.cos(root.angleRadians)
|
||||||
|
y1: root.height / 2.0 - root.gradientRadius * Math.sin(root.angleRadians)
|
||||||
|
y2: root.height / 2.0 + root.gradientRadius * Math.sin(root.angleRadians)
|
||||||
|
|
||||||
GradientStop {
|
GradientStop {
|
||||||
color: "transparent"
|
color: root.transparentColor
|
||||||
position: 0.0
|
position: 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
GradientStop {
|
GradientStop {
|
||||||
color: "transparent"
|
color: root.transparentColor
|
||||||
position: root.midpoint
|
position: root.transitionStart
|
||||||
|
}
|
||||||
|
|
||||||
|
GradientStop {
|
||||||
|
color: root.color
|
||||||
|
position: root.transitionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
GradientStop {
|
GradientStop {
|
||||||
@@ -21,3 +64,12 @@ Gradient {
|
|||||||
position: 1.0
|
position: 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PathRectangle {
|
||||||
|
height: root.height
|
||||||
|
radius: Math.min(root.radius, Math.min(width, height) / 2.0)
|
||||||
|
width: root.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,12 +2,18 @@ import QtQuick
|
|||||||
import "../Color.js" as Colors
|
import "../Color.js" as Colors
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property double fontSize: 12
|
||||||
|
property double fontWeight: 8
|
||||||
|
property bool propo: false
|
||||||
|
|
||||||
color: Colors.base
|
color: Colors.base
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
|
||||||
font {
|
font {
|
||||||
family: "FiraMono Nerd Font"
|
family: root.propo == true ? "FiraMono Nerd Font Propo" : "FiraMono Nerd Font"
|
||||||
pointSize: 12
|
pointSize: fontSize
|
||||||
weight: 800
|
weight: root.fontWeight * 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,160 @@ import QtQuick
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
|
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property UPowerDevice battery: Upower.displayDevice
|
property double batteryPercentage: root.mainBattery.percentage || 0
|
||||||
property bool batteryInUse: root.batteryPresent && root.batteryLaptop
|
property bool batteryPresent: root.mainBattery.ready || false
|
||||||
property bool batteryLaptop: root.battery.isLaptopBattery
|
property UPowerDevice mainBattery: UPower.displayDevice || undefined
|
||||||
property double batteryPercentage: root.battery.percentage
|
property bool hasLaptopBattery: root.mainBattery && root.mainBattery.isLaptopBattery
|
||||||
property bool batteryPresent: root.battery.ready
|
|
||||||
|
|
||||||
function getBatteryIcon() {
|
|
||||||
let battery = root.battery;
|
|
||||||
if (battery.state = UpowerDeviceState.Charging) {
|
function getBatteryColor() {
|
||||||
|
let criticalLevel = 20;
|
||||||
|
let batteryPercentage = getBatteryPercentage(mainBattery);
|
||||||
|
|
||||||
|
if (mainBattery.state == UPowerDeviceState.FullyCharged) {
|
||||||
|
return Colors.sky;
|
||||||
|
} else if (mainBattery.state == UPowerDeviceState.Charging) {
|
||||||
|
return Colors.mauve;
|
||||||
|
} else if (mainBattery.state == UPowerDeviceState.PendingCharge | mainBattery.state
|
||||||
|
== UPowerDeviceState.PendingDischarge) {
|
||||||
|
return Colors.peach;
|
||||||
|
} else if (batteryPercentage <= criticalLevel) {
|
||||||
|
return Colors.red;
|
||||||
|
} else {
|
||||||
|
return Colors.green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBatteryIcon(battery) {
|
||||||
|
if (battery.state == UPowerDeviceState.Charging) {
|
||||||
return "";
|
return "";
|
||||||
}
|
} else if (battery.state == UPowerDeviceState.PendingCharge | battery.state
|
||||||
if (battery.state = UpowerDeviceState.Discharging) {
|
== UPowerDeviceState.PendingDischarge) {
|
||||||
|
return "";
|
||||||
|
} else if (battery.state == UPowerDeviceState.Discharging | battery.state
|
||||||
|
== UPowerDeviceState.FullyCharged) {
|
||||||
|
let iconArr = ["", "", "", "", "", "", "", "", "", ""];
|
||||||
|
let batteryCharge = battery.percentage;
|
||||||
|
let chargeIndex = Math.ceil(batteryCharge * iconArr.length) - 1;
|
||||||
|
return iconArr[chargeIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBatteryName(battery) {
|
||||||
|
let pathsplit = battery.nativePath.split("/");
|
||||||
|
let batteryName = pathsplit[pathsplit.length];
|
||||||
|
return pathsplit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBatteryPercentage(battery) {
|
||||||
|
return battery.percentage * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBatteryText() {
|
||||||
|
let icon = getBatteryIcon(mainBattery);
|
||||||
|
let percentage = getBatteryPercentage(mainBattery);
|
||||||
|
return icon + " " + percentage + "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChargingRateFormat() {
|
||||||
|
let rate = mainBattery.changeRate.toFixed(1);
|
||||||
|
|
||||||
|
let finalString = "harging at " + rate + "W";
|
||||||
|
if (rate == 0) {
|
||||||
|
finalString = "Battery Idle";
|
||||||
|
} else if (rate <= 0 || mainBattery.state == UPowerDeviceState.Charging) {
|
||||||
|
finalString = "C" + finalString;
|
||||||
|
} else {
|
||||||
|
finalString = "Disc" + finalString;
|
||||||
|
}
|
||||||
|
return finalString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMainBatteryInfo() {
|
||||||
|
let battery = UPower.devices.values[0];
|
||||||
|
let batteryState = battery.state;
|
||||||
|
let batteryName = getBatteryName(battery);
|
||||||
|
let time = getTimeFormat();
|
||||||
|
return {
|
||||||
|
"name": batteryName,
|
||||||
|
"charge": battery.percentage,
|
||||||
|
"energy": battery.energy.toFixed(1),
|
||||||
|
"capacity": battery.energyCapacity.toFixed(1),
|
||||||
|
"health": battery.healthPercentage
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimeFormat() {
|
||||||
|
let state = mainBattery.state;
|
||||||
|
let finalString = "";
|
||||||
|
if (state == UPowerDeviceState.FullyCharged) {
|
||||||
|
finalString += "Battery Full";
|
||||||
|
} else if (state == UPowerDeviceState.Charging) {
|
||||||
|
let time = mainBattery.timeToFull;
|
||||||
|
if (time == 0) {
|
||||||
|
return "Getting Time...";
|
||||||
|
} else {
|
||||||
|
let timeArr = secondsToTime(time);
|
||||||
|
// If more than 1 hour
|
||||||
|
if (timeArr.hours >= 1 || timeArr.hourNeedsIncrement == 1) {
|
||||||
|
finalString += timeArr.Hours + " Hours ";
|
||||||
|
// If minutes not 0
|
||||||
|
if (timeArr.minutesRounded > 1) {
|
||||||
|
finalString += timeArr.minutesRounded + " Minutes";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
finalString += timeArr.minutes + " Minutes ";
|
||||||
|
finalString += timeArr.seconds + " Seconds";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalString += " Until Full";
|
||||||
|
} else if (state == UPowerDeviceState.Discharging) {
|
||||||
|
let time = mainBattery.timeToEmpty;
|
||||||
|
if (time == 0) {
|
||||||
|
return "Getting Time...";
|
||||||
|
} else {
|
||||||
|
let timeArr = secondsToTime(time);
|
||||||
|
// If more than 1 hour
|
||||||
|
if (timeArr.hours >= 1 || timeArr.hourNeedsIncrement == 1) {
|
||||||
|
finalString += timeArr.hours + " Hours ";
|
||||||
|
// If minutes not 0
|
||||||
|
if (timeArr.minutesRounded > 1) {
|
||||||
|
finalString += timeArr.minutesRounded + " Minutes";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
finalString += timeArr.minutes + " Minutes ";
|
||||||
|
finalString += timeArr.seconds + " Seconds";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finalString += " Remaining";
|
||||||
|
} else {
|
||||||
|
finalString += "Getting Time...";
|
||||||
|
}
|
||||||
|
return finalString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function secondsToTime(totalSeconds) {
|
||||||
|
totalSeconds = Math.max(0, Number(totalSeconds));
|
||||||
|
|
||||||
|
const hours = Math.floor(totalSeconds / 3600);
|
||||||
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
const seconds = Math.floor(totalSeconds % 60);
|
||||||
|
|
||||||
|
const roundedMinutes = minutes + (seconds >= 30 ? 1 : 0);
|
||||||
|
const hourNeedsIncrement = roundedMinutes === 60;
|
||||||
|
|
||||||
|
return {
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
minutesRounded: hourNeedsIncrement ? 0 : roundedMinutes,
|
||||||
|
hourNeedsIncrement
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,21 +6,59 @@ import Quickshell.Bluetooth
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property BluetoothAdapter defaultAdapter: Bluetooth.defaultAdapter
|
property BluetoothAdapter defaultAdapter: Bluetooth.defaultAdapter || null
|
||||||
property string defaultAdapterName: Bluetooth.defaultAdapter.adapterId
|
property string defaultAdapterName: defaultAdapter ? defaultAdapter.adapterId : ""
|
||||||
|
|
||||||
|
property bool anyConnected: root.defaultAdapter != null
|
||||||
|
&& root.defaultAdapter.devices.values.some(device => device.connected)
|
||||||
|
|
||||||
function getConnected() {
|
function getConnected() {
|
||||||
let deviceList = getDevicesList();
|
return root.anyConnected;
|
||||||
for (let device in deviceList) {
|
}
|
||||||
let currentDevice = deviceList[device];
|
|
||||||
if (currentDevice.connected == true) {
|
function getConnectedDevicesList() {
|
||||||
return true;
|
let devicesList = getDevicesList();
|
||||||
|
if (!devicesList) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
let connectedList = [];
|
||||||
|
for (let device of devicesList) {
|
||||||
|
if (device.connected == true) {
|
||||||
|
connectedList.push(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return connectedList;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDeviceText(device) {
|
||||||
|
if (!device) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let deviceName = device.deviceName;
|
||||||
|
let deviceIcon = getIcon(device.icon);
|
||||||
|
let deviceMac = device.address;
|
||||||
|
let hasBattery = device.batteryAvailable;
|
||||||
|
let deviceBattery = deviceIcon;
|
||||||
|
let deviceBatteryRaw = 0;
|
||||||
|
if (hasBattery) {
|
||||||
|
deviceBattery = device.battery * 100;
|
||||||
|
deviceBatteryRaw = device.battery;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"icon": deviceIcon,
|
||||||
|
"name": deviceName,
|
||||||
|
"mac": deviceMac,
|
||||||
|
"hasBattery": hasBattery,
|
||||||
|
"battery": deviceBattery,
|
||||||
|
"batteryRaw": deviceBatteryRaw
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDevicesList() {
|
function getDevicesList() {
|
||||||
|
if (!root.defaultAdapter) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return root.defaultAdapter.devices.values;
|
return root.defaultAdapter.devices.values;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,29 +79,4 @@ Singleton {
|
|||||||
|
|
||||||
return icons[name] || "";
|
return icons[name] || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function pairTrustConnect(device) {
|
|
||||||
device.pair();
|
|
||||||
device.trusted = true;
|
|
||||||
device.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleDiscover() {
|
|
||||||
if (defaultAdapter.discovering == true) {
|
|
||||||
defaultAdapter.discovering = false;
|
|
||||||
} else {
|
|
||||||
defaultAdapter.discovering = true;
|
|
||||||
discoveringTimeout.running = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: discoveringTimeout
|
|
||||||
|
|
||||||
interval: 15000
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onTriggered: defaultAdapter.discovering = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import Quickshell.Services.Mpris
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property MprisPlayer defaultPlayer: Mpris.players.values[0]
|
property MprisPlayer defaultPlayer: Mpris.players.values[0] || null
|
||||||
property real pos: defaultPlayer.position / defaultPlayer.length
|
|
||||||
|
|
||||||
function getPlaying() {
|
function getPlaying() {
|
||||||
if (!defaultPlayer) {
|
if (!defaultPlayer) {
|
||||||
@@ -17,6 +16,55 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTimeString() {
|
||||||
|
let trackInfo = getTrackInfo();
|
||||||
|
let position = trackInfo["position"];
|
||||||
|
let length = trackInfo["length"];
|
||||||
|
if (length.hours > 0) {
|
||||||
|
return position.hours + ":" + position.minutes + ":" + position.seconds + "/" + length.hours
|
||||||
|
+ ":" + length.minutes + ":" + length.seconds;
|
||||||
|
} else {
|
||||||
|
return position.minutes + ":" + position.seconds + "/" + length.minutes + ":" + length.seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTrackInfo() {
|
||||||
|
let trackName = root.defaultPlayer.trackTitle;
|
||||||
|
let trackArtist = root.defaultPlayer.trackArtist;
|
||||||
|
let trackAlbum = root.defaultPlayer.trackAlbum;
|
||||||
|
let trackPosition = root.defaultPlayer.position;
|
||||||
|
let trackLength = root.defaultPlayer.length;
|
||||||
|
let trackArt = root.defaultPlayer.trackArtUrl;
|
||||||
|
return {
|
||||||
|
"name": trackName,
|
||||||
|
"artist": trackArtist,
|
||||||
|
"album": trackAlbum,
|
||||||
|
"position": msToArray(trackPosition),
|
||||||
|
"length": msToArray(trackLength),
|
||||||
|
"lengthRemaining": msToArray(trackLength - trackPosition),
|
||||||
|
"lengthPercent": trackPosition / trackLength,
|
||||||
|
"albumArt": trackArt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function msToArray(time) {
|
||||||
|
time = Math.max(0, Number(time));
|
||||||
|
|
||||||
|
const inthours = Math.floor(time / 3600000);
|
||||||
|
const intminutes = Math.floor((time % 60000) / 60);
|
||||||
|
const intseconds = Math.floor((time % 1000) % 60);
|
||||||
|
|
||||||
|
const hours = String(inthours).padStart(2, "0");
|
||||||
|
const minutes = String(intminutes).padStart(2, "0");
|
||||||
|
const seconds = String(intseconds).padStart(2, "0");
|
||||||
|
|
||||||
|
return {
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function prev() {
|
function prev() {
|
||||||
defaultPlayer.previous();
|
defaultPlayer.previous();
|
||||||
}
|
}
|
||||||
|
|||||||
99
Services/NetworkManager.qml
Normal file
99
Services/NetworkManager.qml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
pragma Singleton
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Networking
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool connectedWifi: root.defaultAdapter != null && root.defaultAdapter.connected
|
||||||
|
&& root.defaultAdapter.type == DeviceType.Wifi
|
||||||
|
property NetworkDevice defaultAdapter: Networking.devices.values[0] || null
|
||||||
|
|
||||||
|
function getConnectedNetworks(networksArr) {
|
||||||
|
let connectedNetworks = [];
|
||||||
|
|
||||||
|
for (let network of networksArr) {
|
||||||
|
if (network.state == ConnectionState.Connected) {
|
||||||
|
connectedNetworks.push(network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return connectedNetworks;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNetworkDetails(adapter) {
|
||||||
|
if (!adapter) {
|
||||||
|
return {
|
||||||
|
"adapterName": "",
|
||||||
|
"adapterConnected": false,
|
||||||
|
"adapterIsWifi": false,
|
||||||
|
"networkName": "",
|
||||||
|
"networkStrength": 0,
|
||||||
|
"icon": ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let networksArr = adapter.networks.values;
|
||||||
|
let connectedNetworks = getConnectedNetworks(networksArr);
|
||||||
|
let deviceWifi = isDeviceWifi(adapter);
|
||||||
|
|
||||||
|
let primaryNetwork = connectedNetworks[0];
|
||||||
|
if (!primaryNetwork) {
|
||||||
|
return {
|
||||||
|
"adapterName": adapter.name,
|
||||||
|
"adapterConnected": adapter.connected,
|
||||||
|
"adapterIsWifi": deviceWifi,
|
||||||
|
"networkName": "No Network",
|
||||||
|
"networkStrength": 0,
|
||||||
|
"icon": ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let networkName = primaryNetwork.name;
|
||||||
|
let networkStrength = primaryNetwork.signalStrength;
|
||||||
|
|
||||||
|
let networkIcon = getWifiIcon(networkStrength);
|
||||||
|
|
||||||
|
let outputDict = {
|
||||||
|
"adapterName": adapter.name,
|
||||||
|
"adapterConnected": adapter.connected,
|
||||||
|
"adapterIsWifi": deviceWifi,
|
||||||
|
"networkName": networkName,
|
||||||
|
"networkStrength": networkStrength,
|
||||||
|
"icon": networkIcon,
|
||||||
|
"saved": primaryNetwork.known
|
||||||
|
};
|
||||||
|
return outputDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWifiIcon(strength) {
|
||||||
|
let iconArr = ["", "", "", ""];
|
||||||
|
let strengthIndex = Math.ceil(strength * iconArr.length);
|
||||||
|
return iconArr[strengthIndex - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWifiText() {
|
||||||
|
let info = getNetworkDetails(defaultAdapter);
|
||||||
|
|
||||||
|
let adapter = info["adapterName"];
|
||||||
|
let name = info["networkName"];
|
||||||
|
|
||||||
|
let finalString = adapter + " - " + name;
|
||||||
|
return finalString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConnectedAndWifi() {
|
||||||
|
return root.connectedWifi;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDeviceWifi(adapter) {
|
||||||
|
if (adapter.type == DeviceType.Wifi) {
|
||||||
|
return true;
|
||||||
|
} else if (adapter.type == DeviceType.Wired) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
console.log(adapter.type);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,15 @@ pragma Singleton
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
|
import "../Color.js" as Colors
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property alias notif: server
|
property alias notif: server
|
||||||
|
|
||||||
|
signal newNotification(notificiation: Notification)
|
||||||
|
|
||||||
function getLatestNotification() {
|
function getLatestNotification() {
|
||||||
let notificationList = server.trackedNotifications.values;
|
let notificationList = server.trackedNotifications.values;
|
||||||
let len = notificationList.length;
|
let len = notificationList.length;
|
||||||
@@ -24,9 +27,11 @@ Singleton {
|
|||||||
actionsSupported: true
|
actionsSupported: true
|
||||||
bodyMarkupSupported: true
|
bodyMarkupSupported: true
|
||||||
bodySupported: true
|
bodySupported: true
|
||||||
|
imageSupported: true
|
||||||
|
|
||||||
onNotification: notification => {
|
onNotification: notification => {
|
||||||
notification.tracked = true;
|
notification.tracked = true;
|
||||||
|
root.newNotification(notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,17 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getWorkspaceStateIndex(workspace) {
|
||||||
|
let state = getWorkspaceState(workspace);
|
||||||
|
if (state == "focused") {
|
||||||
|
return 0;
|
||||||
|
} else if (state == "active") {
|
||||||
|
return 1;
|
||||||
|
} else if (state == "inactive") {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getWorkspacesForMonitor(monitor) {
|
function getWorkspacesForMonitor(monitor) {
|
||||||
let allWorkspaces = getAllNumberedWorkspaces();
|
let allWorkspaces = getAllNumberedWorkspaces();
|
||||||
let monitorWorkspaces = [];
|
let monitorWorkspaces = [];
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ singleton WorkspaceManager 1.0 WorkspaceManager.qml
|
|||||||
singleton BluetoothManager 1.0 BluetoothManager.qml
|
singleton BluetoothManager 1.0 BluetoothManager.qml
|
||||||
singleton MprisManager 1.0 MprisManager.qml
|
singleton MprisManager 1.0 MprisManager.qml
|
||||||
singleton BatteryManager 1.0 BatteryManager.qml
|
singleton BatteryManager 1.0 BatteryManager.qml
|
||||||
|
singleton NetworkManager 1.0 NetworkManager.qml
|
||||||
|
|||||||
Reference in New Issue
Block a user