1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -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 {
onStreamFinished: {
console.log("SystemMonitorService: CPU usage raw data:", text.trim())
if (text.trim()) {
root.cpuUsage = parseFloat(text.trim())
console.log("SystemMonitorService: CPU usage set to:", root.cpuUsage)
}
}
}
@@ -94,7 +92,6 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
console.log("SystemMonitorService: Memory usage raw data:", text.trim())
if (text.trim()) {
const parts = text.trim().split(" ")
root.memoryUsage = parseFloat(parts[0])
@@ -102,7 +99,6 @@ Singleton {
root.usedMemory = parseFloat(parts[2])
root.availableMemory = parseFloat(parts[3])
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 bool useFahrenheit: false
// Prevent media player from disappearing during track changes
property bool showMediaPlayer: hasActiveMedia || hideMediaTimer.running
Timer {
id: hideMediaTimer
interval: 3000 // 3 second grace period
interval: 3000
running: false
repeat: false
}
@@ -36,8 +35,8 @@ PanelWindow {
visible: root.calendarVisible
implicitWidth: 320
implicitHeight: 400
implicitWidth: 480
implicitHeight: 600
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
@@ -53,55 +52,135 @@ PanelWindow {
}
Rectangle {
width: 400
height: showMediaPlayer ? 540 : (weather?.available ? 480 : 400)
id: mainContainer
width: calculateWidth()
height: calculateHeight()
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
radius: theme.cornerRadiusLarge
border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.12)
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
scale: root.calendarVisible ? 1.0 : 0.85
scale: root.calendarVisible ? 1.0 : 0.92
Behavior on opacity {
NumberAnimation {
duration: theme.mediumDuration
duration: theme.longDuration
easing.type: theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: theme.mediumDuration
duration: theme.longDuration
easing.type: theme.emphasizedEasing
}
}
Column {
Behavior on height {
NumberAnimation {
duration: theme.mediumDuration
easing.type: theme.standardEasing
}
}
Row {
anchors.fill: parent
anchors.margins: theme.spacingL
anchors.margins: theme.spacingM
spacing: theme.spacingM
// Media Player (when active)
MediaPlayerWidget {
visible: showMediaPlayer
theme: centerCommandCenter.theme
// Left section for widgets
Column {
id: leftWidgets
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)
WeatherWidget {
visible: weather?.available && !showMediaPlayer
theme: centerCommandCenter.theme
weather: centerCommandCenter.weather
useFahrenheit: centerCommandCenter.useFahrenheit
}
// Calendar
// Right section for calendar
CalendarWidget {
width: parent.width
height: showMediaPlayer ? parent.height - 200 : (weather?.available ? parent.height - 120 : parent.height - 40)
width: leftWidgets.hasAnyWidgets ? parent.width * 0.55 - theme.spacingL : parent.width
height: parent.height
theme: centerCommandCenter.theme
}
}

View File

@@ -13,12 +13,22 @@ Rectangle {
property var theme: Theme
width: parent.width
height: 160 // Reduced height to prevent overflow
radius: theme.cornerRadius
color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.08)
border.color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.2)
height: parent.height
radius: theme.cornerRadiusLarge
color: Qt.rgba(theme.surfaceContainer.r, theme.surfaceContainer.g, theme.surfaceContainer.b, 0.4)
border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.08)
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
// Simple progress ratio calculation
@@ -68,81 +78,109 @@ Rectangle {
}
Column {
anchors.fill: parent
anchors.margins: theme.spacingM
anchors.centerIn: parent
width: parent.width - theme.spacingM * 2
spacing: theme.spacingM
// Album art and track info
Row {
// Show different content based on whether we have active media
Item {
width: parent.width
height: 70 // Reduced height
spacing: theme.spacingM
height: 80
// Album Art
Rectangle {
width: 70
height: 70
radius: theme.cornerRadius
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
// Placeholder when no media
Column {
anchors.centerIn: parent
spacing: theme.spacingS
visible: !activePlayer || !activePlayer.trackTitle || activePlayer.trackTitle === ""
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 {
text: "music_note"
font.family: theme.iconFont
font.pixelSize: theme.iconSize + 8
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.5)
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
text: "No Media Playing"
font.pixelSize: theme.fontSizeMedium
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
}
}
// Track Info
Column {
width: parent.width - 70 - theme.spacingM
spacing: theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
// Normal media info when playing
Row {
anchors.fill: parent
spacing: theme.spacingM
visible: activePlayer && activePlayer.trackTitle && activePlayer.trackTitle !== ""
Text {
text: activePlayer?.trackTitle || "Unknown Track"
font.pixelSize: theme.fontSizeMedium
font.weight: Font.Bold
color: theme.surfaceText
width: parent.width
elide: Text.ElideRight
// Album Art
Rectangle {
width: 80
height: 80
radius: theme.cornerRadius
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
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 {
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
// Track Info
Column {
width: parent.width - 80 - theme.spacingM
spacing: theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
Text {
text: activePlayer?.trackTitle || "Unknown Track"
font.pixelSize: theme.fontSizeMedium
font.weight: Font.Bold
color: theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
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
radius: 3
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.3)
visible: activePlayer !== null
Rectangle {
id: progressFill
@@ -232,10 +271,11 @@ Rectangle {
}
}
// Control buttons - compact to fit
// Control buttons - always visible
Row {
anchors.horizontalCenter: parent.horizontalCenter
spacing: theme.spacingL
visible: activePlayer !== null
// Previous button
Rectangle {

View File

@@ -1,5 +1,6 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import "../../Common"
import "../../Services"
@@ -11,57 +12,104 @@ Rectangle {
property bool useFahrenheit: false
width: parent.width
height: 80
radius: theme.cornerRadius
color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.08)
border.color: Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.2)
height: parent.height
radius: theme.cornerRadiusLarge
color: Qt.rgba(theme.surfaceContainer.r, theme.surfaceContainer.g, theme.surfaceContainer.b, 0.4)
border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.08)
border.width: 1
Row {
anchors.centerIn: parent
spacing: theme.spacingL
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
}
Column {
anchors.fill: parent
anchors.margins: theme.spacingL
spacing: theme.spacingM
// Weather icon and temp
Column {
spacing: 2
anchors.verticalCenter: parent.verticalCenter
// Show different content based on whether we have weather data
Item {
width: parent.width
height: 60
Text {
text: WeatherService.getWeatherIcon(weather.wCode)
font.family: theme.iconFont
font.pixelSize: theme.iconSize + 4
color: theme.primary
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
// Placeholder when no weather
Column {
anchors.centerIn: parent
spacing: theme.spacingS
visible: !weather
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: useFahrenheit = !useFahrenheit
Text {
text: "cloud_off"
font.family: theme.iconFont
font.pixelSize: theme.iconSize + 8
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 {
text: weather.city
font.pixelSize: theme.fontSizeSmall
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
// Normal weather info when available
Row {
anchors.fill: parent
spacing: theme.spacingL
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
Grid {
columns: 2
spacing: theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter
visible: weather !== null
Row {
spacing: theme.spacingXS
@@ -73,7 +121,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: weather.humidity + "%"
text: weather ? weather.humidity + "%" : "--"
font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -90,7 +138,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: weather.wind
text: weather ? weather.wind : "--"
font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -107,7 +155,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: weather.sunrise
text: weather ? weather.sunrise : "--"
font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
@@ -124,7 +172,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: weather.sunset
text: weather ? weather.sunset : "--"
font.pixelSize: theme.fontSizeSmall
color: theme.surfaceText
anchors.verticalCenter: parent.verticalCenter

View File

@@ -1,33 +1,14 @@
import QtQuick
import Quickshell.Services.Mpris
import "../../Common"
import "../../Services"
Rectangle {
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()
signal clockClicked()
width: {
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)
}
}
width: clockRow.implicitWidth + Theme.spacingM
height: 30
radius: Theme.cornerRadius
color: clockMouseArea.containsMouse ?
@@ -42,94 +23,31 @@ Rectangle {
}
Row {
id: clockRow
anchors.centerIn: parent
spacing: Theme.spacingM
spacing: Theme.spacingS
// Media info or Weather info
Row {
spacing: Theme.spacingXS
visible: root.hasActiveMedia || root.weatherAvailable
Text {
text: Qt.formatTime(root.currentDate, "h:mm AP")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
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: "•"
font.pixelSize: Theme.fontSizeMedium
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
anchors.verticalCenter: parent.verticalCenter
visible: root.hasActiveMedia || root.weatherAvailable
}
// Time and date
Row {
spacing: Theme.spacingS
Text {
text: Qt.formatDate(root.currentDate, "ddd d")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
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 {
id: clockWidget
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: {
if (topBar.shellRoot) {
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
AudioVisualization {
parent: clockWidget.children[0].children[0].children[0] // Row -> Row (media info) -> Item (placeholder)
anchors.fill: parent
hasActiveMedia: topBar.hasActiveMedia
activePlayer: topBar.activePlayer
visible: topBar.hasActiveMedia
onClicked: {
if (topBar.shellRoot) {
topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
}
}
}
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
WorkspaceSwitcher 1.0 WorkspaceSwitcher.qml
ClockWidget 1.0 ClockWidget.qml
MediaWidget 1.0 MediaWidget.qml
WeatherWidget 1.0 WeatherWidget.qml
SystemTrayWidget 1.0 SystemTrayWidget.qml
NotificationCenterButton 1.0 NotificationCenterButton.qml
ControlCenterButton 1.0 ControlCenterButton.qml