mirror of
https://git.pumpin.online/funkpower/menologion.git
synced 2026-10-23 03:07:12 +00:00
212 lines
7.2 KiB
QML
212 lines
7.2 KiB
QML
import QtQuick
|
|||
|
|
import QtQuick.Layouts
|
||
|
|
import qs
|
||
|
|
import qs.services
|
||
|
|
|
||
|
|
Panel {
|
||
|
|
id: root
|
||
|
|
title: "Church calendar"
|
||
|
|
note: Typikon.available
|
||
|
|
? (Typikon.season || Typikon.churchDate)
|
||
|
|
: ""
|
||
|
|
|
||
|
|
// The glyph carries what kind of fast it is, so obligation has to be shown
|
||
|
|
// some other way or it disappears with the text: the weekday takes the
|
||
|
|
// colour. Under the Typikon nothing binds and everything is yellow; under
|
||
|
|
// a particular law that does bind, the days that bind go red. A panel that
|
||
|
|
// blurs the two states something untrue.
|
||
|
|
function tint(d) {
|
||
|
|
if (!d) return Theme.fgDim;
|
||
|
|
if (d.fast === "none") return Theme.fgDim;
|
||
|
|
return d.obligation === "obligatory" ? Theme.red : Theme.yellow;
|
||
|
|
}
|
||
|
|
|
||
|
|
// The legend is built from the week in view rather than hardcoded, because
|
||
|
|
// the levels a tradition uses are its own — six under the Typikon, three
|
||
|
|
// under Ruthenian law — and the words for them differ too.
|
||
|
|
readonly property var legend: {
|
||
|
|
const seen = [], out = [];
|
||
|
|
for (const d of Typikon.week) {
|
||
|
|
if (!d.emoji || seen.indexOf(d.fast) !== -1) continue;
|
||
|
|
seen.push(d.fast);
|
||
|
|
out.push({ emoji: d.emoji, label: d.fastLabel });
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
ColumnLayout {
|
||
|
|
spacing: 7
|
||
|
|
|
||
|
|
Text {
|
||
|
|
visible: !Typikon.available
|
||
|
|
Layout.fillWidth: true
|
||
|
|
text: Typikon.error !== "" ? Typikon.error
|
||
|
|
: "unavailable — is `typikon` on PATH?"
|
||
|
|
color: Theme.fgDim
|
||
|
|
wrapMode: Text.WordWrap
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 1
|
||
|
|
}
|
||
|
|
|
||
|
|
// Today, given room because it is the day being asked about.
|
||
|
|
RowLayout {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
visible: Typikon.available
|
||
|
|
spacing: 11
|
||
|
|
|
||
|
|
Text {
|
||
|
|
text: Typikon.emoji
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: 28
|
||
|
|
}
|
||
|
|
|
||
|
|
ColumnLayout {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
spacing: 1
|
||
|
|
|
||
|
|
Text {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
text: Typikon.title
|
||
|
|
color: Typikon.feast !== "" ? Theme.accent : Theme.fg
|
||
|
|
wrapMode: Text.WordWrap
|
||
|
|
maximumLineCount: 2
|
||
|
|
elide: Text.ElideRight
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize
|
||
|
|
font.bold: true
|
||
|
|
}
|
||
|
|
|
||
|
|
Text {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
text: {
|
||
|
|
const bits = [Typikon.weekday];
|
||
|
|
if (Typikon.churchDate !== ""
|
||
|
|
&& Typikon.churchDate !== Qt.formatDate(new Date(), "d MMMM"))
|
||
|
|
bits.push(Typikon.churchDate);
|
||
|
|
if (Typikon.season !== "") bits.push(Typikon.season);
|
||
|
|
if (Typikon.obligatory) bits.push("obligatory");
|
||
|
|
return bits.join(" · ");
|
||
|
|
}
|
||
|
|
color: root.tint(Typikon.today)
|
||
|
|
elide: Text.ElideRight
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 3
|
||
|
|
font.bold: Typikon.obligatory
|
||
|
|
}
|
||
|
|
|
||
|
|
// Forefeast, afterfeast, leave-taking. These repeat for days at
|
||
|
|
// a time, so they get their own quiet line rather than crowding
|
||
|
|
// out the commemoration that makes the day itself.
|
||
|
|
Text {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
visible: Typikon.cycle !== ""
|
||
|
|
text: Typikon.cycle
|
||
|
|
color: Qt.alpha(Theme.fgDim, 0.8)
|
||
|
|
elide: Text.ElideRight
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 3
|
||
|
|
font.italic: true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// The rest of today's commemorations, under it.
|
||
|
|
ColumnLayout {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
Layout.leftMargin: 39
|
||
|
|
visible: Typikon.available
|
||
|
|
spacing: 0
|
||
|
|
|
||
|
|
Repeater {
|
||
|
|
model: Typikon.commemorations.filter(c => c !== Typikon.title).slice(0, 3)
|
||
|
|
|
||
|
|
delegate: Text {
|
||
|
|
required property var modelData
|
||
|
|
Layout.fillWidth: true
|
||
|
|
text: "· " + modelData
|
||
|
|
color: Theme.fgDim
|
||
|
|
elide: Text.ElideRight
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 3
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Rectangle {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
visible: Typikon.week.length > 1
|
||
|
|
implicitHeight: 1
|
||
|
|
color: Qt.alpha(Theme.overlay, 0.6)
|
||
|
|
}
|
||
|
|
|
||
|
|
// The rest of the week: glyph, weekday, and what is kept that day.
|
||
|
|
Repeater {
|
||
|
|
model: Typikon.week.length > 1 ? Typikon.week.slice(1) : []
|
||
|
|
|
||
|
|
delegate: RowLayout {
|
||
|
|
required property var modelData
|
||
|
|
Layout.fillWidth: true
|
||
|
|
spacing: 9
|
||
|
|
|
||
|
|
Text {
|
||
|
|
text: modelData.emoji
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize + 3
|
||
|
|
}
|
||
|
|
Text {
|
||
|
|
Layout.preferredWidth: 32
|
||
|
|
text: modelData.weekday.substring(0, 3)
|
||
|
|
color: root.tint(modelData)
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 2
|
||
|
|
font.bold: modelData.obligation === "obligatory"
|
||
|
|
}
|
||
|
|
Text {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
text: modelData.title
|
||
|
|
color: modelData.feast ? Theme.accent : Theme.fgDim
|
||
|
|
elide: Text.ElideRight
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 3
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Rectangle {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
visible: Typikon.available
|
||
|
|
implicitHeight: 1
|
||
|
|
color: Qt.alpha(Theme.overlay, 0.6)
|
||
|
|
}
|
||
|
|
|
||
|
|
RowLayout {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
visible: Typikon.available
|
||
|
|
spacing: 10
|
||
|
|
|
||
|
|
Flow {
|
||
|
|
Layout.fillWidth: true
|
||
|
|
spacing: 9
|
||
|
|
|
||
|
|
Repeater {
|
||
|
|
model: root.legend
|
||
|
|
delegate: Text {
|
||
|
|
required property var modelData
|
||
|
|
text: modelData.emoji + " " + modelData.label
|
||
|
|
color: Qt.alpha(Theme.fgDim, 0.75)
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 4
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Text {
|
||
|
|
text: Typikon.pascha
|
||
|
|
color: Theme.fgDim
|
||
|
|
font.family: Config.font
|
||
|
|
font.pixelSize: Config.fontSize - 4
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|