Files
Flora/qml/panels/MonthCalendar.qml
T
grendervill b5a3639e46 Календарь: кнопки не налезают, без прозрачности, круглые, с учётом длинных месяцев
- RowLayout spacing 4, ToolButton 32x32 Layout.preferred 32, background Rectangle color Theme.surface (не прозрачный) + hover Theme.surfaceHover + pressed Theme.surfaceSelected, border Theme.border/Strong/accent, radius 16, contentItem Label
- Label месяца: Layout.minimumWidth 80 preferred 120 fillWidth, elide Right, maximumLineCount 1, NoWrap, pixelSize 12, bold, для 'сентябрь 2026' (8 букв) и узких окон
- Hover/pressed визуально меняются, круглые
2026-09-01 22:09:28 +03:00

219 lines
8.6 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 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
spacing: 4
// Кнопка Назад — круглая, без прозрачности
ToolButton {
text: "‹"
font.pixelSize: 16
font.bold: true
implicitWidth: 32
implicitHeight: 32
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Layout.alignment: Qt.AlignVCenter
background: Rectangle {
color: parent.pressed ? Theme.surfaceSelected : (parent.hovered ? Theme.surfaceHover : Theme.surface)
border.color: parent.pressed ? Theme.accent : (parent.hovered ? Theme.borderStrong : Theme.border)
radius: 16
}
contentItem: Label {
text: parent.text
font: parent.font
color: Theme.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: cal.currentMonth = new Date(year, month - 1, 1)
}
Label {
Layout.fillWidth: true
Layout.minimumWidth: 80
Layout.preferredWidth: 120
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.bold: true
color: Theme.text
font.pixelSize: 12
elide: Text.ElideRight
maximumLineCount: 1
wrapMode: Text.NoWrap
text: Qt.locale().monthName(month, Locale.LongFormat) + " " + year
}
ToolButton {
text: "›"
font.pixelSize: 16
font.bold: true
implicitWidth: 32
implicitHeight: 32
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Layout.alignment: Qt.AlignVCenter
background: Rectangle {
color: parent.pressed ? Theme.surfaceSelected : (parent.hovered ? Theme.surfaceHover : Theme.surface)
border.color: parent.pressed ? Theme.accent : (parent.hovered ? Theme.borderStrong : Theme.border)
radius: 16
}
contentItem: Label {
text: parent.text
font: parent.font
color: Theme.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
onClicked: cal.currentMonth = new Date(year, month + 1, 1)
}
ToolButton {
text: "\u2302"
font.pixelSize: 12
implicitWidth: 32
implicitHeight: 32
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Layout.alignment: Qt.AlignVCenter
background: Rectangle {
color: parent.pressed ? Theme.surfaceSelected : (parent.hovered ? Theme.surfaceHover : Theme.surface)
border.color: parent.pressed ? Theme.accent : (parent.hovered ? Theme.borderStrong : Theme.border)
radius: 16
}
contentItem: Label {
text: parent.text
font: parent.font
color: Theme.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
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
}
}
}