222 lines
7.9 KiB
QML
222 lines
7.9 KiB
QML
// The contents of the date menu, in GNOME's order: date header, notifications,
|
|
// calendar, weather.
|
|
//
|
|
// Kept separate from DateMenu.qml (the PanelWindow) so it can be dropped into a
|
|
// FloatingWindow for testing — layer-shell surfaces cannot map outside a
|
|
// wlroots compositor.
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import qs.config
|
|
import qs.services
|
|
import qs.widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
implicitWidth: 480
|
|
implicitHeight: content.implicitHeight + Theme.popoverPadding * 2
|
|
|
|
// Called by the window when it opens and closes, so the panel is always in
|
|
// a known state rather than wherever the last visit left it.
|
|
function prepare(): void {
|
|
calendar.showToday();
|
|
}
|
|
|
|
function reset(): void {
|
|
notifications.reset();
|
|
}
|
|
|
|
// Minutes precision: the header only shows a date, so this exists purely to
|
|
// roll it over at midnight without a per-second wake.
|
|
SystemClock {
|
|
id: clock
|
|
precision: SystemClock.Minutes
|
|
}
|
|
|
|
Column {
|
|
id: content
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
anchors.margins: Theme.popoverPadding
|
|
spacing: Theme.sectionSpacing
|
|
|
|
// ── Header ──────────────────────────────────────────────────────────
|
|
Item {
|
|
width: parent.width
|
|
height: 34
|
|
|
|
Text {
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 4
|
|
anchors.right: headerActions.left
|
|
anchors.rightMargin: Theme.itemSpacing
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: Qt.formatDateTime(clock.date, "dddd, MMMM d")
|
|
color: Theme.fg
|
|
elide: Text.ElideRight
|
|
font.family: Theme.fontFamily
|
|
// The day number changes in place at midnight.
|
|
font.features: Theme.tabularFigures
|
|
font.pixelSize: Theme.fontSizeTitle
|
|
font.weight: Font.DemiBold
|
|
}
|
|
|
|
Row {
|
|
id: headerActions
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 6
|
|
|
|
// Labelled rather than icon-only: an unexplained crossed-out
|
|
// bell is exactly the kind of thing a normal person has to
|
|
// click to find out about.
|
|
Rectangle {
|
|
id: dndPill
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: dndRow.implicitWidth + 20
|
|
height: 28
|
|
radius: Theme.pillRadius
|
|
border.width: 0
|
|
|
|
color: {
|
|
if (Notifs.doNotDisturb)
|
|
return dndMouse.containsMouse ? Theme.alpha(Theme.accent, 0.42) : Theme.alpha(Theme.accent, 0.28);
|
|
return dndMouse.containsMouse ? Theme.alpha(Theme.fg, 0.16) : Theme.alpha(Theme.fg, 0.08);
|
|
}
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: dndMouse.containsMouse ? Theme.durFast : Theme.durNormal
|
|
}
|
|
}
|
|
|
|
Row {
|
|
id: dndRow
|
|
anchors.centerIn: parent
|
|
spacing: 6
|
|
|
|
ThemedIcon {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
size: 14
|
|
icon: "notifications-disabled-symbolic"
|
|
iconFallback: "user-invisible-symbolic"
|
|
tint: Notifs.doNotDisturb ? Theme.accent : Theme.fgDim
|
|
}
|
|
|
|
Text {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: "Do Not Disturb"
|
|
color: Notifs.doNotDisturb ? Theme.accent : Theme.fg
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
font.weight: Font.Medium
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: dndMouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: Notifs.doNotDisturb = !Notifs.doNotDisturb
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: clearPill
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: clearLabel.implicitWidth + 20
|
|
height: 28
|
|
radius: Theme.pillRadius
|
|
border.width: 0
|
|
// Hidden rather than disabled: there is nothing ambiguous
|
|
// about an empty tray, so the control has no job.
|
|
visible: Notifs.hasNotifications
|
|
color: clearMouse.containsMouse ? Theme.alpha(Theme.fg, 0.16) : Theme.alpha(Theme.fg, 0.08)
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: clearMouse.containsMouse ? Theme.durFast : Theme.durNormal
|
|
}
|
|
}
|
|
|
|
Text {
|
|
id: clearLabel
|
|
anchors.centerIn: parent
|
|
text: "Clear all"
|
|
color: Theme.fg
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
font.weight: Font.Medium
|
|
}
|
|
|
|
MouseArea {
|
|
id: clearMouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: Notifs.dismissAll()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── Notifications ───────────────────────────────────────────────────
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
border.width: 0
|
|
color: Theme.alpha(Theme.fg, 0.1)
|
|
}
|
|
|
|
MediaCard {
|
|
id: media
|
|
width: parent.width
|
|
}
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
border.width: 0
|
|
visible: media.visible
|
|
color: Theme.alpha(Theme.fg, 0.1)
|
|
}
|
|
|
|
NotificationList {
|
|
id: notifications
|
|
width: parent.width
|
|
}
|
|
|
|
// ── Calendar ────────────────────────────────────────────────────────
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
border.width: 0
|
|
color: Theme.alpha(Theme.fg, 0.1)
|
|
}
|
|
|
|
CalendarGrid {
|
|
id: calendar
|
|
width: parent.width
|
|
}
|
|
|
|
// ── Weather ─────────────────────────────────────────────────────────
|
|
// Separator and card share one condition so the panel does not end on a
|
|
// rule with nothing under it.
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
border.width: 0
|
|
visible: Weather.available
|
|
color: Theme.alpha(Theme.fg, 0.1)
|
|
}
|
|
|
|
WeatherCard {
|
|
width: parent.width
|
|
visible: Weather.available
|
|
}
|
|
}
|
|
}
|