mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
831 lines
25 KiB
QML
831 lines
25 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Effects
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Services.Mpris
|
|
import Quickshell.Services.Notifications
|
|
import Quickshell.Services.SystemTray
|
|
import Quickshell.Wayland
|
|
import Quickshell.Widgets
|
|
import qs.Common
|
|
import qs.Modules
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
PanelWindow {
|
|
id: root
|
|
|
|
property var modelData
|
|
property string screenName: modelData.name
|
|
property real backgroundTransparency: SettingsData.topBarTransparency
|
|
readonly property int notificationCount: NotificationService.notifications.length
|
|
|
|
screen: modelData
|
|
implicitHeight: Theme.barHeight - 4
|
|
color: "transparent"
|
|
Component.onCompleted: {
|
|
let fonts = Qt.fontFamilies()
|
|
if (fonts.indexOf("Material Symbols Rounded") === -1)
|
|
ToastService.showError(
|
|
"Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions")
|
|
|
|
SettingsData.forceTopBarLayoutRefresh.connect(function () {
|
|
Qt.callLater(() => {
|
|
leftSection.visible = false
|
|
centerSection.visible = false
|
|
rightSection.visible = false
|
|
Qt.callLater(() => {
|
|
leftSection.visible = true
|
|
centerSection.visible = true
|
|
rightSection.visible = true
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
Connections {
|
|
function onTopBarTransparencyChanged() {
|
|
root.backgroundTransparency = SettingsData.topBarTransparency
|
|
}
|
|
|
|
target: SettingsData
|
|
}
|
|
|
|
Connections {
|
|
target: root.screen
|
|
function onGeometryChanged() {
|
|
// Re-layout center widgets when screen geometry changes
|
|
if (centerSection && centerSection.width > 0) {
|
|
Qt.callLater(centerSection.updateLayout)
|
|
}
|
|
}
|
|
}
|
|
|
|
QtObject {
|
|
id: notificationHistory
|
|
|
|
property int count: 0
|
|
}
|
|
|
|
anchors {
|
|
top: true
|
|
left: true
|
|
right: true
|
|
}
|
|
|
|
Item {
|
|
anchors.fill: parent
|
|
anchors.margins: 2
|
|
anchors.topMargin: 6
|
|
anchors.bottomMargin: 0
|
|
anchors.leftMargin: 8
|
|
anchors.rightMargin: 8
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: Theme.cornerRadius
|
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g,
|
|
Theme.surfaceContainer.b, root.backgroundTransparency)
|
|
layer.enabled: true
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
border.color: Theme.outlineMedium
|
|
border.width: 1
|
|
radius: parent.radius
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g,
|
|
Theme.surfaceTint.b, 0.04)
|
|
radius: parent.radius
|
|
|
|
SequentialAnimation on opacity {
|
|
running: false
|
|
loops: Animation.Infinite
|
|
|
|
NumberAnimation {
|
|
to: 0.08
|
|
duration: Theme.extraLongDuration
|
|
easing.type: Theme.standardEasing
|
|
}
|
|
|
|
NumberAnimation {
|
|
to: 0.02
|
|
duration: Theme.extraLongDuration
|
|
easing.type: Theme.standardEasing
|
|
}
|
|
}
|
|
}
|
|
|
|
layer.effect: MultiEffect {
|
|
shadowEnabled: true
|
|
shadowHorizontalOffset: 0
|
|
shadowVerticalOffset: 4
|
|
shadowBlur: 0.5 // radius/32, adjusted for visual match
|
|
shadowColor: Qt.rgba(0, 0, 0, 0.15)
|
|
shadowOpacity: 0.15
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: topBarContent
|
|
|
|
readonly property int availableWidth: width
|
|
readonly property int launcherButtonWidth: 40
|
|
readonly property int workspaceSwitcherWidth: 120 // Approximate
|
|
readonly property int focusedAppMaxWidth: 456 // Fixed width since we don't have focusedApp reference
|
|
readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth
|
|
+ focusedAppMaxWidth + (Theme.spacingXS * 2)
|
|
readonly property int rightSectionWidth: rightSection.width
|
|
readonly property int clockWidth: 120 // Approximate clock width
|
|
readonly property int mediaMaxWidth: 280 // Normal max width
|
|
readonly property int weatherWidth: 80 // Approximate weather width
|
|
readonly property bool validLayout: availableWidth > 100
|
|
&& estimatedLeftSectionWidth > 0
|
|
&& rightSectionWidth > 0
|
|
readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2
|
|
readonly property int clockRightEdge: clockLeftEdge + clockWidth
|
|
readonly property int leftSectionRightEdge: estimatedLeftSectionWidth
|
|
readonly property int mediaLeftEdge: clockLeftEdge - mediaMaxWidth - Theme.spacingS
|
|
readonly property int rightSectionLeftEdge: availableWidth - rightSectionWidth
|
|
readonly property int leftToClockGap: Math.max(
|
|
0,
|
|
clockLeftEdge - leftSectionRightEdge)
|
|
readonly property int leftToMediaGap: mediaMaxWidth > 0 ? Math.max(
|
|
0,
|
|
mediaLeftEdge - leftSectionRightEdge) : leftToClockGap
|
|
readonly property int mediaToClockGap: mediaMaxWidth > 0 ? Theme.spacingS : 0
|
|
readonly property int clockToRightGap: validLayout ? Math.max(
|
|
0,
|
|
rightSectionLeftEdge
|
|
- clockRightEdge) : 1000
|
|
readonly property bool spacingTight: validLayout
|
|
&& (leftToMediaGap < 150
|
|
|| clockToRightGap < 100)
|
|
readonly property bool overlapping: validLayout
|
|
&& (leftToMediaGap < 100
|
|
|| clockToRightGap < 50)
|
|
|
|
function getWidgetEnabled(enabled) {
|
|
return enabled !== undefined ? enabled : true
|
|
}
|
|
|
|
function getWidgetVisible(widgetId) {
|
|
switch (widgetId) {
|
|
case "launcherButton":
|
|
return true
|
|
case "workspaceSwitcher":
|
|
return true
|
|
case "focusedWindow":
|
|
return true
|
|
case "clock":
|
|
return true
|
|
case "music":
|
|
return true
|
|
case "weather":
|
|
return true
|
|
case "systemTray":
|
|
return true
|
|
case "privacyIndicator":
|
|
return true
|
|
case "clipboard":
|
|
return true
|
|
case "cpuUsage":
|
|
return true
|
|
case "memUsage":
|
|
return true
|
|
case "cpuTemp":
|
|
return true
|
|
case "gpuTemp":
|
|
return true
|
|
case "notificationButton":
|
|
return true
|
|
case "battery":
|
|
return true
|
|
case "controlCenterButton":
|
|
return true
|
|
case "spacer":
|
|
return true
|
|
case "separator":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
function getWidgetComponent(widgetId) {
|
|
switch (widgetId) {
|
|
case "launcherButton":
|
|
return launcherButtonComponent
|
|
case "workspaceSwitcher":
|
|
return workspaceSwitcherComponent
|
|
case "focusedWindow":
|
|
return focusedWindowComponent
|
|
case "clock":
|
|
return clockComponent
|
|
case "music":
|
|
return mediaComponent
|
|
case "weather":
|
|
return weatherComponent
|
|
case "systemTray":
|
|
return systemTrayComponent
|
|
case "privacyIndicator":
|
|
return privacyIndicatorComponent
|
|
case "clipboard":
|
|
return clipboardComponent
|
|
case "cpuUsage":
|
|
return cpuUsageComponent
|
|
case "memUsage":
|
|
return memUsageComponent
|
|
case "cpuTemp":
|
|
return cpuTempComponent
|
|
case "gpuTemp":
|
|
return gpuTempComponent
|
|
case "notificationButton":
|
|
return notificationButtonComponent
|
|
case "battery":
|
|
return batteryComponent
|
|
case "controlCenterButton":
|
|
return controlCenterButtonComponent
|
|
case "spacer":
|
|
return spacerComponent
|
|
case "separator":
|
|
return separatorComponent
|
|
default:
|
|
return null
|
|
}
|
|
}
|
|
|
|
anchors.fill: parent
|
|
anchors.leftMargin: Theme.spacingM
|
|
anchors.rightMargin: Theme.spacingM
|
|
anchors.topMargin: Theme.spacingXS
|
|
anchors.bottomMargin: Theme.spacingXS
|
|
clip: true
|
|
|
|
Row {
|
|
id: leftSection
|
|
|
|
height: parent.height
|
|
spacing: Theme.spacingXS
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
Repeater {
|
|
model: SettingsData.topBarLeftWidgetsModel
|
|
|
|
Loader {
|
|
property string widgetId: model.widgetId
|
|
property var widgetData: model
|
|
property int spacerSize: model.size || 20
|
|
|
|
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
|
active: topBarContent.getWidgetVisible(model.widgetId)
|
|
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
|
opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: centerSection
|
|
|
|
property var centerWidgets: []
|
|
property int totalWidgets: 0
|
|
property real totalWidth: 0
|
|
property real spacing: Theme.spacingS
|
|
|
|
function updateLayout() {
|
|
// Defer layout if dimensions are invalid
|
|
if (width <= 0 || height <= 0 || !visible) {
|
|
Qt.callLater(updateLayout)
|
|
return
|
|
}
|
|
|
|
centerWidgets = []
|
|
totalWidgets = 0
|
|
totalWidth = 0
|
|
for (var i = 0; i < centerRepeater.count; i++) {
|
|
let item = centerRepeater.itemAt(i)
|
|
if (item && item.active && item.item) {
|
|
centerWidgets.push(item.item)
|
|
totalWidgets++
|
|
totalWidth += item.item.width
|
|
}
|
|
}
|
|
if (totalWidgets > 1)
|
|
totalWidth += spacing * (totalWidgets - 1)
|
|
|
|
positionWidgets()
|
|
}
|
|
|
|
function positionWidgets() {
|
|
if (totalWidgets === 0 || width <= 0)
|
|
return
|
|
|
|
let parentCenterX = width / 2
|
|
if (totalWidgets % 2 === 1) {
|
|
let middleIndex = Math.floor(totalWidgets / 2)
|
|
let currentX = parentCenterX - (centerWidgets[middleIndex].width / 2)
|
|
centerWidgets[middleIndex].x = currentX
|
|
centerWidgets[middleIndex].anchors.horizontalCenter = undefined
|
|
currentX = centerWidgets[middleIndex].x
|
|
for (var i = middleIndex - 1; i >= 0; i--) {
|
|
currentX -= (spacing + centerWidgets[i].width)
|
|
centerWidgets[i].x = currentX
|
|
centerWidgets[i].anchors.horizontalCenter = undefined
|
|
}
|
|
currentX = centerWidgets[middleIndex].x + centerWidgets[middleIndex].width
|
|
for (var i = middleIndex + 1; i < totalWidgets; i++) {
|
|
currentX += spacing
|
|
centerWidgets[i].x = currentX
|
|
centerWidgets[i].anchors.horizontalCenter = undefined
|
|
currentX += centerWidgets[i].width
|
|
}
|
|
} else {
|
|
let leftMiddleIndex = (totalWidgets / 2) - 1
|
|
let rightMiddleIndex = totalWidgets / 2
|
|
let gapCenter = parentCenterX
|
|
let halfSpacing = spacing / 2
|
|
centerWidgets[leftMiddleIndex].x = gapCenter - halfSpacing
|
|
- centerWidgets[leftMiddleIndex].width
|
|
centerWidgets[leftMiddleIndex].anchors.horizontalCenter = undefined
|
|
centerWidgets[rightMiddleIndex].x = gapCenter + halfSpacing
|
|
centerWidgets[rightMiddleIndex].anchors.horizontalCenter = undefined
|
|
let currentX = centerWidgets[leftMiddleIndex].x
|
|
for (var i = leftMiddleIndex - 1; i >= 0; i--) {
|
|
currentX -= (spacing + centerWidgets[i].width)
|
|
centerWidgets[i].x = currentX
|
|
centerWidgets[i].anchors.horizontalCenter = undefined
|
|
}
|
|
currentX = centerWidgets[rightMiddleIndex].x + centerWidgets[rightMiddleIndex].width
|
|
for (var i = rightMiddleIndex + 1; i < totalWidgets; i++) {
|
|
currentX += spacing
|
|
centerWidgets[i].x = currentX
|
|
centerWidgets[i].anchors.horizontalCenter = undefined
|
|
currentX += centerWidgets[i].width
|
|
}
|
|
}
|
|
}
|
|
|
|
height: parent.height
|
|
width: parent.width
|
|
anchors.centerIn: parent
|
|
Component.onCompleted: {
|
|
Qt.callLater(() => {
|
|
Qt.callLater(updateLayout)
|
|
})
|
|
}
|
|
|
|
onWidthChanged: {
|
|
if (width > 0) {
|
|
Qt.callLater(updateLayout)
|
|
}
|
|
}
|
|
|
|
onVisibleChanged: {
|
|
if (visible && width > 0) {
|
|
Qt.callLater(updateLayout)
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: centerRepeater
|
|
|
|
model: SettingsData.topBarCenterWidgetsModel
|
|
|
|
Loader {
|
|
property string widgetId: model.widgetId
|
|
property var widgetData: model
|
|
property int spacerSize: model.size || 20
|
|
|
|
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
|
active: topBarContent.getWidgetVisible(model.widgetId)
|
|
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
|
opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0
|
|
onLoaded: {
|
|
if (item) {
|
|
item.onWidthChanged.connect(centerSection.updateLayout)
|
|
if (model.widgetId === "spacer")
|
|
item.spacerSize = Qt.binding(() => {
|
|
return model.size || 20
|
|
})
|
|
|
|
Qt.callLater(centerSection.updateLayout)
|
|
}
|
|
}
|
|
onActiveChanged: {
|
|
Qt.callLater(centerSection.updateLayout)
|
|
}
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
function onCountChanged() {
|
|
Qt.callLater(centerSection.updateLayout)
|
|
}
|
|
|
|
target: SettingsData.topBarCenterWidgetsModel
|
|
}
|
|
}
|
|
|
|
Row {
|
|
id: rightSection
|
|
|
|
height: parent.height
|
|
spacing: Theme.spacingXS
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
Repeater {
|
|
model: SettingsData.topBarRightWidgetsModel
|
|
|
|
Loader {
|
|
property string widgetId: model.widgetId
|
|
property var widgetData: model
|
|
property int spacerSize: model.size || 20
|
|
|
|
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
|
active: topBarContent.getWidgetVisible(model.widgetId)
|
|
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
|
opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: launcherButtonComponent
|
|
|
|
LauncherButton {
|
|
isActive: appDrawerPopout ? appDrawerPopout.isVisible : false
|
|
section: {
|
|
// Determine which section this loader is in by checking parent
|
|
if (parent && parent.parent) {
|
|
if (parent.parent === leftSection)
|
|
return "left"
|
|
if (parent.parent === rightSection)
|
|
return "right"
|
|
if (parent.parent === centerSection)
|
|
return "center"
|
|
}
|
|
return "left" // default fallback
|
|
}
|
|
popupTarget: appDrawerPopout
|
|
parentScreen: root.screen
|
|
onClicked: {
|
|
if (appDrawerPopout)
|
|
appDrawerPopout.toggle()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: workspaceSwitcherComponent
|
|
|
|
WorkspaceSwitcher {
|
|
screenName: root.screenName
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: focusedWindowComponent
|
|
|
|
FocusedApp {
|
|
compactMode: topBarContent.spacingTight
|
|
availableWidth: topBarContent.leftToMediaGap
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: clockComponent
|
|
|
|
Clock {
|
|
compactMode: topBarContent.overlapping
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "center"
|
|
}
|
|
popupTarget: centcomPopout
|
|
parentScreen: root.screen
|
|
onClockClicked: {
|
|
centcomPopout.calendarVisible = !centcomPopout.calendarVisible
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: mediaComponent
|
|
|
|
Media {
|
|
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "center"
|
|
}
|
|
popupTarget: centcomPopout
|
|
parentScreen: root.screen
|
|
onClicked: {
|
|
centcomPopout.calendarVisible = !centcomPopout.calendarVisible
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: weatherComponent
|
|
|
|
Weather {
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "center"
|
|
}
|
|
popupTarget: centcomPopout
|
|
parentScreen: root.screen
|
|
onClicked: {
|
|
centcomPopout.calendarVisible = !centcomPopout.calendarVisible
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: systemTrayComponent
|
|
|
|
SystemTrayBar {
|
|
parentWindow: root
|
|
parentScreen: root.screen
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: privacyIndicatorComponent
|
|
|
|
PrivacyIndicator {
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
parentScreen: root.screen
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: clipboardComponent
|
|
|
|
Rectangle {
|
|
width: 40
|
|
height: 30
|
|
radius: Theme.cornerRadius
|
|
color: {
|
|
const baseColor = clipboardArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover
|
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b,
|
|
baseColor.a * Theme.widgetTransparency)
|
|
}
|
|
|
|
DankIcon {
|
|
anchors.centerIn: parent
|
|
name: "content_paste"
|
|
size: Theme.iconSize - 6
|
|
color: Theme.surfaceText
|
|
}
|
|
|
|
MouseArea {
|
|
id: clipboardArea
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
clipboardHistoryModalPopup.toggle()
|
|
}
|
|
}
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Theme.shortDuration
|
|
easing.type: Theme.standardEasing
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: cpuUsageComponent
|
|
|
|
CpuMonitor {
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: processListPopout
|
|
parentScreen: root.screen
|
|
toggleProcessList: () => {
|
|
return processListPopout.toggle()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: memUsageComponent
|
|
|
|
RamMonitor {
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: processListPopout
|
|
parentScreen: root.screen
|
|
toggleProcessList: () => {
|
|
return processListPopout.toggle()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: cpuTempComponent
|
|
|
|
CpuTemperature {
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: processListPopout
|
|
parentScreen: root.screen
|
|
toggleProcessList: () => {
|
|
return processListPopout.toggle()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: gpuTempComponent
|
|
|
|
GpuTemperature {
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: processListPopout
|
|
parentScreen: root.screen
|
|
widgetData: parent.widgetData
|
|
toggleProcessList: () => {
|
|
return processListPopout.toggle()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: notificationButtonComponent
|
|
|
|
NotificationCenterButton {
|
|
hasUnread: root.notificationCount > 0
|
|
isActive: notificationCenter.notificationHistoryVisible
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: notificationCenter
|
|
parentScreen: root.screen
|
|
onClicked: {
|
|
notificationCenter.notificationHistoryVisible
|
|
= !notificationCenter.notificationHistoryVisible
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: batteryComponent
|
|
|
|
Battery {
|
|
batteryPopupVisible: batteryPopout.batteryPopupVisible
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: batteryPopout
|
|
parentScreen: root.screen
|
|
onToggleBatteryPopup: {
|
|
batteryPopout.batteryPopupVisible = !batteryPopout.batteryPopupVisible
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: controlCenterButtonComponent
|
|
|
|
ControlCenterButton {
|
|
isActive: controlCenterPopout.controlCenterVisible
|
|
section: {
|
|
if (parent && parent.parent === leftSection)
|
|
return "left"
|
|
if (parent && parent.parent === rightSection)
|
|
return "right"
|
|
if (parent && parent.parent === centerSection)
|
|
return "center"
|
|
return "right"
|
|
}
|
|
popupTarget: controlCenterPopout
|
|
parentScreen: root.screen
|
|
onClicked: {
|
|
controlCenterPopout.triggerScreen = root.screen
|
|
controlCenterPopout.controlCenterVisible = !controlCenterPopout.controlCenterVisible
|
|
if (controlCenterPopout.controlCenterVisible) {
|
|
if (NetworkService.wifiEnabled)
|
|
NetworkService.scanWifi()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: spacerComponent
|
|
|
|
Item {
|
|
width: parent.spacerSize || 20
|
|
height: 30
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: "transparent"
|
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
Theme.outline.b, 0.1)
|
|
border.width: 1
|
|
radius: 2
|
|
visible: false
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
onEntered: parent.visible = true
|
|
onExited: parent.visible = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: separatorComponent
|
|
|
|
Rectangle {
|
|
width: 1
|
|
height: 20
|
|
color: Theme.outline
|
|
opacity: 0.3
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|