|
|
|
@ -11,7 +11,6 @@ import NERvGear.Controls 1.0
|
|
|
|
|
import NERvGear.Templates 1.0 as T |
|
|
|
|
import NERvGear.Preferences 1.0 as P |
|
|
|
|
|
|
|
|
|
import "qrc:/qml/com.gpbeta.data.weather" as Private |
|
|
|
|
import "utils.js" as Utils |
|
|
|
|
|
|
|
|
|
WidgetTemplate { |
|
|
|
@ -19,7 +18,7 @@ WidgetTemplate {
|
|
|
|
|
title: qsTr("Ordinal Scale Weather Widget") |
|
|
|
|
editing: styleDialog.active |
|
|
|
|
|
|
|
|
|
version: "1.0.1" |
|
|
|
|
version: "1.1.1" |
|
|
|
|
defaultValues: { |
|
|
|
|
"Display Location": "", |
|
|
|
|
"Update Interval": |
|
|
|
@ -53,6 +52,7 @@ WidgetTemplate {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readonly property var configs: widget.settings.styles |
|
|
|
|
readonly property real w: widget.width |
|
|
|
|
readonly property real h: 0.46*widget.width |
|
|
|
@ -60,13 +60,38 @@ WidgetTemplate {
|
|
|
|
|
readonly property var fontweight: [Font.Light, Font.Normal, Font.Bold] |
|
|
|
|
readonly property var sfontweight: [qsTr("Light"), qsTr("Normal"), qsTr("Bold")] |
|
|
|
|
|
|
|
|
|
readonly property NVG.DataSource dataSource: NVG.DataSource { |
|
|
|
|
configuration: {"mode":0,"unit":"","interval":60000*configs["Update Interval"]["Value"]*(1+59*configs["Update Interval"]["Unit"]),"update":configs["Address"],"source":"nvg://weather.data.gpbeta.com/data#raw","value":"current"} |
|
|
|
|
readonly property var weatherConfig: configs.Address |
|
|
|
|
property T.Value vCurrentWeather |
|
|
|
|
property var currentWeatherData |
|
|
|
|
|
|
|
|
|
onWeatherConfigChanged: { |
|
|
|
|
if (!vCurrentWeather) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
currentWeatherData = undefined; |
|
|
|
|
vCurrentWeather.status = T.Value.Loading; |
|
|
|
|
if (timer.running) |
|
|
|
|
timer.restart(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function updateCurrentWeather() { |
|
|
|
|
if (vCurrentWeather.status === T.Value.Ready) { |
|
|
|
|
currentWeatherData = vCurrentWeather.current; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NVG.DataSourceRawOutput { |
|
|
|
|
id: output |
|
|
|
|
source: dataSource |
|
|
|
|
Timer { |
|
|
|
|
id: timer |
|
|
|
|
repeat: true |
|
|
|
|
triggeredOnStart: true |
|
|
|
|
interval: 60000*configs["Update Interval"]["Value"]*(1+59*configs["Update Interval"]["Unit"]) |
|
|
|
|
|
|
|
|
|
onTriggered: { |
|
|
|
|
if (vCurrentWeather) { |
|
|
|
|
vCurrentWeather.update.execute(); |
|
|
|
|
updateCurrentWeather(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Item { |
|
|
|
@ -152,7 +177,7 @@ WidgetTemplate {
|
|
|
|
|
anchors.centerIn: weather |
|
|
|
|
autoTransform: true |
|
|
|
|
visible: false |
|
|
|
|
source: "../Images/Weather/" + Utils.weather_codes[output.result?.iconCode ?? "44"] + ".png" |
|
|
|
|
source: "../Images/Weather/" + Utils.weather_codes[currentWeatherData?.iconCode ?? "44"] + ".png" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Rectangle { |
|
|
|
@ -209,7 +234,7 @@ WidgetTemplate {
|
|
|
|
|
anchors.horizontalCenterOffset: temper_box.width*configs["Temperature Text Settings"]["X Offset"]/200 |
|
|
|
|
anchors.verticalCenterOffset: h*configs["Temperature Text Settings"]["Y Offset"]/200 |
|
|
|
|
color: configs["Temperature Text Settings"]["Font Color"] |
|
|
|
|
text: (output.result?.temperature ?? "--") + "°" |
|
|
|
|
text: (currentWeatherData?.temperature ?? "--") + "°" |
|
|
|
|
font.pixelSize: w*0.002*configs["Temperature Text Settings"]["Font Size"] |
|
|
|
|
font.family: fonts[configs["Temperature Text Settings"]["Font Name"]] |
|
|
|
|
font.weight: fontweight[configs["Temperature Text Settings"]["Font Weight"]] |
|
|
|
@ -288,108 +313,12 @@ WidgetTemplate {
|
|
|
|
|
widget.settings.styles = rootPreference.save(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
P.DialogPreference { |
|
|
|
|
id: rootPref |
|
|
|
|
label: qsTr("Location") |
|
|
|
|
P.PreferenceLoader { |
|
|
|
|
name: "Address" |
|
|
|
|
|
|
|
|
|
displayValue: widget.settings.styles?.Address ? widget.settings.styles.Address.address : qsTr("Click to set location.") |
|
|
|
|
|
|
|
|
|
load: function (newValue) { |
|
|
|
|
errorLabel.visible = false; |
|
|
|
|
queryField.text = ""; |
|
|
|
|
radioRepeater.model = newValue ? [ newValue ] : undefined; |
|
|
|
|
|
|
|
|
|
if (radioRepeater.count) |
|
|
|
|
radioColumn.children[0].checked = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
save: function () { |
|
|
|
|
return radioGroup.checkedButton ? radioGroup.checkedButton.location : undefined; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function searchLocation() { |
|
|
|
|
if (!queryField.text) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
rootPref.enabled = false; |
|
|
|
|
errorLabel.visible = false; |
|
|
|
|
busyIndicator.running = true; |
|
|
|
|
|
|
|
|
|
Private.Manager.searchLocation(queryField.text) |
|
|
|
|
.then(function (result) { |
|
|
|
|
radioRepeater.model = result; |
|
|
|
|
if (radioRepeater.count) |
|
|
|
|
radioColumn.children[0].checked = true; |
|
|
|
|
}, function (err) { |
|
|
|
|
console.warn(err); |
|
|
|
|
errorLabel.visible = true; |
|
|
|
|
radioRepeater.model = undefined; |
|
|
|
|
}) |
|
|
|
|
.then(function () { |
|
|
|
|
rootPref.enabled = true; |
|
|
|
|
busyIndicator.running = false; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
RowLayout { |
|
|
|
|
TextField { |
|
|
|
|
id: queryField |
|
|
|
|
Layout.fillWidth: true |
|
|
|
|
|
|
|
|
|
placeholderText: qsTr("Search: country, city, district...") |
|
|
|
|
|
|
|
|
|
onAccepted: rootPref.searchLocation() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ToolButton { |
|
|
|
|
icon.name: "regular:\uf002" |
|
|
|
|
|
|
|
|
|
onClicked: rootPref.searchLocation() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Item { |
|
|
|
|
implicitWidth: Math.max(busyIndicator.implicitWidth, radioColumn.implicitWidth) |
|
|
|
|
implicitHeight: Math.max(busyIndicator.implicitHeight, radioColumn.implicitHeight) |
|
|
|
|
|
|
|
|
|
BusyIndicator { |
|
|
|
|
id: busyIndicator |
|
|
|
|
anchors.centerIn: parent |
|
|
|
|
running: false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Label { |
|
|
|
|
id: errorLabel |
|
|
|
|
anchors.centerIn: parent |
|
|
|
|
enabled: false |
|
|
|
|
visible: false |
|
|
|
|
text: qsTr("Location not found") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ButtonGroup { |
|
|
|
|
id: radioGroup |
|
|
|
|
buttons: radioColumn.children |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Column { |
|
|
|
|
id: radioColumn |
|
|
|
|
width: parent.width |
|
|
|
|
|
|
|
|
|
Repeater { |
|
|
|
|
id: radioRepeater |
|
|
|
|
|
|
|
|
|
RadioButton { |
|
|
|
|
readonly property var location: modelData |
|
|
|
|
|
|
|
|
|
text: modelData.address |
|
|
|
|
width: radioColumn.width |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
sourceComponent: widget.vCurrentWeather ? widget.vCurrentWeather.update.preference : null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
P.TextFieldPreference { |
|
|
|
|
name: "Display Location" |
|
|
|
|
label: qsTr("Display Location") |
|
|
|
@ -605,4 +534,23 @@ WidgetTemplate {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onCompleted: { |
|
|
|
|
const url = "nvg://weather.data.gpbeta.com/data#raw"; |
|
|
|
|
const component = Qt.createComponent(Qt.resolvedUrl(url)); |
|
|
|
|
if (component.status === Component.Ready) { |
|
|
|
|
const cfg = Qt.binding(function () { return configs.Address; }); |
|
|
|
|
|
|
|
|
|
const data = component.createObject(widget); |
|
|
|
|
if ((vCurrentWeather = data.query("current"))) { |
|
|
|
|
vCurrentWeather.update.configuration = cfg; |
|
|
|
|
vCurrentWeather.statusChanged.connect(updateCurrentWeather); |
|
|
|
|
} else { |
|
|
|
|
console.warn("cannot find current weather value"); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
console.warn("cannot create weather data source"); |
|
|
|
|
} |
|
|
|
|
timer.running = true; |
|
|
|
|
} |
|
|
|
|
} |