Compare commits
82 commits
unify-wind
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
618fc22e80 | ||
|
|
3c3fe368bc | ||
|
|
fe8261f7af | ||
|
|
823dd66719 | ||
|
|
617931a115 | ||
|
|
2aa72accda | ||
|
|
6b9ecc5b3d | ||
|
|
7ba6222105 | ||
|
|
7935487295 | ||
|
|
d58144a853 | ||
|
|
2bfa0c189a | ||
|
|
3d1816c0f1 | ||
|
|
9c074dc9e5 | ||
|
|
2d251c044d | ||
|
|
e2816bcb1e | ||
|
|
d5a92eb19b | ||
|
|
8fe50936a0 | ||
|
|
450ff7a503 | ||
|
|
3a67bc5204 | ||
|
|
0a445eaa08 | ||
|
|
5e82fd906d | ||
|
|
338e81d3ad | ||
|
|
c22a8f796d | ||
|
|
ed6cd2c8d5 | ||
|
|
bd826c14ac | ||
|
|
c03d24de15 | ||
|
|
7a04cccf0c | ||
|
|
fdf61a0e90 | ||
|
|
37afb798bc | ||
|
|
4007344d9d | ||
|
|
06bbd34b73 | ||
|
|
c76f29345e | ||
|
|
9d6a88aa43 | ||
|
|
185121d0d7 | ||
|
|
f687e17c94 | ||
|
|
b0d9342e1d | ||
|
|
1c30ea270f | ||
|
|
ebb66dee21 | ||
|
|
141c64a0bb | ||
|
|
ad3a275c21 | ||
|
|
1a8a14bf53 | ||
|
|
22cf6cc53e | ||
|
|
8ba0567d28 | ||
|
|
83e9c6f08c | ||
|
|
93b3a09a0a | ||
|
|
9adae58589 | ||
|
|
f974911b1c | ||
|
|
3306bb959c | ||
|
|
8104e3c099 | ||
|
|
2b6b9aee28 | ||
|
|
0ab37420a2 | ||
|
|
01c2ea9044 | ||
|
|
fbc2a10b69 | ||
|
|
a10c2f0254 | ||
|
|
162f8f6b6f | ||
|
|
e180fee2a9 | ||
|
|
32167ef44e | ||
|
|
8aced615ce | ||
|
|
47532bd626 | ||
|
|
25e313e31b | ||
|
|
ea86cc575d | ||
|
|
4bda51f02c | ||
|
|
351fb82ac7 | ||
|
|
112ed0d6de | ||
|
|
fdcaa77581 | ||
|
|
0405dc3414 | ||
|
|
4e2a1874d1 | ||
|
|
96d1352666 | ||
|
|
7022c3a9ae | ||
|
|
8c59137716 | ||
|
|
0c4d2dc597 | ||
|
|
af396bc2c5 | ||
|
|
7de7ae19bb | ||
|
|
205ad37e3e | ||
|
|
4375f6e13d | ||
|
|
467c9bc0e3 | ||
|
|
9fc91a92f7 | ||
|
|
f7e8fb7720 | ||
|
|
a44b6f5e44 | ||
|
|
c53f0c2c41 | ||
|
|
a12b36c188 | ||
|
|
16e5059c7a |
89 changed files with 1871 additions and 1156 deletions
10
README.md
10
README.md
|
|
@ -12,13 +12,11 @@ Run the shell
|
|||
quickshell -c shell
|
||||
```
|
||||
|
||||
Run app launcher
|
||||
|
||||
```shell
|
||||
quickshell -c launcher
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `quickshell`
|
||||
- `qt6-wayland`
|
||||
- `app2unit`
|
||||
- `meson`
|
||||
- `ninja`
|
||||
- `python3`
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@ import qs.config
|
|||
import QtQuick
|
||||
|
||||
Text {
|
||||
color: Theme.palette.basecontent
|
||||
font.family: Styling.lucide.font.family
|
||||
font.pixelSize: 16
|
||||
color: Styling.theme.basecontent
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.gpu.iconSize
|
||||
font.bold: true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,19 +7,21 @@ Button {
|
|||
property alias border: rectangle.border
|
||||
property alias radius: rectangle.radius
|
||||
|
||||
font.pixelSize: 14
|
||||
padding: 6
|
||||
font.pixelSize: Styling.typography.textSize.base
|
||||
font.family: Styling.typography.fontFamily
|
||||
verticalPadding: 6
|
||||
horizontalPadding: 8
|
||||
|
||||
palette.button: hovered ? Theme.palette.primary : Theme.palette.base100
|
||||
palette.button: hovered ? Styling.theme.primary : Styling.theme.base200
|
||||
Behavior on palette.button {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
palette.buttonText: hoverEnabled && hovered ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
palette.buttonText: hoverEnabled && hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
Behavior on palette.buttonText {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +34,6 @@ Button {
|
|||
background: Rectangle {
|
||||
id: rectangle
|
||||
color: root.palette.button
|
||||
radius: 8
|
||||
radius: Styling.theme.radiusField
|
||||
}
|
||||
}
|
||||
|
|
|
|||
107
components/StyledComboBox.qml
Normal file
107
components/StyledComboBox.qml
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell.Widgets
|
||||
|
||||
ComboBox {
|
||||
id: control
|
||||
|
||||
palette.button: Styling.theme.base200
|
||||
palette.buttonText: Styling.theme.basecontent
|
||||
palette.highlight: Styling.theme.primary
|
||||
palette.highlightedText: Styling.theme.primarycontent
|
||||
palette.text: Styling.theme.basecontent
|
||||
palette.window: Styling.theme.base200
|
||||
|
||||
implicitHeight: 40
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: delegate
|
||||
|
||||
required property var model
|
||||
required property int index
|
||||
|
||||
width: control.width
|
||||
contentItem: StyledText {
|
||||
text: delegate.model[control.textRole]
|
||||
color: delegate.highlighted ? palette.highlightedText : palette.buttonText
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
background: Rectangle {
|
||||
color: delegate.highlighted ? palette.highlight : palette.button
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
}
|
||||
highlighted: control.highlightedIndex === index
|
||||
}
|
||||
|
||||
contentItem: StyledText {
|
||||
leftPadding: 12
|
||||
|
||||
text: control.displayText
|
||||
color: control.hovered || control.down ? palette.highlightedText : palette.buttonText
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 120
|
||||
implicitHeight: 40
|
||||
color: control.hovered || control.down ? palette.highlight : palette.button
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
border.color: Styling.theme.base100
|
||||
border.width: control.visualFocus ? 2 : 1
|
||||
radius: Styling.theme.radiusSelector
|
||||
}
|
||||
|
||||
popup: Popup {
|
||||
palette: control.palette
|
||||
y: control.height - 1
|
||||
width: control.width
|
||||
height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin)
|
||||
padding: 1
|
||||
|
||||
contentItem: ClippingWrapperRectangle {
|
||||
radius: Styling.theme.radiusField
|
||||
|
||||
ListView {
|
||||
clip: true
|
||||
implicitHeight: contentHeight + 2
|
||||
model: control.popup.visible ? control.delegateModel : null
|
||||
currentIndex: control.highlightedIndex
|
||||
|
||||
ScrollIndicator.vertical: ScrollIndicator {}
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: palette.window
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
radius: Styling.theme.radiusField
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,29 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Widgets
|
||||
|
||||
Drawer {
|
||||
id: control
|
||||
dim: false
|
||||
background: Rectangle {
|
||||
property bool focused: false
|
||||
|
||||
onVisibleChanged: {
|
||||
focused = visible;
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: control.focused
|
||||
windows: [QsWindow.window]
|
||||
onCleared: {
|
||||
control.focused = false;
|
||||
}
|
||||
}
|
||||
|
||||
background: ClippingWrapperRectangle {
|
||||
margin: 4
|
||||
Component.onCompleted: {
|
||||
if (control.edge == Qt.TopEdge) {
|
||||
radius = 8;
|
||||
|
|
@ -20,6 +38,24 @@ Drawer {
|
|||
topRightRadius = 8;
|
||||
}
|
||||
}
|
||||
color: Theme.palette.base200
|
||||
color: Styling.theme.base300
|
||||
|
||||
Rectangle {
|
||||
Component.onCompleted: {
|
||||
if (control.edge == Qt.TopEdge) {
|
||||
radius = 8;
|
||||
} else if (control.edge == Qt.LeftEdge) {
|
||||
topRightRadius = 8;
|
||||
bottomRightRadius = 8;
|
||||
} else if (control.edge == Qt.RightEdge) {
|
||||
topLeftRadius = 8;
|
||||
bottomLeftRadius = 8;
|
||||
} else if (control.edge == Qt.BottomEdge) {
|
||||
topLeftRadius = 8;
|
||||
topRightRadius = 8;
|
||||
}
|
||||
}
|
||||
color: Styling.theme.base100
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,19 +5,14 @@ import QtQuick.Controls
|
|||
RoundButton {
|
||||
id: control
|
||||
|
||||
FontLoader {
|
||||
id: loader
|
||||
source: "../assets/lucide.woff"
|
||||
}
|
||||
|
||||
property alias border: rect.border
|
||||
property color color: hovered ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
property color color: hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
property int rotation: 0
|
||||
|
||||
font.family: loader.font.family
|
||||
font.pixelSize: 18
|
||||
radius: 8
|
||||
padding: 6
|
||||
font.family: Styling.lucide.font.family
|
||||
font.pixelSize: 16
|
||||
radius: Styling.theme.radiusField
|
||||
padding: 8
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
|
@ -27,34 +22,35 @@ RoundButton {
|
|||
id: icon
|
||||
font: control.font
|
||||
text: control.text
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: control.color
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
rotation: control.rotation
|
||||
Behavior on rotation {
|
||||
RotationAnimation {
|
||||
duration: 200
|
||||
easing.type: Easing.InOutCubic
|
||||
duration: Styling.animations.speed.slow
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
id: rect
|
||||
border.color: control.hovered ? Theme.palette.primary : Theme.palette.base100
|
||||
border.color: control.hovered ? Styling.theme.base300 : Styling.theme.base200
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
border.width: 2
|
||||
color: control.hovered ? Theme.palette.primary : Theme.palette.base100
|
||||
border.width: 0
|
||||
color: control.hovered ? Styling.theme.primary : Styling.theme.base200
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
radius: control.radius
|
||||
|
|
|
|||
17
components/StyledImage.qml
Normal file
17
components/StyledImage.qml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import Quickshell.Widgets
|
||||
|
||||
Image {
|
||||
|
||||
property alias radius: rectangle.radius
|
||||
property alias skeletonColor: rectangle.color
|
||||
|
||||
ClippingRectangle {
|
||||
id: rectangle
|
||||
|
||||
color: Styling.theme.base200
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import Quickshell.Widgets
|
||||
|
||||
WrapperRectangle {
|
||||
id: root
|
||||
margin: 8
|
||||
radius: 8
|
||||
color: Theme.palette.base100
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
|
|
@ -14,7 +15,7 @@ ListView {
|
|||
rebound: Transition {
|
||||
NumberAnimation {
|
||||
properties: "x,y"
|
||||
duration: 400
|
||||
duration: Styling.animations.speed.slow
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: [0.2, 0, 0, 1, 1, 1]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Menu {
|
||||
id: root
|
||||
|
||||
palette.window: Theme.palette.base100
|
||||
palette.base: Theme.palette.base100
|
||||
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
}
|
||||
}
|
||||
exit: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from: 1.0
|
||||
to: 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
MenuItem {
|
||||
palette.text: Theme.palette.basecontent
|
||||
palette.highlight: Theme.palette.primary
|
||||
palette.highlightedText: Theme.palette.primarycontent
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
MenuSeparator {
|
||||
palette.text: Theme.palette.basecontent
|
||||
palette.highlight: Theme.palette.primary
|
||||
palette.highlightedText: Theme.palette.primarycontent
|
||||
}
|
||||
21
components/StyledPane.qml
Normal file
21
components/StyledPane.qml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Pane {
|
||||
id: pane
|
||||
|
||||
padding: 8
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
border.width: Styling.theme.border
|
||||
border.color: pane.hovered ? Styling.theme.accent : Styling.theme.basecontent
|
||||
opacity: 0.33
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
radius: Styling.theme.radiusBox
|
||||
}
|
||||
}
|
||||
74
components/StyledPanelWindow.qml
Normal file
74
components/StyledPanelWindow.qml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
|
||||
PanelWindow {
|
||||
id: window
|
||||
|
||||
default property alias content: contentItem.data
|
||||
property alias background: background
|
||||
required property string name
|
||||
property bool canFocus: true
|
||||
property bool focused: false
|
||||
property int padding: 4
|
||||
|
||||
WlrLayershell.namespace: `lux-${name}`
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: window.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!canFocus)
|
||||
return;
|
||||
focused = visible;
|
||||
}
|
||||
HyprlandFocusGrab {
|
||||
active: window.focused
|
||||
windows: [window]
|
||||
onCleared: {
|
||||
if (!window.canFocus)
|
||||
return;
|
||||
window.focused = false;
|
||||
}
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
radius: Styling.theme.radiusBox
|
||||
Behavior on radius {
|
||||
NumberAnimation {
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
color: Styling.theme.base100
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
border.width: 2
|
||||
border.color: Styling.theme.base300
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: parent.width - 2 * window.padding
|
||||
implicitHeight: parent.height - 2 * window.padding
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
|
||||
implicitWidth: background.implicitWidth
|
||||
implicitHeight: background.implicitHeight
|
||||
color: "transparent"
|
||||
|
||||
function open() {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
function close() {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [root]
|
||||
onCleared: {
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.centerIn: root
|
||||
implicitWidth: root.contentItem.children.reduce((prev, child) => Math.max(prev, child.width), 0)
|
||||
implicitHeight: root.contentItem.children.reduce((prev, child) => prev + child.height, 0)
|
||||
color: Theme.palette.base200
|
||||
radius: 8
|
||||
}
|
||||
}
|
||||
92
components/StyledPopupWindow.qml
Normal file
92
components/StyledPopupWindow.qml
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
|
||||
required property Component content
|
||||
|
||||
implicitWidth: background.width
|
||||
implicitHeight: background.height
|
||||
color: "transparent"
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
active: root.visible
|
||||
windows: [root]
|
||||
onCleared: {
|
||||
background.state = "closed";
|
||||
}
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
background.state = background.state == "opened" ? "closed" : "opened";
|
||||
}
|
||||
|
||||
StyledWrapperRectangle {
|
||||
id: background
|
||||
|
||||
margin: 16
|
||||
focus: true
|
||||
onFocusChanged: {
|
||||
if (!focus) {
|
||||
grab.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
|
||||
state: "closed"
|
||||
states: [
|
||||
State {
|
||||
name: "closed"
|
||||
PropertyChanges {
|
||||
background {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "opened"
|
||||
PropertyChanges {
|
||||
background {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "closed"
|
||||
to: "opened"
|
||||
ScriptAction {
|
||||
script: root.visible = true
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "opened"
|
||||
to: "closed"
|
||||
SequentialAnimation {
|
||||
PauseAnimation {
|
||||
duration: root.animationDuration
|
||||
}
|
||||
ScriptAction {
|
||||
script: root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Loader {
|
||||
active: root.visible
|
||||
sourceComponent: root.content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ ProgressBar {
|
|||
background: Rectangle {
|
||||
implicitWidth: 200
|
||||
implicitHeight: 6
|
||||
color: Theme.palette.base100
|
||||
radius: 8
|
||||
color: Styling.theme.base100
|
||||
radius: Styling.theme.radiusField
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
|
|
@ -27,8 +27,8 @@ ProgressBar {
|
|||
Rectangle {
|
||||
width: control.visualPosition * parent.width
|
||||
height: parent.height
|
||||
radius: 8
|
||||
color: Theme.palette.primary
|
||||
radius: Styling.theme.radiusField
|
||||
color: Styling.theme.primary
|
||||
visible: !control.indeterminate
|
||||
}
|
||||
|
||||
|
|
@ -41,14 +41,14 @@ ProgressBar {
|
|||
Row {
|
||||
Rectangle {
|
||||
id: rect
|
||||
color: Theme.palette.primary
|
||||
color: Styling.theme.primary
|
||||
width: 40
|
||||
height: control.height
|
||||
}
|
||||
XAnimator on x {
|
||||
from: control.width + rect.width
|
||||
to: -rect.width
|
||||
duration: 1000
|
||||
duration: Styling.animations.speed.verySlow
|
||||
loops: Animation.Infinite
|
||||
running: control.indeterminate
|
||||
}
|
||||
|
|
|
|||
12
components/StyledRectangle.qml
Normal file
12
components/StyledRectangle.qml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
|
||||
Rectangle {
|
||||
radius: Styling.theme.radiusBox
|
||||
color: Styling.theme.base200
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,19 +18,19 @@ Slider {
|
|||
implicitHeight: control.height
|
||||
width: control.availableWidth
|
||||
height: implicitHeight
|
||||
radius: 8
|
||||
color: Theme.palette.base100
|
||||
radius: Styling.theme.radiusField
|
||||
color: Styling.theme.base200
|
||||
|
||||
Rectangle {
|
||||
width: control.visualPosition * parent.width
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: 75
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
height: parent.height
|
||||
color: Theme.palette.primary
|
||||
radius: 8
|
||||
color: Styling.theme.primary
|
||||
radius: Styling.theme.radiusField
|
||||
}
|
||||
}
|
||||
handle: null
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Switch {
|
|||
text: control.text
|
||||
font: control.font
|
||||
opacity: enabled ? 1.0 : 0.3
|
||||
color: Theme.palette.basecontent
|
||||
color: Styling.theme.basecontent
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
|
@ -29,9 +29,9 @@ Switch {
|
|||
implicitHeight: 24
|
||||
x: control.width - width - control.rightPadding
|
||||
y: parent.height / 2 - height / 2
|
||||
radius: 16
|
||||
radius: Styling.theme.radiusSelector
|
||||
color: "transparent"
|
||||
border.color: control.checked ? Theme.palette.primary : Theme.palette.basecontent
|
||||
border.color: control.checked ? Styling.theme.primary : Styling.theme.basecontent
|
||||
border.width: 2
|
||||
|
||||
Rectangle {
|
||||
|
|
@ -40,16 +40,15 @@ Switch {
|
|||
y: parent.height / 2 - height / 2
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
duration: 100
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
width: parent.width / 2 - indicator.padding
|
||||
height: parent.height - indicator.padding
|
||||
radius: 16
|
||||
color: control.checked ? Theme.palette.primary : Theme.palette.basecontent
|
||||
// border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999"
|
||||
radius: Styling.theme.radiusSelector
|
||||
color: control.checked ? Styling.theme.primary : Styling.theme.basecontent
|
||||
}
|
||||
}
|
||||
|
||||
background: null
|
||||
background: Item {}
|
||||
}
|
||||
|
|
|
|||
19
components/StyledTabBar.qml
Normal file
19
components/StyledTabBar.qml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Container {
|
||||
id: control
|
||||
|
||||
property alias orientation: view.orientation
|
||||
|
||||
contentItem: ListView {
|
||||
id: view
|
||||
model: control.contentModel
|
||||
currentIndex: control.currentIndex
|
||||
spacing: control.spacing
|
||||
orientation: ListView.Horizontal
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
}
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
46
components/StyledTabButton.qml
Normal file
46
components/StyledTabButton.qml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Button {
|
||||
id: control
|
||||
|
||||
property alias radius: rectangle.radius
|
||||
|
||||
padding: 8
|
||||
radius: Styling.theme.radiusField
|
||||
|
||||
contentItem: Text {
|
||||
font.pixelSize: Styling.typography.textSize.base
|
||||
font.family: Styling.typography.fontFamily
|
||||
text: control.text
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: control.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
id: rectangle
|
||||
color: control.hovered ? Styling.theme.primary : Styling.theme.base100
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
opacity: control.checked || control.hovered ? 1.0 : 0.0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Styling.animations.speed.normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,12 @@ import qs.config
|
|||
import QtQuick
|
||||
|
||||
Text {
|
||||
font.family: Theme.fontFamily
|
||||
color: Theme.palette.basecontent
|
||||
ColorAnimation on color {
|
||||
duration: 100
|
||||
font.family: Styling.typography.fontFamily
|
||||
font.pixelSize: Styling.typography.textSize.base
|
||||
color: Styling.theme.basecontent
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
TextField {
|
||||
|
||||
color: Theme.palette.basecontent
|
||||
background: null
|
||||
color: Styling.theme.basecontent
|
||||
background: Item {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ ToolTip {
|
|||
contentItem: Text {
|
||||
text: control.text
|
||||
font: control.font
|
||||
color: Theme.palette.basecontent
|
||||
color: Styling.theme.basecontent
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
radius: 8
|
||||
color: Theme.palette.base200
|
||||
radius: Styling.theme.radiusBox
|
||||
color: Styling.theme.base100
|
||||
border.color: Styling.theme.base200
|
||||
border.width: Styling.theme.border
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
|
||||
PanelWindow {
|
||||
required property string name
|
||||
|
||||
WlrLayershell.namespace: `lux-${name}`
|
||||
color: "transparent"
|
||||
}
|
||||
|
|
@ -3,12 +3,19 @@ import QtQuick
|
|||
import Quickshell.Widgets
|
||||
|
||||
WrapperRectangle {
|
||||
radius: 8
|
||||
color: Theme.palette.base300
|
||||
margin: 8
|
||||
radius: Styling.theme.radiusBox
|
||||
color: Styling.theme.base100
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
easing.type: Easing.InOutQuad
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
border.width: 2
|
||||
border.color: Styling.theme.base100
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Styling.animations.speed.fast
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.Mpris
|
||||
|
|
@ -16,35 +14,43 @@ Loader {
|
|||
active: player != null
|
||||
|
||||
sourceComponent: ColumnLayout {
|
||||
spacing: 12
|
||||
spacing: Styling.layout.spacing.xl
|
||||
implicitWidth: 800
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
font.pixelSize: Styling.typography.textSize.base
|
||||
text: `${root.player.trackTitle} - ${root.player.trackArtist}`
|
||||
font.pixelSize: Dimensions.mpris.fontSize
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
StyledIconButton {
|
||||
id: backButton
|
||||
text: Icons.skipBack
|
||||
|
||||
text: Styling.lucide.icons.skipBack
|
||||
|
||||
onClicked: {
|
||||
root.player.previous();
|
||||
}
|
||||
}
|
||||
StyledIconButton {
|
||||
id: playPauseButton
|
||||
text: root.player.isPlaying ? Icons.pause : Icons.play
|
||||
|
||||
text: root.player.isPlaying ? Styling.lucide.icons.pause : Styling.lucide.icons.play
|
||||
|
||||
onClicked: {
|
||||
root.player.isPlaying = !root.player.isPlaying;
|
||||
}
|
||||
}
|
||||
StyledIconButton {
|
||||
id: forwardButton
|
||||
text: Icons.skipForward
|
||||
|
||||
text: Styling.lucide.icons.skipForward
|
||||
|
||||
onClicked: {
|
||||
root.player.next();
|
||||
}
|
||||
|
|
@ -53,21 +59,24 @@ Loader {
|
|||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
font.pixelSize: Styling.typography.textSize.sm
|
||||
text: {
|
||||
function formatTime(num) {
|
||||
return Math.floor(num).toString().padStart(2, "0");
|
||||
}
|
||||
return `${formatTime(root.player.position / 60)}:${formatTime(root.player.position % 60)} - ${formatTime(root.player.length / 60)}:${formatTime(root.player.length % 60)}`;
|
||||
}
|
||||
font.pixelSize: Dimensions.mpris.fontSize
|
||||
}
|
||||
|
||||
StyledSlider {
|
||||
Layout.fillWidth: true
|
||||
|
||||
from: 0
|
||||
to: root.player.length ?? 0
|
||||
value: root.player.position
|
||||
implicitHeight: 6
|
||||
Layout.fillWidth: true
|
||||
|
||||
onMoved: {
|
||||
root.player.position = value;
|
||||
}
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
import qs.config
|
||||
import qs.components
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
RowLayout {
|
||||
spacing: 8
|
||||
spacing: Styling.layout.spacing.xl
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
|
|
@ -14,7 +13,7 @@ RowLayout {
|
|||
id: previousPlayerButton
|
||||
|
||||
visible: Mpris.players.length > 1
|
||||
text: Icons.chevronLeft
|
||||
text: Styling.lucide.icons.chevronLeft
|
||||
|
||||
onClicked: {
|
||||
Mpris.previousPlayer();
|
||||
|
|
@ -22,6 +21,7 @@ RowLayout {
|
|||
}
|
||||
|
||||
StyledText {
|
||||
font.pixelSize: Styling.typography.textSize.xl
|
||||
text: {
|
||||
if (!Mpris.active) {
|
||||
return "inactive";
|
||||
|
|
@ -36,14 +36,13 @@ RowLayout {
|
|||
}
|
||||
return displayName;
|
||||
}
|
||||
font.pixelSize: 20
|
||||
}
|
||||
|
||||
StyledIconButton {
|
||||
id: nextPlayerButton
|
||||
|
||||
visible: Mpris.players.length > 1
|
||||
text: Icons.chevronRight
|
||||
text: Styling.lucide.icons.chevronRight
|
||||
|
||||
onClicked: {
|
||||
Mpris.nextPlayer();
|
||||
13
components/composite/ThemeComboBox.qml
Normal file
13
components/composite/ThemeComboBox.qml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import QtQuick
|
||||
|
||||
StyledComboBox {
|
||||
id: control
|
||||
|
||||
currentIndex: Theme.themes.indexOf(Theme.currentTheme)
|
||||
model: Theme.themes
|
||||
onActivated: index => {
|
||||
Theme.currentTheme = Theme.themes[index];
|
||||
}
|
||||
}
|
||||
14
components/composite/WallpaperItem.qml
Normal file
14
components/composite/WallpaperItem.qml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import QtQuick
|
||||
|
||||
Image {
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
sourceSize.width: parent.width
|
||||
sourceSize.height: parent.height
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
65
components/composite/WallpaperList.qml
Normal file
65
components/composite/WallpaperList.qml
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.config
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import Qt.labs.folderlistmodel 2.9
|
||||
import Quickshell.Widgets
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
|
||||
orientation: ListView.Horizontal
|
||||
|
||||
clip: true
|
||||
spacing: 8
|
||||
snapMode: ListView.SnapToItem
|
||||
|
||||
implicitWidth: 160 * 3
|
||||
implicitHeight: 90
|
||||
model: FolderListModel {
|
||||
nameFilters: ["*.jpg"]
|
||||
folder: `file://${Paths.expandTilde(Config.wallpaper.directory)}`
|
||||
showDirs: false
|
||||
}
|
||||
delegate: Item {
|
||||
id: delegate
|
||||
|
||||
required property url fileUrl
|
||||
required property int index
|
||||
property bool hovered: ListView.isCurrentItem
|
||||
|
||||
implicitWidth: 160
|
||||
implicitHeight: 90
|
||||
|
||||
Rectangle {
|
||||
color: Styling.theme.base200
|
||||
anchors.fill: parent
|
||||
radius: 12
|
||||
scale: delegate.hovered ? 1.0 : 0.9
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Styling.animations.veryFast
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
source: delegate.fileUrl
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: image
|
||||
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: list.currentIndex = delegate.index
|
||||
onClicked: WallpaperService.currentWallpaper = delegate.fileUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,39 @@
|
|||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property PowerMenu powermenu: PowerMenu {}
|
||||
readonly property alias powermenu: adapter.powermenu
|
||||
readonly property alias wallpaper: adapter.wallpaper
|
||||
|
||||
FileView {
|
||||
path: `${Paths.config}/shell.json`
|
||||
watchChanges: true
|
||||
onFileChanged: reload()
|
||||
|
||||
// onAdapterUpdated: writeAdapter()
|
||||
|
||||
JsonAdapter {
|
||||
id: adapter
|
||||
|
||||
property var powermenu: PowerMenu {}
|
||||
property var wallpaper: Wallpaper {}
|
||||
}
|
||||
}
|
||||
|
||||
component PowerMenu: JsonObject {
|
||||
property list<PowerMenuItem> actions
|
||||
}
|
||||
|
||||
component PowerMenuItem: JsonObject {
|
||||
property string text
|
||||
property string command
|
||||
}
|
||||
|
||||
component Wallpaper: JsonObject {
|
||||
property string directory
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property int radius: 8
|
||||
|
||||
property Bar bar: Bar {}
|
||||
property Mpris mpris: Mpris {}
|
||||
property Clock clock: Clock {}
|
||||
property Pipewire pipewire: Pipewire {}
|
||||
property Network network: Network {}
|
||||
property Bluetooth bluetooth: Bluetooth {}
|
||||
property Storage storage: Storage {}
|
||||
property Memory memory: Memory {}
|
||||
property Cpu cpu: Cpu {}
|
||||
property Gpu gpu: Gpu {}
|
||||
property Caffeine caffeine: Caffeine {}
|
||||
property Notifications notifications: Notifications {}
|
||||
property Workspace workspace: Workspace {}
|
||||
property Tray tray: Tray {}
|
||||
property TrayMenu trayMenu: TrayMenu {}
|
||||
|
||||
component Bar: QtObject {
|
||||
property int spacing: 8
|
||||
property int border: 2
|
||||
property int height: 50
|
||||
property int verticalMargins: 4
|
||||
property int horizontalMargins: 8
|
||||
property int verticalPadding: 2
|
||||
property int horizontalPadding: 8
|
||||
}
|
||||
|
||||
component Mpris: QtObject {
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Clock: QtObject {
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Pipewire: QtObject {
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Network: QtObject {
|
||||
property int iconSize: 14
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Bluetooth: QtObject {
|
||||
property int fontSize: 16
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Storage: QtObject {
|
||||
property int iconSize: 14
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Memory: QtObject {
|
||||
property int iconSize: 14
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Cpu: QtObject {
|
||||
property int iconSize: 14
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Gpu: QtObject {
|
||||
property int iconSize: 14
|
||||
property int fontSize: 14
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Caffeine: QtObject {
|
||||
property int fontSize: 16
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Notifications: QtObject {
|
||||
property int fontSize: 16
|
||||
property int height: 30
|
||||
property int horizontalPadding: 8
|
||||
property int verticalPadding: 6
|
||||
}
|
||||
|
||||
component Workspace: QtObject {
|
||||
property int spacing: 5
|
||||
property int iconSize: 16
|
||||
property int width: 30
|
||||
property int height: 30
|
||||
property int verticalPadding: 6
|
||||
property int horizontalPadding: 7
|
||||
}
|
||||
|
||||
component Tray: QtObject {
|
||||
property int spacing: 5
|
||||
property int iconSize: 18
|
||||
property int width: 30
|
||||
property int height: 30
|
||||
property int verticalPadding: 6
|
||||
property int horizontalPadding: 7
|
||||
}
|
||||
|
||||
component TrayMenu: QtObject {
|
||||
property int fontSize: 10
|
||||
property int width: 30
|
||||
property int height: 30
|
||||
property int verticalPadding: 6
|
||||
property int horizontalPadding: 7
|
||||
}
|
||||
}
|
||||
45
config/Paths.qml
Normal file
45
config/Paths.qml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Qt.labs.platform
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property url home: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0]
|
||||
readonly property url pictures: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
|
||||
|
||||
readonly property url data: `${StandardPaths.standardLocations(StandardPaths.GenericDataLocation)[0]}/lux`
|
||||
readonly property url state: `${StandardPaths.standardLocations(StandardPaths.GenericStateLocation)[0]}/lux`
|
||||
readonly property url cache: `${StandardPaths.standardLocations(StandardPaths.GenericCacheLocation)[0]}/lux`
|
||||
readonly property url config: `${StandardPaths.standardLocations(StandardPaths.GenericConfigLocation)[0]}/lux`
|
||||
|
||||
function stringify(path: url): string {
|
||||
let str = path.toString();
|
||||
if (str.startsWith("root:/"))
|
||||
str = `file://${Quickshell.shellDir}/${str.slice(6)}`;
|
||||
else if (str.startsWith("/"))
|
||||
str = `file://${str}`;
|
||||
return new URL(str).pathname;
|
||||
}
|
||||
|
||||
function expandTilde(path: string): string {
|
||||
return strip(path.replace("~", stringify(root.home)));
|
||||
}
|
||||
|
||||
function shortenHome(path: string): string {
|
||||
return path.replace(strip(root.home), "~");
|
||||
}
|
||||
|
||||
function strip(path: url): string {
|
||||
return stringify(path).replace("file://", "");
|
||||
}
|
||||
|
||||
function mkdir(path: url): void {
|
||||
Quickshell.execDetached(["mkdir", "-p", strip(path)]);
|
||||
}
|
||||
|
||||
function copy(from: url, to: url): void {
|
||||
Quickshell.execDetached(["cp", strip(from), strip(to)]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
import Quickshell
|
||||
|
||||
PersistentProperties {
|
||||
property list<var> actions: [
|
||||
{
|
||||
text: " Logout",
|
||||
command: "hyprctl dispatch exit"
|
||||
},
|
||||
{
|
||||
text: " Reboot",
|
||||
command: "systemctl reboot"
|
||||
},
|
||||
{
|
||||
text: " Shutdown",
|
||||
command: "systemctl poweroff"
|
||||
}
|
||||
]
|
||||
}
|
||||
132
config/Styling.qml
Normal file
132
config/Styling.qml
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property Animations animations: Animations {}
|
||||
readonly property Typography typography: Typography {}
|
||||
readonly property Layout layout: Layout {}
|
||||
readonly property alias theme: theme
|
||||
readonly property Lucide lucide: Lucide {}
|
||||
|
||||
component Animations: QtObject {
|
||||
readonly property AnimationSpeed speed: AnimationSpeed {}
|
||||
}
|
||||
component AnimationSpeed: QtObject {
|
||||
readonly property int veryFast: 50
|
||||
readonly property int fast: 100
|
||||
readonly property int normal: 200
|
||||
readonly property int slow: 400
|
||||
readonly property int verySlow: 1000
|
||||
}
|
||||
|
||||
component Typography: QtObject {
|
||||
readonly property string fontFamily: "JetBrainsMono Nerd Font"
|
||||
readonly property FontSize textSize: FontSize {}
|
||||
}
|
||||
component FontSize: QtObject {
|
||||
readonly property int sm: 12
|
||||
readonly property int base: 14
|
||||
readonly property int lg: 18
|
||||
readonly property int xl: 24
|
||||
}
|
||||
|
||||
component Layout: QtObject {
|
||||
readonly property LayoutSpacing spacing: LayoutSpacing {}
|
||||
}
|
||||
component LayoutSpacing: QtObject {
|
||||
readonly property int sm: 2
|
||||
readonly property int base: 4
|
||||
readonly property int lg: 8
|
||||
readonly property int xl: 12
|
||||
}
|
||||
|
||||
component Lucide: Item {
|
||||
|
||||
readonly property alias font: loader.font
|
||||
readonly property LucideIcons icons: LucideIcons {}
|
||||
|
||||
FontLoader {
|
||||
id: loader
|
||||
source: "../assets/lucide.woff"
|
||||
}
|
||||
}
|
||||
component LucideIcons: QtObject {
|
||||
readonly property string activity: "\u{E038}"
|
||||
readonly property string audioLines: "\u{E55F}"
|
||||
readonly property string batteryCharging: "\u{E058}"
|
||||
readonly property string batteryFull: "\u{E059}"
|
||||
readonly property string batteryMedium: "\u{E05b}"
|
||||
readonly property string batteryLow: "\u{E05a}"
|
||||
readonly property string batteryWarning: "\u{E3b0}"
|
||||
readonly property string bell: "\u{E05d}"
|
||||
readonly property string bellRing: "\u{E224}"
|
||||
readonly property string bluetooth: "\u{E060}"
|
||||
readonly property string bluetoothConnected: "\u{E1b8}"
|
||||
readonly property string brickWall: "\u{E586}"
|
||||
readonly property string coffee: "\u{E09a}"
|
||||
readonly property string chevronLeft: "\u{E072}"
|
||||
readonly property string chevronRight: "\u{E073}"
|
||||
readonly property string cpu: "\u{E0ad}"
|
||||
readonly property string gpu: "\u{E66f}"
|
||||
readonly property string hardDrive: "\u{E0f1}"
|
||||
readonly property string layoutDashboard: "\u{E1C1}"
|
||||
readonly property string memoryStick: "\u{E44a}"
|
||||
readonly property string pause: "\u{E132}"
|
||||
readonly property string play: "\u{E140}"
|
||||
readonly property string search: "\u{E155}"
|
||||
readonly property string skipBack: "\u{E163}"
|
||||
readonly property string skipForward: "\u{E164}"
|
||||
readonly property string square: "\u{E16B}"
|
||||
readonly property string stop: "\u{E132}"
|
||||
readonly property string swatchBook: "\u{E5A4}"
|
||||
readonly property string wifiOff: "\u{E1af}"
|
||||
readonly property string wifiLow: "\u{E5fd}"
|
||||
readonly property string wifiHigh: "\u{E5fc}"
|
||||
readonly property string wifi: "\u{E1ae}"
|
||||
readonly property string triangle: "\u{E192}"
|
||||
readonly property string triangleDashed: "\u{E642}"
|
||||
}
|
||||
|
||||
FileView {
|
||||
path: `${Paths.config}/themes/${Theme.currentTheme}.json`
|
||||
watchChanges: true
|
||||
onFileChanged: reload()
|
||||
|
||||
// when changes are made to properties in the adapter, save them
|
||||
onAdapterUpdated: writeAdapter()
|
||||
|
||||
JsonAdapter {
|
||||
id: theme
|
||||
property color primary: "#605dff"
|
||||
property color primarycontent: "#edf1fe"
|
||||
property color secondary: "#f43098"
|
||||
property color secondarycontent: "#f9e4f0"
|
||||
property color accent: "#00d3bb"
|
||||
property color accentcontent: "#084d49"
|
||||
property color neutral: "#09090b"
|
||||
property color neutralcontent: "#e4e4e7"
|
||||
property color base100: "#1d232a"
|
||||
property color base200: "#191e24"
|
||||
property color base300: "#15191e"
|
||||
property color basecontent: "#ecf9ff"
|
||||
property color info: "#00bafe"
|
||||
property color infocontent: "#042e49"
|
||||
property color success: "#00d390"
|
||||
property color successcontent: "#004c39"
|
||||
property color warning: "#fcb700"
|
||||
property color warningcontent: "#793205"
|
||||
property color error: "#ff627d"
|
||||
property color errorcontent: "#4d0218"
|
||||
|
||||
property int radiusSelector: 8
|
||||
property int radiusField: 8
|
||||
property int radiusBox: 8
|
||||
property int border: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +1,50 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Qt.labs.folderlistmodel 2.9
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property var lucide: FontLoader {
|
||||
source: "../assets/lucide.woff"
|
||||
}
|
||||
property string fontFamily: "JetBrainsMono Nerd Font"
|
||||
property Palette palette: Palette {}
|
||||
property alias themes: cache.themes
|
||||
property alias currentTheme: cache.current
|
||||
property int currentThemeIndex: themes.indexOf(currentTheme)
|
||||
|
||||
component Palette: QtObject {
|
||||
id: palette
|
||||
FolderListModel {
|
||||
id: model
|
||||
nameFilters: ["*.json"]
|
||||
folder: `${Paths.config}/themes/`
|
||||
showDirs: false
|
||||
onCountChanged: {
|
||||
const arr = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
arr.push(get(i, "fileName").replace(".json", ""));
|
||||
}
|
||||
root.themes = arr;
|
||||
}
|
||||
}
|
||||
|
||||
property color primary: "#1fb854"
|
||||
property color primarycontent: "#000000"
|
||||
property color secondary: "#1eb88e"
|
||||
property color secondarycontent: "#000c07"
|
||||
property color accent: "#1fb8ab"
|
||||
property color accentcontent: "#010c0b"
|
||||
property color neutral: "#19362d"
|
||||
property color neutralcontent: "#cdd3d1"
|
||||
property color base100: "#1b1717"
|
||||
property color base200: "#161212"
|
||||
property color base300: "#110d0d"
|
||||
property color basecontent: "#cac9c9"
|
||||
property color info: "#00b5ff"
|
||||
property color infocontent: "#000000"
|
||||
property color success: "#00a96e"
|
||||
property color successcontent: "#000000"
|
||||
property color warning: "#ffbe00"
|
||||
property color warningcontent: "#000000"
|
||||
property color error: "#ff5861"
|
||||
property color errorcontent: "#000000"
|
||||
FileView {
|
||||
path: `${Paths.cache}/theme.json`
|
||||
|
||||
watchChanges: true
|
||||
onFileChanged: reload()
|
||||
|
||||
// when changes are made to properties in the adapter, save them
|
||||
onAdapterUpdated: writeAdapter()
|
||||
|
||||
JsonAdapter {
|
||||
id: cache
|
||||
|
||||
property string current: "dark"
|
||||
property list<string> themes: ["dark"]
|
||||
onThemesChanged: {
|
||||
if (!themes.includes(current)) {
|
||||
current = themes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
property string batteryCharging: "\u{E058}"
|
||||
property string batteryFull: "\u{E059}"
|
||||
property string batteryMedium: "\u{E05b}"
|
||||
property string batteryLow: "\u{E05a}"
|
||||
property string batteryWarning: "\u{E3b0}"
|
||||
property string bell: "\u{E05d}"
|
||||
property string bellRing: "\u{E224}"
|
||||
property string bluetooth: "\u{E060}"
|
||||
property string bluetoothConnected: "\u{E1b8}"
|
||||
property string brickWall: "\u{E586}"
|
||||
property string coffee: "\u{E09a}"
|
||||
property string chevronLeft: "\u{E072}"
|
||||
property string chevronRight: "\u{E073}"
|
||||
property string cpu: "\u{E0ad}"
|
||||
property string gpu: "\u{E66f}"
|
||||
property string hardDrive: "\u{E0f1}"
|
||||
property string memoryStick: "\u{E44a}"
|
||||
property string pause: "\u{E132}"
|
||||
property string play: "\u{E140}"
|
||||
property string search: "\u{E155}"
|
||||
property string skipBack: "\u{E163}"
|
||||
property string skipForward: "\u{E164}"
|
||||
property string stop: "\u{E132}"
|
||||
property string square: "\u{E16B}"
|
||||
property string wifiOff: "\u{E1af}"
|
||||
property string wifiLow: "\u{E5fd}"
|
||||
property string wifiHigh: "\u{E5fc}"
|
||||
property string wifi: "\u{E1ae}"
|
||||
property string triangle: "\u{E192}"
|
||||
property string triangleDashed: "\u{E642}"
|
||||
}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
import "bar"
|
||||
import "configuration"
|
||||
import "drawers"
|
||||
import "launcher"
|
||||
import "pomodoro"
|
||||
import "powermenu"
|
||||
import "storybook"
|
||||
import Quickshell
|
||||
import "wallpaper"
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
|
@ -15,7 +18,83 @@ Variants {
|
|||
|
||||
required property ShellScreen modelData
|
||||
|
||||
Bar {}
|
||||
PanelWindow {
|
||||
id: background
|
||||
|
||||
// visible: false
|
||||
anchors.top: true
|
||||
anchors.left: true
|
||||
anchors.right: true
|
||||
anchors.bottom: true
|
||||
|
||||
color: "transparent"
|
||||
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.layer: WlrLayer.Background
|
||||
|
||||
Wallpaper {}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: exclusionZone
|
||||
|
||||
anchors.top: true
|
||||
anchors.left: true
|
||||
anchors.right: true
|
||||
|
||||
implicitWidth: bar.width
|
||||
implicitHeight: bar.height + bar.anchors.margins
|
||||
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: topWindow
|
||||
|
||||
anchors.top: true
|
||||
anchors.left: true
|
||||
anchors.right: true
|
||||
anchors.bottom: true
|
||||
|
||||
color: 'transparent'
|
||||
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
|
||||
mask: Region {
|
||||
width: topWindow.width
|
||||
height: topWindow.height
|
||||
intersection: Intersection.Xor
|
||||
regions: regions.instances
|
||||
}
|
||||
|
||||
Variants {
|
||||
id: regions
|
||||
|
||||
model: panels.children
|
||||
|
||||
Region {
|
||||
required property Item modelData
|
||||
|
||||
x: modelData.x
|
||||
y: modelData.y
|
||||
width: modelData.width
|
||||
height: modelData.height
|
||||
intersection: Intersection.Subtract
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: panels
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Bar {
|
||||
id: bar
|
||||
}
|
||||
}
|
||||
}
|
||||
Configuration {}
|
||||
Launcher {}
|
||||
Pomodoro {}
|
||||
PowerMenu {}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ import Quickshell.Hyprland
|
|||
Scope {
|
||||
id: root
|
||||
|
||||
LuxShortcut {
|
||||
name: 'configuration'
|
||||
description: 'Open the configuration screen'
|
||||
onPressed: Visibility.configuration = !Visibility.configuration
|
||||
}
|
||||
|
||||
LuxShortcut {
|
||||
name: 'launcher'
|
||||
description: 'Open the application launcher'
|
||||
|
|
|
|||
|
|
@ -3,56 +3,35 @@ import "components/bluetooth"
|
|||
import "components/hyprland"
|
||||
import "components/notifications"
|
||||
import "components/tray"
|
||||
import qs.components
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
|
||||
PanelWindow {
|
||||
id: parentWindow
|
||||
StyledWrapperRectangle {
|
||||
id: root
|
||||
|
||||
anchors.top: true
|
||||
anchors.left: true
|
||||
anchors.right: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 6
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
|
||||
implicitHeight: Dimensions.bar.height
|
||||
color: 'transparent'
|
||||
border.width: 3
|
||||
border.color: Styling.theme.base200
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
margin: 4
|
||||
color: Styling.theme.base100
|
||||
|
||||
Item {
|
||||
RowLayout {
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Dimensions.bar.horizontalMargins
|
||||
anchors.rightMargin: Dimensions.bar.horizontalMargins
|
||||
anchors.topMargin: Dimensions.bar.verticalMargins
|
||||
anchors.bottomMargin: Dimensions.bar.verticalMargins
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
color: Theme.palette.base300
|
||||
radius: Dimensions.radius
|
||||
|
||||
border {
|
||||
color: Theme.palette.base100
|
||||
width: Dimensions.bar.border
|
||||
pixelAligned: true
|
||||
}
|
||||
}
|
||||
uniformCellSizes: true
|
||||
|
||||
RowLayout {
|
||||
id: leftbar
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
anchors.leftMargin: Dimensions.bar.horizontalPadding
|
||||
anchors.topMargin: Dimensions.bar.verticalPadding
|
||||
anchors.bottomMargin: Dimensions.bar.verticalPadding
|
||||
|
||||
spacing: Dimensions.bar.spacing
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
SystemLogo {
|
||||
implicitSize: 22
|
||||
|
|
@ -66,13 +45,9 @@ PanelWindow {
|
|||
RowLayout {
|
||||
id: centerbar
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
anchors.topMargin: Dimensions.bar.verticalPadding
|
||||
anchors.bottomMargin: Dimensions.bar.verticalPadding
|
||||
|
||||
spacing: Dimensions.bar.spacing
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
Mpris {}
|
||||
}
|
||||
|
|
@ -80,14 +55,9 @@ PanelWindow {
|
|||
RowLayout {
|
||||
id: rightbar
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
anchors.rightMargin: Dimensions.bar.horizontalPadding
|
||||
anchors.topMargin: Dimensions.bar.verticalPadding
|
||||
anchors.bottomMargin: Dimensions.bar.verticalPadding
|
||||
|
||||
spacing: Dimensions.bar.spacing
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
Pywal {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
|
||||
StyledIconButton {
|
||||
id: root
|
||||
|
||||
border.color: Caffeine.enabled ? Theme.palette.secondary : root.hovered ? Theme.palette.primary : Theme.palette.base100
|
||||
text: Icons.coffee
|
||||
border.width: 2
|
||||
border.color: Caffeine.enabled ? Styling.theme.secondary : root.hovered ? Styling.theme.primary : Styling.theme.base300
|
||||
text: Styling.lucide.icons.coffee
|
||||
|
||||
onClicked: {
|
||||
Caffeine.toggle();
|
||||
|
|
|
|||
|
|
@ -1,19 +1,10 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.widgets
|
||||
import Quickshell
|
||||
|
||||
StyledLabel {
|
||||
StyledText {
|
||||
id: text
|
||||
|
||||
font.pixelSize: Dimensions.clock.fontSize
|
||||
|
||||
text: ` ${Qt.formatDateTime(clock.date, "hh:mm:ss AP")}`
|
||||
|
||||
SystemClock {
|
||||
id: clock
|
||||
precision: SystemClock.Seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.utils
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
|
@ -17,30 +15,23 @@ StyledButton {
|
|||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
id: row
|
||||
|
||||
spacing: 0
|
||||
|
||||
Ref {
|
||||
service: SystemInfo
|
||||
}
|
||||
StyledText {
|
||||
id: icon
|
||||
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.cpu.iconSize
|
||||
font.bold: true
|
||||
text: Icons.cpu
|
||||
color: root.hovered ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
LucideIcon {
|
||||
text: Styling.lucide.icons.cpu
|
||||
color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
|
||||
font.pixelSize: Dimensions.cpu.fontSize
|
||||
text: ` ${(SystemInfo.cpuPerc * 100).toFixed().toString().padStart(2, "_")}%`
|
||||
color: root.hovered ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
|
||||
color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
states: [
|
||||
State {
|
||||
name: "showTemp"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.utils
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
|
@ -13,34 +11,27 @@ StyledButton {
|
|||
property bool showTemp: false
|
||||
|
||||
onClicked: {
|
||||
root.showTemp = !root.showTemp;
|
||||
showTemp = !showTemp;
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
id: row
|
||||
|
||||
spacing: 0
|
||||
|
||||
Ref {
|
||||
service: SystemInfo
|
||||
}
|
||||
StyledText {
|
||||
id: icon
|
||||
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.gpu.iconSize
|
||||
font.bold: true
|
||||
text: Icons.gpu
|
||||
color: root.hovered ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
LucideIcon {
|
||||
text: Styling.lucide.icons.gpu
|
||||
color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
|
||||
font.pixelSize: Dimensions.gpu.fontSize
|
||||
text: ` ${(SystemInfo.gpuPerc * 100).toFixed().toString().padStart(2, "_")}%`
|
||||
color: root.hovered ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
|
||||
color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
states: [
|
||||
State {
|
||||
name: "temp"
|
||||
|
|
|
|||
|
|
@ -1,28 +1,21 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.widgets
|
||||
import qs.utils
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledLabel {
|
||||
RowLayout {
|
||||
|
||||
Ref {
|
||||
service: SystemInfo
|
||||
}
|
||||
StyledText {
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.memory.iconSize
|
||||
font.bold: true
|
||||
text: Icons.memoryStick
|
||||
|
||||
LucideIcon {
|
||||
text: Styling.lucide.icons.memoryStick
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
font.pixelSize: Dimensions.memory.fontSize
|
||||
text: ` ${(SystemInfo.memPerc * 100).toFixed()}%`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,26 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.utils
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledLabel {
|
||||
RowLayout {
|
||||
|
||||
Ref {
|
||||
service: NetworkService
|
||||
}
|
||||
StyledText {
|
||||
|
||||
LucideIcon {
|
||||
id: icon
|
||||
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.network.iconSize
|
||||
font.bold: true
|
||||
text: Icons.wifiOff
|
||||
|
||||
text: Styling.lucide.icons.wifiOff
|
||||
states: [
|
||||
State {
|
||||
name: "high"
|
||||
when: NetworkService.active?.strength > 50
|
||||
PropertyChanges {
|
||||
icon {
|
||||
text: Icons.wifi
|
||||
text: Styling.lucide.icons.wifi
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -35,7 +29,7 @@ StyledLabel {
|
|||
when: NetworkService.active?.strength > 25
|
||||
PropertyChanges {
|
||||
icon {
|
||||
text: Icons.wifiHigh
|
||||
text: Styling.lucide.icons.wifiHigh
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -44,7 +38,7 @@ StyledLabel {
|
|||
when: NetworkService.active?.strength > 0
|
||||
PropertyChanges {
|
||||
icon {
|
||||
text: Icons.wifiLow
|
||||
text: Styling.lucide.icons.wifiLow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -53,8 +47,6 @@ StyledLabel {
|
|||
|
||||
StyledText {
|
||||
id: text
|
||||
font.pixelSize: Dimensions.network.fontSize
|
||||
text: ` ${(NetworkService.active?.strength ?? 0).toFixed()}%`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ StyledButton {
|
|||
when: Pipewire.muted
|
||||
PropertyChanges {
|
||||
root {
|
||||
palette.button: Theme.palette.error
|
||||
palette.button: Styling.theme.error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.UPower
|
||||
|
|
@ -10,50 +9,56 @@ StyledButton {
|
|||
property UPowerDevice laptopBattery: UPower.devices.values.find(device => device.isLaptopBattery) ?? null
|
||||
property bool isCritical: laptopBattery?.percentage < 0.10
|
||||
|
||||
visible: laptopBattery
|
||||
|
||||
contentItem: RowLayout {
|
||||
|
||||
spacing: 4
|
||||
|
||||
LucideIcon {
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
color: {
|
||||
if (root.isCritical) {
|
||||
return Theme.palette.error;
|
||||
return Styling.theme.error;
|
||||
}
|
||||
if (root.hovered) {
|
||||
return Theme.palette.primarycontent;
|
||||
return Styling.theme.primarycontent;
|
||||
}
|
||||
return Theme.palette.basecontent;
|
||||
return Styling.theme.basecontent;
|
||||
}
|
||||
font.pixelSize: 16
|
||||
text: {
|
||||
if (root.laptopBattery?.state == UPowerDeviceState.Charging) {
|
||||
return Icons.batteryCharging;
|
||||
return Styling.lucide.icons.batteryCharging;
|
||||
}
|
||||
if (root.isCritical) {
|
||||
return Icons.batteryWarning;
|
||||
return Styling.lucide.icons.batteryWarning;
|
||||
}
|
||||
if (root.laptopBattery?.percentage < 0.33) {
|
||||
return Icons.batteryLow;
|
||||
return Styling.lucide.icons.batteryLow;
|
||||
}
|
||||
if (root.laptopBattery?.percentage < 0.66) {
|
||||
return Icons.batteryMedium;
|
||||
return Styling.lucide.icons.batteryMedium;
|
||||
}
|
||||
return Icons.batteryFull;
|
||||
return Styling.lucide.icons.batteryFull;
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
color: {
|
||||
if (root.isCritical) {
|
||||
return Theme.palette.error;
|
||||
return Styling.theme.error;
|
||||
}
|
||||
if (root.hovered) {
|
||||
return Theme.palette.primarycontent;
|
||||
return Styling.theme.primarycontent;
|
||||
}
|
||||
return Theme.palette.basecontent;
|
||||
return Styling.theme.basecontent;
|
||||
}
|
||||
text: `${(root.laptopBattery?.percentage.toFixed(2) * 100)}%`
|
||||
}
|
||||
}
|
||||
visible: laptopBattery
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import qs.components
|
||||
import qs.constants
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import Quickshell.Io
|
||||
|
||||
StyledIconButton {
|
||||
id: clickable
|
||||
|
||||
text: Icons.brickWall
|
||||
text: Styling.lucide.icons.brickWall
|
||||
|
||||
onClicked: {
|
||||
process.running = true;
|
||||
|
|
|
|||
|
|
@ -1,30 +1,23 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.utils
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledLabel {
|
||||
RowLayout {
|
||||
|
||||
Ref {
|
||||
service: SystemInfo
|
||||
}
|
||||
StyledText {
|
||||
id: icon
|
||||
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.storage.iconSize
|
||||
font.bold: true
|
||||
text: Icons.hardDrive
|
||||
LucideIcon {
|
||||
text: Styling.lucide.icons.hardDrive
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: text
|
||||
font.pixelSize: Dimensions.storage.fontSize
|
||||
|
||||
text: ` ${(SystemInfo.storagePerc * 100).toFixed()}%`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.widgets
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledLabel {
|
||||
StyledWrapperRectangle {
|
||||
id: root
|
||||
required property BluetoothDevice modelData
|
||||
|
||||
RowLayout {
|
||||
id: row
|
||||
|
||||
spacing: 8
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
Loader {
|
||||
active: root.modelData?.icon != undefined
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import qs.components
|
||||
import qs.constants
|
||||
import qs.config
|
||||
|
||||
StyledIconButton {
|
||||
id: root
|
||||
|
||||
text: Icons.bluetooth
|
||||
text: Styling.lucide.icons.bluetooth
|
||||
|
||||
onClicked: popup.toggle()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
|
@ -11,10 +9,6 @@ import Quickshell.Bluetooth
|
|||
StyledPopupWindow {
|
||||
id: root
|
||||
|
||||
backgroundColor: Theme.palette.base300
|
||||
margins: 16
|
||||
radius: 8
|
||||
|
||||
content: ColumnLayout {
|
||||
spacing: 8
|
||||
StyledWrapperRectangle {
|
||||
|
|
|
|||
|
|
@ -2,22 +2,20 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledLabel {
|
||||
StyledWrapperRectangle {
|
||||
id: root
|
||||
required property BluetoothDevice modelData
|
||||
|
||||
RowLayout {
|
||||
id: row
|
||||
|
||||
spacing: 8
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
Loader {
|
||||
active: root.modelData?.icon != undefined
|
||||
|
|
@ -34,12 +32,9 @@ StyledLabel {
|
|||
Loader {
|
||||
active: root.modelData.batteryAvailable
|
||||
sourceComponent: RowLayout {
|
||||
StyledText {
|
||||
LucideIcon {
|
||||
id: icon
|
||||
font.family: Theme.lucide.font.family
|
||||
font.pixelSize: Dimensions.cpu.iconSize
|
||||
font.bold: true
|
||||
text: Icons.batteryFull
|
||||
text: Styling.lucide.icons.batteryFull
|
||||
states: [
|
||||
State {
|
||||
name: "full"
|
||||
|
|
@ -50,7 +45,7 @@ StyledLabel {
|
|||
when: root.modelData.battery > 0.33
|
||||
PropertyChanges {
|
||||
icon {
|
||||
text: Icons.batteryFull
|
||||
text: Styling.lucide.icons.batteryFull
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -59,7 +54,7 @@ StyledLabel {
|
|||
when: root.modelData.battery > 0.10
|
||||
PropertyChanges {
|
||||
icon {
|
||||
text: Icons.batteryFull
|
||||
text: Styling.lucide.icons.batteryFull
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -68,8 +63,8 @@ StyledLabel {
|
|||
when: root.modelData.battery > 0.10
|
||||
PropertyChanges {
|
||||
icon {
|
||||
text: Icons.batteryWarning
|
||||
color: Theme.palette.error
|
||||
text: Styling.lucide.icons.batteryWarning
|
||||
color: Styling.theme.error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +76,7 @@ StyledLabel {
|
|||
StyledButton {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text: 'Disconnect'
|
||||
palette.button: hovered ? Theme.palette.error : Theme.palette.base200
|
||||
palette.button: hovered ? Styling.theme.error : Styling.theme.base200
|
||||
|
||||
onClicked: {
|
||||
if (root.modelData.state != BluetoothDeviceState.Connected) {
|
||||
|
|
|
|||
|
|
@ -2,21 +2,20 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledLabel {
|
||||
StyledWrapperRectangle {
|
||||
id: root
|
||||
required property BluetoothDevice modelData
|
||||
|
||||
RowLayout {
|
||||
id: row
|
||||
|
||||
spacing: 8
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
Loader {
|
||||
active: root.modelData?.icon != undefined
|
||||
|
|
@ -48,7 +47,7 @@ StyledLabel {
|
|||
hoverEnabled: root.modelData.state == BluetoothDeviceState.Disconnected
|
||||
text: 'Unpair'
|
||||
|
||||
palette.button: hovered ? Theme.palette.error : Theme.palette.base100
|
||||
palette.button: hovered ? Styling.theme.error : Styling.theme.base100
|
||||
|
||||
onClicked: {
|
||||
if (!hoverEnabled) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import QtQuick
|
||||
import Quickshell.Hyprland
|
||||
|
||||
|
|
@ -9,7 +8,7 @@ StyledIconButton {
|
|||
|
||||
required property HyprlandWorkspace workspace
|
||||
|
||||
text: Icons.triangle
|
||||
text: Styling.lucide.icons.triangle
|
||||
font.bold: true
|
||||
font.pixelSize: 17
|
||||
padding: 8
|
||||
|
|
@ -23,7 +22,7 @@ StyledIconButton {
|
|||
PropertyChanges {
|
||||
root {
|
||||
rotation: 180
|
||||
color: root.hovered ? Theme.palette.basecontent : Theme.palette.primary
|
||||
color: root.hovered ? Styling.theme.basecontent : Styling.theme.primary
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -32,9 +31,9 @@ StyledIconButton {
|
|||
when: root.workspace.active
|
||||
PropertyChanges {
|
||||
root {
|
||||
text: Icons.triangleDashed
|
||||
text: Styling.lucide.icons.triangleDashed
|
||||
rotation: 180
|
||||
color: root.hovered ? Theme.palette.basecontent : Theme.palette.primary
|
||||
color: root.hovered ? Styling.theme.basecontent : Styling.theme.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
|
|
@ -8,7 +7,7 @@ import Quickshell.Hyprland
|
|||
RowLayout {
|
||||
id: root
|
||||
|
||||
spacing: Dimensions.workspace.spacing
|
||||
spacing: 4
|
||||
|
||||
Repeater {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledLabel {
|
||||
StyledWrapperRectangle {
|
||||
id: root
|
||||
|
||||
required property var modelData
|
||||
|
||||
margin: 16
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,13 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.services
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledPopupWindow {
|
||||
id: root
|
||||
|
||||
backgroundColor: Theme.palette.base300
|
||||
margins: 16
|
||||
radius: 8
|
||||
|
||||
content: GridLayout {
|
||||
|
||||
columns: 2
|
||||
|
|
@ -30,9 +24,8 @@ StyledPopupWindow {
|
|||
onClicked: Notifications.clear()
|
||||
}
|
||||
|
||||
StyledLabel {
|
||||
StyledWrapperRectangle {
|
||||
Layout.columnSpan: 2
|
||||
color: Theme.palette.base200
|
||||
StyledListView {
|
||||
id: notifications
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import qs.components
|
||||
import qs.constants
|
||||
import qs.config
|
||||
import qs.services
|
||||
import QtQuick
|
||||
|
||||
|
|
@ -10,13 +10,13 @@ StyledIconButton {
|
|||
menu.toggle();
|
||||
}
|
||||
|
||||
text: Notifications.hasNotifications ? Icons.bell : Icons.bellRing
|
||||
text: Notifications.hasNotifications ? Styling.lucide.icons.bell : Styling.lucide.icons.bellRing
|
||||
|
||||
states: State {
|
||||
when: Notifications.hasNotifications
|
||||
PropertyChanges {
|
||||
root {
|
||||
text: Icons.bellRing
|
||||
text: Styling.lucide.icons.bellRing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.SystemTray
|
||||
|
|
@ -8,10 +7,10 @@ import Quickshell.Services.SystemTray
|
|||
RowLayout {
|
||||
id: root
|
||||
|
||||
spacing: Dimensions.tray.spacing
|
||||
spacing: 4
|
||||
|
||||
Repeater {
|
||||
model: SystemTray.items
|
||||
model: SystemTray.items.values
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ import QtQuick
|
|||
import Quickshell
|
||||
import Quickshell.Services.SystemTray
|
||||
import Quickshell.Widgets
|
||||
import "menu/"
|
||||
|
||||
StyledIconButton {
|
||||
id: root
|
||||
|
||||
property SystemTrayItem trayItem
|
||||
required property SystemTrayItem trayItem
|
||||
|
||||
onClicked: menu.toggle()
|
||||
|
||||
|
|
@ -28,7 +27,7 @@ StyledIconButton {
|
|||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
TrayMenu {
|
||||
id: menu
|
||||
|
||||
anchor.item: root
|
||||
|
|
|
|||
49
modules/bar/components/tray/TrayMenu.qml
Normal file
49
modules/bar/components/tray/TrayMenu.qml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledPopupWindow {
|
||||
id: window
|
||||
|
||||
required property QsMenuOpener menuOpener
|
||||
|
||||
content: ColumnLayout {
|
||||
spacing: 4
|
||||
Repeater {
|
||||
model: window.menuOpener.children.values
|
||||
delegate: Loader {
|
||||
id: loader
|
||||
required property QsMenuEntry modelData
|
||||
|
||||
active: true
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log(modelData.text);
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 160
|
||||
|
||||
sourceComponent: modelData.isSeparator ? menuSeperator : menuItem
|
||||
property Component menuSeperator: WrapperItem {
|
||||
margin: 4
|
||||
Rectangle {
|
||||
implicitHeight: 2
|
||||
|
||||
color: Styling.theme.base200
|
||||
}
|
||||
}
|
||||
property Component menuItem: StyledButton {
|
||||
text: loader.modelData.text
|
||||
|
||||
onClicked: loader.modelData.triggered()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.config
|
||||
import qs.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
StyledPopupWindow {
|
||||
id: window
|
||||
|
||||
backgroundColor: Theme.palette.base300
|
||||
margins: 14
|
||||
radius: 8
|
||||
|
||||
property QsMenuOpener menuOpener
|
||||
|
||||
content: ColumnLayout {
|
||||
spacing: 8
|
||||
Repeater {
|
||||
model: window.menuOpener.children
|
||||
delegate: Loader {
|
||||
id: loader
|
||||
required property QsMenuEntry modelData
|
||||
|
||||
active: true
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 160
|
||||
|
||||
sourceComponent: modelData.isSeparator ? menuSeperator : menuItem
|
||||
property Component menuSeperator: Rectangle {
|
||||
implicitHeight: 2
|
||||
|
||||
color: Theme.palette.base100
|
||||
}
|
||||
property Component menuItem: MenuItem {
|
||||
menuEntry: loader.modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import qs.components
|
||||
import Quickshell
|
||||
|
||||
StyledButton {
|
||||
id: root
|
||||
|
||||
property QsMenuEntry menuEntry
|
||||
|
||||
text: root.menuEntry.text
|
||||
|
||||
onClicked: menuEntry.triggered()
|
||||
}
|
||||
88
modules/configuration/AudioView.qml
Normal file
88
modules/configuration/AudioView.qml
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
spacing: Styling.layout.spacing.xl
|
||||
|
||||
StyledText {
|
||||
text: "Speaker Settings"
|
||||
}
|
||||
StyledPane {
|
||||
Layout.fillWidth: true
|
||||
padding: 24
|
||||
GridLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
columnSpacing: Styling.layout.spacing.xl
|
||||
|
||||
StyledText {
|
||||
Layout.column: 1
|
||||
Layout.row: 1
|
||||
text: "Device"
|
||||
}
|
||||
|
||||
StyledComboBox {
|
||||
Layout.column: 2
|
||||
Layout.row: 1
|
||||
Layout.fillWidth: true
|
||||
currentIndex: Pipewire.sinks.indexOf(Pipewire.sink)
|
||||
model: Pipewire.sinks.map(sink => sink.nickname ?? sink.name)
|
||||
onActivated: index => {
|
||||
Pipewire.setSink(Pipewire.sinks[index]);
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.column: 1
|
||||
Layout.row: 2
|
||||
text: "Volume"
|
||||
}
|
||||
|
||||
StyledSlider {
|
||||
Layout.column: 2
|
||||
Layout.row: 2
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
value: Pipewire.volume
|
||||
onMoved: {
|
||||
Pipewire.setVolume(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "Microphone Settings"
|
||||
}
|
||||
StyledPane {
|
||||
Layout.fillWidth: true
|
||||
padding: 24
|
||||
GridLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
columnSpacing: Styling.layout.spacing.xl
|
||||
|
||||
StyledText {
|
||||
Layout.column: 1
|
||||
Layout.row: 2
|
||||
text: "Microphones"
|
||||
}
|
||||
|
||||
StyledComboBox {
|
||||
Layout.column: 2
|
||||
Layout.row: 2
|
||||
Layout.fillWidth: true
|
||||
currentIndex: Pipewire.sources.indexOf(Pipewire.source)
|
||||
model: Pipewire.sources.map(source => source.nickname ?? source.name)
|
||||
onActivated: index => {
|
||||
Pipewire.setSource(Pipewire.sinks[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
128
modules/configuration/Configuration.qml
Normal file
128
modules/configuration/Configuration.qml
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledPanelWindow {
|
||||
id: window
|
||||
|
||||
name: "configuration"
|
||||
|
||||
visible: Visibility.configuration
|
||||
implicitWidth: 1000
|
||||
implicitHeight: 600
|
||||
background.color: Styling.theme.base200
|
||||
|
||||
onFocusedChanged: {
|
||||
Visibility.configuration = focused;
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
StyledTabBar {
|
||||
id: tabs
|
||||
|
||||
Layout.preferredWidth: 150
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: 2
|
||||
orientation: ListView.Vertical
|
||||
spacing: 12
|
||||
|
||||
Repeater {
|
||||
model: views.data
|
||||
delegate: StyledTabButton {
|
||||
id: tabButton
|
||||
required property ConfigurationView modelData
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
required property int index
|
||||
|
||||
contentItem: RowLayout {
|
||||
states: [
|
||||
State {
|
||||
when: tabButton.hovered
|
||||
PropertyChanges {
|
||||
tabIcon.color: Styling.theme.primarycontent
|
||||
tabText.color: Styling.theme.primarycontent
|
||||
}
|
||||
}
|
||||
]
|
||||
LucideIcon {
|
||||
id: tabIcon
|
||||
text: tabButton.modelData.icon
|
||||
font.pixelSize: Styling.typography.textSize.lg
|
||||
}
|
||||
StyledText {
|
||||
id: tabText
|
||||
text: tabButton.modelData.title
|
||||
font.pixelSize: Styling.typography.textSize.lg
|
||||
}
|
||||
}
|
||||
text: tabButton.modelData.title
|
||||
|
||||
onClicked: tabs.setCurrentIndex(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwipeView {
|
||||
id: view
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
clip: true
|
||||
orientation: Qt.Vertical
|
||||
|
||||
currentIndex: tabs.currentIndex
|
||||
|
||||
background: Rectangle {
|
||||
color: Styling.theme.base100
|
||||
radius: Styling.theme.radiusBox
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: views.data
|
||||
delegate: ScrollView {
|
||||
id: scrollView
|
||||
required property ConfigurationView modelData
|
||||
padding: 24
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
active: scrollView.modelData.view
|
||||
sourceComponent: scrollView.modelData.view
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: views
|
||||
|
||||
ConfigurationView {
|
||||
icon: Styling.lucide.icons.audioLines
|
||||
title: "Audio"
|
||||
view: AudioView {}
|
||||
}
|
||||
|
||||
ConfigurationView {
|
||||
icon: Styling.lucide.icons.swatchBook
|
||||
title: "Styling"
|
||||
view: StylingView {}
|
||||
}
|
||||
}
|
||||
|
||||
component ConfigurationView: QtObject {
|
||||
property string icon
|
||||
property string title
|
||||
property Component view
|
||||
}
|
||||
}
|
||||
40
modules/configuration/StylingView.qml
Normal file
40
modules/configuration/StylingView.qml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.components.composite
|
||||
import qs.config
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt.labs.folderlistmodel 2.9
|
||||
import Quickshell.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
StyledPane {
|
||||
GridLayout {
|
||||
|
||||
columnSpacing: Styling.layout.spacing.xl
|
||||
|
||||
StyledText {
|
||||
text: "Theme"
|
||||
font.pixelSize: Styling.typography.textSize.lg
|
||||
}
|
||||
|
||||
ThemeComboBox {}
|
||||
}
|
||||
}
|
||||
// StyledPane {
|
||||
// WallpaperList {}
|
||||
// }
|
||||
|
||||
StyledPane {
|
||||
padding: 2
|
||||
ClippingWrapperRectangle {
|
||||
|
||||
radius: Styling.theme.radiusBox
|
||||
color: "transparent"
|
||||
|
||||
WallpaperList {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,22 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.components
|
||||
import qs.components.composite
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledDrawer {
|
||||
id: root
|
||||
|
||||
visible: Visibility.dashboard
|
||||
|
||||
StyledWrapperRectangle {
|
||||
onFocusedChanged: {
|
||||
Visibility.dashboard = focused;
|
||||
}
|
||||
|
||||
WrapperItem {
|
||||
margin: 32
|
||||
ColumnLayout {
|
||||
spacing: 8
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import "items"
|
|||
import "services"
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.widgets
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
|
@ -32,7 +31,7 @@ StyledListView {
|
|||
highlightResizeDuration: 0
|
||||
highlight: Rectangle {
|
||||
radius: 8
|
||||
color: Theme.palette.primary
|
||||
color: Styling.theme.primary
|
||||
}
|
||||
|
||||
header: StyledText {
|
||||
|
|
|
|||
|
|
@ -1,40 +1,29 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
|
||||
import "services"
|
||||
import qs.config
|
||||
import qs.components
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledWindow {
|
||||
id: root
|
||||
StyledPanelWindow {
|
||||
id: window
|
||||
name: "launcher"
|
||||
|
||||
visible: Visibility.launcher
|
||||
implicitWidth: rect.width
|
||||
implicitHeight: rect.height
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: root.visible
|
||||
windows: [search]
|
||||
onCleared: {
|
||||
root.reset();
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
Visibility.launcher = false;
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
list.currentIndex = 0;
|
||||
search.clear();
|
||||
}
|
||||
Visibility.launcher = focused;
|
||||
}
|
||||
implicitWidth: rect.width
|
||||
implicitHeight: rect.height
|
||||
|
||||
StyledWrapperRectangle {
|
||||
WrapperItem {
|
||||
id: rect
|
||||
|
||||
margin: 18
|
||||
|
|
@ -45,13 +34,13 @@ StyledWindow {
|
|||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
margin: 4
|
||||
|
||||
color: Styling.theme.base200
|
||||
|
||||
RowLayout {
|
||||
LucideIcon {
|
||||
id: icon
|
||||
Layout.leftMargin: 8
|
||||
text: Icons.search
|
||||
text: Styling.lucide.icons.search
|
||||
}
|
||||
|
||||
StyledTextField {
|
||||
|
|
@ -60,19 +49,19 @@ StyledWindow {
|
|||
Layout.fillWidth: true
|
||||
implicitHeight: 40
|
||||
cursorVisible: true
|
||||
focus: root.visible
|
||||
focus: window.visible
|
||||
|
||||
placeholderText: "Applications"
|
||||
placeholderTextColor: "grey"
|
||||
|
||||
Keys.onEscapePressed: event => {
|
||||
event.accepted = true;
|
||||
root.reset();
|
||||
Visibility.launcher = false;
|
||||
}
|
||||
Keys.onReturnPressed: event => {
|
||||
event.accepted = true;
|
||||
Apps.launch(list.currentItem.modelData);
|
||||
root.reset();
|
||||
Visibility.launcher = false;
|
||||
}
|
||||
Keys.onUpPressed: event => {
|
||||
event.accepted = true;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ Item {
|
|||
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
Layout.fillWidth: true
|
||||
color: root.active ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
font.pixelSize: 14
|
||||
color: root.active ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
|
|
@ -52,8 +51,8 @@ Item {
|
|||
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.fillWidth: true
|
||||
color: root.active ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
font.pixelSize: 10
|
||||
color: root.active ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
font.pixelSize: Styling.typography.textSize.sm
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,13 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import qs.widgets
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledWindow {
|
||||
StyledPanelWindow {
|
||||
id: root
|
||||
name: "pomodoro"
|
||||
|
||||
|
|
@ -18,10 +16,11 @@ StyledWindow {
|
|||
implicitWidth: rect.width
|
||||
implicitHeight: rect.height
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
onFocusedChanged: {
|
||||
Visibility.pomodoro = focused;
|
||||
}
|
||||
|
||||
StyledWrapperRectangle {
|
||||
WrapperItem {
|
||||
id: rect
|
||||
|
||||
leftMargin: 48
|
||||
|
|
@ -29,14 +28,6 @@ StyledWindow {
|
|||
topMargin: 24
|
||||
bottomMargin: 24
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: Visibility.pomodoro
|
||||
windows: [root]
|
||||
onCleared: {
|
||||
Visibility.pomodoro = false;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
spacing: 22
|
||||
|
|
@ -54,11 +45,11 @@ StyledWindow {
|
|||
Circle {
|
||||
id: circle
|
||||
radius: 150
|
||||
borderColor: Theme.palette.base100
|
||||
strokeColor: Pomodoro.state == "timer" ? Theme.palette.primary : Theme.palette.warning
|
||||
borderColor: Styling.theme.base100
|
||||
strokeColor: PomodoroService.state == "timer" ? Styling.theme.primary : Styling.theme.warning
|
||||
strokeWidth: 12
|
||||
fillColor: button.hovered ? Theme.palette.primary : "transparent"
|
||||
percentage: (Pomodoro.state == "timer" ? (Pomodoro.initialTime - Pomodoro.remainingTime) : Pomodoro.remainingTime) / Pomodoro.initialTime % 1
|
||||
fillColor: button.hovered ? Styling.theme.primary : "transparent"
|
||||
percentage: (PomodoroService.state == "timer" ? (PomodoroService.initialTime - PomodoroService.remainingTime) : PomodoroService.remainingTime) / PomodoroService.initialTime % 1
|
||||
}
|
||||
|
||||
StyledIconButton {
|
||||
|
|
@ -69,17 +60,17 @@ StyledWindow {
|
|||
radius: 9999
|
||||
|
||||
focus: root.visible
|
||||
text: Pomodoro.running ? Icons.square : Icons.play
|
||||
text: PomodoroService.running ? Styling.lucide.icons.square : Styling.lucide.icons.play
|
||||
font.pixelSize: 48
|
||||
|
||||
background: undefined
|
||||
background: Item {}
|
||||
onClicked: {
|
||||
Pomodoro.toggle();
|
||||
PomodoroService.toggle();
|
||||
}
|
||||
|
||||
Keys.onSpacePressed: event => {
|
||||
event.accepted = true;
|
||||
Pomodoro.toggle();
|
||||
PomodoroService.toggle();
|
||||
}
|
||||
Keys.onEscapePressed: event => {
|
||||
event.accepted = true;
|
||||
|
|
@ -87,7 +78,7 @@ StyledWindow {
|
|||
}
|
||||
Keys.onTabPressed: event => {
|
||||
event.accepted = true;
|
||||
Pomodoro.reset();
|
||||
PomodoroService.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +86,7 @@ StyledWindow {
|
|||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: {
|
||||
const date = new Date(Pomodoro.remainingTime);
|
||||
const date = new Date(PomodoroService.remainingTime);
|
||||
return `${date.getMinutes().toString().padStart(2, "0")}:${(date.getSeconds() % 3600).toString().padStart(2, "0")}`;
|
||||
}
|
||||
font.pixelSize: 16
|
||||
|
|
@ -108,7 +99,7 @@ StyledWindow {
|
|||
text: "Reset"
|
||||
|
||||
onClicked: {
|
||||
Pomodoro.reset();
|
||||
PomodoroService.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@ pragma ComponentBehavior: Bound
|
|||
import qs.components
|
||||
import qs.config
|
||||
import qs.services
|
||||
import qs.widgets
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
|
||||
StyledWindow {
|
||||
StyledPanelWindow {
|
||||
id: root
|
||||
name: "powermenu"
|
||||
|
||||
|
|
@ -18,27 +16,18 @@ StyledWindow {
|
|||
implicitWidth: rect.width
|
||||
implicitHeight: rect.height
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
onFocusedChanged: {
|
||||
Visibility.powermenu = focused;
|
||||
}
|
||||
|
||||
Process {
|
||||
id: process
|
||||
}
|
||||
|
||||
StyledWrapperRectangle {
|
||||
WrapperItem {
|
||||
id: rect
|
||||
|
||||
color: Theme.palette.base300
|
||||
margin: 14
|
||||
radius: 8
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: Visibility.powermenu
|
||||
windows: [root]
|
||||
onCleared: {
|
||||
Visibility.powermenu = false;
|
||||
}
|
||||
}
|
||||
|
||||
StyledListView {
|
||||
id: list
|
||||
|
|
@ -69,7 +58,7 @@ StyledWindow {
|
|||
|
||||
model: Config.powermenu.actions
|
||||
|
||||
spacing: 8
|
||||
spacing: Styling.layout.spacing.base
|
||||
|
||||
implicitWidth: 220
|
||||
implicitHeight: 185
|
||||
|
|
@ -78,7 +67,7 @@ StyledWindow {
|
|||
highlightResizeDuration: 0
|
||||
highlight: Rectangle {
|
||||
radius: 8
|
||||
color: Theme.palette.primary
|
||||
color: Styling.theme.primary
|
||||
}
|
||||
|
||||
onCurrentItemChanged: {
|
||||
|
|
@ -105,9 +94,9 @@ StyledWindow {
|
|||
}
|
||||
|
||||
padding: 16
|
||||
color: list.currentIndex == index ? Theme.palette.primarycontent : Theme.palette.basecontent
|
||||
color: list.currentIndex == index ? Styling.theme.primarycontent : Styling.theme.basecontent
|
||||
text: modelData.text
|
||||
font.pixelSize: 18
|
||||
font.pixelSize: Styling.typography.textSize.lg
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
150
modules/storybook/Components.qml
Normal file
150
modules/storybook/Components.qml
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
import qs.components
|
||||
import qs.components.composite
|
||||
import qs.config
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
GridLayout {
|
||||
flow: GridLayout.TopToBottom
|
||||
columns: 2
|
||||
rows: 10
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "ToolTip"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
Button {
|
||||
id: toolTipButton
|
||||
text: "Hello world!"
|
||||
StyledToolTip {
|
||||
visible: toolTipButton.hovered
|
||||
text: qsTr("Save the active project")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "ProgressBar"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
StyledProgressBar {
|
||||
id: progressBar
|
||||
indeterminate: true
|
||||
implicitHeight: 10
|
||||
from: 0
|
||||
to: 100
|
||||
value: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "ListView"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
StyledWrapperRectangle {
|
||||
border.color: Styling.theme.base100
|
||||
border.width: 2
|
||||
StyledListView {
|
||||
implicitWidth: 200
|
||||
implicitHeight: 100
|
||||
model: 10
|
||||
delegate: StyledText {
|
||||
text: "Hello world!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Mpris Player Selector"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
MprisPlayerSelector {}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Mpris Controller"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
MprisController {
|
||||
player: Mpris.active ?? null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Drawer"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
RowLayout {
|
||||
Button {
|
||||
text: "Top"
|
||||
onClicked: {
|
||||
drawer.x = root.width / 2 - drawer.width / 2;
|
||||
drawer.y = 0;
|
||||
drawer.edge = Qt.TopEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Left"
|
||||
onClicked: {
|
||||
drawer.y = root.height / 2 - drawer.height / 2;
|
||||
drawer.x = 0;
|
||||
drawer.edge = Qt.LeftEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Right"
|
||||
onClicked: {
|
||||
drawer.y = root.height / 2 - drawer.height / 2;
|
||||
drawer.x = 0;
|
||||
drawer.edge = Qt.RightEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Bottom"
|
||||
onClicked: {
|
||||
drawer.x = root.width / 2 - drawer.width / 2;
|
||||
drawer.y = 0;
|
||||
drawer.edge = Qt.BottomEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledDrawer {
|
||||
id: drawer
|
||||
edge: Qt.TopEdge
|
||||
width: 400
|
||||
height: 200
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Close"
|
||||
onClicked: drawer.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
53
modules/storybook/Fields.qml
Normal file
53
modules/storybook/Fields.qml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import qs.components
|
||||
import qs.config
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
spacing: Styling.layout.spacing.xl
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Button"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
StyledButton {
|
||||
text: "Button"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Icon Button"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
StyledIconButton {
|
||||
text: Styling.lucide.icons.square
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Slider"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledPane {
|
||||
StyledSlider {
|
||||
id: slider
|
||||
from: 0
|
||||
to: 100
|
||||
value: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component FieldElement: QtObject {
|
||||
property string title
|
||||
property Component component
|
||||
}
|
||||
}
|
||||
22
modules/storybook/Selectors.qml
Normal file
22
modules/storybook/Selectors.qml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import qs.components
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
GridLayout {
|
||||
flow: GridLayout.TopToBottom
|
||||
columns: 2
|
||||
rows: 10
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Switch"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
|
||||
StyledPane {
|
||||
StyledSwitch {
|
||||
text: "Enable"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,243 +2,72 @@ pragma ComponentBehavior: Bound
|
|||
|
||||
import qs.components
|
||||
import qs.config
|
||||
import qs.constants
|
||||
import qs.services
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
StyledWindow {
|
||||
StyledPanelWindow {
|
||||
id: root
|
||||
name: "storybook"
|
||||
|
||||
visible: Visibility.storybook
|
||||
implicitWidth: rect.width
|
||||
implicitHeight: rect.height
|
||||
implicitWidth: 500
|
||||
implicitHeight: 600
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
background.color: Styling.theme.base200
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: Visibility.storybook
|
||||
windows: [root]
|
||||
onCleared: {
|
||||
Visibility.storybook = false;
|
||||
}
|
||||
onFocusedChanged: {
|
||||
Visibility.storybook = focused;
|
||||
}
|
||||
|
||||
StyledWrapperRectangle {
|
||||
id: rect
|
||||
StyledTabBar {
|
||||
id: tabs
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: view.top
|
||||
implicitHeight: 40
|
||||
|
||||
margin: 48
|
||||
|
||||
GridLayout {
|
||||
id: grid
|
||||
|
||||
flow: GridLayout.TopToBottom
|
||||
columns: 2
|
||||
rows: 10
|
||||
|
||||
StyledText {
|
||||
Layout.columnSpan: grid.columns
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
StyledTabButton {
|
||||
text: "Fields"
|
||||
onClicked: tabs.setCurrentIndex(0)
|
||||
}
|
||||
StyledTabButton {
|
||||
text: "Selectors"
|
||||
onClicked: tabs.setCurrentIndex(1)
|
||||
}
|
||||
StyledTabButton {
|
||||
text: "Components"
|
||||
font.pixelSize: 24
|
||||
font.bold: true
|
||||
font.underline: true
|
||||
bottomPadding: 24
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Icon Button"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledIconButton {
|
||||
text: Icons.square
|
||||
onClicked: tabs.setCurrentIndex(2)
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Switch"
|
||||
font.pixelSize: 18
|
||||
SwipeView {
|
||||
id: view
|
||||
|
||||
anchors.top: tabs.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
currentIndex: tabs.currentIndex
|
||||
|
||||
background: Rectangle {
|
||||
color: Styling.theme.base100
|
||||
radius: Styling.theme.radiusBox
|
||||
}
|
||||
|
||||
StyledSwitch {
|
||||
text: "Enable"
|
||||
ScrollView {
|
||||
padding: 36
|
||||
Fields {}
|
||||
}
|
||||
ScrollView {
|
||||
padding: 36
|
||||
Selectors {}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "ToolTip"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
Button {
|
||||
id: toolTipButton
|
||||
text: "Hello world!"
|
||||
StyledToolTip {
|
||||
visible: toolTipButton.hovered
|
||||
text: qsTr("Save the active project")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Slider"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledSlider {
|
||||
id: slider
|
||||
from: 0
|
||||
to: 100
|
||||
value: 50
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "ProgressBar"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledProgressBar {
|
||||
id: progressBar
|
||||
indeterminate: true
|
||||
implicitHeight: 10
|
||||
from: 0
|
||||
to: 100
|
||||
value: 50
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "ListView"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
StyledWrapperRectangle {
|
||||
border.color: Theme.palette.base100
|
||||
border.width: 2
|
||||
StyledListView {
|
||||
implicitWidth: 200
|
||||
implicitHeight: 100
|
||||
model: 10
|
||||
delegate: StyledText {
|
||||
text: "Hello world!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Mpris Player Selector"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
MprisPlayerSelector {}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Mpris Controller"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
MprisController {
|
||||
player: Mpris.active ?? null
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Popup"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
Button {
|
||||
id: fileButton
|
||||
text: "File"
|
||||
onPressed: menu.visible ? menu.close() : menu.open()
|
||||
|
||||
StyledPopup {
|
||||
id: menu
|
||||
|
||||
anchor.item: fileButton
|
||||
|
||||
Column {
|
||||
StyledButton {
|
||||
text: "New..."
|
||||
}
|
||||
StyledButton {
|
||||
text: "Open..."
|
||||
}
|
||||
StyledText {
|
||||
text: "Close"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
StyledText {
|
||||
text: "Drawer"
|
||||
font.pixelSize: 18
|
||||
}
|
||||
RowLayout {
|
||||
Button {
|
||||
text: "Top"
|
||||
onClicked: {
|
||||
drawer.x = root.width / 2 - drawer.width / 2;
|
||||
drawer.y = 0;
|
||||
drawer.edge = Qt.TopEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Left"
|
||||
onClicked: {
|
||||
drawer.y = root.height / 2 - drawer.height / 2;
|
||||
drawer.x = 0;
|
||||
drawer.edge = Qt.LeftEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Right"
|
||||
onClicked: {
|
||||
drawer.y = root.height / 2 - drawer.height / 2;
|
||||
drawer.x = 0;
|
||||
drawer.edge = Qt.RightEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Bottom"
|
||||
onClicked: {
|
||||
drawer.x = root.width / 2 - drawer.width / 2;
|
||||
drawer.y = 0;
|
||||
drawer.edge = Qt.BottomEdge;
|
||||
drawer.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledDrawer {
|
||||
id: drawer
|
||||
edge: Qt.TopEdge
|
||||
width: 400
|
||||
height: 200
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Close"
|
||||
onClicked: drawer.close()
|
||||
ScrollView {
|
||||
padding: 36
|
||||
Components {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
modules/wallpaper/Wallpaper.qml
Normal file
35
modules/wallpaper/Wallpaper.qml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
StackView {
|
||||
id: stack
|
||||
property url wallpaper: WallpaperService.currentWallpaper
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
replaceEnter: Transition {
|
||||
OpacityAnimator {
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
duration: 1000
|
||||
}
|
||||
}
|
||||
replaceExit: Transition {
|
||||
PauseAnimation {
|
||||
duration: 1100
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: img
|
||||
Image {}
|
||||
}
|
||||
|
||||
Component.onCompleted: stack.replace(img, {
|
||||
"source": stack.wallpaper
|
||||
})
|
||||
onWallpaperChanged: stack.replace(img, {
|
||||
"source": stack.wallpaper
|
||||
})
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
|
||||
Singleton {
|
||||
|
||||
|
|
@ -16,16 +16,14 @@ Singleton {
|
|||
|
||||
function toggle() {
|
||||
if (properties.enabled) {
|
||||
process.signal(888);
|
||||
properties.enabled = false;
|
||||
} else {
|
||||
properties.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: process
|
||||
running: properties.enabled
|
||||
command: ["sh", "-c", "systemd-inhibit --what=idle --who=Caffeine --why='Caffeine module is active' --mode=block sleep inf"]
|
||||
IdleInhibitor {
|
||||
id: inhibitor
|
||||
enabled: properties.enabled
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,13 +10,16 @@ Singleton {
|
|||
readonly property PwNode sink: Pipewire.defaultAudioSink
|
||||
readonly property PwNode source: Pipewire.defaultAudioSource
|
||||
|
||||
readonly property list<PwNode> sinks: Pipewire.nodes.values.filter(node => node.audio != null && node.isSink && !node.isStream)
|
||||
readonly property list<PwNode> sources: Pipewire.nodes.values.filter(node => node.audio != null && !node.isSink && !node.isStream)
|
||||
|
||||
readonly property bool muted: sink?.audio?.muted ?? false
|
||||
readonly property real volume: sink?.audio?.volume ?? 0
|
||||
|
||||
function setVolume(volume: real): void {
|
||||
if (sink?.ready && sink?.audio) {
|
||||
sink.audio.muted = false;
|
||||
sink.audio.volume = volume;
|
||||
sink.audio.volume = Math.min(volume, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +45,18 @@ Singleton {
|
|||
sink.audio.muted = !sink.audio.muted;
|
||||
}
|
||||
|
||||
function setSink(node: PwNode) {
|
||||
if (node.audio != null && node.isSink && !node.isStream) {
|
||||
Pipewire.preferredDefaultAudioSink = node;
|
||||
}
|
||||
}
|
||||
|
||||
function setSource(node: PwNode) {
|
||||
if (node.audio != null && !node.isSink && !node.isStream) {
|
||||
Pipewire.preferredDefaultAudioSource = node;
|
||||
}
|
||||
}
|
||||
|
||||
PwObjectTracker {
|
||||
objects: [Pipewire.defaultAudioSink, Pipewire.defaultAudioSource]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,19 @@
|
|||
pragma Singleton
|
||||
|
||||
import qs.widgets
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
property alias configuration: properties.configuration
|
||||
property alias dashboard: properties.dashboard
|
||||
property alias launcher: properties.launcher
|
||||
property alias pomodoro: properties.pomodoro
|
||||
property alias powermenu: properties.powermenu
|
||||
property alias storybook: properties.storybook
|
||||
property StyledPopupWindow activePopup
|
||||
|
||||
function togglePopup(popup: StyledPopupWindow) {
|
||||
if (activePopup && popup != activePopup) {
|
||||
activePopup.state = "";
|
||||
}
|
||||
popup.state = popup.state == "opened" ? "" : "opened";
|
||||
activePopup = popup;
|
||||
}
|
||||
|
||||
PersistentProperties {
|
||||
id: properties
|
||||
|
||||
property bool configuration
|
||||
property bool dashboard
|
||||
property bool launcher
|
||||
property bool pomodoro
|
||||
|
|
|
|||
27
services/WallpaperService.qml
Normal file
27
services/WallpaperService.qml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
pragma Singleton
|
||||
|
||||
import qs.config
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property alias currentWallpaper: properties.currentWallpaper
|
||||
|
||||
FileView {
|
||||
path: `${Paths.cache}/wallpaper.json`
|
||||
|
||||
watchChanges: true
|
||||
onFileChanged: reload()
|
||||
|
||||
// when changes are made to properties in the adapter, save them
|
||||
onAdapterUpdated: writeAdapter()
|
||||
|
||||
JsonAdapter {
|
||||
id: properties
|
||||
|
||||
property url currentWallpaper: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
43
utils/DirectoryWatcher.qml
Normal file
43
utils/DirectoryWatcher.qml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import QtQuick
|
||||
import Quickshell.Io
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property string path
|
||||
property bool recursive: true
|
||||
property list<string> fileFilter: []
|
||||
signal created(path: string)
|
||||
signal modified(path: string)
|
||||
signal deleted(path: string)
|
||||
signal movedFrom(path: string)
|
||||
signal movedTo(path: string)
|
||||
|
||||
Process {
|
||||
running: true
|
||||
command: ["bash", "-c", `inotifywait -m ${root.recursive ? "-r" : ""} ${root.path} -e modify,move,create,delete --format "%e-%w%f"`]
|
||||
stderr: StdioCollector {
|
||||
onStreamFinished: console.error(`DirectoryWatcher: ${this.text}`)
|
||||
}
|
||||
stdout: SplitParser {
|
||||
splitMarker: "\n"
|
||||
onRead: data => {
|
||||
const [action, path] = data.split("-");
|
||||
if (path.endsWith("~") || root.fileFilter.length > 0 && !root.fileFilter.some(filter => path.endsWith(filter))) {
|
||||
return;
|
||||
}
|
||||
if (action.includes("CREATE")) {
|
||||
root.created(path);
|
||||
} else if (action.includes("MODIFY")) {
|
||||
root.modified(path);
|
||||
} else if (action.includes("DELETE")) {
|
||||
root.deleted(path);
|
||||
} else if (action.includes("MOVED_FROM")) {
|
||||
root.movedFrom(path);
|
||||
} else if (action.includes("MOVED_TO")) {
|
||||
root.movedTo(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,8 @@ Item {
|
|||
ShapePath {
|
||||
id: fill
|
||||
|
||||
fillColor: Theme.palette.base100
|
||||
strokeColor: Theme.palette.base200
|
||||
fillColor: Styling.theme.base100
|
||||
strokeColor: Styling.theme.base200
|
||||
strokeWidth: 8
|
||||
|
||||
PathAngleArc {
|
||||
|
|
|
|||
|
|
@ -1,102 +0,0 @@
|
|||
import qs.services
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
property bool opened: false
|
||||
property int animationDuration: 200
|
||||
property alias margins: background.margin
|
||||
property alias backgroundColor: background.color
|
||||
property alias radius: background.radius
|
||||
property alias state: background.state
|
||||
required property Component content
|
||||
|
||||
color: "transparent"
|
||||
|
||||
function toggle() {
|
||||
Visibility.togglePopup(this);
|
||||
}
|
||||
|
||||
implicitWidth: background.width
|
||||
Behavior on implicitWidth {
|
||||
NumberAnimation {
|
||||
duration: 100
|
||||
}
|
||||
}
|
||||
implicitHeight: background.height
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: 100
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 750
|
||||
onTriggered: {
|
||||
if (!root.visible) {
|
||||
return;
|
||||
}
|
||||
root.toggle();
|
||||
}
|
||||
}
|
||||
|
||||
WrapperMouseArea {
|
||||
hoverEnabled: true
|
||||
onExited: {
|
||||
timer.start();
|
||||
}
|
||||
onEntered: {
|
||||
timer.stop();
|
||||
}
|
||||
WrapperRectangle {
|
||||
id: background
|
||||
|
||||
opacity: 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: root.animationDuration
|
||||
}
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "opened"
|
||||
when: root.opened
|
||||
PropertyChanges {
|
||||
background {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: ""
|
||||
to: "opened"
|
||||
ScriptAction {
|
||||
script: root.visible = true
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "opened"
|
||||
to: ""
|
||||
SequentialAnimation {
|
||||
PauseAnimation {
|
||||
duration: root.animationDuration
|
||||
}
|
||||
ScriptAction {
|
||||
script: root.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Loader {
|
||||
active: root.visible
|
||||
sourceComponent: root.content
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue