7.1 KiB · text History ca16122
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 double cfg_Speed
    property int cfg_FrameRate
    property bool cfg_Wordmark
    property bool cfg_Bokeh
    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

    readonly property var patterns: [
        { value: "both", text: "Moire and halftone" },
        { value: "moire", text: "Moire" },
        { value: "halftone", text: "Halftone" },
        { value: "alternate", text: "Fade between moire and halftone" },
    ]

    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

    QQC2.ComboBox {
        Kirigami.FormData.label: "Pattern:"
        implicitContentWidthPolicy: QQC2.ComboBox.WidestText
        model: root.patterns
        textRole: "text"
        currentIndex: Math.max(0, root.patterns.findIndex(p => p.value === root.cfg_Pattern))
        onActivated: index => root.cfg_Pattern = root.patterns[index].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: "Bokeh:"
        text: "Drifting out-of-focus lights"
        checked: root.cfg_Bokeh
        onToggled: root.cfg_Bokeh = 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() }
        }
    }
}