Warning, /plasma/plasma-workspace/kcms/nightcolor/ui/DayNightView.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2022 Bharadwaj Raju <bharadwaj.raju777@protonmail.com>
0003     SPDX-FileCopyrightText: 2023 Ismael Asensio <isma.af@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 import QtQuick
0009 import QtQuick.Layouts
0010 import QtQuick.Controls as QQC2
0011 import org.kde.kirigami as Kirigami
0012 
0013 ColumnLayout {
0014     id: root
0015 
0016     required property int dayTransitionOn
0017     required property int dayTransitionOff
0018     required property int nightTransitionOn
0019     required property int nightTransitionOff
0020 
0021     property bool alwaysOn: false
0022     property int dayTemperature: 6500
0023     property int nightTemperature: 4200
0024 
0025     readonly property bool show24h: true // TODO: Get from user's prefernces
0026     readonly property bool singleColor: root.alwaysOn || !root.enabled
0027 
0028     Rectangle {
0029         id: view
0030 
0031         Layout.fillWidth: true
0032         Layout.preferredHeight: Kirigami.Units.gridUnit * 2
0033         // Align the edges with the center of the first and last labels
0034         Layout.leftMargin: axis.width / 50 - border.width
0035         Layout.rightMargin: Layout.leftMargin
0036         border.color: Qt.alpha(Kirigami.Theme.textColor, 0.2)
0037         radius: 3
0038 
0039         gradient: root.singleColor ? null : grad
0040         // The color only get used when there's no gradient
0041         color: root.enabled ? grad.nightColor : Kirigami.Theme.backgroundColor
0042 
0043         Gradient {
0044             id: grad
0045             orientation: Gradient.Horizontal
0046 
0047             readonly property color dayColor: colorForTemp(root.dayTemperature)
0048             readonly property color nightColor: colorForTemp(root.nightTemperature)
0049             readonly property color edgeColor: (root.nightTransitionOn < root.dayTransitionOff) ? dayColor : nightColor
0050 
0051             GradientStop { position: 0; color: grad.edgeColor }
0052             GradientStop { position: dayTransitionOn/1440; color: grad.nightColor }
0053             GradientStop { position: dayTransitionOff/1440; color: grad.dayColor }
0054             GradientStop { position: nightTransitionOn/1440; color: grad.dayColor }
0055             GradientStop { position: nightTransitionOff/1440; color: grad.nightColor }
0056             GradientStop { position: 1; color: grad.edgeColor }
0057         }
0058 
0059         Repeater {
0060             model: (root.singleColor) ? [ { left: 0, right: 1440, isNight: true } ] : [
0061                 { left: 0, right: Math.min(root.dayTransitionOff, root.nightTransitionOn), isNight: root.dayTransitionOn < root.nightTransitionOn },
0062                 { left: root.dayTransitionOff, right: root.nightTransitionOn, isNight: root.dayTransitionOn > root.nightTransitionOn },
0063                 { left: Math.max(root.dayTransitionOff, root.nightTransitionOff), right: 1440, isNight: root.dayTransitionOff < root.nightTransitionOff },
0064             ]
0065 
0066             Kirigami.Icon {
0067                 source: {
0068                     if (!root.enabled) {
0069                         return 'redshift-status-off'
0070                     }
0071                     if (modelData.isNight) {
0072                         return nightTemperature == 6500 ? 'weather-clear-night-symbolic': 'redshift-status-on'
0073                     }
0074                     return dayTemperature == 6500 ? 'weather-clear-symbolic' : 'redshift-status-day'
0075                 }
0076                 width: Kirigami.Units.iconSizes.medium
0077                 height: width
0078                 x: (modelData.left + modelData.right)/2/1440 * parent.width - width/2
0079                 y: (parent.height - height) / 2
0080                 visible: Math.abs(modelData.right - modelData.left) > 2 * width
0081                 // The view background is always light except when disabled
0082                 color: root.enabled ? 'black'  : Kirigami.Theme.textColor
0083             }
0084         }
0085 
0086         Kirigami.Icon {
0087             x: Math.round(now.minutes/1440 * view.width - width/2)
0088             anchors.top: parent.bottom
0089             source: "draw-triangle4-symbolic"  // Pointing-down triangle
0090             color: Kirigami.Theme.textColor
0091             width: 10
0092             height: 10
0093 
0094             Timer {
0095                 id: now
0096                 property int minutes: 0
0097                 interval: 60
0098                 repeat: true
0099                 running: true
0100                 triggeredOnStart: true
0101                 onTriggered: minutes = minutesForDate(new Date())
0102             }
0103         }
0104 
0105         HoverHandler {
0106             id: hover
0107         }
0108 
0109         QQC2.ToolTip {
0110             readonly property string eveningChange: i18n("Color temperature begins changing to night time at %1 and is fully changed by %2",
0111                                                         prettyTime(nightTransitionOn), prettyTime(nightTransitionOff))
0112 
0113             readonly property string morningChange: i18n("Color temperature begins changing to day time at %1 and is fully changed by %2", prettyTime(dayTransitionOn),
0114                                                         prettyTime(dayTransitionOff))
0115 
0116             text: `${eveningChange}\n\n${morningChange}`
0117             visible: hover.hovered && !root.singleColor
0118 
0119             function prettyTime(minutes) {
0120                 const date = new Date()
0121                 date.setHours(minutes / 60)
0122                 date.setMinutes(minutes % 60)
0123                 return date.toLocaleString(Qt.locale(), "h:mm");
0124             }
0125         }
0126     }
0127 
0128     RowLayout {
0129         id: axis
0130         Layout.fillWidth: true
0131 
0132         Repeater {
0133             model: 25
0134             delegate: QQC2.Label {
0135                 Layout.fillWidth: true
0136                 Layout.preferredWidth: 10  // The actual value doesn't matter. It just makes the labels the same size
0137                 Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
0138                 horizontalAlignment: Text.AlignHCenter
0139                 text: {
0140                     if (root.show24h) {
0141                         return `${index % 24}`
0142                     }
0143                     if (index % 12 == 0) {
0144                         return (index % 24 == 0) ? '12\nAM' : '12\nPM'
0145                     }
0146                     return `${index % 12}`
0147                 }
0148                 textFormat: Text.PlainText
0149                 color: Kirigami.Theme.textColor
0150             }
0151         }
0152     }
0153 
0154     function minutesForDate(date) {
0155         return date.getHours() * 60 + date.getMinutes()
0156     }
0157 
0158     function isThemeDark() {
0159         const bg = Kirigami.Theme.backgroundColor;
0160         const gray = (bg.r + bg.g + bg.b) / 3;
0161         return (gray < 192);
0162     }
0163 
0164     function colorForTemp(temp) {
0165         // from KWin colortemperature.h
0166         /**
0167             * Whitepoint values for temperatures at 100K intervals.
0168             * These will be interpolated for the actual temperature.
0169             * This table was provided by Ingo Thies, 2013.
0170             * See the following file for more information:
0171             * https://github.com/jonls/redshift/blob/master/README-colorramp
0172             */
0173         const temp2RGB = [
0174             [1.00000000, 0.18172716, 0.00000000],     /* 1000K */
0175             [1.00000000, 0.25503671, 0.00000000],     /* 1100K */
0176             [1.00000000, 0.30942099, 0.00000000],     /* 1200K */
0177             [1.00000000, 0.35357379, 0.00000000],     /*  ...  */
0178             [1.00000000, 0.39091524, 0.00000000],
0179             [1.00000000, 0.42322816, 0.00000000],
0180             [1.00000000, 0.45159884, 0.00000000],
0181             [1.00000000, 0.47675916, 0.00000000],
0182             [1.00000000, 0.49923747, 0.00000000],
0183             [1.00000000, 0.51943421, 0.00000000],
0184             [1.00000000, 0.54360078, 0.08679949],     /* 2000K */
0185             [1.00000000, 0.56618736, 0.14065513],
0186             [1.00000000, 0.58734976, 0.18362641],
0187             [1.00000000, 0.60724493, 0.22137978],
0188             [1.00000000, 0.62600248, 0.25591950],
0189             [1.00000000, 0.64373109, 0.28819679],
0190             [1.00000000, 0.66052319, 0.31873863],
0191             [1.00000000, 0.67645822, 0.34786758],
0192             [1.00000000, 0.69160518, 0.37579588],
0193             [1.00000000, 0.70602449, 0.40267128],
0194             [1.00000000, 0.71976951, 0.42860152],     /* 3000K */
0195             [1.00000000, 0.73288760, 0.45366838],
0196             [1.00000000, 0.74542112, 0.47793608],
0197             [1.00000000, 0.75740814, 0.50145662],
0198             [1.00000000, 0.76888303, 0.52427322],
0199             [1.00000000, 0.77987699, 0.54642268],
0200             [1.00000000, 0.79041843, 0.56793692],
0201             [1.00000000, 0.80053332, 0.58884417],
0202             [1.00000000, 0.81024551, 0.60916971],
0203             [1.00000000, 0.81957693, 0.62893653],
0204             [1.00000000, 0.82854786, 0.64816570],     /* 4000K */
0205             [1.00000000, 0.83717703, 0.66687674],
0206             [1.00000000, 0.84548188, 0.68508786],
0207             [1.00000000, 0.85347859, 0.70281616],
0208             [1.00000000, 0.86118227, 0.72007777],
0209             [1.00000000, 0.86860704, 0.73688797],     /* 4500K */
0210             [1.00000000, 0.87576611, 0.75326132],
0211             [1.00000000, 0.88267187, 0.76921169],
0212             [1.00000000, 0.88933596, 0.78475236],
0213             [1.00000000, 0.89576933, 0.79989606],
0214             [1.00000000, 0.90198230, 0.81465502],     /* 5000K */
0215             [1.00000000, 0.90963069, 0.82838210],
0216             [1.00000000, 0.91710889, 0.84190889],
0217             [1.00000000, 0.92441842, 0.85523742],
0218             [1.00000000, 0.93156127, 0.86836903],
0219             [1.00000000, 0.93853986, 0.88130458],
0220             [1.00000000, 0.94535695, 0.89404470],
0221             [1.00000000, 0.95201559, 0.90658983],
0222             [1.00000000, 0.95851906, 0.91894041],
0223             [1.00000000, 0.96487079, 0.93109690],
0224             [1.00000000, 0.97107439, 0.94305985],     /* 6000K */
0225             [1.00000000, 0.97713351, 0.95482993],
0226             [1.00000000, 0.98305189, 0.96640795],
0227             [1.00000000, 0.98883326, 0.97779486],
0228             [1.00000000, 0.99448139, 0.98899179],
0229             [1.00000000, 1.00000000, 1.00000000]      /* 6500K */
0230         ]
0231         var rgb = temp2RGB[(temp - 1000)/100];
0232         var col = Qt.rgba(rgb[0], rgb[1], rgb[2], 1);
0233         if (isThemeDark() && col.hsvSaturation < 0.7) {
0234             col.hsvSaturation += 0.3;
0235         }
0236         return col;
0237     }
0238 }