working mpris and bluetooth menu
This commit is contained in:
4
Bar.qml
4
Bar.qml
@@ -89,6 +89,10 @@ Scope {
|
|||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: 7
|
rightMargin: 7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Right {
|
||||||
|
monitor: win.monitor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import QtQuick
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
|
import Quickshell.Services.Mpris
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
import "../Color.js" as Colors
|
import "../Color.js" as Colors
|
||||||
import "../Components/"
|
import "../Components/"
|
||||||
@@ -49,15 +50,20 @@ Container {
|
|||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
root.boxHeight: 35
|
root.boxHeight: 35
|
||||||
root.boxRadius: 15
|
root.boxRadius: 15
|
||||||
root.boxWidth: 110
|
root.boxWidth: MprisManager.getPlaying() == true ? 350 : 110
|
||||||
root.visibleTopMargin: 0
|
root.visibleTopMargin: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
StateChangeScript {
|
StateChangeScript {
|
||||||
script: {
|
script: {
|
||||||
|
if (MprisManager.getPlaying()) {
|
||||||
|
root.previousState = "mpris";
|
||||||
|
root.stack.replace(mpris);
|
||||||
|
} else {
|
||||||
root.previousState = "hovered";
|
root.previousState = "hovered";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "expanded"
|
name: "expanded"
|
||||||
@@ -121,6 +127,17 @@ Container {
|
|||||||
root.state == "hovered" ? root.state = "expanded" : undefined;
|
root.state == "hovered" ? root.state = "expanded" : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onTrackChanged() {
|
||||||
|
if (Hyprland.focusedMonitor == root.monitor) {
|
||||||
|
musicToastTimer.start();
|
||||||
|
root.state = "hovered";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target: MprisManager.defaultPlayer
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: notificationViewTimer
|
id: notificationViewTimer
|
||||||
|
|
||||||
@@ -133,6 +150,18 @@ Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: musicToastTimer
|
||||||
|
|
||||||
|
interval: 2000
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root.state = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: time
|
id: time
|
||||||
|
|
||||||
@@ -143,6 +172,28 @@ Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: mpris
|
||||||
|
|
||||||
|
Mpris {
|
||||||
|
TapHandler {
|
||||||
|
onTapped: root.state = "expanded"
|
||||||
|
}
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
|
||||||
|
onTapped: MprisManager.skip()
|
||||||
|
}
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.MiddleButton
|
||||||
|
|
||||||
|
onTapped: MprisManager.prev()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: fullTime
|
id: fullTime
|
||||||
|
|
||||||
|
|||||||
62
Bar/Center/Mpris.qml
Normal file
62
Bar/Center/Mpris.qml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,8 @@ Item {
|
|||||||
required property double selectorWidth
|
required property double selectorWidth
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: newWorkspaceButton
|
||||||
|
|
||||||
implicitWidth: 20
|
implicitWidth: 20
|
||||||
opacity: root.extraHoveredWidth > 0 ? 1 : 0
|
opacity: root.extraHoveredWidth > 0 ? 1 : 0
|
||||||
|
|
||||||
@@ -45,7 +47,7 @@ Item {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Colors.red
|
color: Colors.green
|
||||||
radius: 4
|
radius: 4
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ Item {
|
|||||||
fill: parent
|
fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
CenteredText {
|
||||||
anchors.centerIn: parent
|
|
||||||
font.pointSize: 10.5
|
font.pointSize: 10.5
|
||||||
text: root.workspace.id
|
text: root.workspace.id
|
||||||
}
|
}
|
||||||
|
|||||||
21
Bar/Right.qml
Normal file
21
Bar/Right.qml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
Bluetooth {
|
||||||
|
exclusiveMonitor: root.monitor
|
||||||
|
}
|
||||||
|
}
|
||||||
72
Bar/Right/Bluetooth.qml
Normal file
72
Bar/Right/Bluetooth.qml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Bluetooth
|
||||||
|
import "../../Color.js" as Colors
|
||||||
|
import "../../Components/"
|
||||||
|
import "../../Services/"
|
||||||
|
import "Bluetooth"
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
animOffset: 200
|
||||||
|
boxColor: Colors.peach
|
||||||
|
boxHeight: 25
|
||||||
|
boxWidth: 30
|
||||||
|
defaultItem: icon
|
||||||
|
exclusiveToScreen: true
|
||||||
|
forceHidden: BluetoothManager.getConnected()
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
hover.onHoveredChanged: hover.hovered == false ? state = "" : undefined
|
||||||
|
tap.onTapped: state = "expanded"
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
Item {
|
||||||
|
CenteredText {
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: expanded
|
||||||
|
|
||||||
|
Expanded {}
|
||||||
|
}
|
||||||
|
}
|
||||||
384
Bar/Right/Bluetooth/Expanded.qml
Normal file
384
Bar/Right/Bluetooth/Expanded.qml
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,16 +7,17 @@ import Quickshell.Hyprland
|
|||||||
import "../Color.js" as Colors
|
import "../Color.js" as Colors
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: containerRoot
|
id: root
|
||||||
|
|
||||||
|
property double animOffset: 0
|
||||||
property color boxColor: Colors.surface0
|
property color boxColor: Colors.surface0
|
||||||
property double boxHeight: 28
|
property double boxHeight: 28
|
||||||
property double boxRadius: 9
|
property double boxRadius: 9
|
||||||
property double boxWidth: 100
|
property double boxWidth: 100
|
||||||
readonly property double calculatedTopMargin: {
|
readonly property double calculatedTopMargin: {
|
||||||
if (containerRoot.exclusiveToScreen) {
|
if (root.exclusiveToScreen) {
|
||||||
if (Hyprland.focusedMonitor != containerRoot.exclusiveMonitor) {
|
if (Hyprland.focusedMonitor != root.exclusiveMonitor || forceHidden == true) {
|
||||||
return -4 - containerRoot.boxHeight - 5;
|
return -4 - root.boxHeight - 5;
|
||||||
} else {
|
} else {
|
||||||
return visibleTopMargin;
|
return visibleTopMargin;
|
||||||
}
|
}
|
||||||
@@ -27,6 +28,7 @@ Item {
|
|||||||
property Component defaultItem
|
property Component defaultItem
|
||||||
required property HyprlandMonitor exclusiveMonitor
|
required property HyprlandMonitor exclusiveMonitor
|
||||||
property bool exclusiveToScreen: false
|
property bool exclusiveToScreen: false
|
||||||
|
property bool forceHidden: false
|
||||||
property alias hover: hoverHandler
|
property alias hover: hoverHandler
|
||||||
property alias rect: container
|
property alias rect: container
|
||||||
property alias stack: containerContent
|
property alias stack: containerContent
|
||||||
@@ -66,7 +68,7 @@ Item {
|
|||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
id: defaultCurve
|
id: defaultCurve
|
||||||
|
|
||||||
duration: 200
|
duration: 200 + root.animOffset
|
||||||
easing: Easing.InOutBack
|
easing: Easing.InOutBack
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +95,8 @@ Item {
|
|||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
color: containerRoot.boxColor
|
color: root.boxColor
|
||||||
radius: containerRoot.boxRadius
|
radius: root.boxRadius
|
||||||
|
|
||||||
StackView {
|
StackView {
|
||||||
id: containerContent
|
id: containerContent
|
||||||
@@ -125,7 +127,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: containerContent.push(containerRoot.defaultItem)
|
Component.onCompleted: containerContent.push(root.defaultItem)
|
||||||
onCurrentItemChanged: {
|
onCurrentItemChanged: {
|
||||||
if (currentItem) {
|
if (currentItem) {
|
||||||
// Dynamically center the incoming child to the StackView
|
// Dynamically center the incoming child to the StackView
|
||||||
|
|||||||
69
Services/BluetoothManager.qml
Normal file
69
Services/BluetoothManager.qml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
pragma Singleton
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Bluetooth
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property BluetoothAdapter defaultAdapter: Bluetooth.defaultAdapter
|
||||||
|
property string defaultAdapterName: Bluetooth.defaultAdapter.adapterId
|
||||||
|
|
||||||
|
function getConnected() {
|
||||||
|
let deviceList = getDevicesList();
|
||||||
|
for (let device in deviceList) {
|
||||||
|
let currentDevice = deviceList[device];
|
||||||
|
if (currentDevice.connected == true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDevicesList() {
|
||||||
|
return root.defaultAdapter.devices.values;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIcon(name) {
|
||||||
|
const icons = {
|
||||||
|
"audio-card": "",
|
||||||
|
"audio-input-microphone": "",
|
||||||
|
"audio-headphones": "",
|
||||||
|
"audio-headset": "",
|
||||||
|
"battery": "",
|
||||||
|
"camera-photo": "",
|
||||||
|
"computer": "",
|
||||||
|
"input-keyboard": "",
|
||||||
|
"input-mouse": "",
|
||||||
|
"input-gaming": "",
|
||||||
|
"phone": ""
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
27
Services/MprisManager.qml
Normal file
27
Services/MprisManager.qml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
pragma Singleton
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.Mpris
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property MprisPlayer defaultPlayer: Mpris.players.values[0]
|
||||||
|
property real pos: defaultPlayer.position / defaultPlayer.length
|
||||||
|
|
||||||
|
function getPlaying() {
|
||||||
|
if (!defaultPlayer) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return defaultPlayer.playbackState == MprisPlaybackState.Playing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function prev() {
|
||||||
|
defaultPlayer.previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
function skip() {
|
||||||
|
defaultPlayer.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,3 +2,5 @@ module Services
|
|||||||
singleton Time 1.0 Time.qml
|
singleton Time 1.0 Time.qml
|
||||||
singleton NotificationManager 1.0 NotificationManager.qml
|
singleton NotificationManager 1.0 NotificationManager.qml
|
||||||
singleton WorkspaceManager 1.0 WorkspaceManager.qml
|
singleton WorkspaceManager 1.0 WorkspaceManager.qml
|
||||||
|
singleton BluetoothManager 1.0 BluetoothManager.qml
|
||||||
|
singleton MprisManager 1.0 MprisManager.qml
|
||||||
|
|||||||
Reference in New Issue
Block a user