diff --git a/README.md b/README.md index bac08ff..6cdf779 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Everything is computed locally by `typikon`, so none of this touches the network, and the widget re-reads only when the date rolls over — the answer changes at midnight and at no other moment. +![The widget during the Nativity Fast](docs/nativity-fast.png) + ## Install `typikon` first, since all three front ends shell out to it: @@ -107,17 +109,25 @@ set your own before the `@import`. ## What it shows The feast or the day's principal commemoration, the fast and why, the season, -the week ahead, and Pascha. Two details worth pointing out: +the week ahead, and Pascha. -- **The church date** appears beside the civil one whenever they differ, which - on the old calendar is always. 25 December and 7 January are the same feast. -- **Forefeasts, afterfeasts and leave-takings** get their own quiet line rather - than crowding out the commemoration that makes the day itself. They repeat - for days at a time. +**The church date is always in the corner.** On the new calendar it echoes the +wall calendar; on the old it is the answer you came for. Below, ROCOR on 7 +January — which is 25 December, and the Nativity. -The legend is built from the week in view rather than hardcoded, because the +![The Nativity on the old calendar](docs/old-calendar.png) + +**Forefeasts, afterfeasts and leave-takings** get their own quiet line rather +than crowding out the commemoration that makes the day itself. They repeat for +days at a time, and a widget that leads with "Post-festive Day of the +Exaltation" for a week has told you nothing. + +**The legend is built from the week in view**, not hardcoded, because the levels a tradition uses are its own — six under the Typikon, three under -Ruthenian particular law — and the words for them differ too. +Ruthenian particular law — and the words for them differ too. Great Week uses +nearly all of them: + +![Great and Holy Week](docs/great-week.png) ## Licence diff --git a/docs/great-week.png b/docs/great-week.png new file mode 100644 index 0000000..10506c0 Binary files /dev/null and b/docs/great-week.png differ diff --git a/docs/nativity-fast.png b/docs/nativity-fast.png new file mode 100644 index 0000000..8cd9f2b Binary files /dev/null and b/docs/nativity-fast.png differ diff --git a/docs/old-calendar.png b/docs/old-calendar.png new file mode 100644 index 0000000..59bc60d Binary files /dev/null and b/docs/old-calendar.png differ diff --git a/quickshell/modules/Horologion.qml b/quickshell/modules/Horologion.qml index ddc8b67..7053645 100644 --- a/quickshell/modules/Horologion.qml +++ b/quickshell/modules/Horologion.qml @@ -6,9 +6,9 @@ import qs.services Panel { id: root title: "Church calendar" - note: Typikon.available - ? (Typikon.season || Typikon.churchDate) - : "" + // The church date, always: on the old calendar it is the answer people + // came for, and on the new it is a harmless echo of the title bar. + note: Typikon.available ? 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 @@ -80,9 +80,6 @@ Panel { 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(" · "); diff --git a/quickshell/services/Typikon.qml b/quickshell/services/Typikon.qml index 41655b5..8b451c7 100644 --- a/quickshell/services/Typikon.qml +++ b/quickshell/services/Typikon.qml @@ -17,6 +17,9 @@ Singleton { property string jurisdiction: "" // Today plus the next six, so the week ahead is visible at a glance. property int days: 7 + // Empty means today. Set it to an ISO date to look at a different one -- + // useful for seeing what Great Week will ask of you before it arrives. + property string forDate: "" property bool available: false property string error: "" @@ -51,6 +54,8 @@ Singleton { // midnight and at no other moment. readonly property string _day: Qt.formatDateTime(clock.date, "yyyy-MM-dd") on_DayChanged: root.refresh() + onJurisdictionChanged: root.refresh() + onForDateChanged: root.refresh() Component.onCompleted: root.refresh() Process { @@ -59,6 +64,8 @@ Singleton { const c = ["typikon", "--json", "--days", String(root.days)]; if (root.jurisdiction !== "") c.push("--jurisdiction", root.jurisdiction); + if (root.forDate !== "") + c.push("--date", root.forDate); return c; } stdout: StdioCollector { diff --git a/quickshell/shot.qml b/quickshell/shot.qml new file mode 100644 index 0000000..c379ac2 --- /dev/null +++ b/quickshell/shot.qml @@ -0,0 +1,63 @@ +//@ pragma UseQApplication + +// A harness for taking the README screenshots: the real widget, on a plain +// backdrop, at a known position. Not part of the shell -- run it with +// +// SHOT_JURISDICTION=rocor SHOT_DATE=2027-01-07 quickshell -p quickshell/shot.qml +// +// It sits on the overlay layer at a fixed offset so a screen grab of that +// rectangle is always the widget and never whatever was behind it. + +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Wayland +import qs +import qs.modules +import qs.services + +ShellRoot { + PanelWindow { + id: win + screen: Quickshell.screens[0] + + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.namespace: "horologion-shot" + exclusionMode: ExclusionMode.Ignore + color: "transparent" + + anchors { top: true; left: true } + margins { top: 60; left: 60 } + + // Fixed, so a screen grab of exactly this rectangle is exactly this + // window and never the desktop underneath it. The widget is shorter + // than this; the crop takes care of the difference. + implicitWidth: Config.width + 68 + implicitHeight: 700 + + Rectangle { + anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0.0; color: "#1b2016" } + GradientStop { position: 1.0; color: "#0e100c" } + } + + ColumnLayout { + id: body + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 34 + width: Config.width + + Horologion { + Component.onCompleted: { + const j = Quickshell.env("SHOT_JURISDICTION"); + const d = Quickshell.env("SHOT_DATE"); + if (j && j !== "") Typikon.jurisdiction = j; + if (d && d !== "") Typikon.forDate = d; + } + } + } + } + } +}