import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import "schedule.js" as Schedule
import "themes.js" as Themes
Kirigami.FormLayout {
id: root
twinFormLayouts: parentLayout
property alias formLayout: root
property string cfg_Pattern
property string cfg_FadeFrom
property string cfg_FadeTo
property int cfg_BokehLights
property double cfg_Speed
property int cfg_FrameRate
property bool cfg_Wordmark
property bool cfg_ForegroundBokeh
property bool cfg_Stars
property bool cfg_Glints
property bool cfg_Breathing
property bool cfg_Grain
property bool cfg_Dither
property string cfg_ThemeMode
property string cfg_Theme
property string cfg_NightTheme
property string cfg_SunriseTheme
property string cfg_DayTheme
property string cfg_SunsetTheme
property bool cfg_UseLocation
property double cfg_Latitude
property double cfg_Longitude
property string cfg_SunriseTime
property string cfg_SunsetTime
// The patterns a fade can go between; Pattern adds the fade itself.
readonly property var layers: [
{ value: "both", text: "Moire and halftone" },
{ value: "moire", text: "Moire" },
{ value: "halftone", text: "Halftone" },
{ value: "bokeh", text: "Bokeh" },
]
readonly property var patterns: layers.concat([{ value: "alternate", text: "Fade between two…" }])
readonly property bool fading: cfg_Pattern === "alternate"
readonly property bool showsBokeh: cfg_Pattern === "bokeh"
|| (fading && (cfg_FadeFrom === "bokeh" || cfg_FadeTo === "bokeh"))
component PatternBox: QQC2.ComboBox {
property var choices
property string value
signal picked(string value)
implicitContentWidthPolicy: QQC2.ComboBox.WidestText
model: choices
textRole: "text"
currentIndex: Math.max(0, choices.findIndex(p => p.value === value))
onActivated: index => picked(choices[index].value)
}
component ThemeBox: QQC2.ComboBox {
property string value
signal picked(string name)
model: Themes.names
currentIndex: Math.max(0, Themes.names.indexOf(value))
onActivated: index => picked(Themes.names[index])
}
component TimeField: QQC2.TextField {
inputMask: "99:99"
validator: RegularExpressionValidator { regularExpression: /([01]\d|2[0-3]):[0-5]\d/ }
}
component DegreesField: QQC2.TextField {
property double value
signal edited(double value)
text: value.toFixed(4)
validator: DoubleValidator { bottom: -180; top: 180; decimals: 4 }
onEditingFinished: edited(Number(text))
}
// ------------------------------------------------------------ pattern
PatternBox {
Kirigami.FormData.label: "Pattern:"
choices: root.patterns
value: root.cfg_Pattern
onPicked: v => root.cfg_Pattern = v
}
PatternBox {
Kirigami.FormData.label: "From:"
visible: root.fading
choices: root.layers
value: root.cfg_FadeFrom
onPicked: v => root.cfg_FadeFrom = v
}
PatternBox {
Kirigami.FormData.label: "To:"
visible: root.fading
choices: root.layers
value: root.cfg_FadeTo
onPicked: v => root.cfg_FadeTo = v
}
QQC2.SpinBox {
Kirigami.FormData.label: "Bokeh lights:"
visible: root.showsBokeh
from: 4; to: 64
value: root.cfg_BokehLights
onValueModified: root.cfg_BokehLights = value
}
RowLayout {
Kirigami.FormData.label: "Speed:"
QQC2.Slider {
id: speed
from: 0; to: 4; stepSize: 0.25
value: root.cfg_Speed
onMoved: root.cfg_Speed = value
}
QQC2.Label { text: speed.value === 0 ? "still" : speed.value + "×" }
}
QQC2.SpinBox {
Kirigami.FormData.label: "Frame rate:"
from: 5; to: 60
value: root.cfg_FrameRate
onValueModified: root.cfg_FrameRate = value
enabled: root.cfg_Speed > 0
}
QQC2.CheckBox {
Kirigami.FormData.label: "Effects:"
text: "Twinkling stars"
checked: root.cfg_Stars
onToggled: root.cfg_Stars = checked
}
QQC2.CheckBox {
text: "Light glinting across the pattern"
checked: root.cfg_Glints
onToggled: root.cfg_Glints = checked
}
QQC2.CheckBox {
text: "Breathing"
checked: root.cfg_Breathing
onToggled: root.cfg_Breathing = checked
}
QQC2.CheckBox {
text: "Large lights drifting past in front"
checked: root.cfg_ForegroundBokeh
onToggled: root.cfg_ForegroundBokeh = checked
}
QQC2.CheckBox {
text: "Film grain"
checked: root.cfg_Grain
onToggled: root.cfg_Grain = checked
}
QQC2.CheckBox {
text: "Dither (smooths banding in gradients)"
checked: root.cfg_Dither
onToggled: root.cfg_Dither = checked
}
QQC2.CheckBox {
Kirigami.FormData.label: "Wordmark:"
text: "Write NEIAM in the corner"
checked: root.cfg_Wordmark
onToggled: root.cfg_Wordmark = checked
}
// ------------------------------------------------------------- theme
Item { Kirigami.FormData.isSection: true }
QQC2.RadioButton {
Kirigami.FormData.label: "Theme:"
text: "Always the same"
checked: root.cfg_ThemeMode !== "sun"
onToggled: if (checked) root.cfg_ThemeMode = "static"
}
QQC2.RadioButton {
text: "Follow the time of day"
checked: root.cfg_ThemeMode === "sun"
onToggled: if (checked) root.cfg_ThemeMode = "sun"
}
ThemeBox {
Kirigami.FormData.label: "Theme:"
visible: root.cfg_ThemeMode !== "sun"
value: root.cfg_Theme
onPicked: name => root.cfg_Theme = name
}
ThemeBox {
Kirigami.FormData.label: "Night:"
visible: root.cfg_ThemeMode === "sun"
value: root.cfg_NightTheme
onPicked: name => root.cfg_NightTheme = name
}
ThemeBox {
Kirigami.FormData.label: "Sunrise:"
visible: root.cfg_ThemeMode === "sun"
value: root.cfg_SunriseTheme
onPicked: name => root.cfg_SunriseTheme = name
}
ThemeBox {
Kirigami.FormData.label: "Day:"
visible: root.cfg_ThemeMode === "sun"
value: root.cfg_DayTheme
onPicked: name => root.cfg_DayTheme = name
}
ThemeBox {
Kirigami.FormData.label: "Sunset:"
visible: root.cfg_ThemeMode === "sun"
value: root.cfg_SunsetTheme
onPicked: name => root.cfg_SunsetTheme = name
}
// ---------------------------------------------------------- the sun
QQC2.CheckBox {
Kirigami.FormData.label: "Sun:"
visible: root.cfg_ThemeMode === "sun"
text: "Follow the real sun at a location"
checked: root.cfg_UseLocation
onToggled: root.cfg_UseLocation = checked
}
DegreesField {
Kirigami.FormData.label: "Latitude:"
visible: root.cfg_ThemeMode === "sun" && root.cfg_UseLocation
value: root.cfg_Latitude
onEdited: v => root.cfg_Latitude = Math.max(-90, Math.min(90, v))
}
DegreesField {
Kirigami.FormData.label: "Longitude:"
visible: root.cfg_ThemeMode === "sun" && root.cfg_UseLocation
value: root.cfg_Longitude
onEdited: v => root.cfg_Longitude = v
}
TimeField {
Kirigami.FormData.label: "Sunrise at:"
visible: root.cfg_ThemeMode === "sun" && !root.cfg_UseLocation
text: root.cfg_SunriseTime
onEditingFinished: if (acceptableInput) root.cfg_SunriseTime = text
}
TimeField {
Kirigami.FormData.label: "Sunset at:"
visible: root.cfg_ThemeMode === "sun" && !root.cfg_UseLocation
text: root.cfg_SunsetTime
onEditingFinished: if (acceptableInput) root.cfg_SunsetTime = text
}
QQC2.Label {
id: now
Kirigami.FormData.label: "Now:"
visible: root.cfg_ThemeMode === "sun"
function describe() {
var p = Schedule.palette({
ThemeMode: "sun", UseLocation: root.cfg_UseLocation,
Latitude: root.cfg_Latitude, Longitude: root.cfg_Longitude,
SunriseTime: root.cfg_SunriseTime, SunsetTime: root.cfg_SunsetTime,
NightTheme: root.cfg_NightTheme, SunriseTheme: root.cfg_SunriseTheme,
DayTheme: root.cfg_DayTheme, SunsetTheme: root.cfg_SunsetTheme,
}, new Date())
return p.label + (root.cfg_UseLocation
? ", sun at " + p.elevation.toFixed(1) + "°" : "")
}
text: describe()
Timer {
interval: 60000; running: now.visible; repeat: true
onTriggered: now.text = now.describe()
}
Connections {
target: root
function onCfg_UseLocationChanged() { now.text = now.describe() }
function onCfg_LatitudeChanged() { now.text = now.describe() }
function onCfg_LongitudeChanged() { now.text = now.describe() }
function onCfg_SunriseTimeChanged() { now.text = now.describe() }
function onCfg_SunsetTimeChanged() { now.text = now.describe() }
}
}
}
neiam
/neiam-devices
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
9.2 KiB · text
History
cced89e