quickshell media player enchantments
This commit is contained in:
1
quickshell/assets/bar/MutedMic.svg
Normal file
1
quickshell/assets/bar/MutedMic.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#EA3323"><path d="m710-362-58-58q14-23 21-48t7-52h80q0 44-13 83.5T710-362ZM592-482 360-714v-46q0-50 35-85t85-35q50 0 85 35t35 85v240q0 11-2.5 20t-5.5 18ZM440-120v-124q-104-14-172-92.5T200-520h80q0 83 58.5 141.5T480-320q34 0 64.5-10.5T600-360l57 57q-29 23-63.5 38.5T520-244v124h-80Zm352 64L56-792l56-56 736 736-56 56Z"/></svg>
|
||||
|
After Width: | Height: | Size: 424 B |
1
quickshell/assets/bar/MutedSpeaker.svg
Normal file
1
quickshell/assets/bar/MutedSpeaker.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#EA3323"><path d="M792-56 671-177q-25 16-53 27.5T560-131v-82q14-5 27.5-10t25.5-12L480-368v208L280-360H120v-240h128L56-792l56-56 736 736-56 56Zm-8-232-58-58q17-31 25.5-65t8.5-70q0-94-55-168T560-749v-82q124 28 202 125.5T840-481q0 53-14.5 102T784-288ZM650-422l-90-90v-130q47 22 73.5 66t26.5 96q0 15-2.5 29.5T650-422ZM480-592 376-696l104-104v208Z"/></svg>
|
||||
|
After Width: | Height: | Size: 450 B |
@@ -8,6 +8,7 @@ import Quickshell.Widgets
|
||||
import "widgets" as Widgets
|
||||
import "widgets/player" as Player
|
||||
import "widgets/common" as Common
|
||||
import "widgets/clock" as Clock
|
||||
|
||||
// Tako kindly threatened you to sort the naming schema and to put all the svg's in an asset folder, so please do that
|
||||
|
||||
@@ -22,15 +23,20 @@ import "widgets/common" as Common
|
||||
right: true
|
||||
}
|
||||
|
||||
implicitHeight: 30
|
||||
implicitHeight: 32
|
||||
RowLayout {
|
||||
height: 28
|
||||
anchors {
|
||||
fill: parent
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
// bottomMargin: 2
|
||||
leftMargin: 10
|
||||
rightMargin: 10
|
||||
}
|
||||
RowLayout { // Left
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Clock.Date {}
|
||||
}
|
||||
RowLayout { // Center
|
||||
// TODO: add icons of the active window per workspace in the workspace tab
|
||||
@@ -50,13 +56,7 @@ import "widgets/common" as Common
|
||||
}
|
||||
}
|
||||
Common.VerticalSeprator {}
|
||||
WrapperItem {
|
||||
Text { // Date & Time
|
||||
text: Widgets.Time.time
|
||||
color: '#FFFFFF'
|
||||
font.pointSize: 10.75
|
||||
}
|
||||
}
|
||||
Clock.Clock {}
|
||||
Widgets.SystemTray {
|
||||
id: systemTray
|
||||
}
|
||||
@@ -68,7 +68,7 @@ import "widgets/common" as Common
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: 2
|
||||
height: 1
|
||||
color: "#8d8d8d"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,30 +18,26 @@ Item {
|
||||
|
||||
RowLayout {
|
||||
id: row
|
||||
|
||||
Item {
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
radius: 7
|
||||
color: "black"
|
||||
}
|
||||
IconImage {
|
||||
// anchors.centerIn: parent
|
||||
implicitSize: 27
|
||||
source: "root:/assets/bar/Speaker.svg"
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 25
|
||||
source: root.speakerNode.audio.muted ? "root:/assets/bar/MutedSpeaker.svg" : "root:/assets/bar/Speaker.svg"
|
||||
// source: "root:/assets/bar/Speaker.svg"
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
id: text
|
||||
text: root.speakerNode.audio.muted ? "0%" : root.speakerNode.audio.volume * 100 + "%"
|
||||
font.pointSize: 10.75
|
||||
color: root.speakerNode.audio.muted ? "red" : "#FFFFFF"
|
||||
}
|
||||
|
||||
IconImage {
|
||||
implicitSize: 26
|
||||
source: "root:/assets/bar/Mic.svg"
|
||||
}
|
||||
|
||||
Text {
|
||||
text: parseInt(root.microphoneNode.audio.muted ? "0" : root.microphoneNode.audio.volume * 100) + "%"
|
||||
font.pointSize: 10.75
|
||||
color: root.microphoneNode.audio.muted ? "red" : "#FFFFFF"
|
||||
implicitSize: 25
|
||||
source: root.microphoneNode.audio.muted ? "root:/assets/bar/MutedMic.svg" : "root:/assets/bar/Mic.svg"
|
||||
// source: "root:/assets/bar/Mic.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
readonly property string time: {
|
||||
Qt.formatDateTime(clock.date, "ddd d MMM [hh:mm]")
|
||||
}
|
||||
|
||||
|
||||
SystemClock {
|
||||
id: clock
|
||||
precision: SystemClock.Minutes
|
||||
}
|
||||
}
|
||||
18
quickshell/bar/widgets/clock/Clock.qml
Normal file
18
quickshell/bar/widgets/clock/Clock.qml
Normal file
@@ -0,0 +1,18 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
import "../common" as Common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: text.width
|
||||
height: text.height
|
||||
Common.Container {}
|
||||
Text {
|
||||
id: text
|
||||
text: ClockData.time
|
||||
font.pointSize: 10.25
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
22
quickshell/bar/widgets/clock/ClockData.qml
Normal file
22
quickshell/bar/widgets/clock/ClockData.qml
Normal file
@@ -0,0 +1,22 @@
|
||||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
readonly property string time: {
|
||||
// Qt.formatDateTime(clock.date, "ddd d MMM [hh:mm]")
|
||||
Qt.formatDateTime(clock.date, "hh:mm")
|
||||
}
|
||||
readonly property string date: {
|
||||
Qt.formatDateTime(clock.date, "d MMM")
|
||||
// Qt.formatDateTime(clock.date, "hh:mm")
|
||||
}
|
||||
|
||||
SystemClock {
|
||||
id: clock
|
||||
precision: SystemClock.Minutes
|
||||
}
|
||||
}
|
||||
19
quickshell/bar/widgets/clock/Date.qml
Normal file
19
quickshell/bar/widgets/clock/Date.qml
Normal file
@@ -0,0 +1,19 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
import "../common" as Common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: text.width + 15
|
||||
height: text.height
|
||||
Common.Container {}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
id: text
|
||||
text: ClockData.date
|
||||
font.pointSize: 10.25
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
13
quickshell/bar/widgets/common/Container.qml
Normal file
13
quickshell/bar/widgets/common/Container.qml
Normal file
@@ -0,0 +1,13 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
|
||||
Rectangle {
|
||||
z: -1
|
||||
color: "black"
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
height: 25
|
||||
width: parent.width
|
||||
radius: 7
|
||||
}
|
||||
@@ -3,11 +3,16 @@ import QtQuick
|
||||
import Quickshell
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Mpris
|
||||
|
||||
PopupWindow {
|
||||
property PlayerControllerV2 player: PlayerControllerV2;
|
||||
|
||||
readonly property string elementBackgroundColor : "#323232"
|
||||
readonly property string elementButtonBaseColor : "#515151"
|
||||
readonly property string elementButtonHoverColor : "#737373"
|
||||
|
||||
id: audioPopup
|
||||
anchor {
|
||||
item: root
|
||||
@@ -16,6 +21,7 @@ PopupWindow {
|
||||
anchor.rect.y: root.height * 1.2
|
||||
height: columnContainer.height + 5
|
||||
width: 425
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#919191"
|
||||
@@ -26,15 +32,15 @@ PopupWindow {
|
||||
model: player.mpris.players
|
||||
Item {
|
||||
id: root
|
||||
width: 400
|
||||
height: 80
|
||||
width: 375
|
||||
height: 110
|
||||
required property MprisPlayer modelData
|
||||
property string trackPosition: PlayerControllerV2.trackPositionFormatter(root.modelData.position)
|
||||
property string trackLength: "0:00"
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
color: "black"
|
||||
color: audioPopup.elementBackgroundColor
|
||||
radius: 7
|
||||
}
|
||||
MouseArea {
|
||||
@@ -48,21 +54,23 @@ PopupWindow {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width:380
|
||||
width:root.width - 15
|
||||
RowLayout {
|
||||
implicitWidth: 380
|
||||
Item {
|
||||
implicitWidth: 50
|
||||
implicitHeight: 50
|
||||
implicitWidth: root.width - 15
|
||||
ClippingWrapperRectangle {
|
||||
implicitWidth: 75
|
||||
implicitHeight: 75
|
||||
radius: 7
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
mipmap: true
|
||||
source: root.modelData.trackArtUrl
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 2
|
||||
ScrollView {
|
||||
implicitWidth: 230
|
||||
implicitWidth: 180
|
||||
height: parent.height
|
||||
|
||||
Text {
|
||||
@@ -75,7 +83,7 @@ PopupWindow {
|
||||
Text {
|
||||
text: root.modelData.trackArtist
|
||||
color: "white"
|
||||
font.pointSize: 6
|
||||
font.pointSize: 8
|
||||
antialiasing: true
|
||||
}
|
||||
}
|
||||
@@ -84,28 +92,41 @@ PopupWindow {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
// Layout.
|
||||
spacing: 0
|
||||
// buttons
|
||||
Item {
|
||||
width: 30
|
||||
height: 25
|
||||
implicitWidth: 30
|
||||
implicitHeight: 25
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Rectangle {
|
||||
id: gobackButton
|
||||
width: 30
|
||||
height: 25
|
||||
topLeftRadius: 7
|
||||
bottomLeftRadius: 7
|
||||
color: "white"
|
||||
color: audioPopup.elementButtonBaseColor
|
||||
}
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
implicitSize: 25
|
||||
source: "root:/assets/media_player/skip_previous.svg"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
gobackButton.color = "grey"
|
||||
gobackButton.color = audioPopup.elementButtonHoverColor
|
||||
}
|
||||
onExited: event => {
|
||||
gobackButton.color = "white"
|
||||
gobackButton.color = audioPopup.elementButtonBaseColor
|
||||
}
|
||||
onClicked: event => {
|
||||
root.modelData.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,6 +134,7 @@ PopupWindow {
|
||||
width: 30
|
||||
height: 25
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
width: 30
|
||||
height: 25
|
||||
Rectangle {
|
||||
@@ -121,7 +143,13 @@ PopupWindow {
|
||||
height: 25
|
||||
// topLeftRadius: 7
|
||||
// bottomLeftRadius: 7
|
||||
color: "white"
|
||||
color: audioPopup.elementButtonBaseColor
|
||||
}
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 25
|
||||
source: root.modelData.isPlaying ? "root:/assets/media_player/pausebutton.svg" : "root:/assets/media_player/playbutton.svg"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
@@ -129,10 +157,10 @@ PopupWindow {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
pauseButton.color = "grey"
|
||||
pauseButton.color = audioPopup.elementButtonHoverColor
|
||||
}
|
||||
onExited: event => {
|
||||
pauseButton.color = "white"
|
||||
pauseButton.color = audioPopup.elementButtonBaseColor
|
||||
}
|
||||
onClicked: event => {
|
||||
root.modelData.togglePlaying();
|
||||
@@ -142,22 +170,33 @@ PopupWindow {
|
||||
Item {
|
||||
width: 30
|
||||
height: 25
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Rectangle {
|
||||
id: gonextButton
|
||||
width: 30
|
||||
height: 25
|
||||
topRightRadius: 7
|
||||
bottomRightRadius: 7
|
||||
color: "white"
|
||||
color: audioPopup.elementButtonBaseColor
|
||||
}
|
||||
IconImage {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
implicitSize: 25
|
||||
source: "root:/assets/media_player/skip_next.svg"
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: event => {
|
||||
gonextButton.color = "grey"
|
||||
gonextButton.color = audioPopup.elementButtonHoverColor
|
||||
}
|
||||
onExited: event => {
|
||||
gonextButton.color = "white"
|
||||
gonextButton.color = audioPopup.elementButtonBaseColor
|
||||
}
|
||||
onClicked: event => {
|
||||
root.modelData.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,15 +209,20 @@ PopupWindow {
|
||||
from: 0
|
||||
value: root.modelData.position
|
||||
to: root.modelData.length
|
||||
property double lastPosition;
|
||||
property bool debounceValue: false;
|
||||
onMoved: event => {
|
||||
root.modelData.position = slider.value
|
||||
audioPopup.player.update(); // force values to update // causing ui to update with it
|
||||
debounceValue = true; // there is insane lag if we put the move logic here, so its better to trigger a time with the logic instead
|
||||
}
|
||||
Timer {
|
||||
running: root.modelData.playbackState == MprisPlaybackState.Playing
|
||||
interval: 500
|
||||
running: slider.debounceValue
|
||||
interval: 250
|
||||
repeat: true
|
||||
onTriggered: slider.value = root.modelData.position
|
||||
onTriggered: {
|
||||
root.modelData.position = slider.value
|
||||
audioPopup.player.update(); // force values to update // causing ui to update with it
|
||||
slider.debounceValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
@@ -190,12 +234,17 @@ PopupWindow {
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
running: root.modelData.isPlaying
|
||||
interval: 1000
|
||||
id: updateTimer
|
||||
property bool tempOneshot: false;
|
||||
running: root.modelData.isPlaying || (root.modelData.position != slider.lastPosition)
|
||||
interval: 750
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
trackPosition = PlayerControllerV2.trackPositionFormatter(root.modelData.position)
|
||||
trackLength = PlayerControllerV2.trackPositionFormatter(root.modelData.length)
|
||||
updateTimer.tempOneshot = false;
|
||||
slider.lastPosition = slider.value
|
||||
slider.value = root.modelData.position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user