Files
Flora/qml/panels/MonthCalendar.qml
T

157 lines
5.7 KiB
QML
Raw Normal View History

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Flora
Item {
id: cal
signal daySelected(string dateStr)
property date currentMonth: new Date()
readonly property int year: currentMonth.getFullYear()
readonly property int month: currentMonth.getMonth()
function fmtDate(d) {
function pad(n) { return n < 10 ? "0" + n : "" + n }
return d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate())
}
function gridModel() {
const first = new Date(year, month, 1)
const dowSun0 = first.getDay()
const startDow = (dowSun0 + 6) % 7
const daysInMonth = new Date(year, month + 1, 0).getDate()
const list = []
for (let i = 0; i < startDow; ++i) list.push(0)
for (let d = 1; d <= daysInMonth; ++d) list.push(d)
while (list.length % 7 !== 0) list.push(0)
while (list.length < 42) list.push(0)
return list
}
ColumnLayout {
anchors.fill: parent
spacing: 4
RowLayout {
Layout.fillWidth: true
ToolButton {
text: "‹"
font.pixelSize: 16
onClicked: cal.currentMonth = new Date(year, month - 1, 1)
}
Label {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.bold: true
color: Theme.text
text: Qt.locale().monthName(month, Locale.LongFormat) + " " + year
}
ToolButton {
text: "›"
font.pixelSize: 16
onClicked: cal.currentMonth = new Date(year, month + 1, 1)
}
ToolButton {
text: "\u2302"
font.pixelSize: 12
ToolTip.text: qsTr("Сегодня")
ToolTip.visible: hovered
onClicked: cal.currentMonth = new Date()
}
}
RowLayout {
Layout.fillWidth: true
Repeater {
model: ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]
Label {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 10
font.bold: true
color: Theme.textMuted
text: modelData
}
}
}
Grid {
Layout.fillWidth: true
Layout.fillHeight: true
columns: 7
rowSpacing: 2
columnSpacing: 2
Repeater {
model: cal.gridModel()
delegate: Rectangle {
required property int modelData
width: (cal.width - 12) / 7
height: (cal.height - 50) / 6
radius: 6
border.width: isToday ? 1 : 0
border.color: Theme.accent
color: {
if (modelData <= 0) return "transparent"
if (isToday) return Theme.calendarToday
if (isSelected) return Theme.accentMuted
if (hasNote) return Theme.isDark ? "#252a33" : "#f8f9fb"
return Theme.surface
}
readonly property var now: { const t = new Date(); return { day: t.getDate(), month: t.getMonth(), year: t.getFullYear() } }
readonly property bool isToday: modelData > 0 && now.day === modelData && now.month === cal.month && now.year === cal.year
readonly property string ds: modelData > 0 ? Qt.formatDate(new Date(cal.year, cal.month, modelData), "yyyy-MM-dd") : ""
readonly property bool hasNote: {
const _ = cal.currentMonth
if (modelData <= 0 || !fileStore.ready) return false
return fileStore.fileExists(fileStore.vault + "/Журнал/" + ds + ".md")
}
readonly property bool isSelected: false // можно подсветить выбранный день
Label {
id: dayLabel
anchors.centerIn: parent
anchors.verticalCenterOffset: hasNote ? -3 : 0
visible: modelData > 0
text: modelData
font.pixelSize: 11
font.bold: isToday
color: modelData > 0 ? (isToday ? Theme.accentText : Theme.text) : "transparent"
}
Rectangle {
visible: modelData > 0 && parent.hasNote
width: 5; height: 5; radius: 2.5
color: Theme.calendarDot
anchors.top: dayLabel.bottom
anchors.topMargin: 2
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea {
anchors.fill: parent
enabled: modelData > 0
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
const d = new Date(cal.year, cal.month, modelData)
cal.daySelected(fmtDate(d))
}
}
}
}
}
// подпись
Label {
Layout.fillWidth: true
text: qsTr("Клик — заметка дня")
color: Theme.textFaint
font.pixelSize: 9
horizontalAlignment: Text.AlignHCenter
}
}
}