1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-29 07:52:50 -05:00

Redesign center command center

This commit is contained in:
bbedward
2025-07-12 11:49:41 -04:00
parent 2a29f2a0f2
commit ba5217f2f1
9 changed files with 485 additions and 250 deletions

View File

@@ -71,10 +71,8 @@ Singleton {
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
console.log("SystemMonitorService: CPU usage raw data:", text.trim())
if (text.trim()) { if (text.trim()) {
root.cpuUsage = parseFloat(text.trim()) root.cpuUsage = parseFloat(text.trim())
console.log("SystemMonitorService: CPU usage set to:", root.cpuUsage)
} }
} }
} }
@@ -94,7 +92,6 @@ Singleton {
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
console.log("SystemMonitorService: Memory usage raw data:", text.trim())
if (text.trim()) { if (text.trim()) {
const parts = text.trim().split(" ") const parts = text.trim().split(" ")
root.memoryUsage = parseFloat(parts[0]) root.memoryUsage = parseFloat(parts[0])
@@ -102,7 +99,6 @@ Singleton {
root.usedMemory = parseFloat(parts[2]) root.usedMemory = parseFloat(parts[2])
root.availableMemory = parseFloat(parts[3]) root.availableMemory = parseFloat(parts[3])
root.freeMemory = root.totalMemory - root.usedMemory root.freeMemory = root.totalMemory - root.usedMemory
console.log("SystemMonitorService: Memory usage set to:", root.memoryUsage)
} }
} }
} }

View File

