kcms/nightcolor: Add map to "manual location" mode

Most people don't have their latitude and longitude memorized. It is
*far* easier for people to point out their approximate location on a
map, than to look up their latitude and longitude online.

This also removes the need for a "Detect Location" button there.
wilder-5.26
Bharadwaj Raju 4 years ago committed by Nate Graham
parent 0baa8a97fa
commit 648648f118
  1. 2
      kcms/nightcolor/CMakeLists.txt
  2. 11
      kcms/nightcolor/kcm.cpp
  3. 3
      kcms/nightcolor/kcm.h
  4. 268
      kcms/nightcolor/package/contents/ui/LocationsFixedView.qml
  5. 5
      kcms/nightcolor/package/contents/ui/main.qml
  6. BIN
      kcms/nightcolor/worldmap.png

@ -27,4 +27,6 @@ target_link_libraries(kcm_nightcolor
PW::LibColorCorrect PW::LibColorCorrect
) )
install(FILES worldmap.png DESTINATION ${KDE_INSTALL_DATADIR}/plasma/nightcolor)
kpackage_install_package(package kcm_nightcolor kcms) kpackage_install_package(package kcm_nightcolor kcms)

@ -6,6 +6,9 @@
#include "kcm.h" #include "kcm.h"
#include <QIcon>
#include <QStandardPaths>
#include <KLocalizedString> #include <KLocalizedString>
#include <KPluginFactory> #include <KPluginFactory>
@ -22,6 +25,8 @@ KCMNightColor::KCMNightColor(QObject *parent, const KPluginMetaData &data, const
qmlRegisterAnonymousType<NightColorSettings>("org.kde.private.kcms.nightcolor", 1); qmlRegisterAnonymousType<NightColorSettings>("org.kde.private.kcms.nightcolor", 1);
qmlRegisterUncreatableMetaObject(ColorCorrect::staticMetaObject, "org.kde.private.kcms.nightcolor", 1, 0, "NightColorMode", "Error: only enums"); qmlRegisterUncreatableMetaObject(ColorCorrect::staticMetaObject, "org.kde.private.kcms.nightcolor", 1, 0, "NightColorMode", "Error: only enums");
worldMapFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("plasma/nightcolor/worldmap.png"), QStandardPaths::LocateFile);
setButtons(Apply | Default); setButtons(Apply | Default);
} }
@ -30,6 +35,12 @@ NightColorSettings *KCMNightColor::nightColorSettings() const
return m_data->settings(); return m_data->settings();
} }
// FIXME: This was added to work around the nonstandardness of the Breeze zoom icons
// remove once https://bugs.kde.org/show_bug.cgi?id=435671 is fixed
bool KCMNightColor::isIconThemeBreeze()
{
return QIcon::themeName().contains(QStringLiteral("breeze"));
}
} }
#include "kcm.moc" #include "kcm.moc"

@ -18,14 +18,17 @@ class KCMNightColor : public KQuickAddons::ManagedConfigModule
Q_OBJECT Q_OBJECT
Q_PROPERTY(NightColorSettings *nightColorSettings READ nightColorSettings CONSTANT) Q_PROPERTY(NightColorSettings *nightColorSettings READ nightColorSettings CONSTANT)
Q_PROPERTY(QString worldMapFile MEMBER worldMapFile CONSTANT)
public: public:
KCMNightColor(QObject *parent, const KPluginMetaData &data, const QVariantList &args); KCMNightColor(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
~KCMNightColor() override = default; ~KCMNightColor() override = default;
NightColorSettings *nightColorSettings() const; NightColorSettings *nightColorSettings() const;
Q_INVOKABLE bool isIconThemeBreeze();
private: private:
NightColorData *const m_data; NightColorData *const m_data;
QString worldMapFile;
}; };
} }

