Commit 2a42a15c authored by Nate Graham's avatar Nate Graham 💤
Browse files

[KCMs/Night Color] Make activation criteria and times more obvious

Summary:
This patch polishes the Night Color UI to make it more obvious what the feature does,
what the activation triggers are and mean, and when activation will start and end.

Test Plan: {F7816766}

Reviewers: #vdg, #plasma, davidedmundson, romangg, filipf

Reviewed By: #vdg, #plasma, davidedmundson, romangg, filipf

Subscribers: filipf, abetts, romangg, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D25920
parent 115a3e1a
/********************************************************************
Copyright 2017 Roman Gilg <subdiff@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 2.1
import org.kde.kirigami 2.5 as Kirigami
Kirigami.FormLayout {
twinFormLayouts: parentLayout
enabled: activator.checked
property double latitude
property double longitude
onLatitudeChanged: latitudeField.backend = latitude;
onLongitudeChanged: longitudeField.backend = longitude;
NumberField {
id: latitudeField
Kirigami.FormData.label: i18n("Latitude:")
backend: locator.latitude
enabled: false
}
NumberField {
id: longitudeField
Kirigami.FormData.label: i18n("Longitude:")
backend: locator.longitude
enabled: false
}
}
......@@ -15,12 +15,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
import QtQuick 2.1
import org.kde.kirigami 2.5 as Kirigami
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.5 as Kirigami
Kirigami.FormLayout {
twinFormLayouts: parentLayout
enabled: activator.checked
Connections {
target: root
......@@ -32,37 +32,40 @@ Kirigami.FormLayout {
longitudeFixedField.backend = cA.longitudeFixed;
}
QQC2.Button {
text: i18n("Detect Location")
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
icon.name: "find-location"
onClicked: {
latitudeFixedField.backend = locator.latitude;
longitudeFixedField.backend = locator.longitude;
}
}
NumberField {
id: latitudeFixedField
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
Kirigami.FormData.label: i18n("Latitude:")
backend: cA.latitudeFixedStaged
validator: DoubleValidator {bottom: -90; top: 90; decimals: 10}
onBackendChanged: {
cA.latitudeFixedStaged = backend;
manualLocationsViewRow.change();
calcNeedsSave();
}
}
NumberField {
id: longitudeFixedField
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
Kirigami.FormData.label: i18n("Longitude:")
backend: cA.longitudeFixedStaged
validator: DoubleValidator {bottom: -180; top: 180; decimals: 10}
onBackendChanged: {
cA.longitudeFixedStaged = backend;
manualLocationsViewRow.change();
calcNeedsSave();
}
}
QQC2.Button {
text: i18n("Detect Location")
implicitWidth: longitudeFixedField.width // TODO: see if there is a smarter way for doing this
icon.name: "find-location"
onClicked: {
latitudeFixedField.backend = locator.latitude;
longitudeFixedField.backend = locator.longitude;
}
}
}
......@@ -20,7 +20,6 @@ import QtQuick.Controls 2.5 as QQC2
Kirigami.FormLayout {
twinFormLayouts: parentLayout
enabled: activator.checked
property double latitude
property double longitude
......@@ -33,31 +32,33 @@ Kirigami.FormLayout {
eveningTimings = sunCalc.getEveningTimings(latitude, longitude);
}
TimeField {
id: mornBeginField
Kirigami.FormData.label: i18n("Sunrise begins:")
backend: morningTimings.begin
enabled: false
function prettyTime(date) {
return date.toLocaleString(Qt.locale(), "h:m");
}
TimeField {
id: mornEndField
Kirigami.FormData.label: i18n("...and ends:")
backend: morningTimings.end
enabled: false
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
TimeField {
id: evenBeginField
Kirigami.FormData.label: i18n("Sunset begins:")
backend: eveningTimings.begin
enabled: false
QQC2.Label {
wrapMode: Text.Wrap
text: i18n("Night Color begins at %1", prettyTime(eveningTimings.begin))
}
QQC2.Label {
wrapMode: Text.Wrap
text: i18n("Color fully changed at %1", prettyTime(eveningTimings.end))
}
Item {
Kirigami.FormData.isSection: true
}
TimeField {
id: evenEndField
Kirigami.FormData.label: i18n("...and ends:")
backend: eveningTimings.end
enabled: false
QQC2.Label {
wrapMode: Text.Wrap
text: i18n("Night Color begins changing back at %1", prettyTime(morningTimings.begin))
}
QQC2.Label {
wrapMode: Text.Wrap
text: i18n("Normal coloration restored by %1", prettyTime(morningTimings.end))
}
}
......@@ -28,6 +28,7 @@ KCM.SimpleKCM {
property int error: cA.error
property bool defaultRequested: false
implicitHeight: Kirigami.Units.gridUnit * 29
implicitWidth: Kirigami.Units.gridUnit * 35
CC.CompositorAdaptor {
id: cA
......@@ -108,13 +109,22 @@ KCM.SimpleKCM {
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: Math.round(root.width * 0.5)
text: i18n("Night Color makes the colors on the screen warmer to reduce eye strain.")
text: i18n("Night Color makes the colors on the screen warmer to reduce eye strain at the time of your choosing.")
wrapMode: Text.WordWrap
}
Kirigami.FormLayout {
id: parentLayout
Connections {
target: root
onReset: {
mornBeginManField.backend = cA.morningBeginFixed;
evenBeginManField.backend = cA.eveningBeginFixed;
transTimeField.value = cA.transitionTime;
}
}
QQC2.CheckBox {
id: activator
text: i18n("Activate Night Color")
......@@ -132,7 +142,7 @@ KCM.SimpleKCM {
}
GridLayout {
Kirigami.FormData.label: i18n("Night Color temperature:")
Kirigami.FormData.label: i18n("Night Color Temperature:")
Kirigami.FormData.buddyFor: tempSlider
enabled: activator.checked
......@@ -140,9 +150,10 @@ KCM.SimpleKCM {
QQC2.Slider {
id: tempSlider
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
enabled: activator.checked
from: cA.minimalTemperature
implicitWidth: modeSwitcher.width
to: cA.neutralTemperature
value: cA.nightTemperature
stepSize: 100
......@@ -176,201 +187,128 @@ KCM.SimpleKCM {
QQC2.ComboBox {
id: modeSwitcher
Kirigami.FormData.label: i18n("Operation mode:")
// Work around https://bugs.kde.org/show_bug.cgi?id=403153
Layout.minimumWidth: Kirigami.Units.gridUnit * 17
Kirigami.FormData.label: i18n("Activation time:")
enabled: activator.checked
model: [
i18n("Automatic"),
i18n("Location"),
i18n("Times"),
i18n("Constant")
i18n("Sunset to sunrise at current location"),
i18n("Sunset to sunrise at manual location"),
i18n("Custom time"),
i18n("Always on")
]
currentIndex: cA.mode
onCurrentIndexChanged: {
cA.modeStaged = currentIndex;
advancedControlLoader.updatePage(currentIndex);
calcNeedsSave();
}
}
}
Kirigami.FormLayout {
// Show current location in auto mode
QQC2.Label {
visible: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeAutomatic
enabled: activator.checked
wrapMode: Text.Wrap
text: i18n("Latitude: %1 Longitude: %2", locator.latitude, locator.longitude)
}
Loader {
id: advancedControlLoader
function updatePage(index) {
switch (index) {
case CC.CompositorAdaptor.ModeAutomatic:
sourceComponent = automaticView;
break;
case CC.CompositorAdaptor.ModeLocation:
sourceComponent = manualLocationsView;
break;
case CC.CompositorAdaptor.ModeTimings:
sourceComponent = manualTimingsView;
break;
case CC.CompositorAdaptor.ModeConstant:
default:
sourceComponent = undefined;
break;
}
// Show time entry fields in manual timings mode
TimeField {
id: evenBeginManField
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
visible: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeTimings
Kirigami.FormData.label: i18n("Turn on at:")
backend: cA.eveningBeginFixedStaged
onBackendChanged: {cA.eveningBeginFixedStaged = backend;
calcNeedsSave();
}
}
Component {
id: automaticView
QQC2.ToolTip {
text: i18n("Input format: HH:MM")
}
}
ColumnLayout {
TimeField {
id: mornBeginManField
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
visible: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeTimings
Kirigami.FormData.label: i18n("Turn off at:")
backend: cA.morningBeginFixedStaged
onBackendChanged: {cA.morningBeginFixedStaged = backend;
calcNeedsSave();
}
Loader {
sourceComponent: TimingsView {
latitude: locator.latitude
longitude: locator.longitude
}
}
QQC2.ToolTip {
text: i18n("Input format: HH:MM")
}
}
Kirigami.Separator {
Layout.fillWidth: true
Kirigami.FormData.isSection: true
}
QQC2.SpinBox {
id: transTimeField
visible: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeTimings
// Match width of combobox and input fields
Layout.minimumWidth: modeSwitcher.width
Kirigami.FormData.label: i18n("Transition duration:")
from: 1
to: 600 // less than 12 hours (in minutes: 720)
value: cA.transitionTimeStaged
editable: true
onValueModified: {
cA.transitionTimeStaged = value;
calcNeedsSave();
}
textFromValue: function(value, locale) {
return i18np("%1 minute", "%1 minutes", value)
}
valueFromText: function(text, locale) {
return parseInt(text);
}
Loader {
sourceComponent: LocationsAutoView {
latitude: locator.latitude
longitude: locator.longitude
}
}
QQC2.ToolTip {
text: i18n("Input minutes - min. 1, max. 600")
}
}
Component {
id: manualLocationsView
ColumnLayout {
id: manualLocationsViewRow
signal change()
Loader {
sourceComponent: TimingsView {
latitude: cA.latitudeFixedStaged
longitude: cA.longitudeFixedStaged
Connections {
target: manualLocationsViewRow
onChange: {
reset();
}
}
}
}
QQC2.Label {
id: manualTimingsError1
visible: evenBeginManField.getNormedDate() - mornBeginManField.getNormedDate() <= 0
font.italic: true
text: i18n("Error: Morning is before evening.")
}
Kirigami.Separator {
Layout.fillWidth: true
Kirigami.FormData.isSection: true
QQC2.Label {
id: manualTimingsError2
visible: {
if (manualTimingsError1.visible) {
return false;
}
var trTime = transTimeField.backend * 60 * 1000;
var mor = mornBeginManField.getNormedDate();
var eve = evenBeginManField.getNormedDate();
Loader {
sourceComponent: LocationsFixedView {}
}
return eve - mor <= trTime || eve - mor >= 86400000 - trTime;
}
font.italic: true
text: i18n("Error: Transition time overlaps.")
}
}
Component {
id: manualTimingsView
ColumnLayout {
Loader {
sourceComponent: Kirigami.FormLayout {
twinFormLayouts: parentLayout
enabled: activator.checked && cA.timingsEnabled
Connections {
target: root
onReset: {
mornBeginManField.backend = cA.morningBeginFixed;
evenBeginManField.backend = cA.eveningBeginFixed;
transTimeField.backend = cA.transitionTime;
}
}
TimeField {
id: mornBeginManField
Kirigami.FormData.label: i18n("Sunrise begins:")
backend: cA.morningBeginFixedStaged
onBackendChanged: {cA.morningBeginFixedStaged = backend;
calcNeedsSave();
}
QQC2.ToolTip {
text: i18n("(Input format: HH:MM)")
}
}
TimeField {
id: evenBeginManField
Kirigami.FormData.label: i18n("Sunset begins:")
backend: cA.eveningBeginFixedStaged
onBackendChanged: {cA.eveningBeginFixedStaged = backend;
calcNeedsSave();
}
QQC2.ToolTip {
text: i18n("Input format: HH:MM")
}
}
QQC2.SpinBox {
id: transTimeField
// Match width of other text fields
Layout.minimumWidth: 200
Kirigami.FormData.label: i18n("Transition duration:")
from: 1
to: 600 // less than 12 hours (in minutes: 720)
value: cA.transitionTimeStaged
editable: true
onValueModified: {
cA.transitionTimeStaged = value;
calcNeedsSave();
}
textFromValue: function(value, locale) {
return i18np("%1 minute", "%1 minutes", value)
}
valueFromText: function(text, locale) {
return parseInt(text);
}
QQC2.ToolTip {
text: i18n("Input minutes - min. 1, max. 600")
}
}
QQC2.Label {
id: manualTimingsError1
visible: evenBeginManField.getNormedDate() - mornBeginManField.getNormedDate() <= 0
font.italic: true
text: i18n("Error: Morning is before evening.")
}
QQC2.Label {
id: manualTimingsError2
visible: {
if (manualTimingsError1.visible) {
return false;
}
var trTime = transTimeField.backend * 60 * 1000;
var mor = mornBeginManField.getNormedDate();
var eve = evenBeginManField.getNormedDate();
return eve - mor <= trTime || eve - mor >= 86400000 - trTime;
}
font.italic: true
text: i18n("Error: Transition time overlaps.")
}
}
}
}
}
// Show location chooser in manual location mode
LocationsFixedView {
visible: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeLocation
enabled: activator.checked
}
// Show start/end times in automatic and manual location modes
TimingsView {
id: timings
visible: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeAutomatic ||
modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeLocation
enabled: activator.checked
latitude: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeAutomatic ? locator.latitude : cA.latitudeFixedStaged
longitude: modeSwitcher.currentIndex === CC.CompositorAdaptor.ModeAutomatic ? locator.longitude : cA.longitudeFixedStaged
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment