Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

quickshell/nuguland/BrightnessPanel.qml

Raw
pragma ComponentBehavior: Bound
import QtQuick
import "Util.js" as Util

Flickable {
    id: root

    required property Theme theme
    required property Brightness brightnessService
    readonly property var panelState: brightnessService ? Util.parseJson(brightnessService.stateJson(), {}) : ({})
    readonly property var displays: panelState.displays || []
    readonly property var global: panelState.global || ({
            "mode": "none",
            "level": 0,
            "levels": []
        })
    readonly property var setup: panelState.setup || ({
            "needed": false,
            "available": false
        })
    readonly property bool hasGlobal: global.mode !== "none"

    function setAllAt(x, width) {
        if (brightnessService && hasGlobal)
            brightnessService.setAll(Math.max(0, Math.min(1, x / Math.max(1, width))));
    }

    function setDisplayAt(id, x, width) {
        if (brightnessService)
            brightnessService.setDisplay(id, Math.max(0, Math.min(1, x / Math.max(1, width))));
    }

    width: parent ? parent.width : 0
    contentWidth: width
    contentHeight: brightnessCol.height
    clip: true
    interactive: contentHeight > height
    boundsBehavior: Flickable.StopAtBounds
    flickableDirection: Flickable.VerticalFlick

    StableListModel {
        id: displayModel
        rows: root.displays
    }

    Column {
        id: brightnessCol

        width: root.width
        spacing: 12

        PopupButton {
            visible: root.setup.needed
            theme: root.theme
            text: "setup ddc"
            role: "primary"
            enabled: root.setup.available
            tooltip: enabled ? "install ddc support for external displays" : "ddc setup unavailable"
            onClicked: if (root.brightnessService)
                root.brightnessService.setupDdc()
        }

        PopupCard {
            width: parent.width
            height: 48
            visible: root.hasGlobal
            theme: root.theme

            PopupSlider {
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                theme: root.theme
                Accessible.name: "all displays brightness"
                value: Number(root.global.level || 0)
                onMoved: value => root.setAllAt(value, 1)
            }
        }

        Grid {
            id: presetGrid

            width: parent.width
            visible: root.hasGlobal
            columns: 4
            columnSpacing: 8

            Repeater {
                model: [0.25, 0.5, 0.75, 1]

                delegate: PopupButton {
                    id: preset

                    required property real modelData

                    theme: root.theme
                    width: Math.floor((presetGrid.width - presetGrid.columnSpacing * (presetGrid.columns - 1)) / presetGrid.columns)
                    text: `${Math.round(preset.modelData * 100)}%`
                    accessibleName: `all displays brightness ${text}`
                    onClicked: root.setAllAt(preset.modelData, 1)
                }
            }
        }

        NuguText {
            theme: root.theme
            variant: "meta"
            visible: displayModel.count === 0
            text: "no displays"
        }

        Repeater {
            model: displayModel

            delegate: PopupCard {
                id: displayRow

                required property var rowData
                readonly property bool controllable: !!rowData.controllable
                readonly property string issue: String(rowData.issue || "")
                readonly property real level: Math.max(0, Math.min(1, Number(rowData.level || 0)))

                theme: root.theme
                padding: 0
                width: root.width
                height: 44
                attention: issue.length > 0
                Accessible.name: String(rowData.name || "display")
                Accessible.description: issue

                NuguText {
                    id: displayName

                    anchors.left: parent.left
                    anchors.leftMargin: 10
                    anchors.verticalCenter: parent.verticalCenter
                    width: Math.min(128, root.width * 0.28)
                    theme: root.theme
                    text: String(displayRow.rowData.name || "display")
                    elide: Text.ElideRight
                }

                PopupSlider {
                    id: displaySlider

                    anchors.left: displayName.right
                    anchors.leftMargin: 10
                    anchors.right: displayPercent.left
                    anchors.rightMargin: 10
                    anchors.verticalCenter: parent.verticalCenter
                    theme: root.theme
                    enabled: displayRow.controllable
                    Accessible.name: `${displayName.text} brightness`
                    Accessible.description: displayRow.issue
                    value: displayRow.level
                    onMoved: value => root.setDisplayAt(String(displayRow.rowData.id), value, 1)
                }

                NuguText {
                    id: displayPercent

                    anchors.right: issueBadge.visible ? issueBadge.left : parent.right
                    anchors.rightMargin: 10
                    anchors.verticalCenter: parent.verticalCenter
                    width: 44
                    theme: root.theme
                    variant: "meta"
                    text: displayRow.controllable ? `${Math.round(displayRow.level * 100)}%` : "n/a"
                    horizontalAlignment: Text.AlignRight
                }

                NuguText {
                    id: issueBadge

                    visible: displayRow.issue.length > 0
                    anchors.right: parent.right
                    anchors.rightMargin: 10
                    anchors.verticalCenter: parent.verticalCenter
                    width: 90
                    theme: root.theme
                    variant: "meta"
                    text: displayRow.issue.toLowerCase()
                    color: root.theme.warning
                    elide: Text.ElideRight
                    horizontalAlignment: Text.AlignRight
                }
            }
        }
    }
}