@ -4,22 +4,247 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
import QtQuick 2.1 import QtQuick 2.15
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Controls 2.5 as QQC2 import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.5 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kcm 1.5 as KCM import org.kde.kcm 1.5 as KCM
import QtGraphicalEffects 1.12
Kirigami.FormLayout { Kirigami.FormLayout {
twinFormLayouts: parentLayout
/* Equirectangular projection maps (x, y) to (lat, long) cleanly */
function longitudeToX(lon) {
return (lon + 180) * (mapImage.width / 360);
}
function latitudeToY(lat) {
return (90 - lat) * (mapImage.height / 180);
}
function xToLongitude(x) {
return (x / (mapImage.width / 360)) - 180;
}
function yToLatitude(y) {
return 90 - (y / (mapImage.height / 180));
}
ColumnLayout {
QQC2.Label {
id: mapLabel
wrapMode: Text.Wrap
Layout.maximumWidth: mapRect.width
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.alignment: Qt.AlignHCenter
text: Kirigami.Settings.tabletMode
? i18nc("@label:chooser Tap should be translated to mean touching using a touchscreen", "Tap to choose your location on the map.")
: i18nc("@label:chooser Click should be translated to mean clicking using a mouse", "Click to choose your location on the map.")
font: Kirigami.Theme.smallFont
}
Kirigami.ShadowedRectangle {
id: mapRect
Layout.alignment: Qt.AlignHCenter
implicitWidth: Kirigami.Units.gridUnit * 30
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
implicitHeight: Kirigami.Units.gridUnit * 15
Layout.maximumHeight: Kirigami.Units.gridUnit * 15
radius: Kirigami.Units.smallSpacing
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.View
color: Kirigami.Theme.backgroundColor
shadow.xOffset: 0
shadow.yOffset: 2
shadow.size: 10
shadow.color: Qt.rgba(0, 0, 0, 0.3)
property double zoomFactor: 1.2;
property double currentScale: 1.0;
/* Zoom in/out buttons */
RowLayout {
anchors {
right: parent.right
rightMargin: Kirigami.Units.smallSpacing*2
bottom: parent.bottom
bottomMargin: Kirigami.Units.smallSpacing*2
}
// Always show above thumbnail content
z: 9999
QQC2.Button {
// HACK: using list-add and list-remove for more obvious/standard zoom icons till we change the Breeze ones
// https://bugs.kde.org/show_bug.cgi?id=435671
text: i18n("Zoom in")
display: QQC2.AbstractButton.IconOnly
icon.name: kcm.isIconThemeBreeze() ? "list-add" : "zoom-in"
activeFocusOnTab: false
onClicked: {
if (mapRect.currentScale < 5) {
let centrePos = { x: mapImage.width / 2, y: mapImage.height / 2 };
var realX = centrePos.x * mapZoom.xScale
var realY = centrePos.y * mapZoom.yScale
mapFlick.contentX -= (1-mapRect.zoomFactor)*realX
mapFlick.contentY -= (1-mapRect.zoomFactor)*realY
mapRect.currentScale *= mapRect.zoomFactor;
}
}
onDoubleClicked: {
onClicked();
}
QQC2.ToolTip {
text: parent.text
}
}
QQC2.Button {
// HACK: using list-add and list-remove for more obvious/standard zoom icons till we change the Breeze ones
// https://bugs.kde.org/show_bug.cgi?id=435671
text: i18n("Zoom in")
display: QQC2.AbstractButton.IconOnly
icon.name: kcm.isIconThemeBreeze() ? "list-remove" : "zoom-out"
activeFocusOnTab: false
onClicked: {
if (mapRect.currentScale > 1) {
let centrePos = { x: mapImage.width / 2, y: mapImage.height / 2 };
var realX = centrePos.x * mapZoom.xScale
var realY = centrePos.y * mapZoom.yScale
mapFlick.contentX -= (1-(1/mapRect.zoomFactor))*realX
mapFlick.contentY -= (1-(1/mapRect.zoomFactor))*realY
mapRect.currentScale *= (1/mapRect.zoomFactor)
}
}
onDoubleClicked: {
onClicked();
}
QQC2.ToolTip {
text: parent.text
}
}
}
Flickable {
id: mapFlick
anchors {
fill: parent
margins: Kirigami.Units.smallSpacing
}
contentWidth: mapImage.width * mapRect.currentScale
contentHeight: mapImage.height * mapRect.currentScale
clip: true
Image {
id: mapImage
source: kcm.worldMapFile
transform: Scale {
id: mapZoom
xScale: mapRect.currentScale
yScale: mapRect.currentScale
}
Kirigami.Icon {
z: 9999
id: mapPin
property double rawX: longitudeToX(kcm.nightColorSettings.longitudeFixed)
property double rawY: latitudeToY(kcm.nightColorSettings.latitudeFixed)
x: rawX - (width/2)/mapRect.currentScale
y: rawY - (height - 4)/mapRect.currentScale
width: Kirigami.Units.iconSizes.medium
height: Kirigami.Units.iconSizes.medium
source: "mark-location"
color: "#232629"
transform: Scale {
xScale: 1/mapRect.currentScale
yScale: 1/mapRect.currentScale
}
}
Connections {
target: kcm.nightColorSettings
function onLatitudeFixedChanged() {
mapPin.rawY = latitudeToY(kcm.nightColorSettings.latitudeFixed);
}
function onLongitudeFixedChanged() {
mapPin.rawX = longitudeToX(kcm.nightColorSettings.longitudeFixed);
}
}
TapHandler {
onTapped: {
let clickPos = mapImage.mapFromItem(root, eventPoint.scenePosition);
mapPin.rawX = clickPos.x;
mapPin.rawY = clickPos.y;
kcm.nightColorSettings.latitudeFixed = yToLatitude(mapPin.rawY);
kcm.nightColorSettings.longitudeFixed = xToLongitude(mapPin.rawX);
}
}
WheelHandler {
acceptedModifiers: Qt.ControlModifier
onWheel: {
let wheelPos = mapImage.mapFromItem(root, point.scenePosition);
var realX = wheelPos.x * mapZoom.xScale
var realY = wheelPos.y * mapZoom.yScale
let clicks = event.angleDelta.y / 120;
if (clicks > 0 && mapRect.currentScale < 5) {
mapFlick.contentX -= (1-mapRect.zoomFactor)*realX
mapFlick.contentY -= (1-mapRect.zoomFactor)*realY
mapRect.currentScale *= mapRect.zoomFactor;
} else if (clicks < 0 && mapRect.currentScale > 1) {
mapFlick.contentX -= (1-(1/mapRect.zoomFactor))*realX
mapFlick.contentY -= (1-(1/mapRect.zoomFactor))*realY
mapRect.currentScale *= (1/(mapRect.zoomFactor));
}
}
}
Component.onCompleted: {
width = mapFlick.width;
height = mapFlick.height;
}
}
}
}
TextEdit {
id: mapAttributionLabel
textFormat: TextEdit.RichText
wrapMode: Text.Wrap
readOnly: true
color: Kirigami.Theme.textColor
selectedTextColor: Kirigami.Theme.highlightedTextColor
selectionColor: Kirigami.Theme.highlightColor
font: Kirigami.Theme.smallFont
Layout.topMargin: Kirigami.Units.smallSpacing
Layout.maximumWidth: mapRect.width
Layout.alignment: Qt.AlignHCenter
text: xi18nc("@info", "Modified from <link url='https://commons.wikimedia.org/wiki/File:World_location_map_(equirectangular_180).svg'>World location map</link> by TUBS / Wikimedia Commons / <link url='https://creativecommons.org/licenses/by-sa/3.0'>CC BY-SA 3.0</link>")
onLinkActivated: (url) => Qt.openUrlExternally(url)
HoverHandler {
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
RowLayout {
Layout.topMargin: Kirigami.Units.smallSpacing
Layout.alignment: Qt.AlignHCenter
QQC2.Label {
text: i18nc("@label: textbox", "Latitude:")
}
Connections {
target: kcm.nightColorSettings
function onLatitudeFixedChanged() {
latitudeFixedField.backend = kcm.nightColorSettings.latitudeFixed;
}
function onLongitudeFixedChanged() {
longitudeFixedField.backend = kcm.nightColorSettings.longitudeFixed;
}
}
NumberField { NumberField {
id: latitudeFixedField id: latitudeFixedField
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
Layout.maximumWidth: modeSwitcher.width
Kirigami.FormData.label: i18n("Latitude:")
validator: DoubleValidator {bottom: -90; top: 90; decimals: 10} validator: DoubleValidator {bottom: -90; top: 90; decimals: 10}
backend: kcm.nightColorSettings.latitudeFixed backend: kcm.nightColorSettings.latitudeFixed
onBackendChanged: { onBackendChanged: {
@ -32,12 +257,11 @@ Kirigami.FormLayout {
} }
} }
QQC2.Label {
text: i18nc("@label: textbox", "Longitude:")
}
NumberField { NumberField {
id: longitudeFixedField id: longitudeFixedField
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
Layout.maximumWidth: modeSwitcher.width
Kirigami.FormData.label: i18n("Longitude:")
validator: DoubleValidator {bottom: -180; top: 180; decimals: 10} validator: DoubleValidator {bottom: -180; top: 180; decimals: 10}
backend: kcm.nightColorSettings.longitudeFixed backend: kcm.nightColorSettings.longitudeFixed
onBackendChanged: { onBackendChanged: {
@ -49,26 +273,6 @@ Kirigami.FormLayout {
extraEnabledConditions: kcm.nightColorSettings.active extraEnabledConditions: kcm.nightColorSettings.active
} }
} }
QQC2.Button {
text: i18n("Detect Location")
// Match combobox width
Layout.minimumWidth: modeSwitcher.width
icon.name: "find-location"
onClicked: {
startLocator();
latitudeFixedField.backend = locator.latitude;
longitudeFixedField.backend = locator.longitude;
}
} }
// Inform about geolocation access on clicking detect
QQC2.Label {
enabled: activator.checked
wrapMode: Text.Wrap
Layout.maximumWidth: modeSwitcher.width
text: i18n("The device's location will be detected using GPS (if available), or by sending network information to <a href=\"https://location.services.mozilla.com\">Mozilla Location Service</a>.")
onLinkActivated: { Qt.openUrlExternally("https://location.services.mozilla.com"); }
font: Kirigami.Theme.smallFont
} }
} }

@ -187,10 +187,6 @@ KCM.SimpleKCM {
] ]
} }
Item {
Kirigami.FormData.isSection: true
}
QQC2.ComboBox { QQC2.ComboBox {
id: modeSwitcher id: modeSwitcher
// Work around https://bugs.kde.org/show_bug.cgi?id=403153 // Work around https://bugs.kde.org/show_bug.cgi?id=403153
@ -370,6 +366,7 @@ KCM.SimpleKCM {
// Show location chooser in manual location mode // Show location chooser in manual location mode
LocationsFixedView { LocationsFixedView {
visible: kcm.nightColorSettings.mode === NightColorMode.Location visible: kcm.nightColorSettings.mode === NightColorMode.Location
Layout.alignment: Qt.AlignHCenter
enabled: activator.checked enabled: activator.checked
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Loading…
Cancel
Save