diff --git a/Config/Config.qml b/Config/Config.qml index cc2c144..4add513 100644 --- a/Config/Config.qml +++ b/Config/Config.qml @@ -7,6 +7,7 @@ Singleton { property alias appCount: adapter.appCount property alias baseBgColor: adapter.baseBgColor + property alias baseBorderColor: adapter.baseBorderColor property alias accentColor: adapter.accentColor property alias wallpaperPath: adapter.wallpaperPath property alias maxWallpapers: adapter.maxWallpapers @@ -29,6 +30,7 @@ Singleton { property int appCount: 20 property string wallpaperPath: Quickshell.env("HOME") + "/Pictures/Wallpapers" property string baseBgColor: "#801a1a1a" + property string baseBorderColor: "#444444" property AccentColor accentColor: AccentColor {} property int maxWallpapers: 7 property bool wallust: false diff --git a/Modules/Launcher.qml b/Modules/Launcher.qml index 53e021a..1ef14b9 100644 --- a/Modules/Launcher.qml +++ b/Modules/Launcher.qml @@ -71,7 +71,7 @@ Scope { x: Math.round(( parent.width - width ) / 2 ) color: "#d01a1a1a" opacity: 1 - border.color: "#444444" + border.color: Config.baseBorderColor border.width: 1 ParallelAnimation { diff --git a/Modules/Resource.qml b/Modules/Resource.qml index 6c5f971..a9cba01 100644 --- a/Modules/Resource.qml +++ b/Modules/Resource.qml @@ -35,7 +35,6 @@ Item { implicitWidth: 14 implicitHeight: root.implicitHeight - // Background circle Rectangle { id: backgroundCircle anchors.centerIn: parent @@ -47,7 +46,6 @@ Item { border.width: 1 } - // Pie progress indicator Canvas { id: progressCanvas anchors.fill: backgroundCircle @@ -80,28 +78,6 @@ Item { ctx.fill(); } } - - // // Percentage text - // Item { - // anchors.centerIn: backgroundCircle - // implicitWidth: fullPercentageTextMetrics.width - // implicitHeight: percentageText.implicitHeight - // - // TextMetrics { - // id: fullPercentageTextMetrics - // text: "100" - // font.pixelSize: 12 - // } - // - // Text { - // id: percentageText - // anchors.centerIn: parent - // color: "#ffffff" - // font.pixelSize: 12 - // font.bold: true - // text: `${Math.round(percentage * 100).toString()}` - // } - // } } } } diff --git a/Modules/ResourceDetail.qml b/Modules/ResourceDetail.qml new file mode 100644 index 0000000..4df9d7a --- /dev/null +++ b/Modules/ResourceDetail.qml @@ -0,0 +1,72 @@ +import Quickshell +import QtQuick +import QtQuick.Layouts +import qs.Config + +Item { + id: root + required property string resourceName + required property double percentage + required property int warningThreshold + required property string details + required property string iconString + + height: columnLayout.childrenRect.height + anchors.left: parent.left + anchors.right: parent.right + + ColumnLayout { + id: columnLayout + anchors.fill: parent + spacing: 4 + + Row { + spacing: 6 + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + + Text { + font.family: "Material Symbols Rounded" + font.pixelSize: 32 + text: root.iconString + color: "#ffffff" + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: root.resourceName + font.pixelSize: 14 + color: "#ffffff" + } + } + + Rectangle { + Layout.alignment: Qt.AlignLeft + Layout.fillWidth: true + Layout.preferredHeight: 6 + radius: height / 2 + color: "#40000000" + + Rectangle { + width: parent.width * Math.min(root.percentage, 1) + height: parent.height + radius: height / 2 + color: root.percentage * 100 >= root.warningThreshold ? Config.accentColor.accents.warning : Config.accentColor.accents.primary + + Behavior on width { + Anim { + duration: MaterialEasing.expressiveEffectsTime + easing.bezierCurve: MaterialEasing.expressiveEffects + } + } + } + } + + Text { + Layout.alignment: Qt.AlignLeft + text: root.details + font.pixelSize: 12 + color: "#cccccc" + } + } +} diff --git a/Modules/Resources.qml b/Modules/Resources.qml index c84cdb4..f63834c 100644 --- a/Modules/Resources.qml +++ b/Modules/Resources.qml @@ -1,7 +1,10 @@ import QtQuick import Quickshell import QtQuick.Layouts +import Quickshell.Wayland import qs.Modules +import qs.Config +import qs.Effects Item { id: root @@ -76,34 +79,146 @@ Item { } } } + MouseArea { - id: mouseArea anchors.fill: parent hoverEnabled: true + onEntered: { + if (popoutLoader.sourceComponent === null) { + popoutLoader.sourceComponent = resourcePopout; + } + } } Loader { + id: popoutLoader + z: 0 anchors.left: parent.left - sourceComponent: mouseArea.containsMouse ? resourcePopout : null + sourceComponent: null + } + + component ResourcePopout: PanelWindow { + id: popoutWindow + property alias containsMouse: popoutWindow.mouseAreaContainsMouse + property int rectHeight: contentRect.implicitHeight + property bool mouseAreaContainsMouse: mouseArea.containsMouse + WlrLayershell.exclusionMode: ExclusionMode.Ignore + + anchors { + left: true + top: true + right: true + bottom: true + } + + color: "transparent" + + mask: Region { item: contentRect } + + ShadowRect { + anchors.fill: contentRect + radius: 8 + } + + ParallelAnimation { + id: openAnim + Anim { + target: contentRect + property: "y" + to: 0 - 1 + duration: MaterialEasing.expressiveEffectsTime + easing.bezierCurve: MaterialEasing.expressiveEffects + } + } + + ParallelAnimation { + id: closeAnim + Anim { + target: contentRect + property: "y" + to: - contentRect.implicitHeight + duration: MaterialEasing.expressiveEffectsTime + easing.bezierCurve: MaterialEasing.expressiveEffects + } + onStopped: { + popoutLoader.sourceComponent = null + } + } + + Rectangle { + id: contentRect + x: mapFromItem(root, 0, 0).x + y: - implicitHeight + implicitHeight: contentColumn.childrenRect.height + 20 + implicitWidth: root.implicitWidth + color: Config.baseBgColor + border.color: Config.baseBorderColor + border.width: 1 + bottomLeftRadius: 8 + bottomRightRadius: 8 + + + Component.onCompleted: { + openAnim.start(); + } + + Column { + id: contentColumn + anchors.fill: parent + anchors.margins: 10 + spacing: 10 + + ResourceDetail { + resourceName: qsTr("Memory Usage") + iconString: "\uf7a3" + percentage: ResourceUsage.memoryUsedPercentage + warningThreshold: 95 + details: qsTr("%1 of %2 MB used") + .arg(Math.round(ResourceUsage.memoryUsed * 0.001)) + .arg(Math.round(ResourceUsage.memoryTotal * 0.001)) + } + + ResourceDetail { + resourceName: qsTr("CPU Usage") + iconString: "\ue322" + percentage: ResourceUsage.cpuUsage + warningThreshold: 95 + details: qsTr("%1% used") + .arg(Math.round(ResourceUsage.cpuUsage * 100)) + } + + ResourceDetail { + resourceName: qsTr("GPU Usage") + iconString: "\ue30f" + percentage: ResourceUsage.gpuUsage + warningThreshold: 95 + details: qsTr("%1% used") + .arg(Math.round(ResourceUsage.gpuUsage * 100)) + } + + ResourceDetail { + resourceName: qsTr("VRAM Usage") + iconString: "\ue30d" + percentage: ResourceUsage.gpuMemUsage + warningThreshold: 95 + details: qsTr("%1% used") + .arg(Math.round(ResourceUsage.gpuMemUsage * 100)) + } + } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onExited: { + closeAnim.start(); + } + } + } } Component { id: resourcePopout - PanelWindow { - anchors { - left: true - top: true - right: true - bottom: true - } - color: "transparent" - Rectangle { - x: mapFromItem(root, 0, 0).x - implicitHeight: 300 - implicitWidth: root.implicitWidth - color: "#80000000" - radius: 12 - } - } + + ResourcePopout { } } }