diff --git a/Images/Weather/Breezy.png b/Images/Weather/Breezy.png new file mode 100644 index 0000000..9ce338c Binary files /dev/null and b/Images/Weather/Breezy.png differ diff --git a/Images/Weather/Clear.png b/Images/Weather/Clear.png new file mode 100644 index 0000000..0ce7839 Binary files /dev/null and b/Images/Weather/Clear.png differ diff --git a/Images/Weather/Cloudy.png b/Images/Weather/Cloudy.png index bac0eb9..e2f965f 100644 Binary files a/Images/Weather/Cloudy.png and b/Images/Weather/Cloudy.png differ diff --git a/Images/Weather/Fog.png b/Images/Weather/Fog.png index c2d2859..5449535 100644 Binary files a/Images/Weather/Fog.png and b/Images/Weather/Fog.png differ diff --git a/Images/Weather/Hail.png b/Images/Weather/Hail.png new file mode 100644 index 0000000..213e6c7 Binary files /dev/null and b/Images/Weather/Hail.png differ diff --git a/Images/Weather/Hurricane.png b/Images/Weather/Hurricane.png new file mode 100644 index 0000000..a04f115 Binary files /dev/null and b/Images/Weather/Hurricane.png differ diff --git a/Images/Weather/IceCrystals.png b/Images/Weather/IceCrystals.png new file mode 100644 index 0000000..0cbc9fb Binary files /dev/null and b/Images/Weather/IceCrystals.png differ diff --git a/Images/Weather/LightSleet.png b/Images/Weather/LightSleet.png index 1e69b8a..3f10cb5 100644 Binary files a/Images/Weather/LightSleet.png and b/Images/Weather/LightSleet.png differ diff --git a/Images/Weather/LightSnow.png b/Images/Weather/LightSnow.png index 8f1b644..fe18c65 100644 Binary files a/Images/Weather/LightSnow.png and b/Images/Weather/LightSnow.png differ diff --git a/Images/Weather/PartlyCloudy.png b/Images/Weather/PartlyCloudy.png deleted file mode 100644 index e899d30..0000000 Binary files a/Images/Weather/PartlyCloudy.png and /dev/null differ diff --git a/Images/Weather/PartlyCloudyDay.png b/Images/Weather/PartlyCloudyDay.png new file mode 100644 index 0000000..4a54b0f Binary files /dev/null and b/Images/Weather/PartlyCloudyDay.png differ diff --git a/Images/Weather/PartlyCloudyNight.png b/Images/Weather/PartlyCloudyNight.png new file mode 100644 index 0000000..480816a Binary files /dev/null and b/Images/Weather/PartlyCloudyNight.png differ diff --git a/Images/Weather/Sandstorm.png b/Images/Weather/Sandstorm.png new file mode 100644 index 0000000..696c69a Binary files /dev/null and b/Images/Weather/Sandstorm.png differ diff --git a/Images/Weather/SnowShowers.png b/Images/Weather/SnowShowers.png index fe18c65..8f1b644 100644 Binary files a/Images/Weather/SnowShowers.png and b/Images/Weather/SnowShowers.png differ diff --git a/Images/Weather/Sunny.png b/Images/Weather/Sunny.png index 751fcff..3d6bc66 100644 Binary files a/Images/Weather/Sunny.png and b/Images/Weather/Sunny.png differ diff --git a/Images/Weather/ThunderyHeavyRain.png b/Images/Weather/ThunderyHeavyRain.png index 8450939..1969dca 100644 Binary files a/Images/Weather/ThunderyHeavyRain.png and b/Images/Weather/ThunderyHeavyRain.png differ diff --git a/Images/Weather/ThunderyShowers.png b/Images/Weather/ThunderyShowers.png index 4f92558..218f3f8 100644 Binary files a/Images/Weather/ThunderyShowers.png and b/Images/Weather/ThunderyShowers.png differ diff --git a/Images/Weather/Tornado.png b/Images/Weather/Tornado.png new file mode 100644 index 0000000..998aaa4 Binary files /dev/null and b/Images/Weather/Tornado.png differ diff --git a/Images/Weather/Unknown.png b/Images/Weather/Unknown.png index 6377c6a..6e1edaf 100644 Binary files a/Images/Weather/Unknown.png and b/Images/Weather/Unknown.png differ diff --git a/Locales/zh.qm b/Locales/zh.qm index 8e70205..90b9aa2 100644 Binary files a/Locales/zh.qm and b/Locales/zh.qm differ diff --git a/Locales/zh.ts b/Locales/zh.ts index d0d9b43..8ca81a5 100644 --- a/Locales/zh.ts +++ b/Locales/zh.ts @@ -4,48 +4,48 @@ BottomUI - + Ordinal Scale Bottom UI widget 序列之争底部UI挂件 - - + + Settings 设置 - + UI Settings UI设置 - + Configuration 配置项 - + Curve 曲线 - + Line Color 线条颜色 - + Line Width 线宽 - + Shadow Color 阴影颜色 - + Shadow Size 阴影大小 @@ -53,123 +53,123 @@ TopUI - + Ordinal Scale Top UI widget 序列之争顶部UI挂件 - + Light 细体 - + Normal 常规 - + Bold 粗体 - - + + Settings 设置 - + UI Settings UI设置 - + Configuration 设置项 - + Circle Color 中心圆颜色 - + Line Color 线条颜色 - + Top Line Action 顶部UI动作 - + Command 命令 - + Toggle UI 切换UI - + Curve 曲线 - + Line Width 线宽 - + Shadow Color 阴影颜色 - + Shadow Size 阴影大小 - + Battle UI 战斗UI - + Clock Visible 显示时间 - + 24 Hour Clock 24小时制 - + Font Color 字体颜色 - + Font Size 字体大小 - + Font Style 字体样式 - + Font Weight 字体粗细 - + Text Vertical Offset 文字垂直偏移 @@ -183,147 +183,160 @@ 序列之争天气挂件 - + Light 细体 - + Normal 常规 - + Bold 粗体 - - + + Settings 设置 - Refresh - 刷新 + 刷新 - + Configuration 配置项 - + Location 位置 - Search address by location, latitude and longitude. - 按地址、经纬度搜索地址。 + 按地址、经纬度搜索地址。 + + + + Click to set location. + 点击设置位置。 + + + + Search: country, city, district... + 输入:国家、城市或街道名字... + + + + Location not found + 未找到相关地点 - + Display Location 显示地址 - + The location to display in widget. 在挂件中显示的位置。 - + Update Interval 更新间隔 - - + + Minutes 分钟 - - + + Hours 小时 - + Unit 单位 - + Background Color 背景颜色 - + Background Opacity 背景不透明度 - + Area Opacity Difference 区域不透明度差异 - + Icon Color 图标颜色 - + Temperature Text Settings 温度文字设置 - - + + Font Color 字体颜色 - - + + Font Size 字体大小 - - + + Font Style 字体样式 - - + + Font Weight 字体粗细 - - + + X Offset X偏移量 - - + + Y Offset Y偏移量 - + Area Text Settings 地区文字设置 - + Border Margin 边距 diff --git a/package.json b/package.json index 7f5017c..a49e9e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "top.mashiros.widget.ordinalscale", - "version": "1.0.0", + "version": "1.1.1", "title": { "en": "Ordinal Scale Widget Collections", diff --git a/qml/BottomUI.qml b/qml/BottomUI.qml index 48480e6..5931e40 100644 --- a/qml/BottomUI.qml +++ b/qml/BottomUI.qml @@ -7,21 +7,31 @@ import NERvGear.Controls 1.0 import NERvGear.Templates 1.0 as T import NERvGear.Preferences 1.0 as P -T.Widget { +WidgetTemplate { id: widget - solid: true - visible: true title: qsTr("Ordinal Scale Bottom UI widget") - - property real thour: 0 - property real t12hour: 0 - property real tmin: 0 editing: styleDialog.active - readonly property var defaultValues: {"Curve":true,"Circle Color":"#fffcf9","Line Color":"#fffcf9","Line Width":38,"Shadow Color":"#e0e0e0","Shadow Size":0.5,"Battle UI":false,"Clock Visible":true,"Full Clock":true,"Font Color":"#f5f5f5","Font Size":44,"Font Name":0,"Font Weight":0,"Text Vertical Offset":16} - readonly property var configs: widget.settings.styles + version: "1.0.1" + defaultValues: { + "Curve": true, + "Circle Color": "#fffcf9", + "Line Color": "#fffcf9", + "Line Width": 38, + "Shadow Color": "#e0e0e0", + "Shadow Size": 0.5, + "Battle UI": false, + "Clock Visible": true, + "Full Clock": true, + "Font Color": "#f5f5f5", + "Font Size": 44, + "Font Name": 0, + "Font Weight": 0, + "Text Vertical Offset": 16 + } + property string line_color: configs["Line Color"] property string shadowColor: configs["Shadow Color"] property real shadowBlur: configs["Shadow Size"] @@ -30,6 +40,10 @@ T.Widget { readonly property real w: widget.width readonly property real r: (w**2+4*h**2)/2/h + onUpdated: { + widget.settings.styles = Object.assign(defaultValues, widget.settings.styles); + } + onConfigsChanged: { line.requestPaint(); triangle.requestPaint(); @@ -218,8 +232,4 @@ T.Widget { } } } - - Component.onCompleted: { - widget.settings.styles = widget.settings.styles ?? defaultValues; - } } diff --git a/qml/TopUI.qml b/qml/TopUI.qml index ef8cc91..2e68046 100644 --- a/qml/TopUI.qml +++ b/qml/TopUI.qml @@ -7,22 +7,13 @@ import NERvGear.Controls 1.0 import NERvGear.Templates 1.0 as T import NERvGear.Preferences 1.0 as P -T.Widget { +WidgetTemplate { id: widget - solid: true - visible: true title: qsTr("Ordinal Scale Top UI widget") - - property real thour: 0 - property real t12hour: 0 - property real tmin: -1 editing: styleDialog.active - - readonly property var fonts: Qt.fontFamilies() - readonly property var fontweight: [Font.Light, Font.Normal, Font.Bold] - readonly property var sfontweight: [qsTr("Light"), qsTr("Normal"), qsTr("Bold")] - - readonly property var defaultValues: { + + version: "1.0.1" + defaultValues: { "Curve": "true", "Line Color": "#fffcf9", "Line Width": 38, @@ -39,17 +30,9 @@ T.Widget { "Text Vertical Offset": 16 } - readonly property var configs: widget.settings.styles - - property string circle_color: configs["Circle Color"] - property string line_color: configs["Line Color"] - property string shadowColor: configs["Shadow Color"] - property real shadowBlur: configs["Shadow Size"] - readonly property real size: 155 - - readonly property real h: Math.min(widget.width, widget.height) - readonly property real w: widget.width - readonly property real r: (w**2+h**2)/4/h + onUpdated: { + widget.settings.styles = Object.assign(defaultValues, widget.settings.styles); + } onConfigsChanged: { line.requestPaint(); @@ -61,6 +44,20 @@ T.Widget { c5.requestPaint(); } + readonly property var configs: widget.settings.styles + + property real thour: 0 + property real t12hour: 0 + property real tmin: -1 + readonly property var fonts: Qt.fontFamilies() + readonly property var fontweight: [Font.Light, Font.Normal, Font.Bold] + readonly property var sfontweight: [qsTr("Light"), qsTr("Normal"), qsTr("Bold")] + + readonly property real size: 155 + readonly property real h: Math.min(widget.width, widget.height) + readonly property real w: widget.width + readonly property real r: (w**2+h**2)/4/h + action: T.Action { id: thiz @@ -132,17 +129,15 @@ T.Widget { width: size height: size contextType: "2d" - renderTarget: Canvas.FramebufferObject - renderStrategy: Canvas.Cooperative onPaint: { context.reset(); context.clearRect(0,0,size,size); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; - context.lineWidth = size*0.04 - shadowBlur; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; + context.lineWidth = size*0.04 - configs["Shadow Size"]; context.beginPath(); - context.arc(size/2, size/2, size*0.38-shadowBlur/2, -Math.PI/6, -Math.PI/6+Math.PI*2/3 , true); - context.strokeStyle = circle_color; + context.arc(size/2, size/2, size*0.38-configs["Shadow Size"]/2, -Math.PI/6, -Math.PI/6+Math.PI*2/3 , true); + context.strokeStyle = configs["Circle Color"]; context.stroke(); } rotation: -140 @@ -171,17 +166,15 @@ T.Widget { width: size height: size contextType: "2d" - renderTarget: Canvas.FramebufferObject - renderStrategy: Canvas.Cooperative onPaint: { context.reset(); context.clearRect(0,0,size,size); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; - context.lineWidth = size*0.08 - shadowBlur; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; + context.lineWidth = size*0.08 - configs["Shadow Size"]; context.beginPath(); - context.arc(size/2, size/2, size*0.30-shadowBlur/2, -Math.PI/6, -Math.PI/24+Math.PI*2/3 , true); - context.strokeStyle = circle_color; + context.arc(size/2, size/2, size*0.30-configs["Shadow Size"]/2, -Math.PI/6, -Math.PI/24+Math.PI*2/3 , true); + context.strokeStyle = configs["Circle Color"]; context.stroke(); } rotation: 20 @@ -201,17 +194,15 @@ T.Widget { width: size height: size contextType: "2d" - renderTarget: Canvas.FramebufferObject - renderStrategy: Canvas.Cooperative onPaint: { context.reset(); context.clearRect(0,0,size,size); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; - context.lineWidth = size*0.03 - shadowBlur; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; + context.lineWidth = size*0.03 - configs["Shadow Size"]; context.beginPath(); - context.arc(size/2, size/2, size*0.23-shadowBlur/2, -Math.PI/6, Math.PI/12+Math.PI*2/3 , true); - context.strokeStyle = circle_color; + context.arc(size/2, size/2, size*0.23-configs["Shadow Size"]/2, -Math.PI/6, Math.PI/12+Math.PI*2/3 , true); + context.strokeStyle = configs["Circle Color"]; context.stroke(); } rotation: 90 @@ -231,17 +222,15 @@ T.Widget { width: size height: size contextType: "2d" - renderTarget: Canvas.FramebufferObject - renderStrategy: Canvas.Cooperative onPaint: { context.reset(); context.clearRect(0,0,size,size); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; - context.lineWidth = size*0.06 - shadowBlur; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; + context.lineWidth = size*0.06 - configs["Shadow Size"]; context.beginPath(); - context.arc(size/2, size/2, size*0.17-shadowBlur/2, -Math.PI/6, Math.PI/4+Math.PI*2/3 , true); - context.strokeStyle = circle_color; + context.arc(size/2, size/2, size*0.17-configs["Shadow Size"]/2, -Math.PI/6, Math.PI/4+Math.PI*2/3 , true); + context.strokeStyle = configs["Circle Color"]; context.stroke(); } rotation: -70 @@ -270,17 +259,15 @@ T.Widget { width: size height: size contextType: "2d" - renderTarget: Canvas.FramebufferObject - renderStrategy: Canvas.Cooperative onPaint: { context.reset(); context.clearRect(0,0,size,size); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; - context.lineWidth = size*0.1 - shadowBlur; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; + context.lineWidth = size*0.1 - configs["Shadow Size"]; context.beginPath(); - context.arc(size/2, size/2, size*0.05-shadowBlur/2, 0, -Math.PI*2 , true); - context.strokeStyle = circle_color; + context.arc(size/2, size/2, size*0.05-configs["Shadow Size"]/2, 0, -Math.PI*2 , true); + context.strokeStyle = configs["Circle Color"]; context.stroke(); } } @@ -291,17 +278,15 @@ T.Widget { width: size height: size contextType: "2d" - renderTarget: Canvas.FramebufferObject - renderStrategy: Canvas.Cooperative onPaint: { context.reset(); context.clearRect(0,0,size,size); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; - context.lineWidth = size*0.16 - shadowBlur; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; + context.lineWidth = size*0.16 - configs["Shadow Size"]; context.beginPath(); - context.arc(size/2, size/2, size*0.38-shadowBlur/2, 0, -Math.PI/3 , true); - context.strokeStyle = circle_color; + context.arc(size/2, size/2, size*0.38-configs["Shadow Size"]/2, 0, -Math.PI/3 , true); + context.strokeStyle = configs["Circle Color"]; context.stroke(); } @@ -325,10 +310,10 @@ T.Widget { onPaint: { context.reset(); context.clearRect(0,0,width,height); - context.shadowBlur = shadowBlur; - context.shadowColor = shadowColor; + context.shadowBlur = configs["Shadow Size"]; + context.shadowColor = configs["Shadow Color"]; context.lineWidth = Math.max(0.08*configs["Line Width"], 0.1); - context.strokeStyle = line_color; + context.strokeStyle = configs["Line Color"]; let deg = Math.asin(w/2/r)*0.95; context.beginPath(); if (configs["Curve"]) { @@ -578,8 +563,4 @@ T.Widget { } } } - - Component.onCompleted: { - widget.settings.styles = widget.settings.styles ?? defaultValues; - } -} +} \ No newline at end of file diff --git a/qml/WeatherWidget.qml b/qml/WeatherWidget.qml index c1b8a2e..901674b 100644 --- a/qml/WeatherWidget.qml +++ b/qml/WeatherWidget.qml @@ -11,22 +11,66 @@ 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 -T.Widget { +WidgetTemplate { id: widget - title: qsTr("Ordinal Scale Weather Widget") - solid: true + editing: styleDialog.active + + version: "1.0.0" + defaultValues: { + "Display Location": "", + "Update Interval": + { + "Value": 1, + "Unit": 1 + }, + "Background Color": "#ffa502", + "Background Opacity": 60, + "Area Opacity Difference": 17, + "Icon Color": "#fefefe", + "Temperature Text Settings": + { + "Font Color": "#f5f5f5", + "Font Size": 90, + "Font Name": fonts.length - 1, + "Font Weight": 1, + "X Offset": 33, + "Y Offset": 32 + }, + "Area Text Settings": + { + "Font Color": "#f5f5f5", + "Font Size": 60, + "Font Name": fonts.length - 1, + "Font Weight": 1, + "X Offset": 0, + "Y Offset": -56, + "Border Margin": 40 + } + } + onUpdated: { + widget.settings.styles = Object.assign(defaultValues, widget.settings.styles); + } + + readonly property var configs: widget.settings.styles + readonly property real w: widget.width + readonly property real h: 0.46*widget.width readonly property var fonts: Qt.fontFamilies() readonly property var fontweight: [Font.Light, Font.Normal, Font.Bold] readonly property var sfontweight: [qsTr("Light"), qsTr("Normal"), qsTr("Bold")] - readonly property var configs: widget.settings.styles ?? {"Location":"","Display Location":"","Update Interval":{"Value":1,"Unit":1},"Background Color":"#ffa502","Background Opacity":60,"Area Opacity Difference":17,"Icon Color":"#fefefe","Temperature Text Settings":{"Font Color":"#f5f5f5","Font Size":90,"Font Name":fonts.length-1,"Font Weight":1,"X Offset":33,"Y Offset":32},"Area Text Settings":{"Font Color":"#f5f5f5","Font Size":60,"Font Name":fonts.length-1,"Font Weight":1,"X Offset":0,"Y Offset":-56,"Border Margin":40}} + 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 real w: widget.width - readonly property real h: 0.46*widget.width + NVG.DataSourceRawOutput { + id: output + source: dataSource + } Item { id: main @@ -110,7 +154,7 @@ T.Widget { anchors.centerIn: weather autoTransform: true visible: false - source: "../Images/Weather/Unknown.png" + source: "../Images/Weather/" + Utils.weather_codes[output.result?.iconCode ?? "44"] + ".png" } Rectangle { @@ -145,7 +189,7 @@ T.Widget { anchors.horizontalCenterOffset: temper_box.width*configs["Area Text Settings"]["X Offset"]/200 anchors.verticalCenterOffset: h*configs["Area Text Settings"]["Y Offset"]/200 color: configs["Area Text Settings"]["Font Color"] - text: "" + text: configs["Display Location"] font.pixelSize: w*0.0009*configs["Area Text Settings"]["Font Size"] font.family: fonts[configs["Area Text Settings"]["Font Name"]] font.weight: fontweight[configs["Area Text Settings"]["Font Weight"]] @@ -167,63 +211,18 @@ T.Widget { 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: "--°" + text: (output.result?.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"]] } } - function setWeather() { - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if(xhr.readyState === XMLHttpRequest.DONE) { - let data = xhr.responseText.toString(); - if (data) { - let jdata = JSON.parse(data); - temperature.text = jdata["current_condition"][0]["temp_C"] + "°"; - if (!configs["Display Location"] && !configs["Location"]) { - area.text = jdata["nearest_area"][0]["areaName"][0]["value"]; - } - weather_mask.source = "../Images/Weather/" + Utils.weather_codes[jdata["current_condition"][0]["weatherCode"]] ?? "Unknown" + ".png"; - } else { - weather_mask.source = "../Images/Weather/Unknown.png"; - } - } - } - if (configs["Location"]) - xhr.open("GET", 'https://wttr.in/'+configs["Location"]+'?format=j1'); - else - xhr.open("GET", 'https://wttr.in/?format=j1'); - xhr.send(); - if (configs["Display Location"]) { - area.text = configs["Display Location"]; - } else if (configs["Location"]) { - area.text = configs["Location"] - } - } - - Timer { - id: timer - interval: 600000 - running: widget.NVG.View.exposed - repeat: true - triggeredOnStart: true - onTriggered: { - setWeather(); - } - } - menu: Menu { Action { text: qsTr("Settings") + "..." onTriggered: styleDialog.active = true } - - Action { - text: qsTr("Refresh") - onTriggered: timer.restart() - } } Loader { @@ -243,7 +242,6 @@ T.Widget { property var configuration Page { - id: cfg_page anchors.fill: parent header: TitleBar { @@ -255,12 +253,10 @@ T.Widget { configuration = rootPreference.save(); widget.settings.styles = configuration; styleDialog.active = false; - timer.interval = 60000*configs["Update Interval"]["Value"]*(1+59*configs["Update Interval"]["Unit"]) - setWeather(); } onReset: { - rootPreference.load(); + rootPreference.load({"Address": widget.settings.styles?.Address}); let cfg = rootPreference.save(); widget.settings.styles = cfg; } @@ -294,16 +290,113 @@ T.Widget { widget.settings.styles = rootPreference.save(); } - P.TextFieldPreference { - name: "Location" + P.DialogPreference { + id: rootPref label: qsTr("Location") - message: qsTr("Search address by location, latitude and longitude.") + 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 + } + } + } + } } P.TextFieldPreference { name: "Display Location" label: qsTr("Display Location") message: qsTr("The location to display in widget.") + defaultValue: defaultValues["Display Location"] } P.DialogPreference { @@ -318,14 +411,14 @@ T.Widget { from: 1 to: 1440 editable: true - defaultValue: 1 + defaultValue: defaultValues["Update Interval"]["Value"] } P.SelectPreference { id: _cfg_update_interval_unit name: "Unit" label: qsTr("Unit") - defaultValue: 1 + defaultValue: defaultValues["Update Interval"]["Unit"] model: [qsTr("Minutes"), qsTr("Hours")] } } @@ -333,7 +426,7 @@ T.Widget { P.ColorPreference { name: "Background Color" label: qsTr("Background Color") - defaultValue: "#ffa502" + defaultValue: defaultValues["Background Color"] } P.SliderPreference { @@ -342,7 +435,7 @@ T.Widget { from: 0 to: 100 stepSize: 1 - defaultValue: 60 + defaultValue: defaultValues["Background Opacity"] displayValue: value + "%" } @@ -352,14 +445,14 @@ T.Widget { from: 0 to: 100 stepSize: 1 - defaultValue: 17 + defaultValue: defaultValues["Area Opacity Difference"] displayValue: value + "%" } P.ColorPreference { name: "Icon Color" label: qsTr("Icon Color") - defaultValue: "#fefefe" + defaultValue: defaultValues["Icon Color"] } P.Separator {} @@ -373,7 +466,7 @@ T.Widget { P.ColorPreference { name: "Font Color" label: qsTr("Font Color") - defaultValue: "#f5f5f5" + defaultValue: defaultValues["Temperature Text Settings"]["Font Color"] } P.SliderPreference { @@ -382,21 +475,21 @@ T.Widget { from: 1 to: 100 stepSize: 1 - defaultValue: 90 + defaultValue: defaultValues["Temperature Text Settings"]["Font Size"] displayValue: value + "%" } P.SelectPreference { name: "Font Name" label: qsTr("Font Style") - defaultValue: fonts.length-1 + defaultValue: defaultValues["Temperature Text Settings"]["Font Name"] model: fonts } P.SelectPreference { name: "Font Weight" label: qsTr("Font Weight") - defaultValue: 1 + defaultValue: defaultValues["Temperature Text Settings"]["Font Weight"] model: sfontweight } @@ -406,7 +499,7 @@ T.Widget { from: -100 to: 100 stepSize: 1 - defaultValue: 33 + defaultValue: defaultValues["Temperature Text Settings"]["X Offset"] displayValue: value + "%" } @@ -416,7 +509,7 @@ T.Widget { from: -100 to: 100 stepSize: 1 - defaultValue: 32 + defaultValue: defaultValues["Temperature Text Settings"]["Y Offset"] displayValue: value + "%" } } @@ -430,7 +523,7 @@ T.Widget { P.ColorPreference { name: "Font Color" label: qsTr("Font Color") - defaultValue: "#f5f5f5" + defaultValue: defaultValues["Area Text Settings"]["Font Color"] } P.SliderPreference { @@ -439,21 +532,21 @@ T.Widget { from: 1 to: 100 stepSize: 1 - defaultValue: 60 + defaultValue: defaultValues["Area Text Settings"]["Font Size"] displayValue: value + "%" } P.SelectPreference { name: "Font Name" label: qsTr("Font Style") - defaultValue: fonts.length-1 + defaultValue: defaultValues["Area Text Settings"]["Font Name"] model: fonts } P.SelectPreference { name: "Font Weight" label: qsTr("Font Weight") - defaultValue: 1 + defaultValue: defaultValues["Area Text Settings"]["Font Weight"] model: sfontweight } @@ -463,7 +556,7 @@ T.Widget { from: -100 to: 100 stepSize: 1 - defaultValue: 0 + defaultValue: defaultValues["Area Text Settings"]["X Offset"] displayValue: value + "%" } @@ -473,7 +566,7 @@ T.Widget { from: -100 to: 100 stepSize: 1 - defaultValue: -56 + defaultValue: defaultValues["Area Text Settings"]["Y Offset"] displayValue: value + "%" } @@ -483,7 +576,7 @@ T.Widget { from: 0 to: 100 stepSize: 1 - defaultValue: 40 + defaultValue: defaultValues["Area Text Settings"]["Border Margin"] displayValue: value + "%" } } diff --git a/qml/WidgetTemplate.qml b/qml/WidgetTemplate.qml new file mode 100644 index 0000000..290b286 --- /dev/null +++ b/qml/WidgetTemplate.qml @@ -0,0 +1,27 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +import NERvGear 1.0 as NVG +import NERvGear.Templates 1.0 as T + + +T.Widget { + solid: true + visible: true + + property string version: "" + property var defaultValues: {} + signal completed() + signal updated() + + Component.onCompleted: { + if (!widget.settings.styles) { + widget.settings.styles = defaultValues; + widget.settings.version = version; + } else if (widget.settings.version !== version) { + updated(); + widget.settings.version = version; + } + completed(); + } +} diff --git a/qml/utils.js b/qml/utils.js index 9d32aad..7e9cd2e 100644 --- a/qml/utils.js +++ b/qml/utils.js @@ -2,52 +2,52 @@ // https://github.com/chubin/wttr.in/blob/master/lib/constants.py var weather_codes = { - "113": "Sunny", - "116": "PartlyCloudy", - "119": "Cloudy", - "122": "VeryCloudy", - "143": "Fog", - "176": "Showers", - "179": "LightSleet", - "182": "LightSleet", - "185": "LightSleet", - "200": "ThunderyShowers", - "227": "LightSnow", - "230": "HeavySnow", - "248": "Fog", - "260": "Fog", - "263": "Showers", - "266": "LightRain", - "281": "LightSleet", - "284": "LightSleet", - "293": "LightRain", - "296": "LightRain", - "299": "Showers", - "302": "HeavyRain", - "305": "Showers", - "308": "HeavyRain", - "311": "LightSleet", - "314": "LightSleet", - "317": "LightSleet", - "320": "LightSnow", - "323": "SnowShowers", - "326": "SnowShowers", - "329": "HeavySnow", - "332": "HeavySnow", - "335": "SnowShowers", - "338": "HeavySnow", - "350": "LightSleet", - "353": "Showers", - "356": "Showers", - "359": "HeavyRain", - "362": "LightSleet", - "365": "LightSleet", - "368": "SnowShowers", - "371": "SnowShowers", - "374": "LightSleet", - "377": "LightSleet", - "386": "ThunderyShowers", - "389": "ThunderyHeavyRain", - "392": "SnowShowers", - "395": "SnowShowers" + "0": "Tornado", + "1": "Hurricane", + "2": "Hurricane", + "3": "ThunderyHeavyRain", + "4": "ThunderyHeavyRain", + "5": "LightSleet", + "6": "LightSleet", + "7": "LightSleet", + "8": "LightSleet", + "9": "Showers", + "10": "LightSleet", + "11": "LightRain", + "12": "HeavyRain", + "13": "SnowShowers", + "14": "LightSnow", + "15": "SnowShowers", + "16": "LightSnow", + "17": "Hail", + "18": "LightSleet", + "19": "Sandstorm", + "20": "Fog", + "21": "Fog", + "22": "Fog", + "23": "Breezy", + "24": "Breezy", + "25": "IceCrystals", + "26": "Cloudy", + "27": "VeryCloudy", + "28": "VeryCloudy", + "29": "PartlyCloudyNight", + "30": "PartlyCloudyDay", + "31": "Clear", + "32": "Sunny", + "33": "PartlyCloudyNight", + "34": "PartlyCloudyDay", + "35": "Hail", + "36": "Sunny", + "37": "ThunderyShowers", + "38": "ThunderyHeavyRain", + "39": "Showers", + "40": "HeavyRain", + "41": "SnowShowers", + "42": "HeavySnow", + "43": "HeavySnow", + "44": "Unknown", + "45": "Showers", + "46": "SnowShowers", + "47": "ThunderyShowers" }; \ No newline at end of file