@@ -16,12 +16,11 @@ PanelWindow {
property var weather: root.weather property var weather: root.weather
property bool useFahrenheit: false property bool useFahrenheit: false
// Prevent media player from disappearing during track changes
property bool showMediaPlayer: hasActiveMedia || hideMediaTimer.running property bool showMediaPlayer: hasActiveMedia || hideMediaTimer.running
Timer { Timer {
id: hideMediaTimer id: hideMediaTimer
interval: 3000 // 3 second grace period interval: 3000
running: false running: false
repeat: false repeat: false
} }
@@ -36,8 +35,8 @@ PanelWindow {
visible: root.calendarVisible visible: root.calendarVisible
implicitWidth: 320 implicitWidth: 480
implicitHeight: 400 implicitHeight: 600
WlrLayershell.layer: WlrLayershell.Overlay WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1 WlrLayershell.exclusiveZone: -1
@@ -53,55 +52,135 @@ PanelWindow {
} }
Rectangle { Rectangle {
width: 400 id: mainContainer
height: showMediaPlayer ? 540 : (weather?.available ? 480 : 400) width: calculateWidth()
height: calculateHeight()
x: (parent.width - width) / 2 x: (parent.width - width) / 2
y: theme.barHeight + theme.spacingS y: Theme.barHeight + 4
function calculateWidth() {
let baseWidth = 320
if (leftWidgets.hasAnyWidgets) {
return Math.min(parent.width * 0.9, 600)
}
return Math.min(parent.width * 0.7, 400)
}
function calculateHeight() {
let contentHeight = theme.spacingM * 2 // margins
// Calculate widget heights - media widget is always present
let widgetHeight = 160 // Media widget always present
if (weather?.available) {
widgetHeight += (weather ? 140 : 80) + theme.spacingM
}
// Calendar height is always 300
let calendarHeight = 300
// Take the max of widgets and calendar
contentHeight += Math.max(widgetHeight, calendarHeight)
return Math.min(contentHeight, parent.height * 0.85)
}
color: theme.surfaceContainer color: theme.surfaceContainer
radius: theme.cornerRadiusLarge radius: theme.cornerRadiusLarge
border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.12) border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.12)
border.width: 1 border.width: 1
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
shadowBlur: 0.5
shadowColor: Qt.rgba(0, 0, 0, 0.15)
shadowOpacity: 0.15
}
Rectangle {
anchors.fill: parent
color: Qt.rgba(theme.surfaceTint.r, theme.surfaceTint.g, theme.surfaceTint.b, 0.04)
radius: parent.radius
SequentialAnimation on opacity {
running: true
loops: Animation.Infinite
NumberAnimation {
to: 0.08
duration: theme.extraLongDuration
easing.type: theme.standardEasing
}
NumberAnimation {
to: 0.02
duration: theme.extraLongDuration
easing.type: theme.standardEasing
}
}
}
opacity: root.calendarVisible ? 1.0 : 0.0 opacity: root.calendarVisible ? 1.0 : 0.0
scale: root.calendarVisible ? 1.0 : 0.85 scale: root.calendarVisible ? 1.0 : 0.92
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {
duration: theme.mediumDuration duration: theme.longDuration
easing.type: theme.emphasizedEasing easing.type: theme.emphasizedEasing
} }
} }
Behavior on scale { Behavior on scale {
NumberAnimation { NumberAnimation {
duration: theme.mediumDuration duration: theme.longDuration
easing.type: theme.emphasizedEasing easing.type: theme.emphasizedEasing
} }
} }
Column { Behavior on height {
NumberAnimation {
duration: theme.mediumDuration
easing.type: theme.standardEasing
}
}
Row {
anchors.fill: parent anchors.fill: parent
anchors.margins: theme.spacingL anchors.margins: theme.spacingM
spacing: theme.spacingM spacing: theme.spacingM
// Media Player (when active) // Left section for widgets
MediaPlayerWidget { Column {
visible: showMediaPlayer id: leftWidgets
theme: centerCommandCenter.theme width: hasAnyWidgets ? parent.width * 0.45 : 0
height: childrenRect.height
spacing: theme.spacingM
visible: hasAnyWidgets
anchors.top: parent.top
property bool hasAnyWidgets: true || weather?.available // Always show media widget
MediaPlayerWidget {
visible: true // Always visible - shows placeholder when no media
width: parent.width
height: 160
theme: centerCommandCenter.theme
}
WeatherWidget {
visible: weather?.available
width: parent.width
height: weather ? 140 : 80
theme: centerCommandCenter.theme
weather: centerCommandCenter.weather
useFahrenheit: centerCommandCenter.useFahrenheit
}
} }
// Weather header (when available and no media) // Right section for calendar
WeatherWidget {
visible: weather?.available && !showMediaPlayer
theme: centerCommandCenter.theme
weather: centerCommandCenter.weather
useFahrenheit: centerCommandCenter.useFahrenheit
}
// Calendar
CalendarWidget { CalendarWidget {
width: parent.width width: leftWidgets.hasAnyWidgets ? parent.width * 0.55 - theme.spacingL : parent.width
height: showMediaPlayer ? parent.height - 200 : (weather?.available ? parent.height - 120 : parent.height - 40) height: parent.height
theme: centerCommandCenter.theme theme: centerCommandCenter.theme
} }
} }

View File

