brightess and volume control
This commit is contained in:
@@ -10,14 +10,13 @@ Column {
|
||||
width: Math.max(childrenRect.width, 300)
|
||||
height: childrenRect.height
|
||||
anchors.topMargin: 6
|
||||
TapHandler {onTapped: console.log(width)}
|
||||
Rectangle {
|
||||
radius: 12
|
||||
height: 40
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 6
|
||||
color: "#181818"
|
||||
color: "#111"
|
||||
Rectangle {
|
||||
color: "white"
|
||||
width: (parent.width - anchors.margins * 2)/3
|
||||
@@ -116,7 +115,7 @@ Column {
|
||||
id: card
|
||||
required property var data
|
||||
required property var label
|
||||
color: "#181818"
|
||||
color: "#111"
|
||||
height: 60
|
||||
width: 100
|
||||
radius: 12
|
||||
|
||||
154
Panes/Brightness.qml
Normal file
154
Panes/Brightness.qml
Normal file
@@ -0,0 +1,154 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import QtQuick
|
||||
import qs.Services
|
||||
import qs.Widgets as Widgets
|
||||
|
||||
Column {
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 6
|
||||
}
|
||||
width: 300
|
||||
height: childrenRect.height + anchors.margins * 2
|
||||
spacing: 6
|
||||
Item {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 12
|
||||
}
|
||||
width: childrenRect.width
|
||||
height: children[1].height
|
||||
Image {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenterOffset: 1
|
||||
}
|
||||
width: 24
|
||||
height: width
|
||||
sourceSize {width: width; height: height}
|
||||
source: Quickshell.iconPath("brightnesssettings")
|
||||
}
|
||||
Text {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.children[0].right
|
||||
leftMargin: 6
|
||||
}
|
||||
font.pixelSize: 16
|
||||
color: "white"
|
||||
text: "Laptop display"
|
||||
}
|
||||
}
|
||||
Widgets.Slider {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 12
|
||||
}
|
||||
height: 24
|
||||
value: Brightness.monitors[0].value / Brightness.monitors[0].max
|
||||
onMoved: {
|
||||
Brightness.monitors[0].set(Math.round(Brightness.monitors[0].max * position))
|
||||
}
|
||||
}
|
||||
component ToggleButton: Item {
|
||||
id: toggleButton
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 12
|
||||
}
|
||||
height: children[0].height
|
||||
property bool active: false
|
||||
property var text
|
||||
Text {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: 24
|
||||
font.pixelSize: 14
|
||||
color: "white"
|
||||
text: toggleButton.text
|
||||
}
|
||||
Rectangle {
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: (24 - width)/2 + (36-24)/2
|
||||
}
|
||||
radius: height/2
|
||||
color: parent.active ? "white" : "#00ffffff"
|
||||
height: 10
|
||||
width: parent.active ? 36 : 24
|
||||
border.width: parent.active ? height/2 : 2
|
||||
border.color: "white"
|
||||
Behavior on width {NumberAnimation { duration: 150; easing.type: Easing.OutCubic }}
|
||||
Behavior on border.width {NumberAnimation { duration: 150; easing.type: Easing.OutCubic }}
|
||||
}
|
||||
}
|
||||
ToggleButton {
|
||||
id: sunsetToggle
|
||||
text: "Night Light"
|
||||
Process {
|
||||
running: true
|
||||
command: [ "pgrep", "-x", "sunset" ]
|
||||
onExited: (exitCode) => {if (!exitCode) sunsetToggle.active = true}
|
||||
}
|
||||
TapHandler {
|
||||
property var idleProc: Process {command: ["hyprsunset"]}
|
||||
property var idleKill: Process {command: ["pkill", "-x", "hyprsunset"]}
|
||||
onTapped: {
|
||||
parent.active = !parent.active
|
||||
if (parent.active)
|
||||
idleProc.startDetached()
|
||||
else
|
||||
idleKill.startDetached()
|
||||
}
|
||||
}
|
||||
}
|
||||
ToggleButton {
|
||||
id: idleToggle
|
||||
text: "Idle Timer"
|
||||
Process {
|
||||
running: true
|
||||
command: [ "pgrep", "-x", "hypridle" ]
|
||||
onExited: (exitCode) => {if (!exitCode) idleToggle.active = true}
|
||||
}
|
||||
TapHandler {
|
||||
property var idleProc: Process {command: ["hypridle"]}
|
||||
property var idleKill: Process {command: ["pkill", "-x", "hypridle"]}
|
||||
onTapped: {
|
||||
parent.active = !parent.active
|
||||
if (parent.active)
|
||||
idleProc.startDetached()
|
||||
else
|
||||
idleKill.startDetached()
|
||||
}
|
||||
}
|
||||
}
|
||||
ToggleButton {
|
||||
id: dpmsToggle
|
||||
text: "Screen on"
|
||||
active: true
|
||||
TapHandler {
|
||||
property var resetTimer: Timer {
|
||||
interval: 500
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: dpmsToggle.active = true
|
||||
}
|
||||
onTapped: {
|
||||
dpmsToggle.active = false;
|
||||
Hyprland.dispatch("dpms off");
|
||||
resetTimer.start();
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ Item {
|
||||
margins: 6
|
||||
}
|
||||
height: 48
|
||||
color: "#181818"
|
||||
color: "#111"
|
||||
radius: 10
|
||||
TextInput {
|
||||
id: input
|
||||
@@ -95,7 +95,6 @@ Item {
|
||||
property: "x"
|
||||
duration: 300
|
||||
easing.type: Easing.OutQuint
|
||||
onStarted: console.log("displaced")
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
@@ -146,7 +145,7 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 64
|
||||
height: width
|
||||
source: Quickshell.iconPath(modelData.icon)
|
||||
source: Quickshell.iconPath(modelData.icon, "application-default")
|
||||
}
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
@@ -20,7 +20,7 @@ Item {
|
||||
Rectangle {
|
||||
width: 400
|
||||
height: 300
|
||||
color: "#181818"
|
||||
color: "#111"
|
||||
radius: 10
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
@@ -47,7 +47,6 @@ Item {
|
||||
anchors.rightMargin: anchors.leftMargin
|
||||
clip: true
|
||||
spacing: 4
|
||||
interactive: background.index === 3
|
||||
|
||||
add: Transition {NumberAnimation {
|
||||
property: "opacity"
|
||||
@@ -69,7 +68,7 @@ Item {
|
||||
header: Item {height: 4; width: 1}
|
||||
model: Array.from(notifServer.trackedNotifications.values)
|
||||
delegate: Widgets.Notification {
|
||||
color: "#222"
|
||||
color: "#181818"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,25 +97,32 @@ Item {
|
||||
}
|
||||
}
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
margins: 6
|
||||
}
|
||||
opacity: Mpris.players.values.length
|
||||
Behavior on opacity {NumberAnimation {duration: 150}}
|
||||
Shape {
|
||||
id: progressShape
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 180
|
||||
height: 180
|
||||
width: 160
|
||||
height: width
|
||||
property var strokeWidth: 6
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
ShapePath {
|
||||
capStyle: ShapePath.RoundCap
|
||||
strokeColor: "#444"
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 4
|
||||
strokeWidth: progressShape.strokeWidth
|
||||
PathAngleArc {
|
||||
moveToStart: true
|
||||
radiusX: 90 - 6
|
||||
radiusY: 90 - 6
|
||||
centerX: 90
|
||||
centerY: 90
|
||||
radiusX: (progressShape.width-progressShape.strokeWidth)/2
|
||||
radiusY: (progressShape.height-progressShape.strokeWidth)/2
|
||||
centerX: progressShape.width/2
|
||||
centerY: progressShape.height/2
|
||||
startAngle: 90 + 20
|
||||
sweepAngle: 360 - 40
|
||||
}
|
||||
@@ -125,13 +131,13 @@ Item {
|
||||
capStyle: ShapePath.RoundCap
|
||||
strokeColor: "white"
|
||||
fillColor: "transparent"
|
||||
strokeWidth: 4
|
||||
strokeWidth: 6
|
||||
PathAngleArc {
|
||||
moveToStart: true
|
||||
radiusX: 90 - 6
|
||||
radiusY: 90 - 6
|
||||
centerX: 90
|
||||
centerY: 90
|
||||
radiusX: (progressShape.width-progressShape.strokeWidth)/2
|
||||
radiusY: (progressShape.height-progressShape.strokeWidth)/2
|
||||
centerX: progressShape.width/2
|
||||
centerY: progressShape.height/2
|
||||
startAngle: 90 + 20
|
||||
sweepAngle: (player.modelData?.position/player.modelData.length) * (360 - 40)
|
||||
}
|
||||
@@ -140,9 +146,12 @@ Item {
|
||||
color: "transparent"
|
||||
radius: height/2
|
||||
anchors.fill: parent
|
||||
anchors.margins: 12
|
||||
anchors.margins: progressShape.strokeWidth*2
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
mipmap: true
|
||||
smooth: true
|
||||
source: player.modelData?.trackArtUrl ?? source
|
||||
}
|
||||
NumberAnimation on rotation {
|
||||
@@ -159,15 +168,25 @@ Item {
|
||||
}
|
||||
Item {width: 1; height: 10}
|
||||
Text {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
color: "white"
|
||||
text: player.modelData?.trackTitle ?? ""
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.pixelSize: 16
|
||||
}
|
||||
Text {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
color: "white"
|
||||
text: player.modelData?.trackArtist ?? ""
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
font.pixelSize: 12
|
||||
}
|
||||
Item {width: 1; height: 8}
|
||||
|
||||
@@ -9,7 +9,7 @@ Item {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
width: 350
|
||||
height: childrenRect.height
|
||||
height: childrenRect.height + 12
|
||||
Connections {
|
||||
target: notifServer
|
||||
function onNotification(notif) {
|
||||
@@ -22,6 +22,7 @@ Item {
|
||||
}
|
||||
Widgets.Notification {
|
||||
id: notifPopup
|
||||
y: 6
|
||||
anchors.margins: 6
|
||||
modelData: notifServer.trackedNotifications.values[0] ?? undefined
|
||||
color: "transparent"
|
||||
@@ -32,4 +33,8 @@ Item {
|
||||
interval: 3000
|
||||
onTriggered: root.close()
|
||||
}
|
||||
Connections {
|
||||
target: background
|
||||
function onIndexChanged() { timeout.stop() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ Item {
|
||||
bottom: parent.bottom
|
||||
}
|
||||
Widgets.Battery {}
|
||||
Widgets.Volume {}
|
||||
Widgets.Brightness {}
|
||||
}
|
||||
Widgets.Workspaces {
|
||||
height: parent.height
|
||||
@@ -31,6 +33,7 @@ Item {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
Widgets.Uptime {}
|
||||
Widgets.Time {}
|
||||
}
|
||||
}
|
||||
|
||||
104
Panes/Volume.qml
Normal file
104
Panes/Volume.qml
Normal file
@@ -0,0 +1,104 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Pipewire
|
||||
import qs.Widgets as Widgets
|
||||
|
||||
Row {
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
padding: 6
|
||||
height: 316
|
||||
spacing: 6
|
||||
|
||||
PwObjectTracker {
|
||||
objects: Pipewire.nodes.values.filter(node => [17, 21].includes(node.type))
|
||||
}
|
||||
|
||||
component NodeList: ClippingRectangle {
|
||||
id: nodeListRect
|
||||
width: 350
|
||||
color: "transparent"
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 6
|
||||
}
|
||||
radius: 10
|
||||
property var model
|
||||
clip: true
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
spacing: 6
|
||||
header: Item {width: 1; height: 6}
|
||||
footer: header
|
||||
model: nodeListRect.model
|
||||
delegate: Rectangle {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
radius: 12
|
||||
color: "#111"
|
||||
height: children[1].height
|
||||
Image {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 6
|
||||
}
|
||||
sourceSize {width: width; height: height}
|
||||
source: Quickshell.iconPath((() => {
|
||||
const description = modelData.description.toLowerCase();
|
||||
if (description.search("hdmi") !== -1)
|
||||
return "display"
|
||||
if (description.search("speaker") !== -1)
|
||||
return "audio-speakers"
|
||||
if (description.search("earphone") !== -1 || description.search("headphone") !== -1)
|
||||
return "audio-headset"
|
||||
if (modelData.properties["device.icon-name"])
|
||||
return modelData.properties["device.icon-name"]
|
||||
return modelData.properties["application.name"]
|
||||
})()?.toLowerCase(), "audio-on")
|
||||
width: 32
|
||||
height: width
|
||||
}
|
||||
Column {
|
||||
anchors {
|
||||
left: parent.children[0].right
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
margins: 6
|
||||
rightMargin: 12
|
||||
}
|
||||
topPadding: 6
|
||||
bottomPadding: 6
|
||||
spacing: 2
|
||||
Text {
|
||||
text: {
|
||||
if (modelData.nickname !== "") return modelData.nickname
|
||||
if (modelData.description !== "") return description
|
||||
return modelData.name
|
||||
}
|
||||
color: "white"
|
||||
font.pixelSize: 16
|
||||
}
|
||||
Widgets.Slider {
|
||||
value: modelData.audio.volume
|
||||
onMoved: modelData.audio.volume = position
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NodeList {
|
||||
model: Pipewire.nodes.values.filter(node => node.type === 17)
|
||||
}
|
||||
NodeList {
|
||||
model: Pipewire.nodes.values.filter(node => node.type === 21)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user