aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/appearance/SunsetTab.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/appearance/SunsetTab.qml')
-rw-r--r--desktop/modules/appearance/SunsetTab.qml169
1 files changed, 169 insertions, 0 deletions
diff --git a/desktop/modules/appearance/SunsetTab.qml b/desktop/modules/appearance/SunsetTab.qml
new file mode 100644
index 0000000..657a920
--- /dev/null
+++ b/desktop/modules/appearance/SunsetTab.qml
@@ -0,0 +1,169 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+import QtQuick
+import "../.."
+
+Item {
+ implicitHeight: col.implicitHeight
+
+ Column {
+ id: col
+ width: parent.width
+ spacing: 12
+
+ Row {
+ spacing: 8
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ text: "Lat"
+ color: Theme.subtext
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
+ }
+ Field { width: 90; value: Hyprsunset.lat; onEdited: Hyprsunset.lat = value; placeholder: "lat" }
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ text: "Lon"
+ color: Theme.subtext
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
+ }
+ Field { width: 90; value: Hyprsunset.lon; onEdited: Hyprsunset.lon = value; placeholder: "lon" }
+ Toggle {
+ anchors.verticalCenter: parent.verticalCenter
+ checked: Hyprsunset.autoDetect
+ label: "auto"
+ onToggled: Hyprsunset.autoDetect = checked
+ }
+ Tab { text: "Detect"; onClicked: Hyprsunset.detect() }
+ Tab { text: Hyprsunset.busy ? "fetching…" : "Fetch sun times"; onClicked: Hyprsunset.fetchSun() }
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ text: Hyprsunset.sunSummary
+ color: Theme.overlay
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
+ }
+ }
+
+ Repeater {
+ model: Hyprsunset.profiles
+ Rectangle {
+ required property var modelData
+ required property int index
+ width: col.width
+ implicitHeight: 40
+ radius: 8
+ color: Qt.alpha(Theme.surface, 0.35)
+
+ Row {
+ anchors.fill: parent
+ anchors.margins: 8
+ spacing: 8
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ text: index === Hyprsunset.dayIndex(Hyprsunset.profiles) ? "day"
+ : index === Hyprsunset.nightIndex(Hyprsunset.profiles) ? "night" : "profile"
+ color: Theme.subtext
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 }
+ }
+ Field {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 60
+ value: modelData.time
+ placeholder: "HH:MM"
+ onEdited: Hyprsunset.profiles = Hyprsunset.profiles.map(
+ (p, i) => i === index ? Object.assign({}, p, { time: value }) : p)
+ }
+ Toggle {
+ anchors.verticalCenter: parent.verticalCenter
+ checked: modelData.identity
+ label: "identity"
+ onToggled: Hyprsunset.profiles = Hyprsunset.profiles.map(
+ (p, i) => i === index ? Object.assign({}, p, { identity: checked }) : p)
+ }
+ Toggle {
+ anchors.verticalCenter: parent.verticalCenter
+ checked: modelData.temperature !== null && modelData.temperature !== undefined
+ label: "temp"
+ onToggled: Hyprsunset.profiles = Hyprsunset.profiles.map(
+ (p, i) => i === index ? Object.assign({}, p,
+ { temperature: checked ? (p.temperature ?? 5500) : null }) : p)
+ }
+ Field {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 70
+ value: modelData.temperature === null || modelData.temperature === undefined
+ ? "" : String(modelData.temperature)
+ placeholder: "5500"
+ onEdited: Hyprsunset.profiles = Hyprsunset.profiles.map(
+ (p, i) => i === index ? Object.assign({}, p,
+ { temperature: value === "" ? null : parseInt(value, 10) }) : p)
+ }
+ Toggle {
+ anchors.verticalCenter: parent.verticalCenter
+ checked: modelData.gamma !== null && modelData.gamma !== undefined
+ label: "gamma"
+ onToggled: Hyprsunset.profiles = Hyprsunset.profiles.map(
+ (p, i) => i === index ? Object.assign({}, p,
+ { gamma: checked ? (p.gamma ?? 1.0) : null }) : p)
+ }
+ Field {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 60
+ value: modelData.gamma === null || modelData.gamma === undefined
+ ? "" : String(modelData.gamma)
+ placeholder: "0.8"
+ onEdited: Hyprsunset.profiles = Hyprsunset.profiles.map(
+ (p, i) => i === index ? Object.assign({}, p,
+ { gamma: value === "" ? null : parseFloat(value) }) : p)
+ }
+ Item { width: 8; height: 1 }
+ Tab {
+ anchors.verticalCenter: parent.verticalCenter
+ text: "✕"
+ onClicked: Hyprsunset.profiles =
+ Hyprsunset.profiles.filter((p, i) => i !== index)
+ }
+ // The Row is pinned to the card width, so parent.width is
+ // real, but bound it anyway: a narrow enough panel would
+ // make the subtraction negative and put the Row in a
+ // negative-width state.
+ Item { width: Math.max(0, parent.width - 640); height: 1 }
+ }
+ }
+ }
+
+ Row {
+ spacing: 8
+ Tab {
+ text: "+ Add profile"
+ onClicked: Hyprsunset.profiles =
+ Hyprsunset.profiles.concat([{ time: "0:00", identity: false,
+ temperature: null, gamma: null }])
+ }
+ Tab { text: "Live preview"; onClicked: Hyprsunset.preview() }
+ Tab {
+ text: "Save + Restart"
+ selected: true
+ onClicked: Hyprsunset.save()
+ }
+ }
+
+ Text {
+ width: parent.width
+ wrapMode: Text.Wrap
+ visible: Hyprsunset.notice !== ""
+ text: Hyprsunset.notice
+ color: Hyprsunset.notice.indexOf("invalid") === 0 ? Theme.red : Theme.green
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 }
+ }
+ }
+}