@@ -13,12 +13,22 @@ Rectangle {
property var theme: Theme property var theme: Theme
width: parent.width width: parent.width
height: 160 // Reduced height to prevent overflow height: parent.height
radius: theme.cornerRadius radius: theme.cornerRadiusLarge
color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.08) color: Qt.rgba(theme.surfaceContainer.r, theme.surfaceContainer.g, theme.surfaceContainer.b, 0.4)
border.color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.2) border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.08)
border.width: 1 border.width: 1
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 2
shadowBlur: 0.5
shadowColor: Qt.rgba(0, 0, 0, 0.1)
shadowOpacity: 0.1
}
property real currentPosition: 0 property real currentPosition: 0
// Simple progress ratio calculation // Simple progress ratio calculation
@@ -68,81 +78,109 @@ Rectangle {
} }
Column { Column {
anchors.fill: parent anchors.centerIn: parent
anchors.margins: theme.spacingM width: parent.width - theme.spacingM * 2
spacing: theme.spacingM spacing: theme.spacingM
// Album art and track info // Show different content based on whether we have active media
Row { Item {
width: parent.width width: parent.width
height: 70 // Reduced height height: 80
spacing: theme.spacingM
// Album Art // Placeholder when no media
Rectangle { Column {
width: 70 anchors.centerIn: parent
height: 70 spacing: theme.spacingS
radius: theme.cornerRadius visible: !activePlayer || !activePlayer.trackTitle || activePlayer.trackTitle === ""
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
Item { Text {
anchors.fill: parent text: "music_note"
clip: true font.family: theme.iconFont
font.pixelSize: theme.iconSize + 8
Image { color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.5)
id: albumArt anchors.horizontalCenter: parent.horizontalCenter
anchors.fill: parent }
source: activePlayer?.trackArtUrl || ""
fillMode: Image.PreserveAspectCrop Text {
smooth: true text: "No Media Playing"
} font.pixelSize: theme.fontSizeMedium
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
Rectangle { anchors.horizontalCenter: parent.horizontalCenter
anchors.fill: parent
visible: albumArt.status !== Image.Ready
color: "transparent"
Text {
anchors.centerIn: parent
text: "album"
font.family: theme.iconFont
font.pixelSize: 28
color: theme.surfaceVariantText
}
}
} }
} }
// Track Info // Normal media info when playing
Column { Row {
width: parent.width - 70 - theme.spacingM anchors.fill: parent
spacing: theme.spacingXS spacing: theme.spacingM
anchors.verticalCenter: parent.verticalCenter visible: activePlayer && activePlayer.trackTitle && activePlayer.trackTitle !== ""
Text { // Album Art
text: activePlayer?.trackTitle || "Unknown Track" Rectangle {
font.pixelSize: theme.fontSizeMedium width: 80
font.weight: Font.Bold height: 80
color: theme.surfaceText radius: theme.cornerRadius
width: parent.width color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
elide: Text.ElideRight
Item {
anchors.fill: parent
clip: true
Image {
id: albumArt
anchors.fill: parent
source: activePlayer?.trackArtUrl || ""
fillMode: Image.PreserveAspectCrop
smooth: true
}
Rectangle {
anchors.fill: parent
visible: albumArt.status !== Image.Ready
color: "transparent"
Text {
anchors.centerIn: parent
text: "album"
font.family: theme.iconFont
font.pixelSize: 28
color: theme.surfaceVariantText
}
}
}
} }
Text { // Track Info
text: activePlayer?.trackArtist || "Unknown Artist" Column {
font.pixelSize: theme.fontSizeSmall width: parent.width - 80 - theme.spacingM
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.8) spacing: theme.spacingXS
width: parent.width anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
} Text {
text: activePlayer?.trackTitle || "Unknown Track"
Text { font.pixelSize: theme.fontSizeMedium
text: activePlayer?.trackAlbum || "" font.weight: Font.Bold
font.pixelSize: theme.fontSizeSmall color: theme.surfaceText
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.6) width: parent.width
width: parent.width elide: Text.ElideRight
elide: Text.ElideRight }
visible: text.length > 0
Text {
text: activePlayer?.trackArtist || "Unknown Artist"
font.pixelSize: theme.fontSizeSmall
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.8)
width: parent.width
elide: Text.ElideRight
}
Text {
text: activePlayer?.trackAlbum || ""
font.pixelSize: theme.fontSizeSmall
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.6)
width: parent.width
elide: Text.ElideRight
visible: text.length > 0
}
} }
} }
} }
@@ -154,6 +192,7 @@ Rectangle {
height: 6 height: 6
radius: 3 radius: 3
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3) color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
visible: activePlayer !== null
Rectangle { Rectangle {
id: progressFill id: progressFill
@@ -232,10 +271,11 @@ Rectangle {
} }
} }
// Control buttons - compact to fit // Control buttons - always visible
Row { Row {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
spacing: theme.spacingL spacing: theme.spacingL
visible: activePlayer !== null
// Previous button // Previous button
Rectangle { Rectangle {

View File

@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects
import "../../Common" import "../../Common"
import "../../Services" import "../../Services"
@@ -11,57 +12,104 @@ Rectangle {
property bool useFahrenheit: false property bool useFahrenheit: false
width: parent.width width: parent.width
height: 80 height: parent.height
radius: theme.cornerRadius radius: theme.cornerRadiusLarge
color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.08) color: Qt.rgba(theme.surfaceContainer.r, theme.surfaceContainer.g, theme.surfaceContainer.b, 0.4)
border.color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.2) border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.08)
border.width: 1 border.width: 1
Row { layer.enabled: true
anchors.centerIn: parent layer.effect: MultiEffect {
spacing: theme.spacingL shadowEnabled: true
shadowHorizontalOffset: 0
shadowVerticalOffset: 2
shadowBlur: 0.5
shadowColor: Qt.rgba(0, 0, 0, 0.1)
shadowOpacity: 0.1
}
Column {
anchors.fill: parent
anchors.margins: theme.spacingL
spacing: theme.spacingM
// Weather icon and temp // Show different content based on whether we have weather data
Column { Item {
spacing: 2 width: parent.width
anchors.verticalCenter: parent.verticalCenter height: 60
Text { // Placeholder when no weather
text: WeatherService.getWeatherIcon(weather.wCode) Column {
font.family: theme.iconFont anchors.centerIn: parent
font.pixelSize: theme.iconSize + 4 spacing: theme.spacingS
color: theme.primary visible: !weather
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
text: (useFahrenheit ? weather.tempF : weather.temp) + "°" + (useFahrenheit ? "F" : "C")
font.pixelSize: theme.fontSizeLarge
color: theme.surfaceText
font.weight: Font.Bold
anchors.horizontalCenter: parent.horizontalCenter
MouseArea { Text {
anchors.fill: parent text: "cloud_off"
hoverEnabled: true font.family: theme.iconFont
cursorShape: Qt.PointingHandCursor font.pixelSize: theme.iconSize + 8
onClicked: useFahrenheit = !useFahrenheit color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.5)
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
text: "No Weather Data"
font.pixelSize: theme.fontSizeMedium
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
} }
} }
Text { // Normal weather info when available
text: weather.city Row {
font.pixelSize: theme.fontSizeSmall anchors.fill: parent
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7) spacing: theme.spacingL
anchors.horizontalCenter: parent.horizontalCenter visible: weather
// Weather icon
Text {
text: weather ? WeatherService.getWeatherIcon(weather.wCode) : ""
font.family: theme.iconFont
font.pixelSize: theme.iconSize + 8
color: theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
spacing: theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
Text {
text: weather ? ((useFahrenheit ? weather.tempF : weather.temp) + "°" + (useFahrenheit ? "F" : "C")) : ""
font.pixelSize: theme.fontSizeXLarge
color: theme.surfaceText
font.weight: Font.Light
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: if (weather) useFahrenheit = !useFahrenheit
enabled: weather !== null
}
}
Text {
text: weather ? weather.city : ""
font.pixelSize: theme.fontSizeMedium
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
visible: text.length > 0
}
}
} }
} }
// Weather details grid // Weather details grid
Grid { Grid {
columns: 2 columns: 2
spacing: theme.spacingS spacing: theme.spacingM
anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: weather !== null
Row { Row {
spacing: theme.spacingXS spacing: theme.spacingXS
@@ -73,7 +121,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { Text {
text: weather.humidity + "%" text: weather ? weather.humidity + "%" : "--"
font.pixelSize: theme.fontSizeSmall font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -90,7 +138,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { Text {
text: weather.wind text: weather ? weather.wind : "--"
font.pixelSize: theme.fontSizeSmall font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -107,7 +155,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { Text {
text: weather.sunrise text: weather ? weather.sunrise : "--"
font.pixelSize: theme.fontSizeSmall font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -124,7 +172,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { Text {
text: weather.sunset text: weather ? weather.sunset : "--"
font.pixelSize: theme.fontSizeSmall font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View File

@@ -1,33 +1,14 @@
import QtQuick import QtQuick
import Quickshell.Services.Mpris
import "../../Common" import "../../Common"
import "../../Services"
Rectangle { Rectangle {
id: root id: root
property bool hasActiveMedia: false
property var activePlayer: null
property bool weatherAvailable: false
property string weatherCode: ""
property int weatherTemp: 0
property int weatherTempF: 0
property bool useFahrenheit: false
property date currentDate: new Date() property date currentDate: new Date()
signal clockClicked() signal clockClicked()
width: { width: clockRow.implicitWidth + Theme.spacingM
let baseWidth = 200
if (root.hasActiveMedia) {
let mediaWidth = 24 + Theme.spacingXS + mediaTitleText.implicitWidth + Theme.spacingM + 180
return Math.min(Math.max(mediaWidth, 300), parent.width - Theme.spacingL * 2)
} else if (root.weatherAvailable) {
return Math.min(280, parent.width - Theme.spacingL * 2)
} else {
return Math.min(baseWidth, parent.width - Theme.spacingL * 2)
}
}
height: 30 height: 30
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: clockMouseArea.containsMouse ? color: clockMouseArea.containsMouse ?
@@ -42,94 +23,31 @@ Rectangle {
} }
Row { Row {
id: clockRow
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingM spacing: Theme.spacingS
// Media info or Weather info Text {
Row { text: Qt.formatTime(root.currentDate, "h:mm AP")
spacing: Theme.spacingXS font.pixelSize: Theme.fontSizeMedium
visible: root.hasActiveMedia || root.weatherAvailable color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
// Audio visualization placeholder - will be replaced by parent
Item {
id: audioVisualizationPlaceholder
width: 20
height: Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
visible: root.hasActiveMedia
}
// Song title when media is playing
Text {
id: mediaTitleText
text: root.activePlayer?.trackTitle || "Unknown Track"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
visible: root.hasActiveMedia
width: Math.min(implicitWidth, root.width - 100)
elide: Text.ElideRight
}
// Weather icon when no media but weather available
Text {
text: WeatherService.getWeatherIcon(root.weatherCode)
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize - 2
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
visible: !root.hasActiveMedia && root.weatherAvailable
}
// Weather temp when no media but weather available
Text {
text: (root.useFahrenheit ? root.weatherTempF : root.weatherTemp) + "°" + (root.useFahrenheit ? "F" : "C")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
visible: !root.hasActiveMedia && root.weatherAvailable
}
} }
// Separator
Text { Text {
text: "•" text: "•"
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: root.hasActiveMedia || root.weatherAvailable
} }
// Time and date Text {
Row { text: Qt.formatDate(root.currentDate, "ddd d")
spacing: Theme.spacingS font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
Text {
text: Qt.formatTime(root.currentDate, "h:mm AP")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "•"
font.pixelSize: Theme.fontSizeMedium
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: Qt.formatDate(root.currentDate, "ddd d")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
} }
} }

View File

@@ -0,0 +1,67 @@
import QtQuick
import Quickshell.Services.Mpris
import "../../Common"
Rectangle {
id: root
property var activePlayer: null
property bool hasActiveMedia: activePlayer && (activePlayer.trackTitle || activePlayer.trackArtist)
signal clicked()
visible: hasActiveMedia
width: hasActiveMedia ? Math.min(200, mediaText.implicitWidth + Theme.spacingS + 48) : 0
height: 30
radius: Theme.cornerRadius
color: mediaArea.containsMouse ?
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) :
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08)
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Behavior on width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
AudioVisualization {
width: 20
height: Theme.iconSize
anchors.verticalCenter: parent.verticalCenter
hasActiveMedia: root.hasActiveMedia
activePlayer: root.activePlayer
}
Text {
id: mediaText
text: activePlayer?.trackTitle || "Unknown Track"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
width: Math.min(implicitWidth, 150)
elide: Text.ElideRight
}
}
MouseArea {
id: mediaArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.clicked()
}
}

View File

@@ -172,27 +172,44 @@ PanelWindow {
ClockWidget { ClockWidget {
id: clockWidget id: clockWidget
anchors.centerIn: parent anchors.centerIn: parent
hasActiveMedia: topBar.hasActiveMedia
activePlayer: topBar.activePlayer
weatherAvailable: topBar.weatherAvailable
weatherCode: topBar.weatherCode
weatherTemp: topBar.weatherTemp
weatherTempF: topBar.weatherTempF
useFahrenheit: topBar.useFahrenheit
onClockClicked: { onClockClicked: {
if (topBar.shellRoot) { if (topBar.shellRoot) {
topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
} }
} }
}
MediaWidget {
anchors.verticalCenter: parent.verticalCenter
anchors.right: clockWidget.left
anchors.rightMargin: Theme.spacingS
activePlayer: topBar.activePlayer
hasActiveMedia: topBar.hasActiveMedia
// Insert audio visualization into the clock widget placeholder onClicked: {
AudioVisualization { if (topBar.shellRoot) {
parent: clockWidget.children[0].children[0].children[0] // Row -> Row (media info) -> Item (placeholder) topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
anchors.fill: parent }
hasActiveMedia: topBar.hasActiveMedia }
activePlayer: topBar.activePlayer }
visible: topBar.hasActiveMedia
WeatherWidget {
id: weatherWidget
anchors.verticalCenter: parent.verticalCenter
anchors.left: clockWidget.right
anchors.leftMargin: Theme.spacingS
weatherAvailable: topBar.weatherAvailable
weatherCode: topBar.weatherCode
weatherTemp: topBar.weatherTemp
weatherTempF: topBar.weatherTempF
useFahrenheit: topBar.useFahrenheit
onClicked: {
if (topBar.shellRoot) {
topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
}
} }
} }

View File

@@ -0,0 +1,68 @@
import QtQuick
import "../../Common"
import "../../Services"
Rectangle {
id: root
property bool weatherAvailable: false
property string weatherCode: ""
property int weatherTemp: 0
property int weatherTempF: 0
property bool useFahrenheit: false
signal clicked()
visible: weatherAvailable
width: weatherAvailable ? Math.min(100, weatherRow.implicitWidth + Theme.spacingS) : 0
height: 30
radius: Theme.cornerRadius
color: weatherArea.containsMouse ?
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) :
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08)
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Behavior on width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
Row {
id: weatherRow
anchors.centerIn: parent
spacing: Theme.spacingXS
Text {
text: WeatherService.getWeatherIcon(weatherCode)
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize - 4
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: (useFahrenheit ? weatherTempF : weatherTemp) + "°"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: weatherArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.clicked()
}
}

View File

@@ -2,6 +2,8 @@ TopBar 1.0 TopBar.qml
LauncherButton 1.0 LauncherButton.qml LauncherButton 1.0 LauncherButton.qml
WorkspaceSwitcher 1.0 WorkspaceSwitcher.qml WorkspaceSwitcher 1.0 WorkspaceSwitcher.qml
ClockWidget 1.0 ClockWidget.qml ClockWidget 1.0 ClockWidget.qml
MediaWidget 1.0 MediaWidget.qml
WeatherWidget 1.0 WeatherWidget.qml
SystemTrayWidget 1.0 SystemTrayWidget.qml SystemTrayWidget 1.0 SystemTrayWidget.qml
NotificationCenterButton 1.0 NotificationCenterButton.qml NotificationCenterButton 1.0 NotificationCenterButton.qml
ControlCenterButton 1.0 ControlCenterButton.qml ControlCenterButton 1.0 ControlCenterButton.qml