mirror of
https://github.com/kossLAN/dots.git
synced 2025-11-05 06:59:50 -05:00
Initial commit
This commit is contained in:
commit
05cd51b54e
148 changed files with 10112 additions and 0 deletions
31
.stversions/bar/ActiveWindow~20250107-005428.qml
Normal file
31
.stversions/bar/ActiveWindow~20250107-005428.qml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
|
||||
Rectangle {
|
||||
width: 200;
|
||||
height: parent.height;
|
||||
|
||||
Text {
|
||||
id: windowText;
|
||||
text: "";
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
visible: text !== "";
|
||||
elide: Text.ElideRight;
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right;
|
||||
verticalCenter: verticalCenter.parent;
|
||||
|
||||
Connections {
|
||||
target: Hyprland;
|
||||
|
||||
function onRawEvent(event) {
|
||||
if (event.name === "activewindow") {
|
||||
windowText.text = event.parse(2)[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
.stversions/bar/ActiveWindow~20250107-005503.qml
Normal file
33
.stversions/bar/ActiveWindow~20250107-005503.qml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
|
||||
Rectangle {
|
||||
width: 200;
|
||||
height: parent.height;
|
||||
color: "black"
|
||||
|
||||
Text {
|
||||
id: windowText;
|
||||
text: "";
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
visible: text !== "";
|
||||
elide: Text.ElideRight;
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right;
|
||||
verticalCenter: verticalCenter.parent;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Hyprland;
|
||||
|
||||
function onRawEvent(event) {
|
||||
if (event.name === "activewindow") {
|
||||
windowText.text = event.parse(2)[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
.stversions/bar/ActiveWindow~20250107-005542.qml
Normal file
34
.stversions/bar/ActiveWindow~20250107-005542.qml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
|
||||
Rectangle {
|
||||
width: 200;
|
||||
height: parent.height;
|
||||
color: "black"
|
||||
|
||||
Text {
|
||||
id: windowText;
|
||||
text: "";
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
visible: text !== "";
|
||||
elide: Text.ElideRight;
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
//right: parent.right;
|
||||
verticalCenter: verticalCenter.parent;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Hyprland;
|
||||
|
||||
function onRawEvent(event) {
|
||||
if (event.name === "activewindow") {
|
||||
windowText.text = event.parse(2)[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
.stversions/bar/ActiveWindow~20250107-005825.qml
Normal file
34
.stversions/bar/ActiveWindow~20250107-005825.qml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
|
||||
Rectangle {
|
||||
width: 200;
|
||||
height: parent.height;
|
||||
color: "black"
|
||||
|
||||
Text {
|
||||
id: windowText;
|
||||
text: "";
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
visible: text !== "";
|
||||
elide: Text.ElideRight;
|
||||
|
||||
//anchors {
|
||||
// left: parent.left
|
||||
// //right: parent.right;
|
||||
// verticalCenter: verticalCenter.parent;
|
||||
//}
|
||||
|
||||
Connections {
|
||||
target: Hyprland;
|
||||
|
||||
function onRawEvent(event) {
|
||||
if (event.name === "activewindow") {
|
||||
windowText.text = event.parse(2)[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
.stversions/bar/ActiveWindow~20250307-175400.qml
Normal file
22
.stversions/bar/ActiveWindow~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
|
||||
Text {
|
||||
id: windowText;
|
||||
text: "";
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
visible: text !== "";
|
||||
elide: Text.ElideRight;
|
||||
|
||||
Connections {
|
||||
target: Hyprland;
|
||||
|
||||
function onRawEvent(event) {
|
||||
if (event.name === "activewindow") {
|
||||
windowText.text = event.parse(2)[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
.stversions/bar/Bar~20250107-010815.qml
Normal file
94
.stversions/bar/Bar~20250107-010815.qml
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import "mpris" as Mpris
|
||||
import "notifications" as Notifications
|
||||
import "control" as Control
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
id: root;
|
||||
color: ShellGlobals.colors.window;
|
||||
height: 25
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
// Notifications
|
||||
Notifications.Notifications {
|
||||
bar: root;
|
||||
}
|
||||
|
||||
// Widgets - Everything here is sorted where it appears on the bar.
|
||||
|
||||
// Left
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
left: parent.left;
|
||||
bottom: parent.bottom;
|
||||
leftMargin: 10;
|
||||
}
|
||||
|
||||
Workspaces {}
|
||||
|
||||
Separator {
|
||||
visible: activeWindow.visible;
|
||||
}
|
||||
|
||||
ActiveWindow {
|
||||
id: activeWindow;
|
||||
Layout.preferredWidth: 250;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Middle
|
||||
|
||||
Mpris.MediaInfo {
|
||||
id: mediaInfo;
|
||||
bar: root;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
// Right
|
||||
RowLayout {
|
||||
spacing: 20;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
bottom: parent.bottom;
|
||||
right: parent.right;
|
||||
rightMargin: 10;
|
||||
}
|
||||
|
||||
SysTray {
|
||||
id: sysTray;
|
||||
bar: root;
|
||||
}
|
||||
|
||||
Separator {
|
||||
visible: sysTray.visible
|
||||
}
|
||||
|
||||
BatteryIndicator {
|
||||
id: batteryIndicator
|
||||
}
|
||||
|
||||
Control.Control {
|
||||
bar: root;
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Clock {
|
||||
id: clock;
|
||||
color: ShellGlobals.colors.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
98
.stversions/bar/Bar~20250107-010845.qml
Normal file
98
.stversions/bar/Bar~20250107-010845.qml
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import "mpris" as Mpris
|
||||
import "notifications" as Notifications
|
||||
import "control" as Control
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
id: root;
|
||||
color: ShellGlobals.colors.window;
|
||||
height: 25
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
// Notifications
|
||||
Notifications.Notifications {
|
||||
bar: root;
|
||||
}
|
||||
|
||||
// Widgets - Everything here is sorted where it appears on the bar.
|
||||
|
||||
// Left
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
left: parent.left;
|
||||
bottom: parent.bottom;
|
||||
leftMargin: 10;
|
||||
}
|
||||
|
||||
Workspaces {}
|
||||
|
||||
Separator {
|
||||
visible: activeWindow.visible;
|
||||
}
|
||||
|
||||
ActiveWindow {
|
||||
id: activeWindow;
|
||||
Layout.preferredWidth: 250;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Middle
|
||||
|
||||
Mpris.MediaInfo {
|
||||
id: mediaInfo;
|
||||
bar: root;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
// Right
|
||||
RowLayout {
|
||||
spacing: 20;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
bottom: parent.bottom;
|
||||
right: parent.right;
|
||||
rightMargin: 10;
|
||||
}
|
||||
|
||||
SysTray {
|
||||
id: sysTray;
|
||||
bar: root;
|
||||
}
|
||||
|
||||
Separator {
|
||||
visible: sysTray.visible
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
BatteryIndicator {
|
||||
id: batteryIndicator
|
||||
}
|
||||
|
||||
Control.Control {
|
||||
bar: root;
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Clock {
|
||||
id: clock;
|
||||
color: ShellGlobals.colors.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
94
.stversions/bar/Bar~20250107-010938.qml
Normal file
94
.stversions/bar/Bar~20250107-010938.qml
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import "mpris" as Mpris
|
||||
import "notifications" as Notifications
|
||||
import "control" as Control
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
id: root;
|
||||
color: ShellGlobals.colors.window;
|
||||
height: 25
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
// Notifications
|
||||
Notifications.Notifications {
|
||||
bar: root;
|
||||
}
|
||||
|
||||
// Widgets - Everything here is sorted where it appears on the bar.
|
||||
|
||||
// Left
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
left: parent.left;
|
||||
bottom: parent.bottom;
|
||||
leftMargin: 10;
|
||||
}
|
||||
|
||||
Workspaces {}
|
||||
|
||||
Separator {
|
||||
visible: activeWindow.visible;
|
||||
}
|
||||
|
||||
ActiveWindow {
|
||||
id: activeWindow;
|
||||
Layout.preferredWidth: 250;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Middle
|
||||
|
||||
Mpris.MediaInfo {
|
||||
id: mediaInfo;
|
||||
bar: root;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
// Right
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
bottom: parent.bottom;
|
||||
right: parent.right;
|
||||
rightMargin: 10;
|
||||
}
|
||||
|
||||
SysTray {
|
||||
id: sysTray;
|
||||
bar: root;
|
||||
}
|
||||
|
||||
Separator {
|
||||
visible: sysTray.visible
|
||||
}
|
||||
|
||||
BatteryIndicator {
|
||||
id: batteryIndicator
|
||||
}
|
||||
|
||||
Control.Control {
|
||||
bar: root;
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Clock {
|
||||
id: clock;
|
||||
color: ShellGlobals.colors.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
97
.stversions/bar/Bar~20250307-175400.qml
Normal file
97
.stversions/bar/Bar~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import "mpris" as Mpris
|
||||
import "notifications" as Notifications
|
||||
import "control" as Control
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
id: root;
|
||||
color: ShellGlobals.colors.window;
|
||||
height: 25
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
// Notifications
|
||||
Notifications.Notifications {
|
||||
bar: root;
|
||||
}
|
||||
|
||||
// Widgets - Everything here is sorted where it appears on the bar.
|
||||
|
||||
// Left
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
left: parent.left;
|
||||
bottom: parent.bottom;
|
||||
leftMargin: 10;
|
||||
}
|
||||
|
||||
Workspaces {}
|
||||
|
||||
Separator {
|
||||
visible: activeWindow.visible;
|
||||
}
|
||||
|
||||
ActiveWindow {
|
||||
id: activeWindow;
|
||||
Layout.preferredWidth: 250;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Middle
|
||||
Mpris.MediaInfo {
|
||||
id: mediaInfo;
|
||||
bar: root;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
// Right
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
bottom: parent.bottom;
|
||||
right: parent.right;
|
||||
rightMargin: 10;
|
||||
}
|
||||
|
||||
SysTray {
|
||||
id: sysTray;
|
||||
bar: root;
|
||||
}
|
||||
|
||||
Separator {
|
||||
visible: sysTray.visible
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5;
|
||||
|
||||
BatteryIndicator {
|
||||
id: batteryIndicator
|
||||
}
|
||||
|
||||
Control.Control {
|
||||
bar: root;
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Clock {
|
||||
id: clock;
|
||||
color: ShellGlobals.colors.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
93
.stversions/bar/Bar~20250509-203449.qml
Normal file
93
.stversions/bar/Bar~20250509-203449.qml
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import "mpris" as Mpris
|
||||
import "volume" as Volume
|
||||
import "../widgets" as Widgets
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
color: ShellGlobals.colors.base
|
||||
height: 25
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
/// Widgets - Everything here is sorted where it appears on the bar.
|
||||
|
||||
// Left
|
||||
RowLayout {
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
leftMargin: 10
|
||||
}
|
||||
|
||||
// Whatever is available will display
|
||||
HyprWorkspaces {}
|
||||
SwayWorkspaces {}
|
||||
|
||||
Widgets.Separator {
|
||||
visible: activeWindow.visible
|
||||
}
|
||||
|
||||
ActiveWindow {
|
||||
id: activeWindow
|
||||
Layout.preferredWidth: 250
|
||||
}
|
||||
}
|
||||
|
||||
// Middle
|
||||
Mpris.Status {
|
||||
id: mprisStatus
|
||||
bar: root
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
// Right
|
||||
RowLayout {
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
rightMargin: 10
|
||||
}
|
||||
|
||||
SysTray {
|
||||
id: sysTray
|
||||
bar: root
|
||||
}
|
||||
|
||||
Widgets.Separator {
|
||||
visible: sysTray.visible
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
|
||||
BatteryIndicator {
|
||||
id: batteryIndicator
|
||||
}
|
||||
|
||||
Volume.Button {
|
||||
bar: root
|
||||
}
|
||||
}
|
||||
|
||||
Widgets.Separator {}
|
||||
|
||||
Clock {
|
||||
id: clock
|
||||
color: ShellGlobals.colors.text
|
||||
}
|
||||
}
|
||||
}
|
||||
38
.stversions/bar/BatteryIndicator~20250307-175400.qml
Normal file
38
.stversions/bar/BatteryIndicator~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import QtQuick
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.UPower
|
||||
import ".."
|
||||
|
||||
Item {
|
||||
property string batteryStatus: {
|
||||
if (!UPower.onBattery) {
|
||||
return "charging";
|
||||
}
|
||||
|
||||
let percentage = UPower.displayDevice.percentage * 100;
|
||||
let roundedValue = Math.floor(percentage / 5) * 5;
|
||||
return roundedValue.toString();
|
||||
}
|
||||
|
||||
width: 30;
|
||||
height: parent.height;
|
||||
visible: UPower.displayDevice.isLaptopBattery;
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.highlight;
|
||||
width: 12;
|
||||
height: 8;
|
||||
visible: batteryStatus === "charging";
|
||||
|
||||
anchors {
|
||||
centerIn: batteryImage;
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: batteryImage;
|
||||
implicitSize: 20;
|
||||
source: Qt.resolvedUrl(`../resources/battery/battery-${batteryStatus}.svg`);
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
}
|
||||
20
.stversions/bar/Clock~20250307-175400.qml
Normal file
20
.stversions/bar/Clock~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
Text {
|
||||
property string ap: sysClock.hours >= 12 ? "PM" : "AM";
|
||||
property string minutes: sysClock.minutes.toString().padStart(2, '0');
|
||||
property string hours: {
|
||||
var value = sysClock.hours % 12;
|
||||
if (value === 0) return 12;
|
||||
return value;
|
||||
}
|
||||
|
||||
SystemClock {
|
||||
id: sysClock;
|
||||
enabled: true;
|
||||
}
|
||||
|
||||
text: `${hours}:${minutes} ${ap}`
|
||||
font.pointSize: 11;
|
||||
}
|
||||
51
.stversions/bar/HyprWorkspaces~20250509-203448.qml
Normal file
51
.stversions/bar/HyprWorkspaces~20250509-203448.qml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
import ".."
|
||||
|
||||
RowLayout {
|
||||
property var sortedWorkspaces: {
|
||||
let values = Hyprland.workspaces.values.slice();
|
||||
values.sort(function (a, b) {
|
||||
return a.id - b.id;
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
spacing: 6
|
||||
visible: Hyprland.monitors.values.length != 0
|
||||
|
||||
Repeater {
|
||||
model: parent.sortedWorkspaces
|
||||
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
width: 25
|
||||
height: 12
|
||||
radius: 10
|
||||
|
||||
color: {
|
||||
let value = ShellGlobals.colors.light;
|
||||
|
||||
if (!modelData?.id || !Hyprland.focusedMonitor?.activeWorkspace?.id)
|
||||
return value;
|
||||
|
||||
if (workspaceButton.containsMouse) {
|
||||
value = ShellGlobals.colors.midlight;
|
||||
} else if (Hyprland.focusedMonitor.activeWorkspace.id == modelData.id) {
|
||||
value = ShellGlobals.colors.accent;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: workspaceButton
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onPressed: Hyprland.dispatch(`workspace ${parent.modelData.id}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
.stversions/bar/Separator~20250307-175400.qml
Normal file
9
.stversions/bar/Separator~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import QtQuick
|
||||
import ".."
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.highlight;
|
||||
radius: 5;
|
||||
width: 7.5;
|
||||
height: 7.5;
|
||||
}
|
||||
56
.stversions/bar/SwayWorkspaces~20250509-203451.qml
Normal file
56
.stversions/bar/SwayWorkspaces~20250509-203451.qml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.I3
|
||||
import ".."
|
||||
|
||||
RowLayout {
|
||||
property var sortedWorkspaces: {
|
||||
let values = I3.workspaces.values.slice();
|
||||
values.sort(function (a, b) {
|
||||
if (!a?.num)
|
||||
return 1;
|
||||
if (!b?.num)
|
||||
return -1;
|
||||
|
||||
return a.num - b.num;
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
spacing: 6
|
||||
visible: I3.monitors.values.length != 0
|
||||
|
||||
Repeater {
|
||||
model: parent.sortedWorkspaces
|
||||
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
width: 25
|
||||
height: 12
|
||||
radius: 10
|
||||
|
||||
color: getColor(modelData, workspaceButton.containsMouse)
|
||||
|
||||
MouseArea {
|
||||
id: workspaceButton
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onPressed: I3.dispatch(`workspace number ${parent.modelData.num}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getColor(modelData, isHovered) {
|
||||
if (!modelData?.id || !I3.focusedMonitor?.focusedWorkspace?.num)
|
||||
return ShellGlobals.colors.light;
|
||||
|
||||
if (isHovered)
|
||||
return ShellGlobals.colors.midlight;
|
||||
|
||||
if (I3.focusedMonitor.focusedWorkspace.num == modelData.num)
|
||||
return ShellGlobals.colors.accent;
|
||||
|
||||
return ShellGlobals.colors.light;
|
||||
}
|
||||
}
|
||||
26
.stversions/bar/SysTray~20250307-175400.qml
Normal file
26
.stversions/bar/SysTray~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.SystemTray
|
||||
import "../widgets" as Widgets
|
||||
import ".."
|
||||
|
||||
RowLayout {
|
||||
required property var bar;
|
||||
|
||||
spacing: 10;
|
||||
visible: SystemTray.items.values.length > 0
|
||||
|
||||
Repeater {
|
||||
model: SystemTray.items;
|
||||
|
||||
Widgets.IconButton {
|
||||
id: iconButton;
|
||||
implicitSize: 20;
|
||||
source: modelData.icon;
|
||||
|
||||
onClicked: modelData.display(bar, -parent.mapFromGlobal(0, 0).x, root.height+5);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
41
.stversions/bar/SysTray~20250509-203448.qml
Normal file
41
.stversions/bar/SysTray~20250509-203448.qml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.SystemTray
|
||||
import "../widgets" as Widgets
|
||||
import ".."
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
required property var bar
|
||||
spacing: 10
|
||||
visible: SystemTray.items.values.length > 0
|
||||
|
||||
Repeater {
|
||||
model: SystemTray.items
|
||||
|
||||
Widgets.IconButton {
|
||||
id: iconButton
|
||||
implicitSize: 20
|
||||
source: modelData.icon
|
||||
padding: 0
|
||||
|
||||
QsMenuAnchor {
|
||||
id: menuAnchor
|
||||
menu: modelData.menu
|
||||
|
||||
anchor {
|
||||
window: bar
|
||||
adjustment: PopupAdjustment.Flip
|
||||
|
||||
onAnchoring: {
|
||||
anchor.rect = mapToItem(bar.contentItem, -2, height + 4, width + 2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: menuAnchor.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
49
.stversions/bar/Workspaces~20250307-175400.qml
Normal file
49
.stversions/bar/Workspaces~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Io
|
||||
import ".."
|
||||
|
||||
RowLayout {
|
||||
property var sortedWorkspaces: {
|
||||
let values = Hyprland.workspaces.values.slice();
|
||||
values.sort(function(a, b) { return a.id - b.id; });
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
spacing: 6;
|
||||
|
||||
Repeater {
|
||||
model: sortedWorkspaces;
|
||||
|
||||
Rectangle {
|
||||
required property var modelData;
|
||||
width: 25;
|
||||
height: 12;
|
||||
radius: 10;
|
||||
|
||||
color: {
|
||||
let value = ShellGlobals.colors.light;
|
||||
|
||||
if (!modelData?.id || !Hyprland.focusedMonitor?.activeWorkspace?.id)
|
||||
return value;
|
||||
|
||||
if (workspaceButton.containsMouse) {
|
||||
value = ShellGlobals.colors.midlight;
|
||||
} else if (Hyprland.focusedMonitor.activeWorkspace.id == modelData.id) {
|
||||
value = ShellGlobals.colors.highlight;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: workspaceButton;
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onPressed: Hyprland.dispatch('workspace ' + modelData.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
.stversions/bar/control/ControlButton~20250307-175400.qml
Normal file
74
.stversions/bar/control/ControlButton~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Effects
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
property string source;
|
||||
property string text: "";
|
||||
property string subText: "";
|
||||
property real implicitSize; // icon implicit size
|
||||
property real padding: 0;
|
||||
property real radius: 5;
|
||||
signal clicked();
|
||||
|
||||
id: root;
|
||||
width: implicitSize*3;
|
||||
height: implicitSize*1.25;
|
||||
|
||||
Rectangle {
|
||||
id: iconBackground;
|
||||
color: iconButton.containsMouse
|
||||
? ShellGlobals.colors.innerHighlight
|
||||
: ShellGlobals.colors.midlight;
|
||||
border.color: iconButton.containsMouse
|
||||
? ShellGlobals.colors.highlight
|
||||
: ShellGlobals.colors.light;
|
||||
radius: root.radius;
|
||||
anchors.fill: parent;
|
||||
|
||||
RowLayout {
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
margins: root.padding;
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: iconImage;
|
||||
implicitSize: root.implicitSize;
|
||||
source: root.source;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: textLayout;
|
||||
spacing: 3;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
Text {
|
||||
text: root.text;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
font.bold: true;
|
||||
visible: text.length > 0;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.subText;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 10;
|
||||
visible: text.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: iconButton;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
onPressed: root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
96
.stversions/bar/control/ControlPanel~20250307-175400.qml
Normal file
96
.stversions/bar/control/ControlPanel~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.UPower
|
||||
import "../../widgets" as Widgets
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root;
|
||||
width: controlContainer.implicitWidth+25
|
||||
height: controlContainer.implicitHeight+25
|
||||
//width: 275;
|
||||
//height: 400;
|
||||
color: "transparent"
|
||||
visible: controlContainer.opacity > 0;
|
||||
|
||||
function show(x, y) {
|
||||
root.anchor.rect.x = x;
|
||||
root.anchor.rect.y = y;
|
||||
controlContainer.opacity = 1;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
controlContainer.opacity = 0;
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler;
|
||||
enabled: true;
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad;
|
||||
onHoveredChanged: {
|
||||
if (hovered === false) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: controlContainer;
|
||||
color: ShellGlobals.colors.window;
|
||||
radius: 5;
|
||||
opacity: 0; // TODO: change to 0
|
||||
layer.enabled: true;
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.02;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
implicitWidth: columnLayout.implicitWidth + 20 // Add margins
|
||||
implicitHeight: columnLayout.implicitHeight + 20 // Add margins
|
||||
|
||||
anchors {
|
||||
centerIn: parent;
|
||||
margins: 5;
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 300;
|
||||
easing.type: Easing.OutCubic;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
spacing: 10;
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
margins: 10 // Padding from the parent rectangle
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 10;
|
||||
|
||||
Rectangle {
|
||||
width: 120;
|
||||
height: 120;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 120;
|
||||
height: 120;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
.stversions/bar/control/ControlSlider~20250307-175400.qml
Normal file
64
.stversions/bar/control/ControlSlider~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Slider {
|
||||
id: slider;
|
||||
from: 0;
|
||||
to: 100;
|
||||
value: 50;
|
||||
|
||||
background: Rectangle {
|
||||
id: sliderContainer;
|
||||
width: slider.availableWidth;
|
||||
height: slider.availableHeight;
|
||||
color: "#e0e0e0";
|
||||
radius: 10;
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
source: Rectangle {
|
||||
width: sliderContainer.width;
|
||||
height: sliderContainer.height;
|
||||
radius: sliderContainer.radius;
|
||||
color: "white";
|
||||
}
|
||||
|
||||
maskSource: Rectangle {
|
||||
width: sliderContainer.width;
|
||||
height: sliderContainer.height;
|
||||
radius: sliderContainer.radius;
|
||||
color: "black";
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: handle;
|
||||
width: sliderContainer.width * (slider.value / slider.to);
|
||||
height: sliderContainer.height;
|
||||
color: ShellGlobals.colors.highlight;
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: 100;
|
||||
easing.type: Easing.OutQuad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//IconImage {
|
||||
// implicitSize: 20;
|
||||
// source: "root:resources/control/sleep.svg"
|
||||
//
|
||||
// anchors {
|
||||
// verticalCenter: parent.verticalCenter;
|
||||
// left: parent.left;
|
||||
// leftMargin: 15;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
handle: Item { }
|
||||
}
|
||||
70
.stversions/bar/control/ControlVSlider~20250307-175400.qml
Normal file
70
.stversions/bar/control/ControlVSlider~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Slider {
|
||||
id: slider;
|
||||
from: 0;
|
||||
to: 100;
|
||||
value: 50;
|
||||
orientation: Qt.Vertical;
|
||||
|
||||
background: Rectangle {
|
||||
id: sliderContainer;
|
||||
width: slider.availableWidth;
|
||||
height: slider.availableHeight;
|
||||
color: "#e0e0e0";
|
||||
radius: 10;
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
source: Rectangle {
|
||||
width: sliderContainer.width;
|
||||
height: sliderContainer.height;
|
||||
radius: sliderContainer.radius;
|
||||
color: "white";
|
||||
}
|
||||
|
||||
maskSource: Rectangle {
|
||||
width: sliderContainer.width;
|
||||
height: sliderContainer.height;
|
||||
radius: sliderContainer.radius;
|
||||
color: "black";
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: handle;
|
||||
width: sliderContainer.width;
|
||||
height: sliderContainer.height * (slider.value / slider.to);
|
||||
color: ShellGlobals.colors.highlight;
|
||||
|
||||
anchors {
|
||||
bottom: sliderContainer.bottom;
|
||||
horizontalCenter: sliderContainer.horizontalCenter;
|
||||
}
|
||||
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
duration: 100;
|
||||
easing.type: Easing.OutQuad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//IconImage {
|
||||
// implicitSize: 20;
|
||||
// source: "root:resources/control/sleep.svg"
|
||||
//
|
||||
// anchors {
|
||||
// verticalCenter: parent.verticalCenter;
|
||||
// left: parent.left;
|
||||
// leftMargin: 15;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
handle: Item { }
|
||||
}
|
||||
32
.stversions/bar/control/Control~20250307-175400.qml
Normal file
32
.stversions/bar/control/Control~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import "../../widgets" as Widgets
|
||||
import "../.."
|
||||
|
||||
Widgets.IconButton {
|
||||
required property var bar;
|
||||
|
||||
id: root;
|
||||
implicitSize: 20;
|
||||
padding: 2;
|
||||
source: "root:/resources/control/controls-button.svg";
|
||||
onClicked: {
|
||||
if (controlLoader.item.visible) {
|
||||
controlLoader.item.hide();
|
||||
} else {
|
||||
controlLoader.item.show(-root.mapFromGlobal(0, 0).x, bar.height);
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: controlLoader;
|
||||
loading: true;
|
||||
|
||||
ControlPanel {
|
||||
id: controlPanel;
|
||||
anchor.window: bar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
238
.stversions/bar/mpris/Card~20250509-203448.qml
Normal file
238
.stversions/bar/mpris/Card~20250509-203448.qml
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import "../.."
|
||||
import "../../widgets" as Widgets
|
||||
|
||||
Rectangle {
|
||||
required property var player
|
||||
|
||||
radius: 5
|
||||
color: "transparent"
|
||||
implicitHeight: 220
|
||||
|
||||
RowLayout {
|
||||
id: cardLayout
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 10
|
||||
rightMargin: 10
|
||||
topMargin: 10 // Added top margin for better spacing
|
||||
bottomMargin: 10 // Added bottom margin for better spacing
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mprisImage
|
||||
color: "transparent"
|
||||
radius: 10
|
||||
width: 200
|
||||
height: 200
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: true
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: player.trackArtUrl
|
||||
sourceSize.width: 256
|
||||
sourceSize.height: 256
|
||||
fillMode: Image.PreserveAspectFit
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
source: Rectangle {
|
||||
width: mprisImage.width
|
||||
height: mprisImage.height
|
||||
radius: 10
|
||||
color: "white"
|
||||
}
|
||||
|
||||
maskSource: Rectangle {
|
||||
width: mprisImage.width
|
||||
height: mprisImage.height
|
||||
radius: 10
|
||||
color: "black"
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
spread: 0.02
|
||||
samples: 25
|
||||
color: "#80000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 5
|
||||
|
||||
Text {
|
||||
text: player.trackArtist
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 13
|
||||
font.bold: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Text {
|
||||
text: player.trackTitle
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 13
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
text: timeStr(player.position)
|
||||
color: ShellGlobals.colors.text
|
||||
|
||||
font {
|
||||
pointSize: 9
|
||||
bold: true
|
||||
}
|
||||
}
|
||||
|
||||
ColorQuantizer {
|
||||
id: colorQuantizer
|
||||
source: Qt.resolvedUrl(Media.trackedPlayer?.trackArtUrl ?? "")
|
||||
depth: 0
|
||||
rescaleSize: 64
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: slider
|
||||
from: 0
|
||||
to: player.length
|
||||
enabled: false
|
||||
//enabled: player.canSeek
|
||||
value: player.position
|
||||
|
||||
implicitHeight: 7
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 10
|
||||
Layout.leftMargin: 5
|
||||
Layout.rightMargin: 5
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
|
||||
background: Rectangle {
|
||||
id: sliderContainer
|
||||
width: slider.availableWidth
|
||||
height: slider.implicitHeight
|
||||
color: "white"
|
||||
radius: 4
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
source: Rectangle {
|
||||
width: sliderContainer.width
|
||||
height: sliderContainer.height
|
||||
radius: sliderContainer.radius
|
||||
color: "white"
|
||||
}
|
||||
|
||||
maskSource: Rectangle {
|
||||
width: sliderContainer.width
|
||||
height: sliderContainer.height
|
||||
radius: sliderContainer.radius
|
||||
color: "black"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: sliderContainer.width * (slider.value / slider.to)
|
||||
height: sliderContainer.height
|
||||
color: colorQuantizer.colors[0].darker(1.2)
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: 100
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
|
||||
y: slider.topPadding + slider.availableHeight / 2 - height / 2
|
||||
width: 16
|
||||
height: 16
|
||||
radius: width / 2
|
||||
color: colorQuantizer.colors[0].darker(1.4)
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 1
|
||||
radius: 4.0
|
||||
samples: 9
|
||||
color: "#30000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: timeStr(player.length)
|
||||
color: ShellGlobals.colors.text
|
||||
|
||||
font {
|
||||
pointSize: 9
|
||||
bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Music Controls
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
Widgets.IconButton {
|
||||
implicitSize: 36
|
||||
padding: 4
|
||||
source: "root:resources/mpris/previous.svg"
|
||||
onClicked: player.previous()
|
||||
}
|
||||
|
||||
Widgets.IconButton {
|
||||
implicitSize: 36
|
||||
padding: 4
|
||||
source: player?.isPlaying ? "root:resources/mpris/pause.svg" : "root:resources/mpris/play.svg"
|
||||
onClicked: {
|
||||
if (!player.canPlay)
|
||||
return;
|
||||
player.isPlaying ? player.pause() : player.play();
|
||||
}
|
||||
}
|
||||
|
||||
Widgets.IconButton {
|
||||
implicitSize: 36
|
||||
padding: 4
|
||||
source: "root:resources/mpris/next.svg"
|
||||
onClicked: player.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function timeStr(time: int): string {
|
||||
const seconds = time % 60;
|
||||
const minutes = Math.floor(time / 60);
|
||||
|
||||
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
}
|
||||
95
.stversions/bar/mpris/MediaInfo~20250107-004337.qml
Normal file
95
.stversions/bar/mpris/MediaInfo~20250107-004337.qml
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
import QtQuick
|
||||
import Quickshell.Services.Mpris
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
required property var bar;
|
||||
|
||||
width: statusInfo.width;
|
||||
height: parent.height;
|
||||
|
||||
MediaSwitcher {
|
||||
id: mediaSwitcher;
|
||||
anchor.window: bar;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: playButton;
|
||||
hoverEnabled: true;
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse)=> {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
mediaSwitcher.visible = !mediaSwitcher.visible;
|
||||
} else {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusInfo;
|
||||
width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width;
|
||||
visible: Media.trackedPlayer != null;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
top: parent.top;
|
||||
bottom: parent.botton;
|
||||
margins: 3.5;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.innerHighlight;
|
||||
border.color: ShellGlobals.colors.highlight;
|
||||
radius: 5;
|
||||
width: parent.width + 25;
|
||||
height: parent.height;
|
||||
visible: playButton.containsMouse;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: statusIcon;
|
||||
implicitSize: 13;
|
||||
source: Media.trackedPlayer?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg");
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: nowPlayingText.left;
|
||||
rightMargin: 10;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nowPlayingText
|
||||
color: ShellGlobals.colors.text;
|
||||
text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}`;
|
||||
font.pointSize: 11;
|
||||
elide: Text.ElideRight;
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: parent.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 40) {
|
||||
return text.substring(0, 40) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
96
.stversions/bar/mpris/MediaInfo~20250107-004401.qml
Normal file
96
.stversions/bar/mpris/MediaInfo~20250107-004401.qml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import QtQuick
|
||||
import Quickshell.Services.Mpris
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
required property var bar;
|
||||
|
||||
width: statusInfo.width;
|
||||
height: parent.height;
|
||||
|
||||
MediaSwitcher {
|
||||
id: mediaSwitcher;
|
||||
anchor.window: bar;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: playButton;
|
||||
hoverEnabled: true;
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse)=> {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
mediaSwitcher.visible = !mediaSwitcher.visible;
|
||||
} else {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusInfo;
|
||||
width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width;
|
||||
visible: Media.trackedPlayer != null;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
top: parent.top;
|
||||
bottom: parent.botton;
|
||||
margins: 3.5;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.innerHighlight;
|
||||
border.color: ShellGlobals.colors.highlight;
|
||||
radius: 5;
|
||||
width: parent.width + 25;
|
||||
height: parent.height;
|
||||
visible: playButton.containsMouse;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: statusIcon;
|
||||
implicitSize: 13;
|
||||
source: Media.trackedPlayer?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg");
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: nowPlayingText.left;
|
||||
rightMargin: 10;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nowPlayingText
|
||||
color: ShellGlobals.colors.text;
|
||||
text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}`;
|
||||
font.pointSize: 11;
|
||||
elide: Text.ElideRight;
|
||||
contentWidth: 100;
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: parent.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 40) {
|
||||
return text.substring(0, 40) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
96
.stversions/bar/mpris/MediaInfo~20250107-004431.qml
Normal file
96
.stversions/bar/mpris/MediaInfo~20250107-004431.qml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import QtQuick
|
||||
import Quickshell.Services.Mpris
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
required property var bar;
|
||||
|
||||
width: statusInfo.width;
|
||||
height: parent.height;
|
||||
|
||||
MediaSwitcher {
|
||||
id: mediaSwitcher;
|
||||
anchor.window: bar;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: playButton;
|
||||
hoverEnabled: true;
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse)=> {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
mediaSwitcher.visible = !mediaSwitcher.visible;
|
||||
} else {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusInfo;
|
||||
width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width;
|
||||
visible: Media.trackedPlayer != null;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
top: parent.top;
|
||||
bottom: parent.botton;
|
||||
margins: 3.5;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.innerHighlight;
|
||||
border.color: ShellGlobals.colors.highlight;
|
||||
radius: 5;
|
||||
width: parent.width + 25;
|
||||
height: parent.height;
|
||||
visible: playButton.containsMouse;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: statusIcon;
|
||||
implicitSize: 13;
|
||||
source: Media.trackedPlayer?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg");
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: nowPlayingText.left;
|
||||
rightMargin: 10;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nowPlayingText
|
||||
color: ShellGlobals.colors.text;
|
||||
text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}`;
|
||||
font.pointSize: 11;
|
||||
elide: Text.ElideRight;
|
||||
width: 100;
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: parent.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 40) {
|
||||
return text.substring(0, 40) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
96
.stversions/bar/mpris/MediaInfo~20250107-004532.qml
Normal file
96
.stversions/bar/mpris/MediaInfo~20250107-004532.qml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import QtQuick
|
||||
import Quickshell.Services.Mpris
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
required property var bar;
|
||||
|
||||
width: statusInfo.width;
|
||||
height: parent.height;
|
||||
|
||||
MediaSwitcher {
|
||||
id: mediaSwitcher;
|
||||
anchor.window: bar;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: playButton;
|
||||
hoverEnabled: true;
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse)=> {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
mediaSwitcher.visible = !mediaSwitcher.visible;
|
||||
} else {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusInfo;
|
||||
width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width;
|
||||
visible: Media.trackedPlayer != null;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
top: parent.top;
|
||||
bottom: parent.botton;
|
||||
margins: 3.5;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.innerHighlight;
|
||||
border.color: ShellGlobals.colors.highlight;
|
||||
radius: 5;
|
||||
width: parent.width + 25;
|
||||
height: parent.height;
|
||||
visible: playButton.containsMouse;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: statusIcon;
|
||||
implicitSize: 13;
|
||||
source: Media.trackedPlayer?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg");
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: nowPlayingText.left;
|
||||
rightMargin: 10;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nowPlayingText
|
||||
color: ShellGlobals.colors.text;
|
||||
text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}`;
|
||||
font.pointSize: 11;
|
||||
width: 250;
|
||||
elide: Text.ElideRight;
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: parent.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 40) {
|
||||
return text.substring(0, 40) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
96
.stversions/bar/mpris/MediaInfo~20250307-175400.qml
Normal file
96
.stversions/bar/mpris/MediaInfo~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import QtQuick
|
||||
import Quickshell.Services.Mpris
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
required property var bar;
|
||||
|
||||
width: statusInfo.width;
|
||||
height: parent.height;
|
||||
|
||||
MediaSwitcher {
|
||||
id: mediaSwitcher;
|
||||
anchor.window: bar;
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2;
|
||||
anchor.rect.y: parentWindow.height;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: playButton;
|
||||
hoverEnabled: true;
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: (mouse)=> {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
if (mediaSwitcher.visible) {
|
||||
mediaSwitcher.hide();
|
||||
} else {
|
||||
mediaSwitcher.show();
|
||||
}
|
||||
//mediaSwitcher.visible = !mediaSwitcher.visible;
|
||||
} else {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusInfo;
|
||||
width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width;
|
||||
visible: Media.trackedPlayer != null;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
verticalCenter: parent.verticalCenter;
|
||||
top: parent.top;
|
||||
bottom: parent.botton;
|
||||
margins: 3.5;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.innerHighlight;
|
||||
border.color: ShellGlobals.colors.highlight;
|
||||
radius: 3;
|
||||
width: parent.width + 25;
|
||||
height: parent.height;
|
||||
visible: playButton.containsMouse;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: statusIcon;
|
||||
implicitSize: 13;
|
||||
source: Media.trackedPlayer?.isPlaying
|
||||
? "root:resources/mpris/pause.svg"
|
||||
: "root:resources/mpris/play.svg";
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: nowPlayingText.left;
|
||||
rightMargin: 10;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nowPlayingText
|
||||
color: ShellGlobals.colors.text;
|
||||
text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}`;
|
||||
font.pointSize: 11;
|
||||
width: Math.min(implicitWidth, 250);
|
||||
elide: Text.ElideRight;
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter;
|
||||
right: parent.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
.stversions/bar/mpris/MediaSwitcher.qml~20250307-175400.bak
Normal file
122
.stversions/bar/mpris/MediaSwitcher.qml~20250307-175400.bak
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root;
|
||||
width: 500
|
||||
height: 500
|
||||
color: "transparent";
|
||||
visible: false;
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height + 5;
|
||||
|
||||
Rectangle {
|
||||
color: ShellGlobals.colors.window;
|
||||
radius:5;
|
||||
border.color: mouse.hovered
|
||||
? ShellGlobals.colors.highlight
|
||||
: ShellGlobals.colors.light;
|
||||
border.width: 2;
|
||||
anchors.fill: parent;
|
||||
|
||||
// NOTE: You cannot stack mouseArea's that have hovered enabled.
|
||||
// This is the workaround for panel hover detection.
|
||||
HoverHandler {
|
||||
id: mouse
|
||||
enabled: true;
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad;
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
root.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter;
|
||||
top: parent.top;
|
||||
margins: 20;
|
||||
}
|
||||
|
||||
Image {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: 300
|
||||
Layout.preferredHeight: 300
|
||||
source: Media.trackedPlayer.trackArtUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
|
||||
sourceSize {
|
||||
width: 512
|
||||
height: 512
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: truncate(Media.trackedPlayer.trackArtist);
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignHCenter;
|
||||
Layout.topMargin: 20;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: truncate(Media.trackedPlayer.trackTitle);
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignHCenter;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20;
|
||||
Layout.alignment: Qt.AlignHCenter;
|
||||
Layout.topMargin: 10;
|
||||
|
||||
IconButton {
|
||||
implicitSize: 32
|
||||
source: Qt.resolvedUrl("../../resources/mpris/previous.svg");
|
||||
onClicked: {
|
||||
Media.trackedPlayer.previous();
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 36;
|
||||
source: Media.trackedPlayer?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg");
|
||||
onClicked: {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 32;
|
||||
source: Qt.resolvedUrl("../../resources/mpris/next.svg");
|
||||
onClicked: {
|
||||
Media.trackedPlayer.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make this some sort of global function
|
||||
function truncate(text) {
|
||||
if (text?.length > 60) {
|
||||
return text.substring(0, 60) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
179
.stversions/bar/mpris/MediaSwitcher~20250107-004917.qml
Normal file
179
.stversions/bar/mpris/MediaSwitcher~20250107-004917.qml
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mediaPlayerContainer.width + 15;
|
||||
height: mediaPlayerContainer.height + 15;
|
||||
color: "transparent"
|
||||
visible: false
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height;
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: true
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mediaPlayerContainer;
|
||||
width: 500;
|
||||
height: mediaPlayerColumn.height + 20;
|
||||
color: ShellGlobals.colors.window
|
||||
radius: 5
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.02;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
anchors.centerIn: parent;
|
||||
|
||||
//border.color: hoverHandler.hovered
|
||||
// ? ShellGlobals.colors.highlight
|
||||
// : ShellGlobals.colors.light
|
||||
//border.width: 2
|
||||
|
||||
ColumnLayout {
|
||||
id: mediaPlayerColumn;
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Mpris.players
|
||||
|
||||
Rectangle {
|
||||
// TODO: do color quant for a background gradient and then blur it
|
||||
required property var modelData;
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.light;
|
||||
height: 80
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 60
|
||||
Layout.preferredHeight: 60
|
||||
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.fill: parent
|
||||
radius: 5;
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: modelData.trackArtUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: mask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Text {
|
||||
text: modelData.trackArtist;
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 13
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
width: 350;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.trackTitle;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignLeft;
|
||||
Layout.fillWidth: true;
|
||||
//width: 350;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer to push controls to the right
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 20
|
||||
}
|
||||
|
||||
// Controls container
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/previous.svg")
|
||||
onClicked: modelData.previous()
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: modelData?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg")
|
||||
onClicked: {
|
||||
if (!modelData.canPlay)
|
||||
return
|
||||
modelData.isPlaying
|
||||
? modelData.pause()
|
||||
: modelData.play()
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/next.svg")
|
||||
onClicked: modelData.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 30) {
|
||||
return text.substring(0, 30) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
178
.stversions/bar/mpris/MediaSwitcher~20250107-004927.qml
Normal file
178
.stversions/bar/mpris/MediaSwitcher~20250107-004927.qml
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mediaPlayerContainer.width + 15;
|
||||
height: mediaPlayerContainer.height + 15;
|
||||
color: "transparent"
|
||||
visible: false
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height;
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: true
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mediaPlayerContainer;
|
||||
width: 500;
|
||||
height: mediaPlayerColumn.height + 20;
|
||||
color: ShellGlobals.colors.window
|
||||
radius: 5
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.02;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
anchors.centerIn: parent;
|
||||
|
||||
//border.color: hoverHandler.hovered
|
||||
// ? ShellGlobals.colors.highlight
|
||||
// : ShellGlobals.colors.light
|
||||
//border.width: 2
|
||||
|
||||
ColumnLayout {
|
||||
id: mediaPlayerColumn;
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Mpris.players
|
||||
|
||||
Rectangle {
|
||||
// TODO: do color quant for a background gradient and then blur it
|
||||
required property var modelData;
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.light;
|
||||
height: 80
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 60
|
||||
Layout.preferredHeight: 60
|
||||
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.fill: parent
|
||||
radius: 5;
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: modelData.trackArtUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: mask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Text {
|
||||
text: modelData.trackArtist;
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 13
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
width: 350;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.trackTitle;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignLeft;
|
||||
Layout.fillWidth: true;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer to push controls to the right
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 20
|
||||
}
|
||||
|
||||
// Controls container
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/previous.svg")
|
||||
onClicked: modelData.previous()
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: modelData?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg")
|
||||
onClicked: {
|
||||
if (!modelData.canPlay)
|
||||
return
|
||||
modelData.isPlaying
|
||||
? modelData.pause()
|
||||
: modelData.play()
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/next.svg")
|
||||
onClicked: modelData.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 30) {
|
||||
return text.substring(0, 30) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
178
.stversions/bar/mpris/MediaSwitcher~20250107-004947.qml
Normal file
178
.stversions/bar/mpris/MediaSwitcher~20250107-004947.qml
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mediaPlayerContainer.width + 15;
|
||||
height: mediaPlayerContainer.height + 15;
|
||||
color: "transparent"
|
||||
visible: false
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height;
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: true
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mediaPlayerContainer;
|
||||
width: 500;
|
||||
height: mediaPlayerColumn.height + 20;
|
||||
color: ShellGlobals.colors.window
|
||||
radius: 5
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.02;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
anchors.centerIn: parent;
|
||||
|
||||
//border.color: hoverHandler.hovered
|
||||
// ? ShellGlobals.colors.highlight
|
||||
// : ShellGlobals.colors.light
|
||||
//border.width: 2
|
||||
|
||||
ColumnLayout {
|
||||
id: mediaPlayerColumn;
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Mpris.players
|
||||
|
||||
Rectangle {
|
||||
// TODO: do color quant for a background gradient and then blur it
|
||||
required property var modelData;
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.light;
|
||||
height: 80
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 60
|
||||
Layout.preferredHeight: 60
|
||||
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.fill: parent
|
||||
radius: 5;
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: modelData.trackArtUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: mask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Text {
|
||||
text: modelData.trackArtist;
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 13
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
//width: 350;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.trackTitle;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignLeft;
|
||||
Layout.fillWidth: true;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer to push controls to the right
|
||||
//Item {
|
||||
// Layout.fillWidth: true
|
||||
// Layout.minimumWidth: 20
|
||||
//}
|
||||
|
||||
// Controls container
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/previous.svg")
|
||||
onClicked: modelData.previous()
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: modelData?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg")
|
||||
onClicked: {
|
||||
if (!modelData.canPlay)
|
||||
return
|
||||
modelData.isPlaying
|
||||
? modelData.pause()
|
||||
: modelData.play()
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/next.svg")
|
||||
onClicked: modelData.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 30) {
|
||||
return text.substring(0, 30) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
171
.stversions/bar/mpris/MediaSwitcher~20250107-005025.qml
Normal file
171
.stversions/bar/mpris/MediaSwitcher~20250107-005025.qml
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mediaPlayerContainer.width + 15;
|
||||
height: mediaPlayerContainer.height + 15;
|
||||
color: "transparent"
|
||||
visible: false
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height;
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: true
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mediaPlayerContainer;
|
||||
width: 500;
|
||||
height: mediaPlayerColumn.height + 20;
|
||||
color: ShellGlobals.colors.window
|
||||
radius: 5
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.02;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
anchors.centerIn: parent;
|
||||
|
||||
//border.color: hoverHandler.hovered
|
||||
// ? ShellGlobals.colors.highlight
|
||||
// : ShellGlobals.colors.light
|
||||
//border.width: 2
|
||||
|
||||
ColumnLayout {
|
||||
id: mediaPlayerColumn;
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Mpris.players
|
||||
|
||||
Rectangle {
|
||||
// TODO: do color quant for a background gradient and then blur it
|
||||
required property var modelData;
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.light;
|
||||
height: 80
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: 15
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 60
|
||||
Layout.preferredHeight: 60
|
||||
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.fill: parent
|
||||
radius: 5;
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: modelData.trackArtUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: mask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Text {
|
||||
text: modelData.trackArtist;
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 13
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.trackTitle;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignLeft;
|
||||
Layout.fillWidth: true;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
}
|
||||
|
||||
// Controls container
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/previous.svg")
|
||||
onClicked: modelData.previous()
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: modelData?.isPlaying
|
||||
? Qt.resolvedUrl("../../resources/mpris/pause.svg")
|
||||
: Qt.resolvedUrl("../../resources/mpris/play.svg")
|
||||
onClicked: {
|
||||
if (!modelData.canPlay)
|
||||
return
|
||||
modelData.isPlaying
|
||||
? modelData.pause()
|
||||
: modelData.play()
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
implicitSize: 24
|
||||
source: Qt.resolvedUrl("../../resources/mpris/next.svg")
|
||||
onClicked: modelData.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function truncate(text) {
|
||||
if (text?.length > 30) {
|
||||
return text.substring(0, 30) + " ..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
191
.stversions/bar/mpris/MediaSwitcher~20250307-175400.qml
Normal file
191
.stversions/bar/mpris/MediaSwitcher~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import "../../widgets/" as Widgets
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mediaPlayerContainer.width + 10;
|
||||
height: mediaPlayerContainer.height + 10;
|
||||
color: "transparent"
|
||||
visible: mediaPlayerContainer.opacity > 0;
|
||||
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2;
|
||||
anchor.rect.y: parentWindow.height;
|
||||
|
||||
function show() {
|
||||
mediaPlayerContainer.opacity = 1;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
mediaPlayerContainer.opacity = 0;
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler;
|
||||
enabled: true;
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad;
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mediaPlayerContainer;
|
||||
width: 500;
|
||||
height: mediaPlayerColumn.height + 20;
|
||||
color: ShellGlobals.colors.window;
|
||||
radius: 5;
|
||||
opacity: 0;
|
||||
|
||||
layer.enabled: true;
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.02;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
anchors.centerIn: parent;
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 300;
|
||||
easing.type: Easing.OutCubic;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
id: mediaPlayerColumn;
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Mpris.players
|
||||
|
||||
Rectangle {
|
||||
required property var modelData;
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.midlight;
|
||||
border.color: ShellGlobals.colors.light;
|
||||
height: 75;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
RowLayout {
|
||||
spacing: 15;
|
||||
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
leftMargin: 10;
|
||||
rightMargin: 10;
|
||||
topMargin: 0;
|
||||
bottomMargin: 0;
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 60;
|
||||
Layout.preferredHeight: 60;
|
||||
Layout.alignment: Qt.AlignVCenter;
|
||||
visible: modelData.trackArtUrl != "";
|
||||
|
||||
Rectangle {
|
||||
id: mask;
|
||||
anchors.fill: parent;
|
||||
radius: 5;
|
||||
visible: false;
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.fill: parent;
|
||||
source: modelData.trackArtUrl;
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
layer.enabled: true;
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true;
|
||||
Layout.fillHeight: true;
|
||||
spacing: 5;
|
||||
Layout.alignment: Qt.AlignVCenter;
|
||||
|
||||
Item { Layout.fillHeight: true; }
|
||||
|
||||
Text {
|
||||
text: modelData.trackArtist;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
font.bold: true;
|
||||
Layout.alignment: Qt.AlignLeft;
|
||||
Layout.fillWidth: true;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: modelData.trackTitle;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 13;
|
||||
Layout.alignment: Qt.AlignLeft;
|
||||
Layout.fillWidth: true;
|
||||
elide: Text.ElideRight;
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; }
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 2;
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter;
|
||||
|
||||
Widgets.IconButton {
|
||||
implicitSize: 28;
|
||||
padding: 4;
|
||||
source: "root:resources/mpris/previous.svg";
|
||||
onClicked: modelData.previous();
|
||||
}
|
||||
|
||||
Widgets.IconButton {
|
||||
implicitSize: 28;
|
||||
padding: 4;
|
||||
source: modelData?.isPlaying
|
||||
? "root:resources/mpris/pause.svg"
|
||||
: "root:resources/mpris/play.svg";
|
||||
onClicked: {
|
||||
if (!modelData.canPlay)
|
||||
return;
|
||||
modelData.isPlaying
|
||||
? modelData.pause()
|
||||
: modelData.play();
|
||||
}
|
||||
}
|
||||
|
||||
Widgets.IconButton {
|
||||
implicitSize: 28;
|
||||
padding: 4;
|
||||
source: "root:resources/mpris/next.svg";
|
||||
onClicked: modelData.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
45
.stversions/bar/mpris/Media~20250307-175400.qml
Normal file
45
.stversions/bar/mpris/Media~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
|
||||
Singleton {
|
||||
property MprisPlayer trackedPlayer;
|
||||
|
||||
id: root;
|
||||
|
||||
Instantiator {
|
||||
model: Mpris.players;
|
||||
|
||||
Connections {
|
||||
required property MprisPlayer modelData;
|
||||
target: modelData;
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.trackedPlayer == null || modelData.isPlaying) {
|
||||
root.trackedPlayer = modelData;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (root.trackedPlayer == null || !root.trackedPlayer.isPlaying) {
|
||||
for (const player of Mpris.players.values) {
|
||||
if (player.playbackState.isPlaying) {
|
||||
root.trackedPlayer = player;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (trackedPlayer == null && Mpris.players.values.length != 0) {
|
||||
trackedPlayer = Mpris.players.values[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onPlaybackStateChanged() {
|
||||
if (root.trackedPlayer !== modelData) root.trackedPlayer = modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
.stversions/bar/mpris/Player~20250509-203448.qml
Normal file
151
.stversions/bar/mpris/Player~20250509-203448.qml
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Mpris
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mediaPlayerContainer.width + 10
|
||||
height: mediaPlayerContainer.height + 10
|
||||
color: "transparent"
|
||||
visible: mediaPlayerContainer.opacity > 0
|
||||
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height
|
||||
|
||||
function show() {
|
||||
mediaPlayerContainer.opacity = 1;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
mediaPlayerContainer.opacity = 0;
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: true
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mediaPlayerContainer
|
||||
width: 500
|
||||
height: mediaPlayerColumn.height + 20
|
||||
color: ShellGlobals.colors.base
|
||||
radius: 5
|
||||
opacity: 0
|
||||
anchors.centerIn: parent
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
source: Rectangle {
|
||||
width: mediaPlayerContainer.width
|
||||
height: mediaPlayerContainer.height
|
||||
radius: mediaPlayerContainer.radius
|
||||
color: "white"
|
||||
}
|
||||
|
||||
maskSource: Rectangle {
|
||||
width: mediaPlayerContainer.width
|
||||
height: mediaPlayerContainer.height
|
||||
radius: mediaPlayerContainer.radius
|
||||
color: "black"
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
spread: 0.02
|
||||
samples: 25
|
||||
color: "#80000000"
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 300
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
ColorQuantizer {
|
||||
id: colorQuantizer
|
||||
source: Qt.resolvedUrl(Media.trackedPlayer?.trackArtUrl ?? "")
|
||||
depth: 2
|
||||
rescaleSize: 64
|
||||
|
||||
onColorsChanged: {
|
||||
Media.colors = colors;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
property color topLeftColor: colorQuantizer?.colors[0] ?? "white"
|
||||
property color topRightColor: colorQuantizer?.colors[1] ?? "black"
|
||||
property color bottomLeftColor: colorQuantizer?.colors[2] ?? "white"
|
||||
property color bottomRightColor: colorQuantizer?.colors[3] ?? "black"
|
||||
|
||||
anchors.fill: parent
|
||||
fragmentShader: "root:/shaders/vertexgradient.frag.qsb"
|
||||
vertexShader: "root:/shaders/vertexgradient.vert.qsb"
|
||||
|
||||
Behavior on topLeftColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on topRightColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on bottomLeftColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on bottomRightColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: mediaPlayerColumn
|
||||
spacing: 10
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.margins: 10
|
||||
implicitHeight: childrenRect.height
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
// Media Cards
|
||||
Repeater {
|
||||
model: Mpris.players
|
||||
|
||||
Card {
|
||||
required property var modelData
|
||||
player: modelData
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
174
.stversions/bar/mpris/Status~20250509-203451.qml
Normal file
174
.stversions/bar/mpris/Status~20250509-203451.qml
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
import QtQuick
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Mpris
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import "../.."
|
||||
|
||||
Item {
|
||||
id: root
|
||||
required property var bar
|
||||
|
||||
width: statusInfo.width + 125
|
||||
height: parent.height
|
||||
visible: Mpris.players.values.length != 0
|
||||
|
||||
Player {
|
||||
id: mediaPlayer
|
||||
anchor.window: bar
|
||||
anchor.rect.x: parentWindow.width / 2 - width / 2
|
||||
anchor.rect.y: parentWindow.height
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: playButton
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: mouse => {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
if (mediaPlayer.visible) {
|
||||
mediaPlayer.hide();
|
||||
} else {
|
||||
mediaPlayer.show();
|
||||
}
|
||||
} else {
|
||||
if (!Media.trackedPlayer.canPlay || Media.trackedPlayer == null)
|
||||
return;
|
||||
|
||||
if (Media.trackedPlayer.isPlaying)
|
||||
Media.trackedPlayer.pause();
|
||||
else
|
||||
Media.trackedPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: gradientShader
|
||||
property color topLeftColor: Media?.colors[0] ?? "white"
|
||||
property color topRightColor: Media?.colors[1] ?? "black"
|
||||
property color bottomLeftColor: Media?.colors[2] ?? "white"
|
||||
property color bottomRightColor: Media?.colors[3] ?? "black"
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
fragmentShader: "root:/shaders/vertexgradient.frag.qsb"
|
||||
vertexShader: "root:/shaders/vertexgradient.vert.qsb"
|
||||
|
||||
Behavior on topLeftColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on topRightColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on bottomLeftColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on bottomRightColor {
|
||||
ColorAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: artRect
|
||||
anchors.fill: gradientShader
|
||||
antialiasing: true
|
||||
visible: false
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: "transparent"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.5
|
||||
color: "white"
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpacityMask {
|
||||
id: clip
|
||||
source: gradientShader
|
||||
anchors.fill: gradientShader
|
||||
maskSource: artRect
|
||||
cached: false
|
||||
visible: false
|
||||
}
|
||||
|
||||
GaussianBlur {
|
||||
id: blur
|
||||
visible: root.visible
|
||||
source: clip
|
||||
anchors.fill: clip
|
||||
radius: 16
|
||||
samples: radius * 2
|
||||
transparentBorder: true
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusInfo
|
||||
width: statusIcon.width + statusIcon.anchors.rightMargin + nowPlayingText.width
|
||||
height: parent.height
|
||||
visible: Media.trackedPlayer != null
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
verticalCenter: parent.verticalCenter
|
||||
top: parent.top
|
||||
bottom: parent.botton
|
||||
margins: 3.5
|
||||
}
|
||||
|
||||
//Rectangle {
|
||||
// color: ShellGlobals.colors.accent
|
||||
// radius: 3
|
||||
// width: parent.width + 25
|
||||
// height: parent.height - 7
|
||||
// visible: playButton.containsMouse
|
||||
// anchors.centerIn: parent
|
||||
//}
|
||||
|
||||
IconImage {
|
||||
id: statusIcon
|
||||
implicitSize: 13
|
||||
source: Media.trackedPlayer?.isPlaying ? "root:resources/mpris/pause.svg" : "root:resources/mpris/play.svg"
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: nowPlayingText.left
|
||||
rightMargin: 10
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: nowPlayingText
|
||||
color: ShellGlobals.colors.text
|
||||
text: `${Media.trackedPlayer?.trackArtist} - ${Media.trackedPlayer?.trackTitle}`
|
||||
font.pointSize: 11
|
||||
width: Math.min(implicitWidth, 250)
|
||||
elide: Text.ElideRight
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import ".."
|
||||
|
||||
PanelWindow {
|
||||
required property var bar;
|
||||
|
||||
id: notificationWindow;
|
||||
color: "transparent";
|
||||
width: 550;
|
||||
height: 600;
|
||||
visible: true;
|
||||
mask: Region { item: notifLayout; }
|
||||
|
||||
anchors {
|
||||
top: true;
|
||||
bottom: true;
|
||||
}
|
||||
|
||||
margins {
|
||||
top: 5;
|
||||
bottom: 5;
|
||||
right: 5;
|
||||
}
|
||||
|
||||
|
||||
NotificationServer {
|
||||
id: notificationServer;
|
||||
actionsSupported: true;
|
||||
persistenceSupported: true;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: notificationServer;
|
||||
|
||||
function onNotification(notification) {
|
||||
notification.tracked = true;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: notifLayout;
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
left: parent.left;
|
||||
right: parent.right;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: notificationServer.trackedNotifications;
|
||||
|
||||
Toast {
|
||||
required property var modelData;
|
||||
notification: modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Notifications
|
||||
import ".."
|
||||
|
||||
Scope {
|
||||
required property var bar;
|
||||
|
||||
NotificationServer {
|
||||
id: notificationServer;
|
||||
actionsSupported: true;
|
||||
persistenceSupported: true;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: notificationServer;
|
||||
|
||||
function onNotification(notification) {
|
||||
notificationLoader.item.visible = true;
|
||||
notification.tracked = true;
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: notificationLoader;
|
||||
loading: true;
|
||||
|
||||
PanelWindow {
|
||||
id: notificationWindow;
|
||||
color: "transparent";
|
||||
width: 500;
|
||||
visible: false;
|
||||
exclusionMode: ExclusionMode.Normal;
|
||||
mask: Region { item: notifLayout; }
|
||||
|
||||
anchors {
|
||||
top: true;
|
||||
bottom: true;
|
||||
right: true;
|
||||
}
|
||||
|
||||
margins {
|
||||
top: 5;
|
||||
bottom: 5;
|
||||
right: 5;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: notifLayout;
|
||||
spacing: 15;
|
||||
|
||||
anchors {
|
||||
top: parent.top;
|
||||
left: parent.left;
|
||||
right: parent.right;
|
||||
margins: 5;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: notificationServer.trackedNotifications;
|
||||
|
||||
Toast {
|
||||
required property var modelData;
|
||||
notification: modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
.stversions/bar/notifications/Toast~20241229-025203.qml
Normal file
105
.stversions/bar/notifications/Toast~20241229-025203.qml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Notifications
|
||||
import "../.."
|
||||
|
||||
Rectangle {
|
||||
required property var notification
|
||||
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.bar;
|
||||
border.color: notificationArea.containsMouse
|
||||
? ShellGlobals.colors.highlight
|
||||
: ShellGlobals.colors.light;
|
||||
border.width: 2;
|
||||
width: parent.width;
|
||||
height: column.implicitHeight + 20;
|
||||
|
||||
MouseArea {
|
||||
id: notificationArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column;
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
margins: 10;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
IconImage {
|
||||
visible: notification.appIcon == null;
|
||||
source: Qt.resolvedUrl(notification.appIcon);
|
||||
implicitSize: 25;
|
||||
}
|
||||
|
||||
Text {
|
||||
id: summaryText
|
||||
text: notification.summary
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 14
|
||||
font.bold: true
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom;
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 16;
|
||||
height: 16;
|
||||
Layout.alignment: Qt.AlighRight | Qt.AlignTop;
|
||||
|
||||
Rectangle {
|
||||
color: "#FF474D";
|
||||
radius: 5;
|
||||
visible: closeButtonArea.containsMouse;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: closeButtonArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
notification.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
source: "image://icon/window-close";
|
||||
implicitSize: 28;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
id: bodyText
|
||||
text: notification.body
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 11;
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
//IconImage {
|
||||
// visible: notification.image != null;
|
||||
// source: Qt.resolvedUrl(notification.image);
|
||||
// implicitSize: 25;
|
||||
//}
|
||||
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
105
.stversions/bar/notifications/Toast~20241229-183725.qml
Normal file
105
.stversions/bar/notifications/Toast~20241229-183725.qml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Notifications
|
||||
import "../.."
|
||||
|
||||
Rectangle {
|
||||
required property var notification
|
||||
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.bar;
|
||||
border.color: notificationArea.containsMouse
|
||||
? ShellGlobals.colors.highlight
|
||||
: ShellGlobals.colors.light;
|
||||
border.width: 2;
|
||||
width: parent.width;
|
||||
height: column.implicitHeight + 20;
|
||||
|
||||
MouseArea {
|
||||
id: notificationArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column;
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
margins: 10;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
//IconImage {
|
||||
// visible: notification.appIcon == null;
|
||||
// source: Qt.resolvedUrl(notification.appIcon);
|
||||
// implicitSize: 25;
|
||||
//}
|
||||
|
||||
Text {
|
||||
id: summaryText
|
||||
text: notification.summary
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 14
|
||||
font.bold: true
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom;
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 16;
|
||||
height: 16;
|
||||
Layout.alignment: Qt.AlighRight | Qt.AlignTop;
|
||||
|
||||
Rectangle {
|
||||
color: "#FF474D";
|
||||
radius: 5;
|
||||
visible: closeButtonArea.containsMouse;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: closeButtonArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
notification.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
source: "image://icon/window-close";
|
||||
implicitSize: 28;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
id: bodyText
|
||||
text: notification.body
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 11;
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
//IconImage {
|
||||
// visible: notification.image != null;
|
||||
// source: Qt.resolvedUrl(notification.image);
|
||||
// implicitSize: 25;
|
||||
//}
|
||||
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
105
.stversions/bar/notifications/Toast~20241229-183824.qml
Normal file
105
.stversions/bar/notifications/Toast~20241229-183824.qml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Notifications
|
||||
import "../.."
|
||||
|
||||
Rectangle {
|
||||
required property var notification
|
||||
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.bar;
|
||||
border.color: notificationArea.containsMouse
|
||||
? ShellGlobals.colors.highlight
|
||||
: ShellGlobals.colors.light;
|
||||
border.width: 2;
|
||||
width: parent.width;
|
||||
height: column.implicitHeight + 20;
|
||||
|
||||
MouseArea {
|
||||
id: notificationArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column;
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
margins: 10;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
//IconImage {
|
||||
// visible: notification.appIcon == null;
|
||||
// source: Qt.resolvedUrl(notification.appIcon);
|
||||
// implicitSize: 25;
|
||||
//}
|
||||
|
||||
Text {
|
||||
id: summaryText
|
||||
text: notification.summary
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 14
|
||||
font.bold: true
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom;
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 16;
|
||||
height: 16;
|
||||
Layout.alignment: Qt.AlighRight | Qt.AlignTop;
|
||||
|
||||
Rectangle {
|
||||
color: "#FF474D";
|
||||
radius: 5;
|
||||
visible: closeButtonArea.containsMouse;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: closeButtonArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
notification.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
source: "image://icon/window-close";
|
||||
implicitSize: 28;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
id: bodyText
|
||||
text: notification.body
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 11;
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
IconImage {
|
||||
visible: notification.image != null;
|
||||
source: Qt.resolvedUrl(notification.image);
|
||||
implicitSize: 25;
|
||||
}
|
||||
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
105
.stversions/bar/notifications/Toast~20241229-184059.qml
Normal file
105
.stversions/bar/notifications/Toast~20241229-184059.qml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Notifications
|
||||
import "../.."
|
||||
|
||||
Rectangle {
|
||||
required property var notification
|
||||
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.bar;
|
||||
border.color: notificationArea.containsMouse
|
||||
? ShellGlobals.colors.highlight
|
||||
: ShellGlobals.colors.light;
|
||||
border.width: 2;
|
||||
width: parent.width;
|
||||
height: column.implicitHeight + 20;
|
||||
|
||||
MouseArea {
|
||||
id: notificationArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column;
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
margins: 10;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 5;
|
||||
Layout.fillWidth: true;
|
||||
|
||||
IconImage {
|
||||
visible: notification.appIcon == null;
|
||||
source: Qt.resolvedUrl(notification.appIcon);
|
||||
implicitSize: 25;
|
||||
}
|
||||
|
||||
Text {
|
||||
id: summaryText
|
||||
text: notification.summary
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 14
|
||||
font.bold: true
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignBottom;
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 16;
|
||||
height: 16;
|
||||
Layout.alignment: Qt.AlighRight | Qt.AlignTop;
|
||||
|
||||
Rectangle {
|
||||
color: "#FF474D";
|
||||
radius: 5;
|
||||
visible: closeButtonArea.containsMouse;
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: closeButtonArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
notification.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
source: "image://icon/window-close";
|
||||
implicitSize: 28;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
id: bodyText
|
||||
text: notification.body
|
||||
color: ShellGlobals.colors.text
|
||||
font.pointSize: 11;
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
IconImage {
|
||||
visible: notification.image != null;
|
||||
source: Qt.resolvedUrl(notification.image);
|
||||
implicitSize: 25;
|
||||
}
|
||||
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
215
.stversions/bar/notifications/Toast~20250307-175400.qml
Normal file
215
.stversions/bar/notifications/Toast~20250307-175400.qml
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.Notifications
|
||||
import ".."
|
||||
import "../.."
|
||||
|
||||
Rectangle {
|
||||
required property var notification;
|
||||
|
||||
id: notificationRoot;
|
||||
radius: 5;
|
||||
color: ShellGlobals.colors.window;
|
||||
width: parent.width;
|
||||
height: column.implicitHeight + 30;
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true;
|
||||
spread: 0.01;
|
||||
samples: 25;
|
||||
color: "#80000000";
|
||||
}
|
||||
|
||||
Item {
|
||||
property int totalDuration: 5000;
|
||||
property int remainingTime: totalDuration;
|
||||
property bool isRunning: false;
|
||||
property real lastTime: 0;
|
||||
|
||||
id: timerController;
|
||||
|
||||
Timer {
|
||||
id: internalTimer;
|
||||
interval: 16;
|
||||
repeat: true;
|
||||
running: timerController.isRunning;
|
||||
|
||||
onTriggered: {
|
||||
var currentTime = Date.now()
|
||||
if (timerController.lastTime > 0) {
|
||||
var delta = currentTime - timerController.lastTime;
|
||||
timerController.remainingTime -= delta;
|
||||
if (timerController.remainingTime <= 0) {
|
||||
timerController.isRunning = false;
|
||||
notification.expire();
|
||||
}
|
||||
}
|
||||
timerController.lastTime = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (!isRunning) {
|
||||
lastTime = Date.now();
|
||||
isRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
function pause() {
|
||||
isRunning = false;
|
||||
lastTime = 0;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: notificationArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
|
||||
onContainsMouseChanged: {
|
||||
progressAnimation.paused = containsMouse;
|
||||
if (containsMouse) {
|
||||
timerController.pause();
|
||||
} else {
|
||||
timerController.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: column;
|
||||
spacing: 5;
|
||||
|
||||
anchors {
|
||||
fill: parent;
|
||||
margins: 15;
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true;
|
||||
|
||||
RowLayout {
|
||||
id: topRow;
|
||||
spacing: 10;
|
||||
|
||||
IconImage {
|
||||
visible: notification.appIcon != "";
|
||||
source: Quickshell.iconPath(notification.appIcon);
|
||||
implicitSize: 24;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
id: appName;
|
||||
text: notification.appName;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
font.bold: true;
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: false;
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
Text {
|
||||
id: summaryText;
|
||||
text: notification.summary;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: closeButton;
|
||||
width: 24;
|
||||
height: 24;
|
||||
Layout.alignment: Qt.AlignTop;
|
||||
|
||||
Canvas {
|
||||
id: progressCircle;
|
||||
anchors.fill: parent;
|
||||
antialiasing: true;
|
||||
|
||||
property real progress: 1.0;
|
||||
onProgressChanged: requestPaint();
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
var centerX = width / 2;
|
||||
var centerY = height / 2;
|
||||
var radius = Math.min(width, height) / 2 - 2;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + 2 * Math.PI * progress);
|
||||
ctx.strokeStyle = ShellGlobals.colors.highlight;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: progressAnimation;
|
||||
target: progressCircle;
|
||||
property: "progress";
|
||||
from: 1.0;
|
||||
to: 0.0;
|
||||
duration: 5000;
|
||||
running: true;
|
||||
easing.type: Easing.Linear;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: closeButtonBg;
|
||||
anchors.centerIn: parent;
|
||||
width: 16;
|
||||
height: 16;
|
||||
color: "#FF474D";
|
||||
radius: 10;
|
||||
visible: closeButtonArea.containsMouse;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: closeButtonArea;
|
||||
hoverEnabled: true;
|
||||
anchors.fill: parent;
|
||||
onPressed: {
|
||||
notification.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
IconImage {
|
||||
source: "image://icon/window-close";
|
||||
implicitSize: 16;
|
||||
anchors.centerIn: parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
Text {
|
||||
id: bodyText;
|
||||
text: notification.body;
|
||||
color: ShellGlobals.colors.text;
|
||||
font.pointSize: 11;
|
||||
wrapMode: Text.Wrap;
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
.stversions/bar/volume/Button~20250509-203451.qml
Normal file
35
.stversions/bar/volume/Button~20250509-203451.qml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import "../../widgets/" as Widgets
|
||||
import "../.."
|
||||
|
||||
|
||||
Widgets.IconButton {
|
||||
required property var bar;
|
||||
|
||||
id: iconButton
|
||||
implicitSize: 20
|
||||
source: "root:/resources/volume/volume-full.svg"
|
||||
padding: 2
|
||||
|
||||
onClicked:{
|
||||
if (volumeControl.visible) {
|
||||
volumeControl.hide()
|
||||
}
|
||||
else {
|
||||
volumeControl.show()
|
||||
}
|
||||
}
|
||||
|
||||
ControlPanel {
|
||||
id: volumeControl
|
||||
|
||||
anchor {
|
||||
window: bar
|
||||
|
||||
onAnchoring: {
|
||||
anchor.rect = mapToItem(bar.contentItem, 0, bar.height, width , 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
76
.stversions/bar/volume/Card~20250509-203451.qml
Normal file
76
.stversions/bar/volume/Card~20250509-203451.qml
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.Pipewire
|
||||
import "../.."
|
||||
import "../../widgets/" as Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
required property PwNode node
|
||||
color: ShellGlobals.colors.light
|
||||
radius: 5
|
||||
|
||||
PwObjectTracker {
|
||||
id: defaultSourceTracker
|
||||
objects: [root.node]
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 8
|
||||
|
||||
Widgets.IconButton {
|
||||
source: {
|
||||
if (!node.properties["application.icon-name"]) {
|
||||
return root.node.audio.muted ? "root:resources/volume/volume-mute.svg" : "root:resources/volume/volume-full.svg";
|
||||
} else {
|
||||
return `image://icon/${node.properties["application.icon-name"]}`;
|
||||
}
|
||||
}
|
||||
|
||||
implicitSize: 32
|
||||
padding: 4
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: 5
|
||||
|
||||
onClicked: {
|
||||
root.node.audio.muted = !root.node.audio.muted;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 4
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Text {
|
||||
color: ShellGlobals.colors.text
|
||||
text: {
|
||||
// Taken from quickshell-examples
|
||||
const app = node.properties["application.name"] ?? (node.description != "" ? node.description : node.name);
|
||||
const media = node.properties["media.name"];
|
||||
return media != undefined ? `${app} - ${media}` : app;
|
||||
}
|
||||
|
||||
font.bold: true
|
||||
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 5
|
||||
Layout.rightMargin: 5
|
||||
Layout.bottomMargin: 5
|
||||
}
|
||||
|
||||
Widgets.RoundSlider {
|
||||
implicitHeight: 7
|
||||
from: 0
|
||||
to: 1
|
||||
value: root.node.audio.volume
|
||||
onValueChanged: node.audio.volume = value
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 10
|
||||
Layout.bottomMargin: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
.stversions/bar/volume/ControlPanel~20250509-203451.qml
Normal file
117
.stversions/bar/volume/ControlPanel~20250509-203451.qml
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pipewire
|
||||
import "../.."
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
width: mainContainer.width + 10
|
||||
height: mainContainer.height + 10
|
||||
color: "transparent"
|
||||
visible: mainContainer.opacity > 0
|
||||
|
||||
function show() {
|
||||
mainContainer.opacity = 1;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
mainContainer.opacity = 0;
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: true
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
onHoveredChanged: {
|
||||
if (hovered == false) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mainContainer
|
||||
width: 400
|
||||
height: 400
|
||||
color: ShellGlobals.colors.base
|
||||
radius: 5
|
||||
opacity: 0
|
||||
anchors.centerIn: parent
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
transparentBorder: true
|
||||
spread: 0.02
|
||||
samples: 25
|
||||
color: "#80000000"
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 300
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: mainColumn
|
||||
spacing: 10
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.margins: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 10
|
||||
}
|
||||
|
||||
PwNodeLinkTracker {
|
||||
id: linkTracker
|
||||
node: Pipewire.defaultAudioSink
|
||||
}
|
||||
|
||||
Card {
|
||||
node: Pipewire.defaultAudioSink
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
color: ShellGlobals.colors.light
|
||||
implicitHeight: 2
|
||||
radius: 1
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
contentWidth: availableWidth
|
||||
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
spacing: 10
|
||||
|
||||
Repeater {
|
||||
model: linkTracker.linkGroups
|
||||
|
||||
Card {
|
||||
required property PwLinkGroup modelData
|
||||
|
||||
node: modelData.source
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 45
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue