diff --git a/README.md b/README.md index 1214637..8faca34 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,13 @@ Run the shell quickshell -c shell ``` +Run app launcher + +```shell +quickshell -c launcher +``` + ## Dependencies - `quickshell` -- `qt6-wayland` - `app2unit` -- `meson` -- `ninja` -- `python3` diff --git a/components/LucideIcon.qml b/components/LucideIcon.qml index 8788c0d..206d5b4 100644 --- a/components/LucideIcon.qml +++ b/components/LucideIcon.qml @@ -2,12 +2,13 @@ import qs.config import QtQuick Text { - font.family: Styling.lucide.font.family - font.pixelSize: 16 - color: Styling.theme.basecontent + color: Theme.palette.basecontent Behavior on color { ColorAnimation { - duration: Styling.animations.speed.fast + duration: 100 } } + font.family: Theme.lucide.font.family + font.pixelSize: Dimensions.gpu.iconSize + font.bold: true } diff --git a/components/composite/MprisController.qml b/components/MprisController.qml similarity index 83% rename from components/composite/MprisController.qml rename to components/MprisController.qml index 4ad8be0..9b92b0a 100644 --- a/components/composite/MprisController.qml +++ b/components/MprisController.qml @@ -2,6 +2,8 @@ pragma ComponentBehavior: Bound import qs.components import qs.config +import qs.constants +import qs.widgets import QtQuick import QtQuick.Layouts import Quickshell.Services.Mpris @@ -14,43 +16,35 @@ Loader { active: player != null sourceComponent: ColumnLayout { - spacing: Styling.layout.spacing.xl + spacing: 12 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: Styling.lucide.icons.skipBack - + text: Icons.skipBack onClicked: { root.player.previous(); } } StyledIconButton { id: playPauseButton - - text: root.player.isPlaying ? Styling.lucide.icons.pause : Styling.lucide.icons.play - + text: root.player.isPlaying ? Icons.pause : Icons.play onClicked: { root.player.isPlaying = !root.player.isPlaying; } } StyledIconButton { id: forwardButton - - text: Styling.lucide.icons.skipForward - + text: Icons.skipForward onClicked: { root.player.next(); } @@ -59,24 +53,21 @@ 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; } diff --git a/components/composite/MprisPlayerSelector.qml b/components/MprisPlayerSelector.qml similarity index 77% rename from components/composite/MprisPlayerSelector.qml rename to components/MprisPlayerSelector.qml index bd81afc..3a39693 100644 --- a/components/composite/MprisPlayerSelector.qml +++ b/components/MprisPlayerSelector.qml @@ -1,11 +1,12 @@ -import qs.config import qs.components +import qs.constants import qs.services +import qs.widgets import QtQuick import QtQuick.Layouts RowLayout { - spacing: Styling.layout.spacing.xl + spacing: 8 Layout.alignment: Qt.AlignHCenter @@ -13,7 +14,7 @@ RowLayout { id: previousPlayerButton visible: Mpris.players.length > 1 - text: Styling.lucide.icons.chevronLeft + text: Icons.chevronLeft onClicked: { Mpris.previousPlayer(); @@ -21,7 +22,6 @@ RowLayout { } StyledText { - font.pixelSize: Styling.typography.textSize.xl text: { if (!Mpris.active) { return "inactive"; @@ -29,20 +29,21 @@ RowLayout { const player = Mpris.active; const displayName = player.identity ?? player.desktopEntry ?? player.dbusName ?? "unknown"; if (displayName.toLowerCase().includes('tidal')) { - return "Tidal"; + return "Tidal"; } if (displayName.toLowerCase().includes('zen')) { - return "Zen"; + return "Zen"; } return displayName; } + font.pixelSize: 20 } StyledIconButton { id: nextPlayerButton visible: Mpris.players.length > 1 - text: Styling.lucide.icons.chevronRight + text: Icons.chevronRight onClicked: { Mpris.nextPlayer(); diff --git a/components/StyledButton.qml b/components/StyledButton.qml index 9d0ee64..ead62b4 100644 --- a/components/StyledButton.qml +++ b/components/StyledButton.qml @@ -7,21 +7,19 @@ Button { property alias border: rectangle.border property alias radius: rectangle.radius - font.pixelSize: Styling.typography.textSize.base - font.family: Styling.typography.fontFamily - verticalPadding: 6 - horizontalPadding: 8 + font.pixelSize: 14 + padding: 6 - palette.button: hovered ? Styling.theme.primary : Styling.theme.base200 + palette.button: hovered ? Theme.palette.primary : Theme.palette.base100 Behavior on palette.button { ColorAnimation { - duration: Styling.animations.speed.normal + duration: 100 } } - palette.buttonText: hoverEnabled && hovered ? Styling.theme.primarycontent : Styling.theme.basecontent + palette.buttonText: hoverEnabled && hovered ? Theme.palette.primarycontent : Theme.palette.basecontent Behavior on palette.buttonText { ColorAnimation { - duration: Styling.animations.speed.normal + duration: 100 } } @@ -34,6 +32,6 @@ Button { background: Rectangle { id: rectangle color: root.palette.button - radius: Styling.theme.radiusField + radius: 8 } } diff --git a/components/StyledComboBox.qml b/components/StyledComboBox.qml deleted file mode 100644 index 5f9784e..0000000 --- a/components/StyledComboBox.qml +++ /dev/null @@ -1,107 +0,0 @@ -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 - } - } -} diff --git a/components/StyledDrawer.qml b/components/StyledDrawer.qml index a87f8fd..c153482 100644 --- a/components/StyledDrawer.qml +++ b/components/StyledDrawer.qml @@ -1,29 +1,11 @@ import qs.config import QtQuick import QtQuick.Controls -import Quickshell -import Quickshell.Hyprland -import Quickshell.Widgets Drawer { id: control dim: false - property bool focused: false - - onVisibleChanged: { - focused = visible; - } - - HyprlandFocusGrab { - active: control.focused - windows: [QsWindow.window] - onCleared: { - control.focused = false; - } - } - - background: ClippingWrapperRectangle { - margin: 4 + background: Rectangle { Component.onCompleted: { if (control.edge == Qt.TopEdge) { radius = 8; @@ -38,24 +20,6 @@ Drawer { topRightRadius = 8; } } - 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 - } + color: Theme.palette.base200 } } diff --git a/components/StyledIconButton.qml b/components/StyledIconButton.qml index 3e5731b..780113d 100644 --- a/components/StyledIconButton.qml +++ b/components/StyledIconButton.qml @@ -5,14 +5,19 @@ import QtQuick.Controls RoundButton { id: control + FontLoader { + id: loader + source: "../assets/lucide.woff" + } + property alias border: rect.border - property color color: hovered ? Styling.theme.primarycontent : Styling.theme.basecontent + property color color: hovered ? Theme.palette.primarycontent : Theme.palette.basecontent property int rotation: 0 - font.family: Styling.lucide.font.family - font.pixelSize: 16 - radius: Styling.theme.radiusField - padding: 8 + font.family: loader.font.family + font.pixelSize: 18 + radius: 8 + padding: 6 HoverHandler { cursorShape: Qt.PointingHandCursor @@ -22,35 +27,34 @@ RoundButton { id: icon font: control.font text: control.text - verticalAlignment: Text.AlignVCenter color: control.color Behavior on color { ColorAnimation { - duration: Styling.animations.speed.normal + duration: 100 } } rotation: control.rotation Behavior on rotation { RotationAnimation { - duration: Styling.animations.speed.slow - easing.type: Easing.OutQuad + duration: 200 + easing.type: Easing.InOutCubic } } } background: Rectangle { id: rect - border.color: control.hovered ? Styling.theme.base300 : Styling.theme.base200 + border.color: control.hovered ? Theme.palette.primary : Theme.palette.base100 Behavior on border.color { ColorAnimation { - duration: Styling.animations.speed.normal + duration: 100 } } - border.width: 0 - color: control.hovered ? Styling.theme.primary : Styling.theme.base200 + border.width: 2 + color: control.hovered ? Theme.palette.primary : Theme.palette.base100 Behavior on color { ColorAnimation { - duration: Styling.animations.speed.normal + duration: 100 } } radius: control.radius diff --git a/components/StyledImage.qml b/components/StyledImage.qml deleted file mode 100644 index d7d7081..0000000 --- a/components/StyledImage.qml +++ /dev/null @@ -1,17 +0,0 @@ -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 - } -} diff --git a/components/StyledLabel.qml b/components/StyledLabel.qml new file mode 100644 index 0000000..4b9dd07 --- /dev/null +++ b/components/StyledLabel.qml @@ -0,0 +1,16 @@ +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 + } + } +} diff --git a/components/StyledListView.qml b/components/StyledListView.qml index 5c853b4..733d258 100644 --- a/components/StyledListView.qml +++ b/components/StyledListView.qml @@ -1,4 +1,3 @@ -import qs.config import QtQuick import QtQuick.Controls @@ -15,7 +14,7 @@ ListView { rebound: Transition { NumberAnimation { properties: "x,y" - duration: Styling.animations.speed.slow + duration: 400 easing.type: Easing.BezierSpline easing.bezierCurve: [0.2, 0, 0, 1, 1, 1] } diff --git a/components/StyledPane.qml b/components/StyledPane.qml deleted file mode 100644 index b9f0f47..0000000 --- a/components/StyledPane.qml +++ /dev/null @@ -1,21 +0,0 @@ -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 - } -} diff --git a/components/StyledPanelWindow.qml b/components/StyledPanelWindow.qml deleted file mode 100644 index ebadb64..0000000 --- a/components/StyledPanelWindow.qml +++ /dev/null @@ -1,74 +0,0 @@ -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 - } -} diff --git a/components/StyledPopupWindow.qml b/components/StyledPopupWindow.qml index cf87fb1..955f92d 100644 --- a/components/StyledPopupWindow.qml +++ b/components/StyledPopupWindow.qml @@ -6,87 +6,33 @@ import Quickshell.Hyprland PopupWindow { id: root - required property Component content - - implicitWidth: background.width - implicitHeight: background.height + implicitWidth: contentItem.children.reduce((prev, child) => Math.max(prev, child.width), 0) + implicitHeight: contentItem.children.reduce((prev, child) => prev + child.height, 0) color: "transparent" + contentItem.focus: visible + function open() { + visible = true; + } + + function close() { + visible = false; + } + + // WlrLayershell.layer: WlrLayer.Top + // WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None HyprlandFocusGrab { - id: grab active: root.visible windows: [root] onCleared: { - background.state = "closed"; + root.close(); } } - function toggle() { - background.state = background.state == "opened" ? "closed" : "opened"; - } - - StyledWrapperRectangle { + Rectangle { 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 - } + anchors.fill: parent + color: Theme.palette.base200 + radius: 8 } } diff --git a/components/StyledProgressBar.qml b/components/StyledProgressBar.qml index 6075b4d..f0c0ef6 100644 --- a/components/StyledProgressBar.qml +++ b/components/StyledProgressBar.qml @@ -15,8 +15,8 @@ ProgressBar { background: Rectangle { implicitWidth: 200 implicitHeight: 6 - color: Styling.theme.base100 - radius: Styling.theme.radiusField + color: Theme.palette.base100 + radius: 8 } contentItem: Item { @@ -27,8 +27,8 @@ ProgressBar { Rectangle { width: control.visualPosition * parent.width height: parent.height - radius: Styling.theme.radiusField - color: Styling.theme.primary + radius: 8 + color: Theme.palette.primary visible: !control.indeterminate } @@ -40,15 +40,15 @@ ProgressBar { Row { Rectangle { - id: rect - color: Styling.theme.primary - width: 40 - height: control.height - } + id: rect + color: Theme.palette.primary + width: 40 + height: control.height + } XAnimator on x { from: control.width + rect.width to: -rect.width - duration: Styling.animations.speed.verySlow + duration: 1000 loops: Animation.Infinite running: control.indeterminate } diff --git a/components/StyledRectangle.qml b/components/StyledRectangle.qml deleted file mode 100644 index 77ad318..0000000 --- a/components/StyledRectangle.qml +++ /dev/null @@ -1,12 +0,0 @@ -import qs.config -import QtQuick - -Rectangle { - radius: Styling.theme.radiusBox - color: Styling.theme.base200 - Behavior on color { - ColorAnimation { - duration: Styling.animations.speed.normal - } - } -} diff --git a/components/StyledSlider.qml b/components/StyledSlider.qml index 34d0633..e0b0fca 100644 --- a/components/StyledSlider.qml +++ b/components/StyledSlider.qml @@ -18,19 +18,19 @@ Slider { implicitHeight: control.height width: control.availableWidth height: implicitHeight - radius: Styling.theme.radiusField - color: Styling.theme.base200 + radius: 8 + color: Theme.palette.base100 Rectangle { width: control.visualPosition * parent.width Behavior on width { NumberAnimation { - duration: Styling.animations.speed.fast + duration: 75 } } height: parent.height - color: Styling.theme.primary - radius: Styling.theme.radiusField + color: Theme.palette.primary + radius: 8 } } handle: null diff --git a/components/StyledSwitch.qml b/components/StyledSwitch.qml index 7d909ac..c2af7db 100644 --- a/components/StyledSwitch.qml +++ b/components/StyledSwitch.qml @@ -11,7 +11,7 @@ Switch { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 - color: Styling.theme.basecontent + color: Theme.palette.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: Styling.theme.radiusSelector + radius: 16 color: "transparent" - border.color: control.checked ? Styling.theme.primary : Styling.theme.basecontent + border.color: control.checked ? Theme.palette.primary : Theme.palette.basecontent border.width: 2 Rectangle { @@ -40,15 +40,16 @@ Switch { y: parent.height / 2 - height / 2 Behavior on x { NumberAnimation { - duration: Styling.animations.speed.fast + duration: 100 } } width: parent.width / 2 - indicator.padding height: parent.height - indicator.padding - radius: Styling.theme.radiusSelector - color: control.checked ? Styling.theme.primary : Styling.theme.basecontent + radius: 16 + color: control.checked ? Theme.palette.primary : Theme.palette.basecontent + // border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" } } - background: Item {} + background: null } diff --git a/components/StyledTabBar.qml b/components/StyledTabBar.qml deleted file mode 100644 index 512ce5a..0000000 --- a/components/StyledTabBar.qml +++ /dev/null @@ -1,19 +0,0 @@ -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 {} -} diff --git a/components/StyledTabButton.qml b/components/StyledTabButton.qml deleted file mode 100644 index 15d9859..0000000 --- a/components/StyledTabButton.qml +++ /dev/null @@ -1,46 +0,0 @@ -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 - } -} diff --git a/components/StyledText.qml b/components/StyledText.qml index 95ac150..4fe365e 100644 --- a/components/StyledText.qml +++ b/components/StyledText.qml @@ -2,12 +2,9 @@ import qs.config import QtQuick Text { - font.family: Styling.typography.fontFamily - font.pixelSize: Styling.typography.textSize.base - color: Styling.theme.basecontent - Behavior on color { - ColorAnimation { - duration: Styling.animations.speed.fast - } + font.family: Theme.fontFamily + color: Theme.palette.basecontent + ColorAnimation on color { + duration: 100 } } diff --git a/components/StyledTextField.qml b/components/StyledTextField.qml index aa98e33..bae90ba 100644 --- a/components/StyledTextField.qml +++ b/components/StyledTextField.qml @@ -1,9 +1,8 @@ import qs.config -import QtQuick import QtQuick.Controls TextField { - color: Styling.theme.basecontent - background: Item {} + color: Theme.palette.basecontent + background: null } diff --git a/components/StyledToolTip.qml b/components/StyledToolTip.qml index 9015122..0c09a95 100644 --- a/components/StyledToolTip.qml +++ b/components/StyledToolTip.qml @@ -9,13 +9,11 @@ ToolTip { contentItem: Text { text: control.text font: control.font - color: Styling.theme.basecontent + color: Theme.palette.basecontent } background: Rectangle { - radius: Styling.theme.radiusBox - color: Styling.theme.base100 - border.color: Styling.theme.base200 - border.width: Styling.theme.border + radius: 8 + color: Theme.palette.base200 } } diff --git a/components/StyledWindow.qml b/components/StyledWindow.qml new file mode 100644 index 0000000..f1275ba --- /dev/null +++ b/components/StyledWindow.qml @@ -0,0 +1,9 @@ +import Quickshell +import Quickshell.Wayland + +PanelWindow { + required property string name + + WlrLayershell.namespace: `lux-${name}` + color: "transparent" +} diff --git a/components/StyledWrapperRectangle.qml b/components/StyledWrapperRectangle.qml index 1a89fa8..19a70d1 100644 --- a/components/StyledWrapperRectangle.qml +++ b/components/StyledWrapperRectangle.qml @@ -3,19 +3,12 @@ import QtQuick import Quickshell.Widgets WrapperRectangle { - margin: 8 - radius: Styling.theme.radiusBox - color: Styling.theme.base100 + radius: 8 + color: Theme.palette.base300 Behavior on color { ColorAnimation { - duration: Styling.animations.speed.fast - } - } - border.width: 2 - border.color: Styling.theme.base100 - Behavior on border.color { - ColorAnimation { - duration: Styling.animations.speed.fast + duration: 200 + easing.type: Easing.InOutQuad } } } diff --git a/components/composite/ThemeComboBox.qml b/components/composite/ThemeComboBox.qml deleted file mode 100644 index 251648b..0000000 --- a/components/composite/ThemeComboBox.qml +++ /dev/null @@ -1,13 +0,0 @@ -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]; - } -} diff --git a/components/composite/WallpaperItem.qml b/components/composite/WallpaperItem.qml deleted file mode 100644 index 779fb62..0000000 --- a/components/composite/WallpaperItem.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick - -Image { - asynchronous: true - fillMode: Image.PreserveAspectCrop - sourceSize.width: parent.width - sourceSize.height: parent.height - - Behavior on scale { - NumberAnimation { - duration: 200 - } - } -} diff --git a/components/composite/WallpaperList.qml b/components/composite/WallpaperList.qml deleted file mode 100644 index 3dfb330..0000000 --- a/components/composite/WallpaperList.qml +++ /dev/null @@ -1,65 +0,0 @@ -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 - } - } - } -} diff --git a/config/Config.qml b/config/Config.qml index 416d739..2cd8ea0 100644 --- a/config/Config.qml +++ b/config/Config.qml @@ -1,39 +1,9 @@ pragma Singleton import Quickshell -import Quickshell.Io Singleton { id: root - 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 actions - } - - component PowerMenuItem: JsonObject { - property string text - property string command - } - - component Wallpaper: JsonObject { - property string directory - } + readonly property PowerMenu powermenu: PowerMenu {} } diff --git a/config/Dimensions.qml b/config/Dimensions.qml new file mode 100644 index 0000000..6b3deaf --- /dev/null +++ b/config/Dimensions.qml @@ -0,0 +1,144 @@ +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 + } +} diff --git a/config/Paths.qml b/config/Paths.qml deleted file mode 100644 index 2fb9e08..0000000 --- a/config/Paths.qml +++ /dev/null @@ -1,45 +0,0 @@ -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)]); - } -} diff --git a/config/PowerMenu.qml b/config/PowerMenu.qml new file mode 100644 index 0000000..0046bd9 --- /dev/null +++ b/config/PowerMenu.qml @@ -0,0 +1,18 @@ +import Quickshell + +PersistentProperties { + property list actions: [ + { + text: "󰍃 Logout", + command: "hyprctl dispatch exit" + }, + { + text: "󰜉 Reboot", + command: "systemctl reboot" + }, + { + text: " Shutdown", + command: "systemctl poweroff" + } + ] +} diff --git a/config/Styling.qml b/config/Styling.qml deleted file mode 100644 index e509c18..0000000 --- a/config/Styling.qml +++ /dev/null @@ -1,132 +0,0 @@ -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 - } - } -} diff --git a/config/Theme.qml b/config/Theme.qml index 4aac927..91fbf0b 100644 --- a/config/Theme.qml +++ b/config/Theme.qml @@ -1,50 +1,39 @@ pragma Singleton import QtQuick -import Qt.labs.folderlistmodel 2.9 import Quickshell -import Quickshell.Io Singleton { id: root - property alias themes: cache.themes - property alias currentTheme: cache.current - property int currentThemeIndex: themes.indexOf(currentTheme) - - 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 var lucide: FontLoader { + source: "../assets/lucide.woff" } + property string fontFamily: "JetBrainsMono Nerd Font" + property Palette palette: Palette {} - FileView { - path: `${Paths.cache}/theme.json` + component Palette: QtObject { + id: palette - 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 themes: ["dark"] - onThemesChanged: { - if (!themes.includes(current)) { - current = themes[0]; - } - } - } + 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" } } diff --git a/constants/Icons.qml b/constants/Icons.qml new file mode 100644 index 0000000..881277e --- /dev/null +++ b/constants/Icons.qml @@ -0,0 +1,36 @@ +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}" +} diff --git a/modules/Shell.qml b/modules/Shell.qml index be31896..69e9e2b 100644 --- a/modules/Shell.qml +++ b/modules/Shell.qml @@ -1,11 +1,9 @@ import "bar" -import "configuration" import "drawers" import "launcher" import "pomodoro" import "powermenu" import "storybook" -import "wallpaper" import QtQuick import Quickshell import Quickshell.Wayland @@ -18,23 +16,6 @@ Variants { required property ShellScreen modelData - 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 @@ -43,7 +24,7 @@ Variants { anchors.right: true implicitWidth: bar.width - implicitHeight: bar.height + bar.anchors.margins + implicitHeight: bar.height color: "transparent" } @@ -94,11 +75,14 @@ Variants { } } } - Configuration {} Launcher {} Pomodoro {} PowerMenu {} - Storybook {} + Storybook { + anchor.window: topWindow + anchor.rect.x: topWindow.width / 2 - width / 2 + anchor.rect.y: topWindow.height / 4 + } Drawers {} } } diff --git a/modules/Shortcuts.qml b/modules/Shortcuts.qml index 7027fcd..e240bf9 100644 --- a/modules/Shortcuts.qml +++ b/modules/Shortcuts.qml @@ -5,12 +5,6 @@ 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' diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml index 7523fcc..231600b 100644 --- a/modules/bar/Bar.qml +++ b/modules/bar/Bar.qml @@ -14,24 +14,19 @@ StyledWrapperRectangle { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top - anchors.margins: 6 - anchors.leftMargin: 10 - anchors.rightMargin: 10 + anchors.leftMargin: Dimensions.bar.horizontalMargins + anchors.rightMargin: Dimensions.bar.horizontalMargins + anchors.topMargin: Dimensions.bar.verticalMargins + anchors.bottomMargin: Dimensions.bar.verticalMargins - border.width: 3 - border.color: Styling.theme.base200 - - margin: 4 - color: Styling.theme.base100 + margin: 6 RowLayout { - uniformCellSizes: true - RowLayout { id: leftbar - spacing: Styling.layout.spacing.base + spacing: Dimensions.bar.spacing SystemLogo { implicitSize: 22 @@ -47,7 +42,7 @@ StyledWrapperRectangle { Layout.alignment: Qt.AlignHCenter - spacing: Styling.layout.spacing.base + spacing: Dimensions.bar.spacing Mpris {} } @@ -57,7 +52,7 @@ StyledWrapperRectangle { Layout.alignment: Qt.AlignRight - spacing: Styling.layout.spacing.base + spacing: Dimensions.bar.spacing Pywal {} diff --git a/modules/bar/components/Caffeine.qml b/modules/bar/components/Caffeine.qml index 126ec7a..82861f9 100644 --- a/modules/bar/components/Caffeine.qml +++ b/modules/bar/components/Caffeine.qml @@ -1,13 +1,13 @@ import qs.components import qs.config +import qs.constants import qs.services StyledIconButton { id: root - border.width: 2 - border.color: Caffeine.enabled ? Styling.theme.secondary : root.hovered ? Styling.theme.primary : Styling.theme.base300 - text: Styling.lucide.icons.coffee + border.color: Caffeine.enabled ? Theme.palette.secondary : root.hovered ? Theme.palette.primary : Theme.palette.base100 + text: Icons.coffee onClicked: { Caffeine.toggle(); diff --git a/modules/bar/components/Clock.qml b/modules/bar/components/Clock.qml index 1941417..c18d940 100644 --- a/modules/bar/components/Clock.qml +++ b/modules/bar/components/Clock.qml @@ -1,10 +1,19 @@ import qs.components +import qs.config +import qs.widgets import Quickshell -StyledText { - text: ` ${Qt.formatDateTime(clock.date, "hh:mm:ss AP")}` - SystemClock { - id: clock - precision: SystemClock.Seconds +StyledLabel { + StyledText { + id: text + + font.pixelSize: Dimensions.clock.fontSize + + text: ` ${Qt.formatDateTime(clock.date, "hh:mm:ss AP")}` + + SystemClock { + id: clock + precision: SystemClock.Seconds + } } } diff --git a/modules/bar/components/Cpu.qml b/modules/bar/components/Cpu.qml index dda97c9..41085be 100644 --- a/modules/bar/components/Cpu.qml +++ b/modules/bar/components/Cpu.qml @@ -1,7 +1,9 @@ import qs.components import qs.config +import qs.constants import qs.services import qs.utils +import qs.widgets import QtQuick import QtQuick.Layouts @@ -15,23 +17,30 @@ StyledButton { } contentItem: RowLayout { + id: row spacing: 0 Ref { service: SystemInfo } + StyledText { + id: icon - LucideIcon { - text: Styling.lucide.icons.cpu - color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent + 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 } StyledText { id: text + font.pixelSize: Dimensions.cpu.fontSize text: ` ${(SystemInfo.cpuPerc * 100).toFixed().toString().padStart(2, "_")}%` - color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent + color: root.hovered ? Theme.palette.primarycontent : Theme.palette.basecontent + states: [ State { name: "showTemp" diff --git a/modules/bar/components/Gpu.qml b/modules/bar/components/Gpu.qml index e7ee38b..fa29708 100644 --- a/modules/bar/components/Gpu.qml +++ b/modules/bar/components/Gpu.qml @@ -1,7 +1,9 @@ import qs.components import qs.config +import qs.constants import qs.services import qs.utils +import qs.widgets import QtQuick import QtQuick.Layouts @@ -11,27 +13,34 @@ StyledButton { property bool showTemp: false onClicked: { - showTemp = !showTemp; + root.showTemp = !root.showTemp; } contentItem: RowLayout { + id: row spacing: 0 Ref { service: SystemInfo } + StyledText { + id: icon - LucideIcon { - text: Styling.lucide.icons.gpu - color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent + 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 } StyledText { id: text + font.pixelSize: Dimensions.gpu.fontSize text: ` ${(SystemInfo.gpuPerc * 100).toFixed().toString().padStart(2, "_")}%` - color: root.hovered ? Styling.theme.primarycontent : Styling.theme.basecontent + color: root.hovered ? Theme.palette.primarycontent : Theme.palette.basecontent + states: [ State { name: "temp" diff --git a/modules/bar/components/Memory.qml b/modules/bar/components/Memory.qml index deafda7..24a967a 100644 --- a/modules/bar/components/Memory.qml +++ b/modules/bar/components/Memory.qml @@ -1,21 +1,28 @@ import qs.components import qs.config +import qs.constants import qs.services +import qs.widgets import qs.utils import QtQuick import QtQuick.Layouts -RowLayout { +StyledLabel { + RowLayout { + Ref { + service: SystemInfo + } + StyledText { + font.family: Theme.lucide.font.family + font.pixelSize: Dimensions.memory.iconSize + font.bold: true + text: Icons.memoryStick + } - Ref { - service: SystemInfo - } - - LucideIcon { - text: Styling.lucide.icons.memoryStick - } - - StyledText { - text: ` ${(SystemInfo.memPerc * 100).toFixed()}%` + StyledText { + id: text + font.pixelSize: Dimensions.memory.fontSize + text: ` ${(SystemInfo.memPerc * 100).toFixed()}%` + } } } diff --git a/modules/bar/components/Network.qml b/modules/bar/components/Network.qml index 7b65d2c..f89010d 100644 --- a/modules/bar/components/Network.qml +++ b/modules/bar/components/Network.qml @@ -1,52 +1,60 @@ import qs.components import qs.config +import qs.constants import qs.services import qs.utils +import qs.widgets import QtQuick import QtQuick.Layouts -RowLayout { +StyledLabel { + RowLayout { + Ref { + service: NetworkService + } + StyledText { + id: icon - Ref { - service: NetworkService - } + font.family: Theme.lucide.font.family + font.pixelSize: Dimensions.network.iconSize + font.bold: true + text: Icons.wifiOff - LucideIcon { - id: icon - text: Styling.lucide.icons.wifiOff - states: [ - State { - name: "high" - when: NetworkService.active?.strength > 50 - PropertyChanges { - icon { - text: Styling.lucide.icons.wifi + states: [ + State { + name: "high" + when: NetworkService.active?.strength > 50 + PropertyChanges { + icon { + text: Icons.wifi + } + } + }, + State { + name: "medium" + when: NetworkService.active?.strength > 25 + PropertyChanges { + icon { + text: Icons.wifiHigh + } + } + }, + State { + name: "low" + when: NetworkService.active?.strength > 0 + PropertyChanges { + icon { + text: Icons.wifiLow + } } } - }, - State { - name: "medium" - when: NetworkService.active?.strength > 25 - PropertyChanges { - icon { - text: Styling.lucide.icons.wifiHigh - } - } - }, - State { - name: "low" - when: NetworkService.active?.strength > 0 - PropertyChanges { - icon { - text: Styling.lucide.icons.wifiLow - } - } - } - ] - } + ] + } - StyledText { - id: text - text: ` ${(NetworkService.active?.strength ?? 0).toFixed()}%` + StyledText { + id: text + font.pixelSize: Dimensions.network.fontSize + text: ` ${(NetworkService.active?.strength ?? 0).toFixed()}%` + } } } diff --git a/modules/bar/components/Pipewire.qml b/modules/bar/components/Pipewire.qml index f677e4b..cde5842 100644 --- a/modules/bar/components/Pipewire.qml +++ b/modules/bar/components/Pipewire.qml @@ -28,7 +28,7 @@ StyledButton { when: Pipewire.muted PropertyChanges { root { - palette.button: Styling.theme.error + palette.button: Theme.palette.error } } } diff --git a/modules/bar/components/Power.qml b/modules/bar/components/Power.qml index 0dfde02..a42a23c 100644 --- a/modules/bar/components/Power.qml +++ b/modules/bar/components/Power.qml @@ -1,5 +1,6 @@ import qs.components import qs.config +import qs.constants import QtQuick import QtQuick.Layouts import Quickshell.Services.UPower @@ -9,56 +10,50 @@ 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 Styling.theme.error; + return Theme.palette.error; } if (root.hovered) { - return Styling.theme.primarycontent; + return Theme.palette.primarycontent; } - return Styling.theme.basecontent; + return Theme.palette.basecontent; } + font.pixelSize: 16 text: { if (root.laptopBattery?.state == UPowerDeviceState.Charging) { - return Styling.lucide.icons.batteryCharging; + return Icons.batteryCharging; } if (root.isCritical) { - return Styling.lucide.icons.batteryWarning; + return Icons.batteryWarning; } if (root.laptopBattery?.percentage < 0.33) { - return Styling.lucide.icons.batteryLow; + return Icons.batteryLow; } if (root.laptopBattery?.percentage < 0.66) { - return Styling.lucide.icons.batteryMedium; + return Icons.batteryMedium; } - return Styling.lucide.icons.batteryFull; + return Icons.batteryFull; } } StyledText { - Layout.alignment: Qt.AlignVCenter - color: { if (root.isCritical) { - return Styling.theme.error; + return Theme.palette.error; } if (root.hovered) { - return Styling.theme.primarycontent; + return Theme.palette.primarycontent; } - return Styling.theme.basecontent; + return Theme.palette.basecontent; } text: `${(root.laptopBattery?.percentage.toFixed(2) * 100)}%` } } + visible: laptopBattery } diff --git a/modules/bar/components/Pywal.qml b/modules/bar/components/Pywal.qml index 5a38593..d83c508 100644 --- a/modules/bar/components/Pywal.qml +++ b/modules/bar/components/Pywal.qml @@ -1,12 +1,12 @@ import qs.components -import qs.config +import qs.constants import QtQuick import Quickshell.Io StyledIconButton { id: clickable - text: Styling.lucide.icons.brickWall + text: Icons.brickWall onClicked: { process.running = true; diff --git a/modules/bar/components/Storage.qml b/modules/bar/components/Storage.qml index 7450969..56fbeb3 100644 --- a/modules/bar/components/Storage.qml +++ b/modules/bar/components/Storage.qml @@ -1,23 +1,30 @@ import qs.components import qs.config +import qs.constants import qs.services import qs.utils +import qs.widgets import QtQuick import QtQuick.Layouts -RowLayout { +StyledLabel { + RowLayout { + Ref { + service: SystemInfo + } + StyledText { + id: icon - Ref { - service: SystemInfo - } + 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 - - text: ` ${(SystemInfo.storagePerc * 100).toFixed()}%` + StyledText { + id: text + font.pixelSize: Dimensions.storage.fontSize + text: ` ${(SystemInfo.storagePerc * 100).toFixed()}%` + } } } diff --git a/modules/bar/components/bluetooth/AvailableDevice.qml b/modules/bar/components/bluetooth/AvailableDevice.qml index 9196210..e868b8e 100644 --- a/modules/bar/components/bluetooth/AvailableDevice.qml +++ b/modules/bar/components/bluetooth/AvailableDevice.qml @@ -1,21 +1,21 @@ 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 -StyledWrapperRectangle { +StyledLabel { id: root required property BluetoothDevice modelData RowLayout { id: row - spacing: Styling.layout.spacing.base + spacing: 8 Loader { active: root.modelData?.icon != undefined diff --git a/modules/bar/components/bluetooth/Bluetooth.qml b/modules/bar/components/bluetooth/Bluetooth.qml index e30639d..c12c93b 100644 --- a/modules/bar/components/bluetooth/Bluetooth.qml +++ b/modules/bar/components/bluetooth/Bluetooth.qml @@ -1,10 +1,10 @@ import qs.components -import qs.config +import qs.constants StyledIconButton { id: root - text: Styling.lucide.icons.bluetooth + text: Icons.bluetooth onClicked: popup.toggle() diff --git a/modules/bar/components/bluetooth/BluetoothMenu.qml b/modules/bar/components/bluetooth/BluetoothMenu.qml index 7e953cf..14e9759 100644 --- a/modules/bar/components/bluetooth/BluetoothMenu.qml +++ b/modules/bar/components/bluetooth/BluetoothMenu.qml @@ -1,6 +1,8 @@ pragma ComponentBehavior: Bound import qs.components +import qs.config +import qs.widgets import QtQuick import QtQuick.Layouts import Quickshell @@ -9,6 +11,10 @@ import Quickshell.Bluetooth StyledPopupWindow { id: root + backgroundColor: Theme.palette.base300 + margins: 16 + radius: 8 + content: ColumnLayout { spacing: 8 StyledWrapperRectangle { diff --git a/modules/bar/components/bluetooth/ConnectedDevice.qml b/modules/bar/components/bluetooth/ConnectedDevice.qml index 960acf9..ce72790 100644 --- a/modules/bar/components/bluetooth/ConnectedDevice.qml +++ b/modules/bar/components/bluetooth/ConnectedDevice.qml @@ -2,20 +2,22 @@ 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 -StyledWrapperRectangle { +StyledLabel { id: root required property BluetoothDevice modelData RowLayout { id: row - spacing: Styling.layout.spacing.base + spacing: 8 Loader { active: root.modelData?.icon != undefined @@ -32,9 +34,12 @@ StyledWrapperRectangle { Loader { active: root.modelData.batteryAvailable sourceComponent: RowLayout { - LucideIcon { + StyledText { id: icon - text: Styling.lucide.icons.batteryFull + font.family: Theme.lucide.font.family + font.pixelSize: Dimensions.cpu.iconSize + font.bold: true + text: Icons.batteryFull states: [ State { name: "full" @@ -45,7 +50,7 @@ StyledWrapperRectangle { when: root.modelData.battery > 0.33 PropertyChanges { icon { - text: Styling.lucide.icons.batteryFull + text: Icons.batteryFull } } }, @@ -54,7 +59,7 @@ StyledWrapperRectangle { when: root.modelData.battery > 0.10 PropertyChanges { icon { - text: Styling.lucide.icons.batteryFull + text: Icons.batteryFull } } }, @@ -63,8 +68,8 @@ StyledWrapperRectangle { when: root.modelData.battery > 0.10 PropertyChanges { icon { - text: Styling.lucide.icons.batteryWarning - color: Styling.theme.error + text: Icons.batteryWarning + color: Theme.palette.error } } } @@ -76,7 +81,7 @@ StyledWrapperRectangle { StyledButton { Layout.alignment: Qt.AlignRight text: 'Disconnect' - palette.button: hovered ? Styling.theme.error : Styling.theme.base200 + palette.button: hovered ? Theme.palette.error : Theme.palette.base200 onClicked: { if (root.modelData.state != BluetoothDeviceState.Connected) { diff --git a/modules/bar/components/bluetooth/PairedDevice.qml b/modules/bar/components/bluetooth/PairedDevice.qml index f8583b0..443ec90 100644 --- a/modules/bar/components/bluetooth/PairedDevice.qml +++ b/modules/bar/components/bluetooth/PairedDevice.qml @@ -2,20 +2,21 @@ 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 -StyledWrapperRectangle { +StyledLabel { id: root required property BluetoothDevice modelData RowLayout { id: row - spacing: Styling.layout.spacing.base + spacing: 8 Loader { active: root.modelData?.icon != undefined @@ -47,7 +48,7 @@ StyledWrapperRectangle { hoverEnabled: root.modelData.state == BluetoothDeviceState.Disconnected text: 'Unpair' - palette.button: hovered ? Styling.theme.error : Styling.theme.base100 + palette.button: hovered ? Theme.palette.error : Theme.palette.base100 onClicked: { if (!hoverEnabled) { diff --git a/modules/bar/components/hyprland/Workspace.qml b/modules/bar/components/hyprland/Workspace.qml index 3f983f9..07acca9 100644 --- a/modules/bar/components/hyprland/Workspace.qml +++ b/modules/bar/components/hyprland/Workspace.qml @@ -1,5 +1,6 @@ import qs.components import qs.config +import qs.constants import QtQuick import Quickshell.Hyprland @@ -8,7 +9,7 @@ StyledIconButton { required property HyprlandWorkspace workspace - text: Styling.lucide.icons.triangle + text: Icons.triangle font.bold: true font.pixelSize: 17 padding: 8 @@ -22,7 +23,7 @@ StyledIconButton { PropertyChanges { root { rotation: 180 - color: root.hovered ? Styling.theme.basecontent : Styling.theme.primary + color: root.hovered ? Theme.palette.basecontent : Theme.palette.primary } } }, @@ -31,9 +32,9 @@ StyledIconButton { when: root.workspace.active PropertyChanges { root { - text: Styling.lucide.icons.triangleDashed + text: Icons.triangleDashed rotation: 180 - color: root.hovered ? Styling.theme.basecontent : Styling.theme.primary + color: root.hovered ? Theme.palette.basecontent : Theme.palette.primary } } } diff --git a/modules/bar/components/hyprland/Workspaces.qml b/modules/bar/components/hyprland/Workspaces.qml index 5a4d10e..44a3e16 100644 --- a/modules/bar/components/hyprland/Workspaces.qml +++ b/modules/bar/components/hyprland/Workspaces.qml @@ -1,5 +1,6 @@ pragma ComponentBehavior: Bound +import qs.config import QtQuick import QtQuick.Layouts import Quickshell.Hyprland @@ -7,7 +8,7 @@ import Quickshell.Hyprland RowLayout { id: root - spacing: 4 + spacing: Dimensions.workspace.spacing Repeater { diff --git a/modules/bar/components/notifications/NotificationItem.qml b/modules/bar/components/notifications/NotificationItem.qml index 21b69f5..690d800 100644 --- a/modules/bar/components/notifications/NotificationItem.qml +++ b/modules/bar/components/notifications/NotificationItem.qml @@ -1,16 +1,18 @@ pragma ComponentBehavior: Bound import qs.components +import qs.widgets import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.Widgets -StyledWrapperRectangle { +StyledLabel { id: root required property var modelData + margin: 16 anchors.left: parent.left anchors.right: parent.right diff --git a/modules/bar/components/notifications/NotificationMenu.qml b/modules/bar/components/notifications/NotificationMenu.qml index 43f2f19..7354f86 100644 --- a/modules/bar/components/notifications/NotificationMenu.qml +++ b/modules/bar/components/notifications/NotificationMenu.qml @@ -1,13 +1,19 @@ 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 @@ -24,8 +30,9 @@ StyledPopupWindow { onClicked: Notifications.clear() } - StyledWrapperRectangle { + StyledLabel { Layout.columnSpan: 2 + color: Theme.palette.base200 StyledListView { id: notifications diff --git a/modules/bar/components/notifications/Notifications.qml b/modules/bar/components/notifications/Notifications.qml index a0080c2..a33b673 100644 --- a/modules/bar/components/notifications/Notifications.qml +++ b/modules/bar/components/notifications/Notifications.qml @@ -1,5 +1,5 @@ import qs.components -import qs.config +import qs.constants import qs.services import QtQuick @@ -10,13 +10,13 @@ StyledIconButton { menu.toggle(); } - text: Notifications.hasNotifications ? Styling.lucide.icons.bell : Styling.lucide.icons.bellRing + text: Notifications.hasNotifications ? Icons.bell : Icons.bellRing states: State { when: Notifications.hasNotifications PropertyChanges { root { - text: Styling.lucide.icons.bellRing + text: Icons.bellRing } } } diff --git a/modules/bar/components/tray/Tray.qml b/modules/bar/components/tray/Tray.qml index 89eacf9..ac343f8 100644 --- a/modules/bar/components/tray/Tray.qml +++ b/modules/bar/components/tray/Tray.qml @@ -1,5 +1,6 @@ pragma ComponentBehavior: Bound +import qs.config import QtQuick import QtQuick.Layouts import Quickshell.Services.SystemTray @@ -7,10 +8,10 @@ import Quickshell.Services.SystemTray RowLayout { id: root - spacing: 4 + spacing: Dimensions.tray.spacing Repeater { - model: SystemTray.items.values + model: SystemTray.items Loader { id: loader diff --git a/modules/bar/components/tray/TrayItem.qml b/modules/bar/components/tray/TrayItem.qml index 4a27057..1e05ff7 100644 --- a/modules/bar/components/tray/TrayItem.qml +++ b/modules/bar/components/tray/TrayItem.qml @@ -5,11 +5,12 @@ import QtQuick import Quickshell import Quickshell.Services.SystemTray import Quickshell.Widgets +import "menu/" StyledIconButton { id: root - required property SystemTrayItem trayItem + property SystemTrayItem trayItem onClicked: menu.toggle() @@ -27,7 +28,7 @@ StyledIconButton { } } - TrayMenu { + Menu { id: menu anchor.item: root diff --git a/modules/bar/components/tray/TrayMenu.qml b/modules/bar/components/tray/TrayMenu.qml deleted file mode 100644 index 88137e2..0000000 --- a/modules/bar/components/tray/TrayMenu.qml +++ /dev/null @@ -1,49 +0,0 @@ -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() - } - } - } - } -} diff --git a/modules/bar/components/tray/menu/Menu.qml b/modules/bar/components/tray/menu/Menu.qml new file mode 100644 index 0000000..5b57904 --- /dev/null +++ b/modules/bar/components/tray/menu/Menu.qml @@ -0,0 +1,43 @@ +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 + } + } + } + } +} diff --git a/modules/bar/components/tray/menu/MenuItem.qml b/modules/bar/components/tray/menu/MenuItem.qml new file mode 100644 index 0000000..056b3ba --- /dev/null +++ b/modules/bar/components/tray/menu/MenuItem.qml @@ -0,0 +1,12 @@ +import qs.components +import Quickshell + +StyledButton { + id: root + + property QsMenuEntry menuEntry + + text: root.menuEntry.text + + onClicked: menuEntry.triggered() +} diff --git a/modules/configuration/AudioView.qml b/modules/configuration/AudioView.qml deleted file mode 100644 index aed90ba..0000000 --- a/modules/configuration/AudioView.qml +++ /dev/null @@ -1,88 +0,0 @@ -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]); - } - } - } - } -} diff --git a/modules/configuration/Configuration.qml b/modules/configuration/Configuration.qml deleted file mode 100644 index 7582efe..0000000 --- a/modules/configuration/Configuration.qml +++ /dev/null @@ -1,127 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.components -import qs.config -import qs.services -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -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: "Look And Feel" - view: LookAndFeel {} - } - } - - component ConfigurationView: QtObject { - property string icon - property string title - property Component view - } -} diff --git a/modules/configuration/LookAndFeel.qml b/modules/configuration/LookAndFeel.qml deleted file mode 100644 index 02461a3..0000000 --- a/modules/configuration/LookAndFeel.qml +++ /dev/null @@ -1,40 +0,0 @@ -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 {} - } - } -} diff --git a/modules/drawers/dashboard/Dashboard.qml b/modules/drawers/dashboard/Dashboard.qml index 5af5285..b98647d 100644 --- a/modules/drawers/dashboard/Dashboard.qml +++ b/modules/drawers/dashboard/Dashboard.qml @@ -1,22 +1,16 @@ 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 - onFocusedChanged: { - Visibility.dashboard = focused; - } - - WrapperItem { + StyledWrapperRectangle { margin: 32 ColumnLayout { spacing: 8 diff --git a/modules/launcher/AppList.qml b/modules/launcher/AppList.qml index ed026b9..d8dbe22 100644 --- a/modules/launcher/AppList.qml +++ b/modules/launcher/AppList.qml @@ -4,6 +4,7 @@ import "items" import "services" import qs.components import qs.config +import qs.widgets import Quickshell import QtQuick import QtQuick.Controls @@ -31,7 +32,7 @@ StyledListView { highlightResizeDuration: 0 highlight: Rectangle { radius: 8 - color: Styling.theme.primary + color: Theme.palette.primary } header: StyledText { diff --git a/modules/launcher/Launcher.qml b/modules/launcher/Launcher.qml index 4c51b54..137c861 100644 --- a/modules/launcher/Launcher.qml +++ b/modules/launcher/Launcher.qml @@ -1,29 +1,40 @@ 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 -StyledPanelWindow { - id: window +StyledWindow { + id: root name: "launcher" visible: Visibility.launcher - onVisibleChanged: { - if (!visible) { - list.currentIndex = 0; - search.clear(); - } - Visibility.launcher = focused; - } implicitWidth: rect.width implicitHeight: rect.height - WrapperItem { + 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; + list.currentIndex = 0; + search.clear(); + } + + StyledWrapperRectangle { id: rect margin: 18 @@ -34,13 +45,13 @@ StyledPanelWindow { Layout.fillWidth: true Layout.alignment: Qt.AlignTop - - color: Styling.theme.base200 + margin: 4 RowLayout { LucideIcon { + id: icon Layout.leftMargin: 8 - text: Styling.lucide.icons.search + text: Icons.search } StyledTextField { @@ -49,19 +60,19 @@ StyledPanelWindow { Layout.fillWidth: true implicitHeight: 40 cursorVisible: true - focus: window.visible + focus: root.visible placeholderText: "Applications" placeholderTextColor: "grey" Keys.onEscapePressed: event => { event.accepted = true; - Visibility.launcher = false; + root.reset(); } Keys.onReturnPressed: event => { event.accepted = true; Apps.launch(list.currentItem.modelData); - Visibility.launcher = false; + root.reset(); } Keys.onUpPressed: event => { event.accepted = true; diff --git a/modules/launcher/items/AppItem.qml b/modules/launcher/items/AppItem.qml index 8ef6c46..7a10111 100644 --- a/modules/launcher/items/AppItem.qml +++ b/modules/launcher/items/AppItem.qml @@ -42,7 +42,8 @@ Item { Layout.alignment: Qt.AlignBottom Layout.fillWidth: true - color: root.active ? Styling.theme.primarycontent : Styling.theme.basecontent + color: root.active ? Theme.palette.primarycontent : Theme.palette.basecontent + font.pixelSize: 14 font.bold: true } @@ -51,8 +52,8 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true - color: root.active ? Styling.theme.primarycontent : Styling.theme.basecontent - font.pixelSize: Styling.typography.textSize.sm + color: root.active ? Theme.palette.primarycontent : Theme.palette.basecontent + font.pixelSize: 10 elide: Text.ElideRight } } diff --git a/modules/launcher/services/Apps.qml b/modules/launcher/services/Apps.qml index 269ee8a..e459c31 100644 --- a/modules/launcher/services/Apps.qml +++ b/modules/launcher/services/Apps.qml @@ -10,7 +10,7 @@ FuzzySearch { function launch(entry: DesktopEntry): void { if (entry.runInTerminal) Quickshell.execDetached({ - command: ["app2unit", "--", "alacritty", "exec", ...entry.command], + command: ["app2unit", "--", "kitty", "exec", ...entry.command], workingDirectory: entry.workingDirectory }); else diff --git a/modules/pomodoro/Pomodoro.qml b/modules/pomodoro/Pomodoro.qml index 627520d..9dba513 100644 --- a/modules/pomodoro/Pomodoro.qml +++ b/modules/pomodoro/Pomodoro.qml @@ -2,13 +2,15 @@ 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 -StyledPanelWindow { +StyledWindow { id: root name: "pomodoro" @@ -16,11 +18,10 @@ StyledPanelWindow { implicitWidth: rect.width implicitHeight: rect.height - onFocusedChanged: { - Visibility.pomodoro = focused; - } + WlrLayershell.layer: WlrLayer.Top + WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None - WrapperItem { + StyledWrapperRectangle { id: rect leftMargin: 48 @@ -28,6 +29,14 @@ StyledPanelWindow { topMargin: 24 bottomMargin: 24 + HyprlandFocusGrab { + active: Visibility.pomodoro + windows: [root] + onCleared: { + Visibility.pomodoro = false; + } + } + ColumnLayout { spacing: 22 @@ -45,10 +54,10 @@ StyledPanelWindow { Circle { id: circle radius: 150 - borderColor: Styling.theme.base100 - strokeColor: PomodoroService.state == "timer" ? Styling.theme.primary : Styling.theme.warning + borderColor: Theme.palette.base100 + strokeColor: PomodoroService.state == "timer" ? Theme.palette.primary : Theme.palette.warning strokeWidth: 12 - fillColor: button.hovered ? Styling.theme.primary : "transparent" + fillColor: button.hovered ? Theme.palette.primary : "transparent" percentage: (PomodoroService.state == "timer" ? (PomodoroService.initialTime - PomodoroService.remainingTime) : PomodoroService.remainingTime) / PomodoroService.initialTime % 1 } @@ -60,10 +69,10 @@ StyledPanelWindow { radius: 9999 focus: root.visible - text: PomodoroService.running ? Styling.lucide.icons.square : Styling.lucide.icons.play + text: PomodoroService.running ? Icons.square : Icons.play font.pixelSize: 48 - background: Item {} + background: undefined onClicked: { PomodoroService.toggle(); } diff --git a/modules/powermenu/PowerMenu.qml b/modules/powermenu/PowerMenu.qml index e784007..cea98f8 100644 --- a/modules/powermenu/PowerMenu.qml +++ b/modules/powermenu/PowerMenu.qml @@ -3,12 +3,14 @@ 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 -StyledPanelWindow { +StyledWindow { id: root name: "powermenu" @@ -16,18 +18,27 @@ StyledPanelWindow { implicitWidth: rect.width implicitHeight: rect.height - onFocusedChanged: { - Visibility.powermenu = focused; - } + WlrLayershell.layer: WlrLayer.Top + WlrLayershell.keyboardFocus: root.visible ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None Process { id: process } - WrapperItem { + StyledWrapperRectangle { id: rect + color: Theme.palette.base300 margin: 14 + radius: 8 + + HyprlandFocusGrab { + active: Visibility.powermenu + windows: [root] + onCleared: { + Visibility.powermenu = false; + } + } StyledListView { id: list @@ -58,7 +69,7 @@ StyledPanelWindow { model: Config.powermenu.actions - spacing: Styling.layout.spacing.base + spacing: 8 implicitWidth: 220 implicitHeight: 185 @@ -67,7 +78,7 @@ StyledPanelWindow { highlightResizeDuration: 0 highlight: Rectangle { radius: 8 - color: Styling.theme.primary + color: Theme.palette.primary } onCurrentItemChanged: { @@ -94,9 +105,9 @@ StyledPanelWindow { } padding: 16 - color: list.currentIndex == index ? Styling.theme.primarycontent : Styling.theme.basecontent + color: list.currentIndex == index ? Theme.palette.primarycontent : Theme.palette.basecontent text: modelData.text - font.pixelSize: Styling.typography.textSize.lg + font.pixelSize: 18 font.bold: true } } diff --git a/modules/storybook/Components.qml b/modules/storybook/Components.qml deleted file mode 100644 index 0ff3836..0000000 --- a/modules/storybook/Components.qml +++ /dev/null @@ -1,150 +0,0 @@ -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() - } - } -} diff --git a/modules/storybook/Fields.qml b/modules/storybook/Fields.qml deleted file mode 100644 index 1c76a2f..0000000 --- a/modules/storybook/Fields.qml +++ /dev/null @@ -1,53 +0,0 @@ -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 - } -} diff --git a/modules/storybook/Selectors.qml b/modules/storybook/Selectors.qml deleted file mode 100644 index 002de46..0000000 --- a/modules/storybook/Selectors.qml +++ /dev/null @@ -1,22 +0,0 @@ -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" - } - } - } -} diff --git a/modules/storybook/Storybook.qml b/modules/storybook/Storybook.qml index 8a1a9b9..0021fcb 100644 --- a/modules/storybook/Storybook.qml +++ b/modules/storybook/Storybook.qml @@ -2,72 +2,191 @@ pragma ComponentBehavior: Bound import qs.components import qs.config +import qs.constants import qs.services import QtQuick import QtQuick.Controls +import QtQuick.Layouts -StyledPanelWindow { +StyledPopupWindow { id: root - name: "storybook" visible: Visibility.storybook - implicitWidth: 500 - implicitHeight: 600 - background.color: Styling.theme.base200 + GridLayout { + id: grid - onFocusedChanged: { - Visibility.storybook = focused; - } + flow: GridLayout.TopToBottom + columns: 2 + rows: 10 - StyledTabBar { - id: tabs - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: view.top - implicitHeight: 40 - - StyledTabButton { - text: "Fields" - onClicked: tabs.setCurrentIndex(0) - } - StyledTabButton { - text: "Selectors" - onClicked: tabs.setCurrentIndex(1) - } - StyledTabButton { + StyledText { + Layout.columnSpan: grid.columns + Layout.alignment: Qt.AlignHCenter text: "Components" - onClicked: tabs.setCurrentIndex(2) + font.pixelSize: 24 + font.bold: true + font.underline: true + bottomPadding: 24 + } + + ColumnLayout { + StyledText { + text: "Icon Button" + font.pixelSize: 18 + } + StyledIconButton { + text: Icons.square + } + } + + ColumnLayout { + StyledText { + text: "Switch" + font.pixelSize: 18 + } + + StyledSwitch { + text: "Enable" + } + } + + 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: "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(); + } + } + } } } - 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 - } - - ScrollView { - padding: 36 - Fields {} - } - ScrollView { - padding: 36 - Selectors {} - } - ScrollView { - padding: 36 - Components {} + StyledDrawer { + id: drawer + edge: Qt.TopEdge + width: 400 + height: 200 + Button { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + text: "Close" + onClicked: drawer.close() } } } diff --git a/modules/wallpaper/Wallpaper.qml b/modules/wallpaper/Wallpaper.qml deleted file mode 100644 index f03cbdb..0000000 --- a/modules/wallpaper/Wallpaper.qml +++ /dev/null @@ -1,35 +0,0 @@ -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 - }) -} diff --git a/services/Caffeine.qml b/services/Caffeine.qml index f4acebb..04680b0 100644 --- a/services/Caffeine.qml +++ b/services/Caffeine.qml @@ -1,7 +1,7 @@ pragma Singleton import Quickshell -import Quickshell.Wayland +import Quickshell.Io Singleton { @@ -16,14 +16,16 @@ Singleton { function toggle() { if (properties.enabled) { + process.signal(888); properties.enabled = false; } else { properties.enabled = true; } } - IdleInhibitor { - id: inhibitor - enabled: properties.enabled + Process { + id: process + running: properties.enabled + command: ["sh", "-c", "systemd-inhibit --what=idle --who=Caffeine --why='Caffeine module is active' --mode=block sleep inf"] } } diff --git a/services/Pipewire.qml b/services/Pipewire.qml index 5e28710..53cc141 100644 --- a/services/Pipewire.qml +++ b/services/Pipewire.qml @@ -10,16 +10,13 @@ Singleton { readonly property PwNode sink: Pipewire.defaultAudioSink readonly property PwNode source: Pipewire.defaultAudioSource - readonly property list sinks: Pipewire.nodes.values.filter(node => node.audio != null && node.isSink && !node.isStream) - readonly property list 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 = Math.min(volume, 1.0); + sink.audio.volume = volume; } } @@ -45,18 +42,6 @@ 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] } diff --git a/services/Visibility.qml b/services/Visibility.qml index a2576e0..d8deed4 100644 --- a/services/Visibility.qml +++ b/services/Visibility.qml @@ -1,19 +1,27 @@ 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 diff --git a/services/WallpaperService.qml b/services/WallpaperService.qml deleted file mode 100644 index 94adbbd..0000000 --- a/services/WallpaperService.qml +++ /dev/null @@ -1,27 +0,0 @@ -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: "" - } - } -} diff --git a/utils/DirectoryWatcher.qml b/utils/DirectoryWatcher.qml deleted file mode 100644 index 776e4cf..0000000 --- a/utils/DirectoryWatcher.qml +++ /dev/null @@ -1,43 +0,0 @@ -import QtQuick -import Quickshell.Io - -Item { - id: root - - required property string path - property bool recursive: true - property list 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); - } - } - } - } -} diff --git a/widgets/Circle.qml b/widgets/Circle.qml index 226bcf0..33207a5 100644 --- a/widgets/Circle.qml +++ b/widgets/Circle.qml @@ -22,8 +22,8 @@ Item { ShapePath { id: fill - fillColor: Styling.theme.base100 - strokeColor: Styling.theme.base200 + fillColor: Theme.palette.base100 + strokeColor: Theme.palette.base200 strokeWidth: 8 PathAngleArc { diff --git a/widgets/StyledPopupWindow.qml b/widgets/StyledPopupWindow.qml new file mode 100644 index 0000000..4927cfb --- /dev/null +++ b/widgets/StyledPopupWindow.qml @@ -0,0 +1,102 @@ +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 + } + } + } +}