Files
dotfiles/roles/quickshell/files/bar/Clock.qml
2026-04-06 01:30:28 +02:00

197 lines
7.0 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Quickshell
import QtQuick
import "../components"
Item {
id: root
implicitWidth: timeLabel.implicitWidth + 10
implicitHeight: 24
property var now: new Date()
Timer {
interval: 1000
running: true
repeat: true
onTriggered: root.now = new Date()
}
readonly property string display: {
const d = now
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
const h = String(d.getHours()).padStart(2, "0")
const m = String(d.getMinutes()).padStart(2, "0")
const s = String(d.getSeconds()).padStart(2, "0")
return days[d.getDay()] + " " + h + ":" + m + ":" + s
}
Text {
id: timeLabel
anchors.centerIn: parent
text: root.display
color: Theme.text
font.pixelSize: 12
font.family: "JetBrainsMono Nerd Font Mono"
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: calPopup.visible = !calPopup.visible
}
// --------------- Calendar popup ---------------
PopupWindow {
id: calPopup
visible: false
anchor.item: root
anchor.edges: Edges.Bottom
anchor.gravity: Edges.Bottom
// calendar state
property int viewYear: root.now.getFullYear()
property int viewMonth: root.now.getMonth() // 0-based
readonly property var monthNames: [
"January","February","March","April","May","June",
"July","August","September","October","November","December"
]
readonly property int daysInMonth: new Date(viewYear, viewMonth + 1, 0).getDate()
// first weekday of month: Mon=0 … Sun=6
readonly property int startOffset: (new Date(viewYear, viewMonth, 1).getDay() + 6) % 7
readonly property int totalCells: Math.ceil((startOffset + daysInMonth) / 7) * 7
readonly property int todayYear: root.now.getFullYear()
readonly property int todayMonth: root.now.getMonth()
readonly property int todayDay: root.now.getDate()
implicitWidth: calBg.implicitWidth
implicitHeight: calBg.implicitHeight
Rectangle {
id: calBg
anchors.fill: parent
color: Theme.bg
border.color: Theme.border
border.width: Theme.borderWidth
radius: Theme.radius
implicitWidth: calLayout.implicitWidth + 24
implicitHeight: calLayout.implicitHeight + 24
Column {
id: calLayout
anchors { fill: parent; margins: 12 }
spacing: 6
// Month navigation
Row {
width: parent.width
spacing: 0
Text {
text: ""
color: Theme.text
font.pixelSize: 16
width: 20
horizontalAlignment: Text.AlignHCenter
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (calPopup.viewMonth === 0) {
calPopup.viewMonth = 11
calPopup.viewYear--
} else {
calPopup.viewMonth--
}
}
}
}
Text {
text: calPopup.monthNames[calPopup.viewMonth] + " " + calPopup.viewYear
color: Theme.text
font.pixelSize: 13
font.bold: true
// fill remaining space between arrows
width: parent.width - 40
horizontalAlignment: Text.AlignHCenter
}
Text {
text: ""
color: Theme.text
font.pixelSize: 16
width: 20
horizontalAlignment: Text.AlignHCenter
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (calPopup.viewMonth === 11) {
calPopup.viewMonth = 0
calPopup.viewYear++
} else {
calPopup.viewMonth++
}
}
}
}
}
// Weekday headers
Row {
spacing: 2
Repeater {
model: ["Mo","Tu","We","Th","Fr","Sa","Su"]
Text {
text: modelData
color: Theme.textDim
font.pixelSize: 10
width: 28
horizontalAlignment: Text.AlignHCenter
}
}
}
// Day grid
Grid {
columns: 7
spacing: 2
Repeater {
model: calPopup.totalCells
delegate: Item {
width: 28
height: 22
readonly property int dayNum: index - calPopup.startOffset + 1
readonly property bool valid:
index >= calPopup.startOffset &&
index < calPopup.startOffset + calPopup.daysInMonth
readonly property bool isToday:
valid &&
calPopup.viewYear === calPopup.todayYear &&
calPopup.viewMonth === calPopup.todayMonth &&
dayNum === calPopup.todayDay
Rectangle {
anchors.fill: parent
radius: 3
color: isToday ? Theme.accent : "transparent"
visible: isToday
}
Text {
anchors.centerIn: parent
text: parent.valid ? String(parent.dayNum) : ""
color: parent.isToday ? Theme.text : Theme.textDim
font.pixelSize: 11
font.bold: parent.isToday
}
}
}
}
}
}
}
}