quickshell-toki-night/modules/bar/popouts/Calendar.qml

289 lines
8.3 KiB
QML

pragma ComponentBehavior: Bound
import qs.config
import qs.custom
import qs.services
import qs.util
import Quickshell
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ColumnLayout {
id: root
spacing: 4
property date currentDate: new Date()
property int currentYear: currentDate.getFullYear()
property int currentMonth: currentDate.getMonth()
RowLayout {
Layout.alignment: Qt.AlignHCenter
MaterialIcon {
Layout.bottomMargin: 1
text: "calendar_month"
color: Config.colors.primary
font.pointSize: Config.font.size.large
}
CustomText {
text: Time.format("hh:mm:ss")
color: Config.colors.primary
font.weight: 600
font.pointSize: Config.font.size.large
font.family: Config.font.family.mono
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 10
Layout.rightMargin: 4
spacing: 0
CustomText {
text: Time.format("dddd, MMMM d")
font.weight: 600
font.pointSize: Config.font.size.normal
}
CustomText {
text: Time.format("yyyy-MM-dd")
color: Config.colors.tertiary
font.pointSize: Config.font.size.smaller
}
}
}
// Calendar grid
GridLayout {
id: calendarGrid
Layout.fillWidth: true
Layout.margins: 10
rowSpacing: 7
columnSpacing: 2
// Month navigation
RowLayout {
Layout.fillWidth: true
Layout.bottomMargin: 7
Layout.columnSpan: 2
CustomRect {
implicitWidth: implicitHeight
implicitHeight: prevIcon.implicitHeight + 8
radius: 1000
color: Config.colors.container
StateLayer {
anchors.fill: parent
function onClicked(): void {
if (root.currentMonth !== 0) {
root.currentMonth = root.currentMonth - 1;
} else {
root.currentMonth = 11;
root.currentYear = root.currentYear - 1;
}
}
}
MaterialIcon {
id: prevIcon
anchors.centerIn: parent
text: "chevron_left"
color: Config.colors.secondary
}
}
CustomText {
Layout.fillWidth: true
readonly property list<string> monthNames:
Array.from({ length: 12 }, (_, i) => Qt.locale().monthName(i, Qt.locale().LongFormat))
text: monthNames[root.currentMonth] + " " + root.currentYear
horizontalAlignment: Text.AlignHCenter
font.weight: 600
font.pointSize: Config.font.size.normal
}
CustomRect {
implicitWidth: implicitHeight
implicitHeight: nextIcon.implicitHeight + 8
radius: 1000
color: Config.colors.container
StateLayer {
anchors.fill: parent
function onClicked(): void {
if (root.currentMonth !== 11) {
root.currentMonth = root.currentMonth + 1;
} else {
root.currentMonth = 0;
root.currentYear = root.currentYear + 1;
}
}
}
MaterialIcon {
id: nextIcon
anchors.centerIn: parent
text: "chevron_right"
color: Config.colors.primary
}
}
}
// Day headers
DayOfWeekRow {
Layout.row: 1
Layout.column: 1
Layout.fillWidth: true
Layout.preferredHeight: Config.font.size.largest
delegate: CustomText {
required property var model
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: model.shortName
color: Config.colors.tertiary
font.pointSize: Config.font.size.small
font.weight: 500
}
}
CustomText {
Layout.row: 1
Layout.leftMargin: -2
text: "Week"
color: Config.colors.tertiary
font.pointSize: Config.font.size.small
font.weight: 500
font.italic: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
// ISO week markers
WeekNumberColumn {
Layout.row: 2
Layout.fillHeight: true
Layout.rightMargin: 15
height: 240
month: root.currentMonth
year: root.currentYear
delegate: CustomText {
required property var model
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: model.weekNumber
color: Config.colors.tertiary
font.pointSize: Config.font.size.small
font.weight: 600
font.italic: true
}
}
// Calendar days grid
MonthGrid {
Layout.row: 2
Layout.column: 1
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
Layout.margins: 6
month: root.currentMonth
year: root.currentYear
spacing: 20
delegate: Item {
id: dayItem
required property var model
implicitWidth: implicitHeight
implicitHeight: dayText.implicitHeight + 10
CustomRect {
anchors.centerIn: parent
implicitWidth: parent.implicitHeight
implicitHeight: parent.implicitHeight
radius: 1000
color: dayItem.model.today ? Config.colors.calendar : "transparent"
StateLayer {
anchors.fill: parent
visible: dayItem.model.month === root.currentMonth
function onClicked(): void {}
}
CustomText {
id: dayText
anchors.centerIn: parent
anchors.verticalCenterOffset: 0.5
horizontalAlignment: Text.AlignHCenter
text: Qt.formatDate(dayItem.model.date, "d")
color: dayItem.model.today ? Config.colors.primaryDark :
dayItem.model.month === root.currentMonth ? Config.colors.primary : Config.colors.inactive
font.pointSize: Config.font.size.small
font.weight: dayItem.model.today ? 600 : 400
}
}
}
}
}
// Today button
CustomRect {
Layout.fillWidth: true
implicitHeight: todayBtn.implicitHeight + 10
radius: 25
color: Config.colors.calendar
StateLayer {
anchors.fill: parent
color: Config.colors.secondary
function onClicked(): void {
const today = new Date();
root.currentYear = today.getFullYear();
root.currentMonth = today.getMonth();
}
}
Row {
id: todayBtn
anchors.centerIn: parent
spacing: 7
MaterialIcon {
anchors.verticalCenter: parent.verticalCenter
text: "today"
color: Config.colors.primaryDark
font.pointSize: Config.font.size.normal
}
CustomText {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Today")
color: Config.colors.primaryDark
}
}
}
}