SidePanel cards in a Cards directory
This commit is contained in:
parent
986eac179e
commit
a11e310580
5 changed files with 1 additions and 0 deletions
47
Modules/SidePanel/Cards/MediaCard.qml
Normal file
47
Modules/SidePanel/Cards/MediaCard.qml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Media player area (placeholder until MediaPlayer service is wired)
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
readonly property real scaling: Scaling.scale(screen)
|
||||
|
||||
Layout.fillWidth: true
|
||||
// Let content dictate the height (no hardcoded height here)
|
||||
// Height can be overridden by parent layout (SidePanel binds it to stats card)
|
||||
implicitHeight: content.implicitHeight + Style.marginLarge * 2 * scaling
|
||||
|
||||
Column {
|
||||
id: content
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Style.marginMedium * scaling
|
||||
spacing: Style.marginMedium * scaling
|
||||
|
||||
Item {
|
||||
height: Style.marginLarge * scaling
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "music_note"
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pointSize: 28 * scaling
|
||||
color: Colors.textSecondary
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
NText {
|
||||
text: "No music player detected"
|
||||
color: Colors.textSecondary
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
height: Style.marginLarge * scaling
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Modules/SidePanel/Cards/ProfileCard.qml
Normal file
118
Modules/SidePanel/Cards/ProfileCard.qml
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Header card with avatar, user and quick actions
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
readonly property real scaling: Scaling.scale(screen)
|
||||
// Hold a single instance of the Settings window (root is NLoader)
|
||||
property var settingsWindow: null
|
||||
|
||||
property string uptimeText: "--"
|
||||
|
||||
Layout.fillWidth: true
|
||||
// Height driven by content
|
||||
implicitHeight: content.implicitHeight + Style.marginMedium * 2 * scaling
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Style.marginMedium * scaling
|
||||
spacing: Style.marginMedium * scaling
|
||||
|
||||
NImageRounded {
|
||||
width: Style.baseWidgetSize * 1.25 * scaling
|
||||
height: Style.baseWidgetSize * 1.25 * scaling
|
||||
imagePath: Settings.data.general.avatarImage
|
||||
fallbackIcon: "person"
|
||||
borderColor: Colors.accentPrimary
|
||||
borderWidth: Math.max(1, Style.borderMedium * scaling)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2 * scaling
|
||||
NText {
|
||||
text: Quickshell.env("USER") || "user"
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
NText {
|
||||
text: `System Uptime: ${uptimeText}`
|
||||
color: Colors.textSecondary
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginSmall * scaling
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
NIconButton {
|
||||
icon: "settings"
|
||||
onClicked: function () {
|
||||
if (!root.settingsWindow) {
|
||||
const comp = Qt.createComponent("../Settings/SettingsWindow.qml")
|
||||
if (comp.status === Component.Ready) {
|
||||
root.settingsWindow = comp.createObject(root)
|
||||
} else {
|
||||
comp.statusChanged.connect(function () {
|
||||
if (comp.status === Component.Ready) {
|
||||
root.settingsWindow = comp.createObject(root)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (root.settingsWindow) {
|
||||
root.settingsWindow.isLoaded = !root.settingsWindow.isLoaded
|
||||
}
|
||||
}
|
||||
}
|
||||
NIconButton {
|
||||
icon: "power_settings_new"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 60000
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: uptimeProcess.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: uptimeProcess
|
||||
command: ["cat", "/proc/uptime"]
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var uptimeSeconds = parseFloat(this.text.trim().split(' ')[0])
|
||||
var minutes = Math.floor(uptimeSeconds / 60) % 60
|
||||
var hours = Math.floor(uptimeSeconds / 3600) % 24
|
||||
var days = Math.floor(uptimeSeconds / 86400)
|
||||
|
||||
// Format the output
|
||||
if (days > 0) {
|
||||
uptimeText = days + "d " + hours + "h"
|
||||
} else if (hours > 0) {
|
||||
uptimeText = hours + "h" + minutes + "m"
|
||||
} else {
|
||||
uptimeText = minutes + "m"
|
||||
}
|
||||
|
||||
uptimeProcess.running = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Modules/SidePanel/Cards/SystemCard.qml
Normal file
75
Modules/SidePanel/Cards/SystemCard.qml
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Unified system card: monitors CPU, temp, memory, disk
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
readonly property real scaling: Scaling.scale(screen)
|
||||
|
||||
Layout.preferredWidth: 84 * scaling
|
||||
implicitHeight: content.implicitHeight + Style.marginTiny * 2 * scaling
|
||||
|
||||
Column {
|
||||
id: content
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.leftMargin: Style.marginSmall * scaling
|
||||
anchors.rightMargin: Style.marginSmall * scaling
|
||||
anchors.topMargin: Style.marginTiny * scaling
|
||||
anchors.bottomMargin: Style.marginMedium * scaling
|
||||
spacing: Style.marginSmall * scaling
|
||||
|
||||
// Slight top padding
|
||||
Item {
|
||||
height: Style.marginTiny * scaling
|
||||
}
|
||||
|
||||
NSystemMonitor {
|
||||
id: sysMon
|
||||
intervalSeconds: 1
|
||||
}
|
||||
|
||||
NCircleStat {
|
||||
value: sysMon.cpuUsage || SysInfo.cpuUsage
|
||||
icon: "speed"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
width: 72 * scaling
|
||||
height: 68 * scaling
|
||||
}
|
||||
NCircleStat {
|
||||
value: sysMon.cpuTemp || SysInfo.cpuTemp
|
||||
suffix: "°C"
|
||||
icon: "device_thermostat"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
width: 72 * scaling
|
||||
height: 68 * scaling
|
||||
}
|
||||
NCircleStat {
|
||||
value: sysMon.memoryUsagePer || SysInfo.memoryUsagePer
|
||||
icon: "memory"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
width: 72 * scaling
|
||||
height: 68 * scaling
|
||||
}
|
||||
NCircleStat {
|
||||
value: sysMon.diskUsage || SysInfo.diskUsage
|
||||
icon: "data_usage"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
width: 72 * scaling
|
||||
height: 68 * scaling
|
||||
}
|
||||
|
||||
// Extra bottom padding to shift the perceived stack slightly upward
|
||||
Item {
|
||||
height: Style.marginMedium * scaling
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Modules/SidePanel/Cards/WeatherCard.qml
Normal file
121
Modules/SidePanel/Cards/WeatherCard.qml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Weather overview card (placeholder data)
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
readonly property real scaling: Scaling.scale(screen)
|
||||
readonly property bool weatherReady: (Location.data.weather !== null)
|
||||
|
||||
Layout.fillWidth: true
|
||||
// Height driven by content
|
||||
implicitHeight: content.implicitHeight + Style.marginLarge * 2 * scaling
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Style.marginMedium * scaling
|
||||
spacing: Style.marginMedium * scaling
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginSmall * scaling
|
||||
NText {
|
||||
text: weatherReady ? Location.weatherSymbolFromCode(Location.data.weather.current_weather.weathercode) : ""
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pointSize: Style.fontSizeXXL * 1.25 * scaling
|
||||
color: Colors.accentSecondary
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
NText {
|
||||
text: Settings.data.location.name
|
||||
font.weight: Style.fontWeightBold
|
||||
font.pointSize: Style.fontSizeXL * scaling
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
NText {
|
||||
visible: weatherReady
|
||||
text: {
|
||||
if (!weatherReady) {
|
||||
return ""
|
||||
}
|
||||
var temp = Location.data.weather.current_weather.temperature
|
||||
if (Settings.data.location.useFahrenheit) {
|
||||
temp = Location.celsiusToFahrenheit(temp)
|
||||
}
|
||||
temp = Math.round(temp)
|
||||
return `${temp}°`
|
||||
}
|
||||
font.pointSize: Style.fontSizeXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
NText {
|
||||
text: weatherReady ? `(${Location.data.weather.timezone_abbreviation})` : ""
|
||||
font.pointSize: Style.fontSizeSmall * scaling
|
||||
visible: Location.data.weather
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
visible: weatherReady
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: weatherReady
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginLarge * scaling
|
||||
Repeater {
|
||||
model: weatherReady ? Location.data.weather.daily.time : []
|
||||
delegate: ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginSmall * scaling
|
||||
NText {
|
||||
text: Qt.formatDateTime(new Date(Location.data.weather.daily.time[index]), "ddd")
|
||||
color: Colors.textPrimary
|
||||
}
|
||||
NText {
|
||||
text: Location.weatherSymbolFromCode(Location.data.weather.daily.weathercode[index])
|
||||
font.family: "Material Symbols Outlined"
|
||||
font.pointSize: Style.fontSizeXL * scaling
|
||||
color: Colors.textSecondary
|
||||
}
|
||||
NText {
|
||||
text: {
|
||||
var max = Location.data.weather.daily.temperature_2m_max[index]
|
||||
var min = Location.data.weather.daily.temperature_2m_min[index]
|
||||
if (Settings.data.location.useFahrenheit) {
|
||||
max = Location.celsiusToFahrenheit(max)
|
||||
min = Location.celsiusToFahrenheit(min)
|
||||
}
|
||||
max = Math.round(max)
|
||||
min = Math.round(min)
|
||||
return `${max}°/${min}°`
|
||||
}
|
||||
font.pointSize: Style.fontSizeSmall * scaling
|
||||
color: Colors.textSecondary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: !weatherReady
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
NBusyIndicator {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue