mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 22:15:38 -05:00
meta: large-scale refactor progress
This commit is contained in:
@@ -2,7 +2,8 @@ pragma Singleton
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Qt.labs.platform // ← gives us StandardPaths
|
import Qt.labs.platform
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
@@ -53,7 +54,8 @@ Singleton {
|
|||||||
|
|
||||||
if (!matugenAvailable) {
|
if (!matugenAvailable) {
|
||||||
console.warn("Matugen missing → dynamic theme disabled")
|
console.warn("Matugen missing → dynamic theme disabled")
|
||||||
Theme.rootObj.wallpaperErrorStatus = "matugen_missing"
|
ToastService.wallpaperErrorStatus = "matugen_missing"
|
||||||
|
ToastService.showWarning("matugen not found - dynamic theming disabled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +76,8 @@ Singleton {
|
|||||||
} else {
|
} else {
|
||||||
console.error("code", code)
|
console.error("code", code)
|
||||||
console.error("Wallpaper not found:", wallpaperPath)
|
console.error("Wallpaper not found:", wallpaperPath)
|
||||||
Theme.rootObj.showWallpaperError()
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Wallpaper processing failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,17 +94,20 @@ Singleton {
|
|||||||
const out = matugenCollector.text
|
const out = matugenCollector.text
|
||||||
if (!out.length) {
|
if (!out.length) {
|
||||||
console.error("matugen produced zero bytes\nstderr:", matugenProcess.stderr)
|
console.error("matugen produced zero bytes\nstderr:", matugenProcess.stderr)
|
||||||
Theme.rootObj.showWallpaperError()
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Wallpaper processing failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
root.matugenJson = out
|
root.matugenJson = out
|
||||||
root.matugenColors = JSON.parse(out)
|
root.matugenColors = JSON.parse(out)
|
||||||
root.colorsUpdated()
|
root.colorsUpdated()
|
||||||
Theme.rootObj.wallpaperErrorStatus = ""
|
ToastService.clearWallpaperError()
|
||||||
|
ToastService.showInfo("Dynamic theme colors updated")
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("JSON parse failed:", e)
|
console.error("JSON parse failed:", e)
|
||||||
Theme.rootObj.showWallpaperError()
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Wallpaper processing failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ import Quickshell.Io
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Reference to the main shell root for calling functions
|
|
||||||
property var rootObj: null
|
|
||||||
|
|
||||||
// Initialize theme system
|
// Initialize theme system
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
console.log("Theme Component.onCompleted")
|
console.log("Theme Component.onCompleted")
|
||||||
@@ -609,4 +606,19 @@ Singleton {
|
|||||||
default: return "Custom power profile"
|
default: return "Custom power profile"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wallpaper IPC handler
|
||||||
|
IpcHandler {
|
||||||
|
target: "wallpaper"
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
console.log("Wallpaper IPC: refresh() called")
|
||||||
|
// Trigger color extraction if using dynamic theme
|
||||||
|
if (typeof Theme !== "undefined" && Theme.isDynamicTheme) {
|
||||||
|
console.log("Triggering color extraction due to wallpaper IPC")
|
||||||
|
Colors.extractColors()
|
||||||
|
}
|
||||||
|
return "WALLPAPER_REFRESH_SUCCESS"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
83
Services/ToastService.qml
Normal file
83
Services/ToastService.qml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property int levelInfo: 0
|
||||||
|
readonly property int levelWarn: 1
|
||||||
|
readonly property int levelError: 2
|
||||||
|
|
||||||
|
property string currentMessage: ""
|
||||||
|
property int currentLevel: levelInfo
|
||||||
|
property bool toastVisible: false
|
||||||
|
property var toastQueue: []
|
||||||
|
|
||||||
|
property string wallpaperErrorStatus: ""
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: toastTimer
|
||||||
|
interval: 5000
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: hideToast()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: queueTimer
|
||||||
|
interval: 500
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: processQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
function showToast(message, level = levelInfo) {
|
||||||
|
toastQueue.push({ message, level })
|
||||||
|
if (!toastVisible) {
|
||||||
|
processQueue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showInfo(message) {
|
||||||
|
showToast(message, levelInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
function showWarning(message) {
|
||||||
|
showToast(message, levelWarn)
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError(message) {
|
||||||
|
showToast(message, levelError)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideToast() {
|
||||||
|
toastVisible = false
|
||||||
|
currentMessage = ""
|
||||||
|
currentLevel = levelInfo
|
||||||
|
toastTimer.stop()
|
||||||
|
if (toastQueue.length > 0) {
|
||||||
|
queueTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processQueue() {
|
||||||
|
if (toastQueue.length === 0) return
|
||||||
|
|
||||||
|
const toast = toastQueue.shift()
|
||||||
|
currentMessage = toast.message
|
||||||
|
currentLevel = toast.level
|
||||||
|
toastVisible = true
|
||||||
|
|
||||||
|
toastTimer.interval =
|
||||||
|
toast.level === levelError ? 8000 :
|
||||||
|
toast.level === levelWarn ? 6000 : 5000
|
||||||
|
toastTimer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearWallpaperError() {
|
||||||
|
wallpaperErrorStatus = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -263,6 +263,21 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-refresh timer for when control center is open
|
||||||
|
property bool autoRefreshEnabled: false
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: autoRefreshTimer
|
||||||
|
interval: 20000
|
||||||
|
running: root.autoRefreshEnabled
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
if (root.autoRefreshEnabled) {
|
||||||
|
root.scanWifi()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateCurrentWifiInfo() {
|
function updateCurrentWifiInfo() {
|
||||||
console.log("Updating current WiFi info...")
|
console.log("Updating current WiFi info...")
|
||||||
currentWifiInfo.running = true
|
currentWifiInfo.running = true
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import qs.Services
|
|||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: batteryControlPopup
|
id: root
|
||||||
|
|
||||||
visible: root.batteryPopupVisible
|
property bool batteryPopupVisible: false
|
||||||
|
|
||||||
|
visible: batteryPopupVisible
|
||||||
|
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: 300
|
implicitHeight: 300
|
||||||
@@ -32,7 +34,7 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.batteryPopupVisible = false
|
batteryPopupVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,8 +48,8 @@ PanelWindow {
|
|||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
opacity: root.batteryPopupVisible ? 1.0 : 0.0
|
opacity: batteryPopupVisible ? 1.0 : 0.0
|
||||||
scale: root.batteryPopupVisible ? 1.0 : 0.85
|
scale: batteryPopupVisible ? 1.0 : 0.85
|
||||||
|
|
||||||
// Prevent click-through to background
|
// Prevent click-through to background
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -114,7 +116,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.batteryPopupVisible = false
|
batteryPopupVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ import qs.Services
|
|||||||
Column {
|
Column {
|
||||||
id: calendarWidget
|
id: calendarWidget
|
||||||
|
|
||||||
property var theme: Theme
|
|
||||||
property date displayDate: new Date()
|
property date displayDate: new Date()
|
||||||
property date selectedDate: new Date()
|
property date selectedDate: new Date()
|
||||||
|
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
// Load events when display date changes
|
// Load events when display date changes
|
||||||
onDisplayDateChanged: {
|
onDisplayDateChanged: {
|
||||||
@@ -61,16 +60,16 @@ Column {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
width: 40
|
width: 40
|
||||||
height: 40
|
height: 40
|
||||||
radius: theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: prevMonthArea.containsMouse ? Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.12) : "transparent"
|
color: prevMonthArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "chevron_left"
|
text: "chevron_left"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize
|
font.pixelSize: Theme.iconSize
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
font.weight: theme.iconFontWeight
|
font.weight: Theme.iconFontWeight
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -91,8 +90,8 @@ Column {
|
|||||||
width: parent.width - 80
|
width: parent.width - 80
|
||||||
height: 40
|
height: 40
|
||||||
text: Qt.formatDate(displayDate, "MMMM yyyy")
|
text: Qt.formatDate(displayDate, "MMMM yyyy")
|
||||||
font.pixelSize: theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
@@ -101,16 +100,16 @@ Column {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
width: 40
|
width: 40
|
||||||
height: 40
|
height: 40
|
||||||
radius: theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: nextMonthArea.containsMouse ? Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.12) : "transparent"
|
color: nextMonthArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "chevron_right"
|
text: "chevron_right"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize
|
font.pixelSize: Theme.iconSize
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
font.weight: theme.iconFontWeight
|
font.weight: Theme.iconFontWeight
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -144,8 +143,8 @@ Column {
|
|||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: modelData
|
text: modelData
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.6)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,20 +182,20 @@ Column {
|
|||||||
property bool isToday: dayDate.toDateString() === new Date().toDateString()
|
property bool isToday: dayDate.toDateString() === new Date().toDateString()
|
||||||
property bool isSelected: dayDate.toDateString() === selectedDate.toDateString()
|
property bool isSelected: dayDate.toDateString() === selectedDate.toDateString()
|
||||||
|
|
||||||
color: isSelected ? theme.primary :
|
color: isSelected ? Theme.primary :
|
||||||
isToday ? Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.12) :
|
isToday ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) :
|
||||||
dayArea.containsMouse ? Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.08) : "transparent"
|
dayArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
|
||||||
|
|
||||||
radius: theme.cornerRadiusSmall
|
radius: Theme.cornerRadiusSmall
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: dayDate.getDate()
|
text: dayDate.getDate()
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: isSelected ? theme.surface :
|
color: isSelected ? Theme.surface :
|
||||||
isToday ? theme.primary :
|
isToday ? Theme.primary :
|
||||||
isCurrentMonth ? theme.surfaceText :
|
isCurrentMonth ? Theme.surfaceText :
|
||||||
Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.4)
|
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4)
|
||||||
font.weight: isToday || isSelected ? Font.Medium : Font.Normal
|
font.weight: isToday || isSelected ? Font.Medium : Font.Normal
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,11 +214,11 @@ Column {
|
|||||||
color: {
|
color: {
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// Use a lighter tint of primary for selected state
|
// Use a lighter tint of primary for selected state
|
||||||
return Qt.lighter(theme.primary, 1.3)
|
return Qt.lighter(Theme.primary, 1.3)
|
||||||
} else if (isToday) {
|
} else if (isToday) {
|
||||||
return theme.primary
|
return Theme.primary
|
||||||
} else {
|
} else {
|
||||||
return theme.primary
|
return Theme.primary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,22 +237,22 @@ Column {
|
|||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: centerCommandCenter
|
id: root
|
||||||
|
|
||||||
property var theme: Theme
|
|
||||||
readonly property bool hasActiveMedia: MprisController.activePlayer !== null
|
readonly property bool hasActiveMedia: MprisController.activePlayer !== null
|
||||||
|
property bool calendarVisible: false
|
||||||
|
|
||||||
visible: root.calendarVisible
|
visible: calendarVisible
|
||||||
|
|
||||||
implicitWidth: 480
|
implicitWidth: 480
|
||||||
implicitHeight: 600
|
implicitHeight: 600
|
||||||
@@ -48,15 +48,15 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calculateHeight() {
|
function calculateHeight() {
|
||||||
let contentHeight = theme.spacingM * 2 // margins
|
let contentHeight = Theme.spacingM * 2 // margins
|
||||||
|
|
||||||
// Main row with widgets and calendar
|
// Main row with widgets and calendar
|
||||||
let widgetHeight = 160 // Media widget always present
|
let widgetHeight = 160 // Media widget always present
|
||||||
widgetHeight += 140 + theme.spacingM // Weather widget always present
|
widgetHeight += 140 + Theme.spacingM // Weather widget always present
|
||||||
let calendarHeight = 300
|
let calendarHeight = 300
|
||||||
let mainRowHeight = Math.max(widgetHeight, calendarHeight)
|
let mainRowHeight = Math.max(widgetHeight, calendarHeight)
|
||||||
|
|
||||||
contentHeight += mainRowHeight + theme.spacingM // Add spacing between main row and events
|
contentHeight += mainRowHeight + Theme.spacingM
|
||||||
|
|
||||||
// Add events widget height - use calculated height instead of actual
|
// Add events widget height - use calculated height instead of actual
|
||||||
if (CalendarService && CalendarService.khalAvailable) {
|
if (CalendarService && CalendarService.khalAvailable) {
|
||||||
@@ -68,9 +68,9 @@ PanelWindow {
|
|||||||
return Math.min(contentHeight, parent.height * 0.9)
|
return Math.min(contentHeight, parent.height * 0.9)
|
||||||
}
|
}
|
||||||
|
|
||||||
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.08)
|
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.enabled: true
|
||||||
@@ -85,27 +85,27 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Qt.rgba(theme.surfaceTint.r, theme.surfaceTint.g, theme.surfaceTint.b, 0.04)
|
color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04)
|
||||||
radius: parent.radius
|
radius: parent.radius
|
||||||
|
|
||||||
SequentialAnimation on opacity {
|
SequentialAnimation on opacity {
|
||||||
running: root.calendarVisible
|
running: calendarVisible
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
to: 0.08
|
to: 0.08
|
||||||
duration: theme.extraLongDuration
|
duration: Theme.extraLongDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
to: 0.02
|
to: 0.02
|
||||||
duration: theme.extraLongDuration
|
duration: Theme.extraLongDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opacity: root.calendarVisible ? 1.0 : 0.0
|
opacity: calendarVisible ? 1.0 : 0.0
|
||||||
scale: root.calendarVisible ? 1.0 : 0.92
|
scale: calendarVisible ? 1.0 : 0.92
|
||||||
|
|
||||||
// Update height when calendar service events change
|
// Update height when calendar service events change
|
||||||
Connections {
|
Connections {
|
||||||
@@ -130,47 +130,47 @@ PanelWindow {
|
|||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.longDuration
|
duration: Theme.longDuration
|
||||||
easing.type: theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.longDuration
|
duration: Theme.longDuration
|
||||||
easing.type: theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
// Main row with widgets and calendar
|
// Main row with widgets and calendar
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: {
|
height: {
|
||||||
let widgetHeight = 160 // Media widget always present
|
let widgetHeight = 160 // Media widget always present
|
||||||
widgetHeight += 140 + theme.spacingM // Weather widget always present
|
widgetHeight += 140 + Theme.spacingM // Weather widget always present
|
||||||
let calendarHeight = 300
|
let calendarHeight = 300
|
||||||
return Math.max(widgetHeight, calendarHeight)
|
return Math.max(widgetHeight, calendarHeight)
|
||||||
}
|
}
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
// Left section for widgets
|
// Left section for widgets
|
||||||
Column {
|
Column {
|
||||||
id: leftWidgets
|
id: leftWidgets
|
||||||
width: hasAnyWidgets ? parent.width * 0.45 : 0
|
width: hasAnyWidgets ? parent.width * 0.45 : 0
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
visible: hasAnyWidgets
|
visible: hasAnyWidgets
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
||||||
@@ -180,23 +180,20 @@ PanelWindow {
|
|||||||
visible: true // Always visible - shows placeholder when no media
|
visible: true // Always visible - shows placeholder when no media
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 160
|
height: 160
|
||||||
theme: centerCommandCenter.theme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WeatherWidget {
|
WeatherWidget {
|
||||||
visible: true // Always visible - shows placeholder when no weather
|
visible: true // Always visible - shows placeholder when no weather
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 140
|
height: 140
|
||||||
theme: centerCommandCenter.theme
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right section for calendar
|
// Right section for calendar
|
||||||
CalendarWidget {
|
CalendarWidget {
|
||||||
id: calendarWidget
|
id: calendarWidget
|
||||||
width: leftWidgets.hasAnyWidgets ? parent.width * 0.55 - theme.spacingL : parent.width
|
width: leftWidgets.hasAnyWidgets ? parent.width * 0.55 - Theme.spacingL : parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
theme: centerCommandCenter.theme
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +201,6 @@ PanelWindow {
|
|||||||
EventsWidget {
|
EventsWidget {
|
||||||
id: eventsWidget
|
id: eventsWidget
|
||||||
width: parent.width
|
width: parent.width
|
||||||
theme: centerCommandCenter.theme
|
|
||||||
selectedDate: calendarWidget.selectedDate
|
selectedDate: calendarWidget.selectedDate
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -215,7 +211,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: -1
|
z: -1
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.calendarVisible = false
|
calendarVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,6 @@ import qs.Services
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: eventsWidget
|
id: eventsWidget
|
||||||
|
|
||||||
property var theme: Theme
|
|
||||||
property date selectedDate: new Date()
|
property date selectedDate: new Date()
|
||||||
property var selectedDateEvents: []
|
property var selectedDateEvents: []
|
||||||
property bool hasEvents: selectedDateEvents && selectedDateEvents.length > 0
|
property bool hasEvents: selectedDateEvents && selectedDateEvents.length > 0
|
||||||
@@ -21,9 +20,9 @@ Rectangle {
|
|||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: shouldShow ? (hasEvents ? Math.min(300, 80 + selectedDateEvents.length * 60) : 120) : 0
|
height: shouldShow ? (hasEvents ? Math.min(300, 80 + selectedDateEvents.length * 60) : 120) : 0
|
||||||
radius: theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
color: Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.12)
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.12)
|
||||||
border.color: Qt.rgba(theme.outline.r, theme.outline.g, theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
visible: shouldShow
|
visible: shouldShow
|
||||||
|
|
||||||
@@ -40,8 +39,8 @@ Rectangle {
|
|||||||
|
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +80,14 @@ Rectangle {
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "event"
|
text: "event"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize - 2
|
font.pixelSize: Theme.iconSize - 2
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +96,8 @@ Rectangle {
|
|||||||
(Qt.formatDate(selectedDate, "MMM d") + " • " +
|
(Qt.formatDate(selectedDate, "MMM d") + " • " +
|
||||||
(selectedDateEvents.length === 1 ? "1 event" : selectedDateEvents.length + " events")) :
|
(selectedDateEvents.length === 1 ? "1 event" : selectedDateEvents.length + " events")) :
|
||||||
Qt.formatDate(selectedDate, "MMM d")
|
Qt.formatDate(selectedDate, "MMM d")
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -107,21 +106,21 @@ Rectangle {
|
|||||||
// No events placeholder - centered in entire widget (not just content area)
|
// No events placeholder - centered in entire widget (not just content area)
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
visible: !hasEvents
|
visible: !hasEvents
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "event_busy"
|
text: "event_busy"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize + 8
|
font.pixelSize: Theme.iconSize + 8
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.3)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3)
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "No events"
|
text: "No events"
|
||||||
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)
|
||||||
font.weight: Font.Normal
|
font.weight: Font.Normal
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
@@ -134,12 +133,12 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.margins: theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
anchors.topMargin: theme.spacingM
|
anchors.topMargin: Theme.spacingM
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
opacity: hasEvents ? 1.0 : 0.0
|
opacity: hasEvents ? 1.0 : 0.0
|
||||||
clip: true
|
clip: true
|
||||||
spacing: theme.spacingS
|
spacing: Theme.spacingS
|
||||||
boundsMovement: Flickable.StopAtBounds
|
boundsMovement: Flickable.StopAtBounds
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
@@ -149,28 +148,28 @@ Rectangle {
|
|||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
width: eventsList.width
|
width: eventsList.width
|
||||||
height: eventContent.implicitHeight + theme.spacingM
|
height: eventContent.implicitHeight + Theme.spacingM
|
||||||
radius: theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
if (modelData.url && eventMouseArea.containsMouse) {
|
if (modelData.url && eventMouseArea.containsMouse) {
|
||||||
return Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.12)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||||
} else if (eventMouseArea.containsMouse) {
|
} else if (eventMouseArea.containsMouse) {
|
||||||
return Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.06)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.06)
|
||||||
}
|
}
|
||||||
return Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.06)
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.06)
|
||||||
}
|
}
|
||||||
border.color: {
|
border.color: {
|
||||||
if (modelData.url && eventMouseArea.containsMouse) {
|
if (modelData.url && eventMouseArea.containsMouse) {
|
||||||
return Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.3)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3)
|
||||||
} else if (eventMouseArea.containsMouse) {
|
} else if (eventMouseArea.containsMouse) {
|
||||||
return Qt.rgba(theme.primary.r, theme.primary.g, theme.primary.b, 0.15)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.15)
|
||||||
}
|
}
|
||||||
return "transparent"
|
return "transparent"
|
||||||
}
|
}
|
||||||
@@ -184,7 +183,7 @@ Rectangle {
|
|||||||
anchors.leftMargin: 4
|
anchors.leftMargin: 4
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
radius: 2
|
radius: 2
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,15 +192,15 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: theme.spacingL + 4
|
anchors.leftMargin: Theme.spacingL + 4
|
||||||
anchors.rightMargin: theme.spacingM
|
anchors.rightMargin: Theme.spacingM
|
||||||
spacing: 6
|
spacing: 6
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: modelData.title
|
text: modelData.title
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
@@ -220,9 +219,9 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "schedule"
|
text: "schedule"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,8 +239,8 @@ Rectangle {
|
|||||||
return startTime
|
return startTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
font.weight: Font.Normal
|
font.weight: Font.Normal
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -256,16 +255,16 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "location_on"
|
text: "location_on"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: modelData.location
|
text: modelData.location
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
@@ -293,15 +292,15 @@ Rectangle {
|
|||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on border.color {
|
Behavior on border.color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ Rectangle {
|
|||||||
id: mediaPlayerWidget
|
id: mediaPlayerWidget
|
||||||
|
|
||||||
property MprisPlayer activePlayer: MprisController.activePlayer
|
property MprisPlayer activePlayer: MprisController.activePlayer
|
||||||
property var theme: Theme
|
|
||||||
|
|
||||||
property string lastValidTitle: ""
|
property string lastValidTitle: ""
|
||||||
property string lastValidArtist: ""
|
property string lastValidArtist: ""
|
||||||
@@ -40,9 +39,9 @@ Rectangle {
|
|||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
radius: theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
color: Qt.rgba(theme.surfaceContainer.r, theme.surfaceContainer.g, theme.surfaceContainer.b, 0.4)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
@@ -96,26 +95,26 @@ Rectangle {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: theme.spacingS
|
anchors.margins: Theme.spacingS
|
||||||
|
|
||||||
// Placeholder when no media - centered in entire widget
|
// Placeholder when no media - centered in entire widget
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: (!activePlayer && !lastValidTitle) || (activePlayer && activePlayer.trackTitle === "" && lastValidTitle === "")
|
visible: (!activePlayer && !lastValidTitle) || (activePlayer && activePlayer.trackTitle === "" && lastValidTitle === "")
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "music_note"
|
text: "music_note"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize + 8
|
font.pixelSize: Theme.iconSize + 8
|
||||||
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.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "No Media Playing"
|
text: "No Media Playing"
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,21 +122,21 @@ Rectangle {
|
|||||||
// Active content in a column
|
// Active content in a column
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: activePlayer && activePlayer.trackTitle !== "" || lastValidTitle !== ""
|
visible: activePlayer && activePlayer.trackTitle !== "" || lastValidTitle !== ""
|
||||||
|
|
||||||
// Normal media info when playing
|
// Normal media info when playing
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 60
|
height: 60
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
// Album Art
|
// Album Art
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 60
|
width: 60
|
||||||
height: 60
|
height: 60
|
||||||
radius: theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
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)
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -164,9 +163,9 @@ Rectangle {
|
|||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "album"
|
text: "album"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: 28
|
font.pixelSize: 28
|
||||||
color: theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,9 +173,9 @@ Rectangle {
|
|||||||
|
|
||||||
// Track Info
|
// Track Info
|
||||||
Column {
|
Column {
|
||||||
width: parent.width - 60 - theme.spacingM
|
width: parent.width - 60 - Theme.spacingM
|
||||||
height: parent.height
|
height: parent.height
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: activePlayer?.trackTitle || lastValidTitle || "Unknown Track"
|
text: activePlayer?.trackTitle || lastValidTitle || "Unknown Track"
|
||||||
@@ -185,9 +184,9 @@ Rectangle {
|
|||||||
lastValidTitle = activePlayer.trackTitle;
|
lastValidTitle = activePlayer.trackTitle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
width: parent.width
|
width: parent.width
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
@@ -199,8 +198,8 @@ Rectangle {
|
|||||||
lastValidArtist = activePlayer.trackArtist;
|
lastValidArtist = activePlayer.trackArtist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.8)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.8)
|
||||||
width: parent.width
|
width: parent.width
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
@@ -212,8 +211,8 @@ Rectangle {
|
|||||||
lastValidAlbum = activePlayer.trackAlbum;
|
lastValidAlbum = activePlayer.trackAlbum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.6)
|
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
|
visible: text.length > 0
|
||||||
@@ -232,7 +231,7 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
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
|
visible: activePlayer !== null
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
@@ -240,7 +239,7 @@ Rectangle {
|
|||||||
id: progressFill
|
id: progressFill
|
||||||
height: parent.height
|
height: parent.height
|
||||||
radius: parent.radius
|
radius: parent.radius
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
|
|
||||||
width: parent.width * ratio()
|
width: parent.width * ratio()
|
||||||
|
|
||||||
@@ -255,8 +254,8 @@ Rectangle {
|
|||||||
width: 12
|
width: 12
|
||||||
height: 12
|
height: 12
|
||||||
radius: 6
|
radius: 6
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
border.color: Qt.lighter(theme.primary, 1.3)
|
border.color: Qt.lighter(Theme.primary, 1.3)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
x: Math.max(0, Math.min(parent.width - width, progressFill.width - width/2))
|
x: Math.max(0, Math.min(parent.width - width, progressFill.width - width/2))
|
||||||
@@ -346,7 +345,7 @@ Rectangle {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
// Previous button
|
// Previous button
|
||||||
@@ -354,14 +353,14 @@ Rectangle {
|
|||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
color: prevBtnArea.containsMouse ? Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.12) : "transparent"
|
color: prevBtnArea.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.12) : "transparent"
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "skip_previous"
|
text: "skip_previous"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -388,14 +387,14 @@ Rectangle {
|
|||||||
width: 32
|
width: 32
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: activePlayer?.playbackState === MprisPlaybackState.Playing ? "pause" : "play_arrow"
|
text: activePlayer?.playbackState === MprisPlaybackState.Playing ? "pause" : "play_arrow"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: 20
|
font.pixelSize: 20
|
||||||
color: theme.background
|
color: Theme.background
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -411,14 +410,14 @@ Rectangle {
|
|||||||
width: 28
|
width: 28
|
||||||
height: 28
|
height: 28
|
||||||
radius: 14
|
radius: 14
|
||||||
color: nextBtnArea.containsMouse ? Qt.rgba(theme.surfaceVariant.r, theme.surfaceVariant.g, theme.surfaceVariant.b, 0.12) : "transparent"
|
color: nextBtnArea.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.12) : "transparent"
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "skip_next"
|
text: "skip_next"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ import qs.Services
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: weatherWidget
|
id: weatherWidget
|
||||||
|
|
||||||
property var theme: Theme
|
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
radius: theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
color: Qt.rgba(theme.surfaceContainer.r, theme.surfaceContainer.g, theme.surfaceContainer.b, 0.4)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
@@ -29,21 +28,21 @@ Rectangle {
|
|||||||
// Placeholder when no weather - centered in entire widget
|
// Placeholder when no weather - centered in entire widget
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: !WeatherService.weather.available || WeatherService.weather.temp === 0
|
visible: !WeatherService.weather.available || WeatherService.weather.temp === 0
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "cloud_off"
|
text: "cloud_off"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize + 8
|
font.pixelSize: Theme.iconSize + 8
|
||||||
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.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "No Weather Data"
|
text: "No Weather Data"
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,8 +50,8 @@ Rectangle {
|
|||||||
// Weather content when available - original Column structure
|
// Weather content when available - original Column structure
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: WeatherService.weather.available && WeatherService.weather.temp !== 0
|
visible: WeatherService.weather.available && WeatherService.weather.temp !== 0
|
||||||
|
|
||||||
// Weather header info
|
// Weather header info
|
||||||
@@ -62,25 +61,25 @@ Rectangle {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: theme.spacingL
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
// Weather icon
|
// Weather icon
|
||||||
Text {
|
Text {
|
||||||
text: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
|
text: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.iconSize + 8
|
font.pixelSize: Theme.iconSize + 8
|
||||||
color: theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: (Prefs.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp) + "°" + (Prefs.useFahrenheit ? "F" : "C")
|
text: (Prefs.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp) + "°" + (Prefs.useFahrenheit ? "F" : "C")
|
||||||
font.pixelSize: theme.fontSizeXLarge
|
font.pixelSize: Theme.fontSizeXLarge
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Light
|
font.weight: Font.Light
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -94,8 +93,8 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: WeatherService.weather.city || ""
|
text: WeatherService.weather.city || ""
|
||||||
font.pixelSize: theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Qt.rgba(theme.surfaceText.r, theme.surfaceText.g, theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
visible: text.length > 0
|
visible: text.length > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,73 +104,73 @@ Rectangle {
|
|||||||
// Weather details grid
|
// Weather details grid
|
||||||
Grid {
|
Grid {
|
||||||
columns: 2
|
columns: 2
|
||||||
spacing: theme.spacingM
|
spacing: Theme.spacingM
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
Text {
|
Text {
|
||||||
text: "humidity_low"
|
text: "humidity_low"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: WeatherService.weather.humidity ? WeatherService.weather.humidity + "%" : "--"
|
text: WeatherService.weather.humidity ? WeatherService.weather.humidity + "%" : "--"
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
Text {
|
Text {
|
||||||
text: "air"
|
text: "air"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: WeatherService.weather.wind || "--"
|
text: WeatherService.weather.wind || "--"
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
Text {
|
Text {
|
||||||
text: "wb_twilight"
|
text: "wb_twilight"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: WeatherService.weather.sunrise || "--"
|
text: WeatherService.weather.sunrise || "--"
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
Text {
|
Text {
|
||||||
text: "bedtime"
|
text: "bedtime"
|
||||||
font.family: theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: WeatherService.weather.sunset || "--"
|
text: WeatherService.weather.sunset || "--"
|
||||||
font.pixelSize: theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,16 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: controlCenterPopup
|
id: root
|
||||||
|
|
||||||
visible: root.controlCenterVisible
|
property bool controlCenterVisible: false
|
||||||
|
|
||||||
|
visible: controlCenterVisible
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
// Enable/disable WiFi auto-refresh based on control center visibility
|
||||||
|
WifiService.autoRefreshEnabled = visible && NetworkService.wifiEnabled
|
||||||
|
}
|
||||||
|
|
||||||
implicitWidth: 600
|
implicitWidth: 600
|
||||||
implicitHeight: 500
|
implicitHeight: 500
|
||||||
@@ -34,7 +41,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: Math.min(600, Screen.width - Theme.spacingL * 2)
|
width: Math.min(600, Screen.width - Theme.spacingL * 2)
|
||||||
height: controlCenterPopup.powerOptionsExpanded ? 570 : 500
|
height: root.powerOptionsExpanded ? 570 : 500
|
||||||
x: Math.max(Theme.spacingL, Screen.width - width - Theme.spacingL)
|
x: Math.max(Theme.spacingL, Screen.width - width - Theme.spacingL)
|
||||||
y: Theme.barHeight + Theme.spacingXS
|
y: Theme.barHeight + Theme.spacingXS
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
@@ -46,15 +53,15 @@ PanelWindow {
|
|||||||
transform: [
|
transform: [
|
||||||
Scale {
|
Scale {
|
||||||
id: scaleTransform
|
id: scaleTransform
|
||||||
origin.x: parent.width // Scale from top-right corner
|
origin.x: 600 // Use fixed width since popup is max 600px wide
|
||||||
origin.y: 0
|
origin.y: 0
|
||||||
xScale: root.controlCenterVisible ? 1.0 : 0.95
|
xScale: controlCenterVisible ? 1.0 : 0.95
|
||||||
yScale: root.controlCenterVisible ? 1.0 : 0.8
|
yScale: controlCenterVisible ? 1.0 : 0.8
|
||||||
},
|
},
|
||||||
Translate {
|
Translate {
|
||||||
id: translateTransform
|
id: translateTransform
|
||||||
x: root.controlCenterVisible ? 0 : 15 // Slide slightly left when hidden
|
x: controlCenterVisible ? 0 : 15 // Slide slightly left when hidden
|
||||||
y: root.controlCenterVisible ? 0 : -30
|
y: controlCenterVisible ? 0 : -30
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -62,13 +69,13 @@ PanelWindow {
|
|||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "visible"
|
name: "visible"
|
||||||
when: root.controlCenterVisible
|
when: controlCenterVisible
|
||||||
PropertyChanges { target: scaleTransform; xScale: 1.0; yScale: 1.0 }
|
PropertyChanges { target: scaleTransform; xScale: 1.0; yScale: 1.0 }
|
||||||
PropertyChanges { target: translateTransform; x: 0; y: 0 }
|
PropertyChanges { target: translateTransform; x: 0; y: 0 }
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "hidden"
|
name: "hidden"
|
||||||
when: !root.controlCenterVisible
|
when: !controlCenterVisible
|
||||||
PropertyChanges { target: scaleTransform; xScale: 0.95; yScale: 0.8 }
|
PropertyChanges { target: scaleTransform; xScale: 0.95; yScale: 0.8 }
|
||||||
PropertyChanges { target: translateTransform; x: 15; y: -30 }
|
PropertyChanges { target: translateTransform; x: 15; y: -30 }
|
||||||
}
|
}
|
||||||
@@ -96,7 +103,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
opacity: root.controlCenterVisible ? 1.0 : 0.0
|
opacity: controlCenterVisible ? 1.0 : 0.0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -253,7 +260,7 @@ PanelWindow {
|
|||||||
width: 40
|
width: 40
|
||||||
height: 40
|
height: 40
|
||||||
radius: 20
|
radius: 20
|
||||||
color: powerButton.containsMouse || controlCenterPopup.powerOptionsExpanded ?
|
color: powerButton.containsMouse || root.powerOptionsExpanded ?
|
||||||
Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) :
|
Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) :
|
||||||
Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||||
|
|
||||||
@@ -267,10 +274,10 @@ PanelWindow {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: controlCenterPopup.powerOptionsExpanded ? "expand_less" : "power_settings_new"
|
text: root.powerOptionsExpanded ? "expand_less" : "power_settings_new"
|
||||||
font.family: Theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: Theme.iconSize - 2
|
font.pixelSize: Theme.iconSize - 2
|
||||||
color: powerButton.containsMouse || controlCenterPopup.powerOptionsExpanded ? Theme.error : Theme.surfaceText
|
color: powerButton.containsMouse || root.powerOptionsExpanded ? Theme.error : Theme.surfaceText
|
||||||
|
|
||||||
Behavior on text {
|
Behavior on text {
|
||||||
// Smooth icon transition
|
// Smooth icon transition
|
||||||
@@ -302,7 +309,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterPopup.powerOptionsExpanded = !controlCenterPopup.powerOptionsExpanded
|
root.powerOptionsExpanded = !root.powerOptionsExpanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,8 +345,8 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.controlCenterVisible = false
|
controlCenterVisible = false
|
||||||
root.settingsVisible = true
|
settingsPopup.settingsVisible = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,12 +363,12 @@ PanelWindow {
|
|||||||
// Animated Collapsible Power Options (optimized)
|
// Animated Collapsible Power Options (optimized)
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: controlCenterPopup.powerOptionsExpanded ? 60 : 0
|
height: root.powerOptionsExpanded ? 60 : 0
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.4)
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.4)
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: controlCenterPopup.powerOptionsExpanded ? 1 : 0
|
border.width: root.powerOptionsExpanded ? 1 : 0
|
||||||
opacity: controlCenterPopup.powerOptionsExpanded ? 1.0 : 0.0
|
opacity: root.powerOptionsExpanded ? 1.0 : 0.0
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
// Single coordinated animation for power options
|
// Single coordinated animation for power options
|
||||||
@@ -382,7 +389,7 @@ PanelWindow {
|
|||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
visible: controlCenterPopup.powerOptionsExpanded
|
visible: root.powerOptionsExpanded
|
||||||
|
|
||||||
// Logout
|
// Logout
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -421,11 +428,13 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterPopup.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
root.powerConfirmAction = "logout"
|
if (typeof root !== "undefined" && root.powerConfirmDialog) {
|
||||||
root.powerConfirmTitle = "Logout"
|
root.powerConfirmDialog.powerConfirmAction = "logout"
|
||||||
root.powerConfirmMessage = "Are you sure you want to logout?"
|
root.powerConfirmDialog.powerConfirmTitle = "Logout"
|
||||||
root.powerConfirmVisible = true
|
root.powerConfirmDialog.powerConfirmMessage = "Are you sure you want to logout?"
|
||||||
|
root.powerConfirmDialog.powerConfirmVisible = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,11 +483,13 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterPopup.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
root.powerConfirmAction = "reboot"
|
if (typeof root !== "undefined" && root.powerConfirmDialog) {
|
||||||
root.powerConfirmTitle = "Restart"
|
root.powerConfirmDialog.powerConfirmAction = "reboot"
|
||||||
root.powerConfirmMessage = "Are you sure you want to restart?"
|
root.powerConfirmDialog.powerConfirmTitle = "Restart"
|
||||||
root.powerConfirmVisible = true
|
root.powerConfirmDialog.powerConfirmMessage = "Are you sure you want to restart?"
|
||||||
|
root.powerConfirmDialog.powerConfirmVisible = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,11 +538,13 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterPopup.powerOptionsExpanded = false
|
root.powerOptionsExpanded = false
|
||||||
root.powerConfirmAction = "poweroff"
|
if (typeof root !== "undefined" && root.powerConfirmDialog) {
|
||||||
root.powerConfirmTitle = "Shutdown"
|
root.powerConfirmDialog.powerConfirmAction = "poweroff"
|
||||||
root.powerConfirmMessage = "Are you sure you want to shutdown?"
|
root.powerConfirmDialog.powerConfirmTitle = "Shutdown"
|
||||||
root.powerConfirmVisible = true
|
root.powerConfirmDialog.powerConfirmMessage = "Are you sure you want to shutdown?"
|
||||||
|
root.powerConfirmDialog.powerConfirmVisible = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,7 +592,7 @@ PanelWindow {
|
|||||||
width: (parent.width - Theme.spacingXS * (tabCount - 1)) / tabCount
|
width: (parent.width - Theme.spacingXS * (tabCount - 1)) / tabCount
|
||||||
height: 40
|
height: 40
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: controlCenterPopup.currentTab === modelData.id ?
|
color: root.currentTab === modelData.id ?
|
||||||
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) :
|
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) :
|
||||||
tabArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
|
tabArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
|
||||||
|
|
||||||
@@ -591,15 +604,15 @@ PanelWindow {
|
|||||||
text: modelData.icon
|
text: modelData.icon
|
||||||
font.family: Theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: Theme.iconSize - 4
|
font.pixelSize: Theme.iconSize - 4
|
||||||
color: controlCenterPopup.currentTab === modelData.id ? Theme.primary : Theme.surfaceText
|
color: root.currentTab === modelData.id ? Theme.primary : Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: modelData.name
|
text: modelData.name
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: controlCenterPopup.currentTab === modelData.id ? Theme.primary : Theme.surfaceText
|
color: root.currentTab === modelData.id ? Theme.primary : Theme.surfaceText
|
||||||
font.weight: controlCenterPopup.currentTab === modelData.id ? Font.Medium : Font.Normal
|
font.weight: root.currentTab === modelData.id ? Font.Medium : Font.Normal
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -611,7 +624,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterPopup.currentTab = modelData.id
|
root.currentTab = modelData.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,7 +642,7 @@ PanelWindow {
|
|||||||
// Tab content area
|
// Tab content area
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: controlCenterPopup.powerOptionsExpanded ? 240 : 300
|
height: root.powerOptionsExpanded ? 240 : 300
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.1)
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.1)
|
||||||
|
|
||||||
@@ -644,36 +657,29 @@ PanelWindow {
|
|||||||
NetworkTab {
|
NetworkTab {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
visible: controlCenterPopup.currentTab === "network"
|
visible: root.currentTab === "network"
|
||||||
|
|
||||||
wifiPasswordSSID: root.wifiPasswordSSID
|
|
||||||
wifiPasswordInput: root.wifiPasswordInput
|
|
||||||
wifiPasswordDialogVisible: root.wifiPasswordDialogVisible
|
|
||||||
|
|
||||||
onWifiAutoRefreshEnabledChanged: {
|
|
||||||
root.wifiAutoRefreshEnabled = wifiAutoRefreshEnabled
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio Tab
|
// Audio Tab
|
||||||
AudioTab {
|
AudioTab {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
visible: controlCenterPopup.currentTab === "audio"
|
visible: root.currentTab === "audio"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bluetooth Tab
|
// Bluetooth Tab
|
||||||
BluetoothTab {
|
BluetoothTab {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
visible: BluetoothService.available && controlCenterPopup.currentTab === "bluetooth"
|
visible: BluetoothService.available && root.currentTab === "bluetooth"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display Tab
|
// Display Tab
|
||||||
DisplayTab {
|
DisplayTab {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
visible: controlCenterPopup.currentTab === "display"
|
visible: root.currentTab === "display"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -685,7 +691,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: -1
|
z: -1
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.controlCenterVisible = false
|
controlCenterVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,11 +16,6 @@ Item {
|
|||||||
else return 1 // Default to WiFi when nothing is connected
|
else return 1 // Default to WiFi when nothing is connected
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expose properties that the parent needs to bind to
|
|
||||||
property bool wifiAutoRefreshEnabled: false
|
|
||||||
property string wifiPasswordSSID: ""
|
|
||||||
property string wifiPasswordInput: ""
|
|
||||||
property bool wifiPasswordDialogVisible: false
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -67,7 +62,7 @@ Item {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
networkTab.networkSubTab = 0
|
networkTab.networkSubTab = 0
|
||||||
networkTab.wifiAutoRefreshEnabled = false
|
WifiService.autoRefreshEnabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +103,7 @@ Item {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
networkTab.networkSubTab = 1
|
networkTab.networkSubTab = 1
|
||||||
networkTab.wifiAutoRefreshEnabled = true
|
WifiService.autoRefreshEnabled = true
|
||||||
if (NetworkService.wifiEnabled) {
|
if (NetworkService.wifiEnabled) {
|
||||||
WifiService.scanWifi()
|
WifiService.scanWifi()
|
||||||
}
|
}
|
||||||
@@ -795,9 +790,9 @@ Item {
|
|||||||
WifiService.connectToWifi(modelData.ssid)
|
WifiService.connectToWifi(modelData.ssid)
|
||||||
} else if (modelData.secured) {
|
} else if (modelData.secured) {
|
||||||
// Secured network, need password - use root dialog
|
// Secured network, need password - use root dialog
|
||||||
root.wifiPasswordSSID = modelData.ssid
|
wifiPasswordDialog.wifiPasswordSSID = modelData.ssid
|
||||||
root.wifiPasswordInput = ""
|
wifiPasswordDialog.wifiPasswordInput = ""
|
||||||
root.wifiPasswordDialogVisible = true
|
wifiPasswordDialog.wifiPasswordDialogVisible = true
|
||||||
} else {
|
} else {
|
||||||
// Open network, connect directly
|
// Open network, connect directly
|
||||||
WifiService.connectToWifi(modelData.ssid)
|
WifiService.connectToWifi(modelData.ssid)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ Rectangle {
|
|||||||
|
|
||||||
property bool showPercentage: true
|
property bool showPercentage: true
|
||||||
property bool showIcon: true
|
property bool showIcon: true
|
||||||
property var processDropdown: null
|
|
||||||
|
|
||||||
width: 55
|
width: 55
|
||||||
height: 30
|
height: 30
|
||||||
@@ -18,10 +17,6 @@ Rectangle {
|
|||||||
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) :
|
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) :
|
||||||
Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
|
Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
// CPU widget initialized
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: cpuArea
|
id: cpuArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -29,10 +24,8 @@ Rectangle {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (processDropdown) {
|
ProcessMonitorService.setSortBy("cpu")
|
||||||
ProcessMonitorService.setSortBy("cpu")
|
processListDropdown.toggle()
|
||||||
processDropdown.toggle()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: notificationHistoryPopup
|
id: root
|
||||||
|
|
||||||
property bool notificationHistoryVisible: false
|
property bool notificationHistoryVisible: false
|
||||||
signal closeRequested()
|
|
||||||
|
|
||||||
visible: notificationHistoryVisible
|
visible: notificationHistoryVisible
|
||||||
|
|
||||||
@@ -35,7 +34,7 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
closeRequested()
|
notificationHistoryVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ PanelWindow {
|
|||||||
transform: [
|
transform: [
|
||||||
Scale {
|
Scale {
|
||||||
id: scaleTransform
|
id: scaleTransform
|
||||||
origin.x: parent.width
|
origin.x: 400 // Use fixed width since popup is 400px wide
|
||||||
origin.y: 0
|
origin.y: 0
|
||||||
xScale: notificationHistoryVisible ? 1.0 : 0.95
|
xScale: notificationHistoryVisible ? 1.0 : 0.95
|
||||||
yScale: notificationHistoryVisible ? 1.0 : 0.8
|
yScale: notificationHistoryVisible ? 1.0 : 0.8
|
||||||
|
|||||||
@@ -7,9 +7,14 @@ import Quickshell.Io
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: powerConfirmDialog
|
id: root
|
||||||
|
|
||||||
visible: root.powerConfirmVisible
|
property bool powerConfirmVisible: false
|
||||||
|
property string powerConfirmAction: ""
|
||||||
|
property string powerConfirmTitle: ""
|
||||||
|
property string powerConfirmMessage: ""
|
||||||
|
|
||||||
|
visible: powerConfirmVisible
|
||||||
|
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: 300
|
implicitHeight: 300
|
||||||
@@ -43,8 +48,8 @@ PanelWindow {
|
|||||||
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
|
||||||
|
|
||||||
opacity: root.powerConfirmVisible ? 1.0 : 0.0
|
opacity: powerConfirmVisible ? 1.0 : 0.0
|
||||||
scale: root.powerConfirmVisible ? 1.0 : 0.9
|
scale: powerConfirmVisible ? 1.0 : 0.9
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -67,10 +72,10 @@ PanelWindow {
|
|||||||
|
|
||||||
// Title
|
// Title
|
||||||
Text {
|
Text {
|
||||||
text: root.powerConfirmTitle
|
text: powerConfirmTitle
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
color: {
|
color: {
|
||||||
switch(root.powerConfirmAction) {
|
switch(powerConfirmAction) {
|
||||||
case "poweroff": return Theme.error
|
case "poweroff": return Theme.error
|
||||||
case "reboot": return Theme.warning
|
case "reboot": return Theme.warning
|
||||||
default: return Theme.surfaceText
|
default: return Theme.surfaceText
|
||||||
@@ -83,7 +88,7 @@ PanelWindow {
|
|||||||
|
|
||||||
// Message
|
// Message
|
||||||
Text {
|
Text {
|
||||||
text: root.powerConfirmMessage
|
text: powerConfirmMessage
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -119,7 +124,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerConfirmVisible = false
|
powerConfirmVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +136,7 @@ PanelWindow {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
let baseColor
|
let baseColor
|
||||||
switch(root.powerConfirmAction) {
|
switch(powerConfirmAction) {
|
||||||
case "poweroff": baseColor = Theme.error; break
|
case "poweroff": baseColor = Theme.error; break
|
||||||
case "reboot": baseColor = Theme.warning; break
|
case "reboot": baseColor = Theme.warning; break
|
||||||
default: baseColor = Theme.primary; break
|
default: baseColor = Theme.primary; break
|
||||||
@@ -155,8 +160,8 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerConfirmVisible = false
|
powerConfirmVisible = false
|
||||||
executePowerAction(root.powerConfirmAction)
|
executePowerAction(powerConfirmAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ import Quickshell.Io
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: powerMenuPopup
|
id: root
|
||||||
|
|
||||||
visible: root.powerMenuVisible
|
property bool powerMenuVisible: false
|
||||||
|
|
||||||
|
visible: powerMenuVisible
|
||||||
|
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: 320
|
implicitHeight: 320
|
||||||
@@ -31,7 +33,7 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +47,8 @@ PanelWindow {
|
|||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
opacity: root.powerMenuVisible ? 1.0 : 0.0
|
opacity: powerMenuVisible ? 1.0 : 0.0
|
||||||
scale: root.powerMenuVisible ? 1.0 : 0.85
|
scale: powerMenuVisible ? 1.0 : 0.85
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -109,7 +111,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,7 +158,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "logout"
|
root.powerConfirmAction = "logout"
|
||||||
root.powerConfirmTitle = "Log Out"
|
root.powerConfirmTitle = "Log Out"
|
||||||
root.powerConfirmMessage = "Are you sure you want to log out?"
|
root.powerConfirmMessage = "Are you sure you want to log out?"
|
||||||
@@ -201,7 +203,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "suspend"
|
root.powerConfirmAction = "suspend"
|
||||||
root.powerConfirmTitle = "Suspend"
|
root.powerConfirmTitle = "Suspend"
|
||||||
root.powerConfirmMessage = "Are you sure you want to suspend the system?"
|
root.powerConfirmMessage = "Are you sure you want to suspend the system?"
|
||||||
@@ -246,7 +248,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "reboot"
|
root.powerConfirmAction = "reboot"
|
||||||
root.powerConfirmTitle = "Reboot"
|
root.powerConfirmTitle = "Reboot"
|
||||||
root.powerConfirmMessage = "Are you sure you want to reboot the system?"
|
root.powerConfirmMessage = "Are you sure you want to reboot the system?"
|
||||||
@@ -291,7 +293,7 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.powerMenuVisible = false
|
powerMenuVisible = false
|
||||||
root.powerConfirmAction = "poweroff"
|
root.powerConfirmAction = "poweroff"
|
||||||
root.powerConfirmTitle = "Power Off"
|
root.powerConfirmTitle = "Power Off"
|
||||||
root.powerConfirmMessage = "Are you sure you want to power off the system?"
|
root.powerConfirmMessage = "Are you sure you want to power off the system?"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: processDropdown
|
id: processListDropdown
|
||||||
|
|
||||||
property bool isVisible: false
|
property bool isVisible: false
|
||||||
property var parentWidget: null
|
property var parentWidget: null
|
||||||
@@ -41,7 +41,7 @@ PanelWindow {
|
|||||||
// Click outside to close
|
// Click outside to close
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: processDropdown.hide()
|
onClicked: processListDropdown.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -63,8 +63,8 @@ PanelWindow {
|
|||||||
id: scaleTransform
|
id: scaleTransform
|
||||||
origin.x: parent.width * 0.85 // Scale from top-right
|
origin.x: parent.width * 0.85 // Scale from top-right
|
||||||
origin.y: 0
|
origin.y: 0
|
||||||
xScale: processDropdown.isVisible ? 1.0 : 0.95
|
xScale: processListDropdown.isVisible ? 1.0 : 0.95
|
||||||
yScale: processDropdown.isVisible ? 1.0 : 0.8
|
yScale: processListDropdown.isVisible ? 1.0 : 0.8
|
||||||
|
|
||||||
Behavior on xScale {
|
Behavior on xScale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -82,8 +82,8 @@ PanelWindow {
|
|||||||
},
|
},
|
||||||
Translate {
|
Translate {
|
||||||
id: translateTransform
|
id: translateTransform
|
||||||
x: processDropdown.isVisible ? 0 : 20
|
x: processListDropdown.isVisible ? 0 : 20
|
||||||
y: processDropdown.isVisible ? 0 : -30
|
y: processListDropdown.isVisible ? 0 : -30
|
||||||
|
|
||||||
Behavior on x {
|
Behavior on x {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -101,7 +101,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
opacity: processDropdown.isVisible ? 1.0 : 0.0
|
opacity: processListDropdown.isVisible ? 1.0 : 0.0
|
||||||
|
|
||||||
// Add shadow effect
|
// Add shadow effect
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
@@ -111,7 +111,7 @@ PanelWindow {
|
|||||||
shadowVerticalOffset: 8
|
shadowVerticalOffset: 8
|
||||||
shadowBlur: 1.0
|
shadowBlur: 1.0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.15)
|
shadowColor: Qt.rgba(0, 0, 0, 0.15)
|
||||||
shadowOpacity: processDropdown.isVisible ? 0.15 : 0
|
shadowOpacity: processListDropdown.isVisible ? 0.15 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ Rectangle {
|
|||||||
|
|
||||||
property bool showPercentage: true
|
property bool showPercentage: true
|
||||||
property bool showIcon: true
|
property bool showIcon: true
|
||||||
property var processDropdown: null
|
|
||||||
|
|
||||||
width: 55
|
width: 55
|
||||||
height: 30
|
height: 30
|
||||||
@@ -18,10 +17,6 @@ Rectangle {
|
|||||||
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) :
|
Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) :
|
||||||
Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
|
Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
// RAM widget initialized
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: ramArea
|
id: ramArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -29,10 +24,8 @@ Rectangle {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (processDropdown) {
|
ProcessMonitorService.setSortBy("memory")
|
||||||
ProcessMonitorService.setSortBy("memory")
|
processListDropdown.toggle()
|
||||||
processDropdown.toggle()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: themePicker
|
id: themePicker
|
||||||
@@ -198,7 +199,7 @@ Column {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
color: {
|
color: {
|
||||||
if (root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing") {
|
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") {
|
||||||
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
||||||
} else {
|
} else {
|
||||||
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
@@ -206,7 +207,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
border.color: {
|
border.color: {
|
||||||
if (root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing") {
|
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") {
|
||||||
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.5)
|
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.5)
|
||||||
} else if (Theme.isDynamicTheme) {
|
} else if (Theme.isDynamicTheme) {
|
||||||
return Theme.primary
|
return Theme.primary
|
||||||
@@ -223,13 +224,13 @@ Column {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: {
|
text: {
|
||||||
if (root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing") return "error"
|
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") return "error"
|
||||||
else return "palette"
|
else return "palette"
|
||||||
}
|
}
|
||||||
font.family: Theme.iconFont
|
font.family: Theme.iconFont
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: {
|
color: {
|
||||||
if (root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing") return Theme.error
|
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") return Theme.error
|
||||||
else return Theme.surfaceText
|
else return Theme.surfaceText
|
||||||
}
|
}
|
||||||
font.weight: Theme.iconFontWeight
|
font.weight: Theme.iconFontWeight
|
||||||
@@ -238,13 +239,13 @@ Column {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: {
|
text: {
|
||||||
if (root.wallpaperErrorStatus === "error") return "Error"
|
if (ToastService.wallpaperErrorStatus === "error") return "Error"
|
||||||
else if (root.wallpaperErrorStatus === "matugen_missing") return "No matugen"
|
else if (ToastService.wallpaperErrorStatus === "matugen_missing") return "No matugen"
|
||||||
else return "Auto"
|
else return "Auto"
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: {
|
color: {
|
||||||
if (root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing") return Theme.error
|
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") return Theme.error
|
||||||
else return Theme.surfaceText
|
else return Theme.surfaceText
|
||||||
}
|
}
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
@@ -297,21 +298,21 @@ Column {
|
|||||||
anchors.bottom: parent.top
|
anchors.bottom: parent.top
|
||||||
anchors.bottomMargin: Theme.spacingS
|
anchors.bottomMargin: Theme.spacingS
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: autoMouseArea.containsMouse && (!Theme.isDynamicTheme || root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing")
|
visible: autoMouseArea.containsMouse && (!Theme.isDynamicTheme || ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: autoTooltipText
|
id: autoTooltipText
|
||||||
text: {
|
text: {
|
||||||
if (root.wallpaperErrorStatus === "error") {
|
if (ToastService.wallpaperErrorStatus === "error") {
|
||||||
return "Wallpaper symlink missing at ~/quickshell/current_wallpaper"
|
return "Wallpaper symlink missing at ~/quickshell/current_wallpaper"
|
||||||
} else if (root.wallpaperErrorStatus === "matugen_missing") {
|
} else if (ToastService.wallpaperErrorStatus === "matugen_missing") {
|
||||||
return "Install matugen package for dynamic themes"
|
return "Install matugen package for dynamic themes"
|
||||||
} else {
|
} else {
|
||||||
return "Dynamic wallpaper-based colors"
|
return "Dynamic wallpaper-based colors"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: (root.wallpaperErrorStatus === "error" || root.wallpaperErrorStatus === "matugen_missing") ? Theme.error : Theme.surfaceText
|
color: (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") ? Theme.error : Theme.surfaceText
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: Math.min(implicitWidth, 250)
|
width: Math.min(implicitWidth, 250)
|
||||||
|
|||||||
125
Widgets/ToastWidget.qml
Normal file
125
Widgets/ToastWidget.qml
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
visible: ToastService.toastVisible
|
||||||
|
|
||||||
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
|
WlrLayershell.exclusiveZone: -1
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Makes the background transparent to mouse events
|
||||||
|
mask: Region {
|
||||||
|
item: toast
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: toast
|
||||||
|
width: Math.min(400, Screen.width - Theme.spacingL * 2)
|
||||||
|
height: toastContent.height + Theme.spacingL * 2
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
y: Theme.barHeight + Theme.spacingL
|
||||||
|
|
||||||
|
color: {
|
||||||
|
switch (ToastService.currentLevel) {
|
||||||
|
case ToastService.levelError: return Theme.error
|
||||||
|
case ToastService.levelWarn: return Theme.warning
|
||||||
|
case ToastService.levelInfo: return Theme.primary
|
||||||
|
default: return Theme.primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
radius: Theme.cornerRadiusLarge
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
shadowEnabled: true
|
||||||
|
shadowHorizontalOffset: 0
|
||||||
|
shadowVerticalOffset: 4
|
||||||
|
shadowBlur: 0.8
|
||||||
|
shadowColor: Qt.rgba(0, 0, 0, 0.3)
|
||||||
|
shadowOpacity: 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
opacity: ToastService.toastVisible ? 0.9 : 0.0
|
||||||
|
scale: ToastService.toastVisible ? 1.0 : 0.9
|
||||||
|
|
||||||
|
transform: Translate {
|
||||||
|
y: ToastService.toastVisible ? 0 : -20
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.mediumDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: toastContent
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: {
|
||||||
|
switch (ToastService.currentLevel) {
|
||||||
|
case ToastService.levelError: return "error"
|
||||||
|
case ToastService.levelWarn: return "warning"
|
||||||
|
case ToastService.levelInfo: return "info"
|
||||||
|
default: return "info"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
font.family: Theme.iconFont
|
||||||
|
font.pixelSize: Theme.iconSize
|
||||||
|
color: Theme.background
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: ToastService.currentMessage
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.background
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: Math.min(implicitWidth, 300)
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: ToastService.hideToast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ import qs.Widgets
|
|||||||
import "../../Common/Utilities.js" as Utils
|
import "../../Common/Utilities.js" as Utils
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: topBar
|
id: root
|
||||||
|
|
||||||
property var modelData
|
property var modelData
|
||||||
screen: modelData
|
screen: modelData
|
||||||
@@ -26,31 +26,16 @@ PanelWindow {
|
|||||||
Connections {
|
Connections {
|
||||||
target: Prefs
|
target: Prefs
|
||||||
function onTopBarTransparencyChanged() {
|
function onTopBarTransparencyChanged() {
|
||||||
topBar.backgroundTransparency = Prefs.topBarTransparency
|
root.backgroundTransparency = Prefs.topBarTransparency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties exposed to shell
|
|
||||||
|
|
||||||
// Shell reference to access root properties directly
|
|
||||||
property var shellRoot: null
|
|
||||||
|
|
||||||
// Notification properties
|
// Notification properties
|
||||||
property int notificationCount: 0
|
readonly property int notificationCount: NotificationService.notifications.length
|
||||||
|
|
||||||
// Process dropdown reference
|
|
||||||
property var processDropdown: null
|
|
||||||
|
|
||||||
|
|
||||||
// Clipboard properties
|
|
||||||
signal clipboardRequested()
|
|
||||||
|
|
||||||
// Tray menu properties
|
|
||||||
property bool showTrayMenu: false
|
|
||||||
property var currentTrayMenu: null
|
|
||||||
property var currentTrayItem: null
|
|
||||||
property real trayMenuX: 0
|
|
||||||
property real trayMenuY: 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -83,7 +68,7 @@ PanelWindow {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Theme.cornerRadiusXLarge
|
radius: Theme.cornerRadiusXLarge
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, topBar.backgroundTransparency)
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, root.backgroundTransparency)
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
@@ -146,7 +131,7 @@ PanelWindow {
|
|||||||
|
|
||||||
WorkspaceSwitcher {
|
WorkspaceSwitcher {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
screenName: topBar.screenName
|
screenName: root.screenName
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusedAppWidget {
|
FocusedAppWidget {
|
||||||
@@ -160,9 +145,7 @@ PanelWindow {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
onClockClicked: {
|
onClockClicked: {
|
||||||
if (topBar.shellRoot) {
|
centerCommandCenter.calendarVisible = !centerCommandCenter.calendarVisible
|
||||||
topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,9 +156,7 @@ PanelWindow {
|
|||||||
visible: Prefs.showMusic && MprisController.activePlayer
|
visible: Prefs.showMusic && MprisController.activePlayer
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (topBar.shellRoot) {
|
centerCommandCenter.calendarVisible = !centerCommandCenter.calendarVisible
|
||||||
topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,9 +169,7 @@ PanelWindow {
|
|||||||
visible: Prefs.showWeather && WeatherService.weather.available && WeatherService.weather.temp > 0 && WeatherService.weather.tempF > 0
|
visible: Prefs.showWeather && WeatherService.weather.available && WeatherService.weather.temp > 0 && WeatherService.weather.tempF > 0
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (topBar.shellRoot) {
|
centerCommandCenter.calendarVisible = !centerCommandCenter.calendarVisible
|
||||||
topBar.shellRoot.calendarVisible = !topBar.shellRoot.calendarVisible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,13 +184,11 @@ PanelWindow {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: Prefs.showSystemTray
|
visible: Prefs.showSystemTray
|
||||||
onMenuRequested: (menu, item, x, y) => {
|
onMenuRequested: (menu, item, x, y) => {
|
||||||
if (topBar.shellRoot) {
|
trayMenuPopup.currentTrayMenu = menu
|
||||||
topBar.shellRoot.currentTrayMenu = menu
|
trayMenuPopup.currentTrayItem = item
|
||||||
topBar.shellRoot.currentTrayItem = item
|
trayMenuPopup.trayMenuX = rightSection.x + rightSection.width - 400 - Theme.spacingL
|
||||||
topBar.shellRoot.trayMenuX = rightSection.x + rightSection.width - 400 - Theme.spacingL
|
trayMenuPopup.trayMenuY = Theme.barHeight - Theme.spacingXS
|
||||||
topBar.shellRoot.trayMenuY = Theme.barHeight - Theme.spacingXS
|
trayMenuPopup.showTrayMenu = true
|
||||||
topBar.shellRoot.showTrayMenu = true
|
|
||||||
}
|
|
||||||
menu.menuVisible = true
|
menu.menuVisible = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,7 +217,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
topBar.clipboardRequested()
|
clipboardHistoryPopup.toggle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,48 +233,42 @@ PanelWindow {
|
|||||||
CpuMonitorWidget {
|
CpuMonitorWidget {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: Prefs.showSystemResources
|
visible: Prefs.showSystemResources
|
||||||
processDropdown: topBar.processDropdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RamMonitorWidget {
|
RamMonitorWidget {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: Prefs.showSystemResources
|
visible: Prefs.showSystemResources
|
||||||
processDropdown: topBar.processDropdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationCenterButton {
|
NotificationCenterButton {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
hasUnread: topBar.notificationCount > 0
|
hasUnread: root.notificationCount > 0
|
||||||
isActive: topBar.shellRoot ? topBar.shellRoot.notificationHistoryVisible : false
|
isActive: notificationCenter.notificationHistoryVisible
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (topBar.shellRoot) {
|
notificationCenter.notificationHistoryVisible = !notificationCenter.notificationHistoryVisible
|
||||||
topBar.shellRoot.notificationHistoryVisible = !topBar.shellRoot.notificationHistoryVisible
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Battery Widget
|
// Battery Widget
|
||||||
BatteryWidget {
|
BatteryWidget {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
batteryPopupVisible: topBar.shellRoot.batteryPopupVisible
|
batteryPopupVisible: batteryControlPopup.batteryPopupVisible
|
||||||
onToggleBatteryPopup: {
|
onToggleBatteryPopup: {
|
||||||
topBar.shellRoot.batteryPopupVisible = !topBar.shellRoot.batteryPopupVisible
|
batteryControlPopup.batteryPopupVisible = !batteryControlPopup.batteryPopupVisible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlCenterButton {
|
ControlCenterButton {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
isActive: topBar.shellRoot ? topBar.shellRoot.controlCenterVisible : false
|
isActive: controlCenterPopup.controlCenterVisible
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (topBar.shellRoot) {
|
controlCenterPopup.controlCenterVisible = !controlCenterPopup.controlCenterVisible
|
||||||
topBar.shellRoot.controlCenterVisible = !topBar.shellRoot.controlCenterVisible
|
if (controlCenterPopup.controlCenterVisible) {
|
||||||
if (topBar.shellRoot.controlCenterVisible) {
|
if (NetworkService.wifiEnabled) {
|
||||||
if (NetworkService.wifiEnabled) {
|
WifiService.scanWifi()
|
||||||
WifiService.scanWifi()
|
|
||||||
}
|
|
||||||
// Bluetooth devices are automatically updated via signals
|
|
||||||
}
|
}
|
||||||
|
// Bluetooth devices are automatically updated via signals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,15 @@ import Quickshell.Wayland
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: trayMenuPopup
|
id: root
|
||||||
|
|
||||||
visible: root.showTrayMenu
|
property bool showTrayMenu: false
|
||||||
|
property real trayMenuX: 0
|
||||||
|
property real trayMenuY: 0
|
||||||
|
property var currentTrayMenu: null
|
||||||
|
property var currentTrayItem: null
|
||||||
|
|
||||||
|
visible: showTrayMenu
|
||||||
|
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
@@ -25,8 +31,8 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: menuContainer
|
id: menuContainer
|
||||||
x: root.trayMenuX
|
x: trayMenuX
|
||||||
y: root.trayMenuY
|
y: trayMenuY
|
||||||
width: Math.max(180, Math.min(300, menuList.maxTextWidth + Theme.spacingL * 2))
|
width: Math.max(180, Math.min(300, menuList.maxTextWidth + Theme.spacingL * 2))
|
||||||
height: Math.max(60, menuList.contentHeight + Theme.spacingS * 2)
|
height: Math.max(60, menuList.contentHeight + Theme.spacingS * 2)
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
@@ -47,8 +53,8 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Material 3 animations
|
// Material 3 animations
|
||||||
opacity: root.showTrayMenu ? 1.0 : 0.0
|
opacity: showTrayMenu ? 1.0 : 0.0
|
||||||
scale: root.showTrayMenu ? 1.0 : 0.85
|
scale: showTrayMenu ? 1.0 : 0.85
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -70,7 +76,7 @@ PanelWindow {
|
|||||||
|
|
||||||
QsMenuOpener {
|
QsMenuOpener {
|
||||||
id: menuOpener
|
id: menuOpener
|
||||||
menu: root.currentTrayItem ? root.currentTrayItem.menu : null
|
menu: currentTrayItem ? currentTrayItem.menu : null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom menu styling using ListView
|
// Custom menu styling using ListView
|
||||||
@@ -151,7 +157,7 @@ PanelWindow {
|
|||||||
if (modelData.triggered) {
|
if (modelData.triggered) {
|
||||||
modelData.triggered()
|
modelData.triggered()
|
||||||
}
|
}
|
||||||
root.showTrayMenu = false
|
showTrayMenu = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +177,7 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: -1
|
z: -1
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.showTrayMenu = false
|
showTrayMenu = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,9 +7,13 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: wifiPasswordDialog
|
id: root
|
||||||
|
|
||||||
visible: root.wifiPasswordDialogVisible
|
property bool wifiPasswordDialogVisible: false
|
||||||
|
property string wifiPasswordSSID: ""
|
||||||
|
property string wifiPasswordInput: ""
|
||||||
|
|
||||||
|
visible: wifiPasswordDialogVisible
|
||||||
anchors {
|
anchors {
|
||||||
top: true
|
top: true
|
||||||
left: true
|
left: true
|
||||||
@@ -19,7 +23,7 @@ PanelWindow {
|
|||||||
|
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
WlrLayershell.keyboardFocus: root.wifiPasswordDialogVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: wifiPasswordDialogVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
@@ -32,7 +36,7 @@ PanelWindow {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Qt.rgba(0, 0, 0, 0.5)
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
opacity: root.wifiPasswordDialogVisible ? 1.0 : 0.0
|
opacity: wifiPasswordDialogVisible ? 1.0 : 0.0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -44,8 +48,8 @@ PanelWindow {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.wifiPasswordDialogVisible = false
|
wifiPasswordDialogVisible = false
|
||||||
root.wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,8 +63,8 @@ PanelWindow {
|
|||||||
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
|
||||||
|
|
||||||
opacity: root.wifiPasswordDialogVisible ? 1.0 : 0.0
|
opacity: wifiPasswordDialogVisible ? 1.0 : 0.0
|
||||||
scale: root.wifiPasswordDialogVisible ? 1.0 : 0.9
|
scale: wifiPasswordDialogVisible ? 1.0 : 0.9
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -97,7 +101,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: "Enter password for \"" + root.wifiPasswordSSID + "\""
|
text: "Enter password for \"" + wifiPasswordSSID + "\""
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -125,8 +129,8 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.wifiPasswordDialogVisible = false
|
wifiPasswordDialogVisible = false
|
||||||
root.wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,15 +166,15 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
root.wifiPasswordInput = text
|
wifiPasswordInput = text
|
||||||
}
|
}
|
||||||
|
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
WifiService.connectToWifiWithPassword(root.wifiPasswordSSID, root.wifiPasswordInput)
|
WifiService.connectToWifiWithPassword(wifiPasswordSSID, wifiPasswordInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (root.wifiPasswordDialogVisible) {
|
if (wifiPasswordDialogVisible) {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,8 +264,8 @@ PanelWindow {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.wifiPasswordDialogVisible = false
|
wifiPasswordDialogVisible = false
|
||||||
root.wifiPasswordInput = ""
|
wifiPasswordInput = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,7 +275,7 @@ PanelWindow {
|
|||||||
height: 36
|
height: 36
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: connectArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
|
color: connectArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
|
||||||
enabled: root.wifiPasswordInput.length > 0
|
enabled: wifiPasswordInput.length > 0
|
||||||
opacity: enabled ? 1.0 : 0.5
|
opacity: enabled ? 1.0 : 0.5
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
@@ -290,7 +294,7 @@ PanelWindow {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: parent.enabled
|
enabled: parent.enabled
|
||||||
onClicked: {
|
onClicked: {
|
||||||
WifiService.connectToWifiWithPassword(root.wifiPasswordSSID, root.wifiPasswordInput)
|
WifiService.connectToWifiWithPassword(wifiPasswordSSID, wifiPasswordInput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
187
shell.qml
187
shell.qml
@@ -1,161 +1,51 @@
|
|||||||
//@ pragma UseQApplication
|
//@ pragma UseQApplication
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Effects
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import Quickshell.Io
|
|
||||||
import Quickshell.Services.SystemTray
|
|
||||||
import Quickshell.Services.Notifications
|
|
||||||
import Quickshell.Services.Mpris
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Widgets.CenterCommandCenter
|
import qs.Widgets.CenterCommandCenter
|
||||||
import qs.Widgets.ControlCenter
|
import qs.Widgets.ControlCenter
|
||||||
import qs.Widgets.TopBar
|
import qs.Widgets.TopBar
|
||||||
import qs.Common
|
|
||||||
import "./Common/Utilities.js" as Utils
|
|
||||||
|
|
||||||
ShellRoot {
|
ShellRoot {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
// Make root accessible to Theme singleton for error handling
|
|
||||||
Theme.rootObj = root
|
|
||||||
|
|
||||||
// Initialize service monitoring states based on preferences
|
|
||||||
SystemMonitorService.enableTopBarMonitoring(Prefs.showSystemResources)
|
|
||||||
ProcessMonitorService.enableMonitoring(false) // Start disabled, enable when process dropdown is opened
|
|
||||||
// Audio service auto-updates devices, no manual scanning needed
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool calendarVisible: false
|
|
||||||
property bool showTrayMenu: false
|
|
||||||
property real trayMenuX: 0
|
|
||||||
property real trayMenuY: 0
|
|
||||||
property var currentTrayMenu: null
|
|
||||||
property var currentTrayItem: null
|
|
||||||
property bool notificationHistoryVisible: false
|
|
||||||
property bool mediaPlayerVisible: false
|
|
||||||
property bool hasActiveMedia: MprisController.active && (MprisController.active.trackTitle || MprisController.active.trackArtist)
|
|
||||||
property bool controlCenterVisible: false
|
|
||||||
|
|
||||||
property bool batteryPopupVisible: false
|
|
||||||
property bool powerMenuVisible: false
|
|
||||||
property bool powerConfirmVisible: false
|
|
||||||
property string powerConfirmAction: ""
|
|
||||||
property string powerConfirmTitle: ""
|
|
||||||
property string powerConfirmMessage: ""
|
|
||||||
property bool settingsVisible: false
|
|
||||||
|
|
||||||
|
|
||||||
// WiFi password dialog
|
|
||||||
property bool wifiPasswordDialogVisible: false
|
|
||||||
property string wifiPasswordSSID: ""
|
|
||||||
property string wifiPasswordInput: ""
|
|
||||||
property bool wifiAutoRefreshEnabled: false
|
|
||||||
|
|
||||||
// Wallpaper error status
|
|
||||||
property string wallpaperErrorStatus: ""
|
|
||||||
|
|
||||||
|
|
||||||
// Screen size breakpoints for responsive design
|
|
||||||
property real screenWidth: Screen.width
|
|
||||||
property bool isSmallScreen: screenWidth < 1200
|
|
||||||
property bool isMediumScreen: screenWidth >= 1200 && screenWidth < 1600
|
|
||||||
property bool isLargeScreen: screenWidth >= 1600
|
|
||||||
|
|
||||||
|
|
||||||
// Weather configuration
|
|
||||||
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: wifiAutoRefreshTimer
|
|
||||||
interval: 20000
|
|
||||||
running: root.wifiAutoRefreshEnabled && root.controlCenterVisible
|
|
||||||
repeat: true
|
|
||||||
onTriggered: {
|
|
||||||
if (root.wifiAutoRefreshEnabled && root.controlCenterVisible && NetworkService.wifiEnabled) {
|
|
||||||
WifiService.scanWifi()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WiFi Connection Status Timer
|
|
||||||
Timer {
|
|
||||||
id: wifiConnectionStatusTimer
|
|
||||||
interval: 3000 // 3 seconds
|
|
||||||
running: false
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
root.wifiConnectionStatus = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wallpaper Error Status Timer
|
|
||||||
Timer {
|
|
||||||
id: wallpaperErrorTimer
|
|
||||||
interval: 5000 // 5 seconds
|
|
||||||
running: false
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
root.wallpaperErrorStatus = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to show wallpaper error
|
|
||||||
function showWallpaperError() {
|
|
||||||
console.log("showWallpaperError called - setting error status")
|
|
||||||
root.wallpaperErrorStatus = "error"
|
|
||||||
wallpaperErrorTimer.restart()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Multi-monitor support using Variants
|
// Multi-monitor support using Variants
|
||||||
Variants {
|
Variants {
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
delegate: TopBar {
|
delegate: TopBar {
|
||||||
modelData: item
|
modelData: item
|
||||||
|
|
||||||
// Connect shell properties
|
|
||||||
shellRoot: root
|
|
||||||
notificationCount: NotificationService.notifications.length
|
|
||||||
processDropdown: processListDropdown
|
|
||||||
|
|
||||||
// Connect tray menu properties
|
|
||||||
showTrayMenu: root.showTrayMenu
|
|
||||||
currentTrayMenu: root.currentTrayMenu
|
|
||||||
currentTrayItem: root.currentTrayItem
|
|
||||||
trayMenuX: root.trayMenuX
|
|
||||||
trayMenuY: root.trayMenuY
|
|
||||||
|
|
||||||
// Connect clipboard
|
|
||||||
onClipboardRequested: {
|
|
||||||
clipboardHistoryPopup.toggle()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global popup windows
|
// Global popup windows
|
||||||
CenterCommandCenter {}
|
CenterCommandCenter {
|
||||||
TrayMenuPopup {}
|
id: centerCommandCenter
|
||||||
|
}
|
||||||
|
TrayMenuPopup {
|
||||||
|
id: trayMenuPopup
|
||||||
|
}
|
||||||
NotificationInit {}
|
NotificationInit {}
|
||||||
NotificationCenter {
|
NotificationCenter {
|
||||||
notificationHistoryVisible: root.notificationHistoryVisible
|
id: notificationCenter
|
||||||
onCloseRequested: {
|
}
|
||||||
root.notificationHistoryVisible = false
|
ControlCenterPopup {
|
||||||
}
|
id: controlCenterPopup
|
||||||
|
}
|
||||||
|
WifiPasswordDialog {
|
||||||
|
id: wifiPasswordDialog
|
||||||
}
|
}
|
||||||
ControlCenterPopup {}
|
|
||||||
WifiPasswordDialog {}
|
|
||||||
InputDialog {
|
InputDialog {
|
||||||
id: globalInputDialog
|
id: globalInputDialog
|
||||||
}
|
}
|
||||||
BatteryControlPopup {}
|
BatteryControlPopup {
|
||||||
PowerMenuPopup {}
|
id: batteryControlPopup
|
||||||
PowerConfirmDialog {}
|
}
|
||||||
|
PowerMenuPopup {
|
||||||
|
id: powerMenuPopup
|
||||||
|
}
|
||||||
|
PowerConfirmDialog {
|
||||||
|
id: powerConfirmDialog
|
||||||
|
}
|
||||||
|
|
||||||
ProcessListDropdown {
|
ProcessListDropdown {
|
||||||
id: processListDropdown
|
id: processListDropdown
|
||||||
@@ -163,24 +53,6 @@ ShellRoot {
|
|||||||
|
|
||||||
SettingsPopup {
|
SettingsPopup {
|
||||||
id: settingsPopup
|
id: settingsPopup
|
||||||
settingsVisible: root.settingsVisible
|
|
||||||
|
|
||||||
// Use a more direct approach for two-way binding
|
|
||||||
onSettingsVisibleChanged: {
|
|
||||||
if (settingsVisible !== root.settingsVisible) {
|
|
||||||
root.settingsVisible = settingsVisible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also listen to root changes
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onSettingsVisibleChanged() {
|
|
||||||
if (settingsPopup.settingsVisible !== root.settingsVisible) {
|
|
||||||
settingsPopup.settingsVisible = root.settingsVisible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Application and clipboard components
|
// Application and clipboard components
|
||||||
@@ -200,17 +72,8 @@ ShellRoot {
|
|||||||
id: clipboardHistoryPopup
|
id: clipboardHistoryPopup
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcHandler {
|
ToastWidget {
|
||||||
target: "wallpaper"
|
id: toastWidget
|
||||||
|
|
||||||
function refresh() {
|
|
||||||
console.log("Wallpaper IPC: refresh() called")
|
|
||||||
// Trigger color extraction if using dynamic theme
|
|
||||||
if (typeof Theme !== "undefined" && Theme.isDynamicTheme) {
|
|
||||||
console.log("Triggering color extraction due to wallpaper IPC")
|
|
||||||
Colors.extractColors()
|
|
||||||
}
|
|
||||||
return "WALLPAPER_REFRESH_SUCCESS"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user