commit de5149080799bccce71e992542da78ed2f291782
Author: SO_RA <490328928@qq.com>
Date: Thu Mar 24 02:31:42 2022 +0800
initial commit
diff --git a/Locales/zh.qm b/Locales/zh.qm
new file mode 100644
index 0000000..1d112c1
Binary files /dev/null and b/Locales/zh.qm differ
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..e8ed14e
--- /dev/null
+++ b/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "top.mashiros.widget.nclocks",
+ "version": "1.0.0",
+
+ "title": {
+ "en": "Clock Collections Plugin",
+ "zh": "时钟合集插件"
+ },
+
+ "description": {
+ "en": "Cool collection of clocks for SAO Utils 2",
+ "zh": "用于 SAO Utils 2的酷炫时钟集合"
+ },
+
+ "author": {
+ "name": "Mashiro_Sorata",
+ "email": "mashiro_sorata@qq.com",
+ "url": "http://www.mashiros.top/"
+ },
+
+ "homepage": "https://nvg.dev/Mashiro_Sorata/nClocks",
+
+ "bugs": {
+ "email": "mashiro_sorata@qq.com",
+ "url": "https://nvg.dev/Mashiro_Sorata/nClocks/issues"
+ },
+
+ "engines": {
+ "qt": "~5",
+ "qt.quick": ">=2.12",
+ "nvg.api": "~1"
+ },
+
+ "resources": [
+ {
+ "location": "/nclocks/solars",
+ "catalog": "widget",
+ "title": {
+ "en": "Solars Clock Widget",
+ "zh": "太阳系时钟挂件"
+ },
+ "preview": "preview/solars_clock.png",
+ "entry": "solars_clock.qml"
+ },
+ {
+ "location": "/nclocks/reflection",
+ "catalog": "widget",
+ "title": {
+ "en": "Reflection Clock Widget",
+ "zh": "倒影时钟挂件"
+ },
+ "preview": "preview/reflection_clock.png",
+ "entry": "reflection_clock.qml"
+ },
+ {
+ "location": "/nclocks/round",
+ "catalog": "widget",
+ "title": {
+ "en": "Round Clock Widget",
+ "zh": "圆盘时钟挂件"
+ },
+ "preview": "preview/round_clock.png",
+ "entry": "round_clock.qml"
+ },
+ {
+ "location": "/nclocks/text",
+ "catalog": "widget",
+ "title": {
+ "en": "Text Clock Widget",
+ "zh": "文字时钟挂件"
+ },
+ "preview": "preview/text_clock.png",
+ "entry": "text_clock.qml"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/preview/reflection_clock.png b/preview/reflection_clock.png
new file mode 100644
index 0000000..345f5c9
Binary files /dev/null and b/preview/reflection_clock.png differ
diff --git a/preview/round_clock.png b/preview/round_clock.png
new file mode 100644
index 0000000..9385ffd
Binary files /dev/null and b/preview/round_clock.png differ
diff --git a/preview/solars_clock.png b/preview/solars_clock.png
new file mode 100644
index 0000000..fd0cfd8
Binary files /dev/null and b/preview/solars_clock.png differ
diff --git a/preview/text_clock.png b/preview/text_clock.png
new file mode 100644
index 0000000..94dd672
Binary files /dev/null and b/preview/text_clock.png differ
diff --git a/reflection_clock.qml b/reflection_clock.qml
new file mode 100644
index 0000000..b22c216
--- /dev/null
+++ b/reflection_clock.qml
@@ -0,0 +1,465 @@
+import QtQuick 2.12
+
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+import QtGraphicalEffects 1.0
+
+import NERvGear 1.0 as NVG
+import NERvGear.Templates 1.0 as T
+import NERvGear.Preferences 1.0 as P
+
+
+
+T.Widget {
+ id: widget
+ solid: true
+ title: qsTr("Reflection Clock")
+ resizable: true
+
+ readonly property real minWH: Math.min(width, height)
+ readonly property real multi: minWH/220
+
+ readonly property bool full_clock: widget.settings.styles ? widget.settings.styles["Hour Settings"]["Full Clock"] : true
+ property string am_pm: ""
+
+ Rectangle {
+ id: main
+ color: "transparent"
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+ width: 345*multi
+ height: 222*multi
+
+ Rectangle {
+ id: hour
+ color: "transparent"
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: parent.left
+ anchors.leftMargin: 15*multi
+ width: 100*multi
+ height: 111*multi
+
+ Rectangle {
+ id: hour_top
+ color: widget.settings.styles ? widget.settings.styles["Hour Settings"]["Clock BG Color"] : "#2196f3"
+ width: 100*multi
+ height: 80*multi
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+
+ Text {
+ id: hour_text
+ text: ""
+ color: widget.settings.styles ? widget.settings.styles["Hour Settings"]["Clock Font Color"] : "#ffffff"
+ anchors.centerIn: parent
+ font.pointSize: 35*multi
+ font.weight: Font.Light
+ font.family: "Microsoft YaHei"
+ }
+ }
+
+ Rectangle {
+ id: hour_bottom
+ color: widget.settings.styles ? widget.settings.styles["Hour Settings"]["Panel BG Color"] : "#2196f3"
+ width: 100*multi
+ height: 30*multi
+ anchors.top: hour_top.bottom
+ anchors.topMargin: multi
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+
+ Text {
+ text: "HOURS"+am_pm
+ color: widget.settings.styles ? widget.settings.styles["Hour Settings"]["Panel Font Color"] : "#ffffff"
+ anchors.centerIn: parent
+ font.pointSize: 9*multi
+ font.weight: Font.Normal
+ font.family: "Microsoft YaHei"
+ font.letterSpacing: 2*multi
+ }
+ }
+ }
+
+
+ Rectangle {
+ id: min
+ color: "transparent"
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: hour.right
+ anchors.leftMargin: 15*multi
+ width: 100*multi
+ height: 111*multi
+
+ Rectangle {
+ id: min_top
+ color: widget.settings.styles ? widget.settings.styles["Min Settings"]["Clock BG Color"] : "#2196f3"
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+ width: 100*multi
+ height: 80*multi
+
+ Text {
+ id: min_text
+ text: ""
+ color: widget.settings.styles ? widget.settings.styles["Min Settings"]["Clock Font Color"] : "#ffffff"
+ anchors.centerIn: parent
+ font.pointSize: 35*multi
+ font.weight: Font.Light
+ font.family: "Microsoft YaHei"
+ }
+ }
+
+ Rectangle {
+ id: min_bottom
+ color: widget.settings.styles ? widget.settings.styles["Min Settings"]["Panel BG Color"] : "#2196f3"
+ width: 100*multi
+ height: 30*multi
+ anchors.top: min_top.bottom
+ anchors.topMargin: multi
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+
+ Text {
+ text: "MINUTES"
+ color: widget.settings.styles ? widget.settings.styles["Min Settings"]["Panel Font Color"] : "#ffffff"
+ anchors.centerIn: parent
+ font.pointSize: 9*multi
+ font.weight: Font.Normal
+ font.family: "Microsoft YaHei"
+ font.letterSpacing: 2*multi
+ }
+ }
+ }
+
+
+ Rectangle {
+ id: sec
+ color: "transparent"
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: min.right
+ anchors.leftMargin: 15*multi
+ visible: widget.settings.styles ? widget.settings.styles["Sec Settings"]["Visible"] : true
+ width: 100*multi
+ height: 111*multi
+
+ Rectangle {
+ id: sec_top
+ color: widget.settings.styles ? widget.settings.styles["Sec Settings"]["Clock BG Color"] : "#ff006a"
+ width: 100*multi
+ height: 80*multi
+ anchors.top: parent.top
+ anchors.topMargin: 0
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+
+ Text {
+ id: sec_text
+ text: ""
+ color: widget.settings.styles ? widget.settings.styles["Sec Settings"]["Clock Font Color"] : "#ffffff"
+ anchors.centerIn: parent
+ font.pointSize: 35*multi
+ font.weight: Font.Light
+ font.family: "Microsoft YaHei"
+ }
+ }
+
+ Rectangle {
+ id: sec_bottom
+ color: widget.settings.styles ? widget.settings.styles["Sec Settings"]["Panel BG Color"] : "#ff006a"
+ width: 100*multi
+ height: 30*multi
+ anchors.top: sec_top.bottom
+ anchors.topMargin: multi
+ anchors.left: parent.left
+ anchors.leftMargin: 0
+
+ Text {
+ text: "SECONDS"
+ color: widget.settings.styles ? widget.settings.styles["Sec Settings"]["Panel Font Color"] : "#ffffff"
+ anchors.centerIn: parent
+ font.pointSize: 9*multi
+ font.weight: Font.Normal
+ font.family: "Microsoft YaHei"
+ font.letterSpacing: 2*multi
+ }
+ }
+ }
+ }
+
+ OpacityMask {
+ width: main.width
+ height: main.height
+ anchors.top: main.bottom
+ anchors.topMargin: multi
+
+ source: main
+ maskSource: Rectangle {
+ width: main.width
+ height: main.height
+ gradient: Gradient{
+ GradientStop{position: 0.0;color:"transparent"}
+ GradientStop{position: 1.0;color:"#FFF"}
+ }
+ }
+ transform: Scale {yScale: -1}
+ }
+
+ Timer {
+ interval: 250
+ repeat: true
+ running: widget.NVG.View.exposed
+ onTriggered: {
+ var now = new Date(),
+ sec = now.getSeconds(),
+ min = now.getMinutes(),
+ hr = now.getHours();
+ if(!full_clock) {
+ am_pm = "|" + (hr > 11 ? "PM" : "AM");
+ if (hr === 0 || hr === 24)
+ hr = 12;
+ else if(hr > 12)
+ hr -= 12;
+ } else {
+ am_pm = "";
+ }
+
+ hour_text.text = hr < 10 ? "0"+hr : hr;
+ min_text.text = min < 10 ? "0"+min : min;
+ sec_text.text = sec < 10 ? "0"+sec : sec;
+ }
+ }
+
+ menu: Menu {
+ Action {
+ text: qsTr("Settings") + "..."
+ onTriggered: styleDialog.active = true
+ }
+ }
+
+ Loader {
+ id: styleDialog
+ active: false
+ sourceComponent: NVG.Window {
+ id: window
+ title: qsTr("Clock Settings")
+ visible: true
+ minimumWidth: 380
+ minimumHeight: 480
+ maximumWidth: minimumWidth
+ maximumHeight: minimumHeight
+ width: minimumWidth
+ height: minimumHeight
+
+ transientParent: widget.NVG.View.window
+
+ property var configuration
+
+ ColumnLayout {
+ id: root
+ anchors.fill: parent
+ anchors.margins: 16
+ anchors.topMargin: 0
+
+ Row {
+ spacing: 234
+
+ ToolButton {
+ text: qsTr("Save")
+ onClicked: {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+
+ ToolButton {
+ text: qsTr("Reset")
+ onClicked: {
+ rootPreference.load();
+ let cfg = rootPreference.save();
+ widget.settings.styles = cfg;
+ }
+ }
+ }
+
+ Label {
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Settings")
+ font.pixelSize: 24
+ }
+
+ Flickable {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ clip: true
+ contentWidth: preferenceLayout.implicitWidth
+ contentHeight: preferenceLayout.implicitHeight
+
+ ColumnLayout {
+ id: preferenceLayout
+ width: root.width
+
+ P.PreferenceGroup {
+ id: rootPreference
+ Layout.fillWidth: true
+
+ label: qsTr("Configuration")
+
+ onPreferenceEdited: {
+ widget.settings.styles = rootPreference.save();
+ }
+
+ P.DialogPreference {
+ name: "Hour Settings"
+ label: qsTr("Hour Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.SwitchPreference {
+ name: "Full Clock"
+ label: qsTr("24 Hour Clock")
+ defaultValue: true
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "Clock BG Color"
+ label: qsTr("Clock Background Color")
+ defaultValue: "#2196f3"
+ }
+
+ P.ColorPreference {
+ name: "Clock Font Color"
+ label: qsTr("Clock Font Color")
+ defaultValue: "#ffffff"
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "Panel BG Color"
+ label: qsTr("Panel Background Color")
+ defaultValue: "#2196f3"
+ }
+
+ P.ColorPreference {
+ name: "Panel Font Color"
+ label: qsTr("Panel Font Color")
+ defaultValue: "#ffffff"
+ }
+ }
+
+ P.Separator {}
+
+ P.DialogPreference {
+ name: "Min Settings"
+ label: qsTr("Minute Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.ColorPreference {
+ name: "Clock BG Color"
+ label: qsTr("Clock Background Color")
+ defaultValue: "#2196f3"
+ }
+
+ P.ColorPreference {
+ name: "Clock Font Color"
+ label: qsTr("Clock Font Color")
+ defaultValue: "#ffffff"
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "Panel BG Color"
+ label: qsTr("Panel Background Color")
+ defaultValue: "#2196f3"
+ }
+
+ P.ColorPreference {
+ name: "Panel Font Color"
+ label: qsTr("Panel Font Color")
+ defaultValue: "#ffffff"
+ }
+ }
+
+ P.Separator {}
+
+ P.DialogPreference {
+ name: "Sec Settings"
+ label: qsTr("Second Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.SwitchPreference {
+ id: cfg_sec_en
+ name: "Visible"
+ label: qsTr("Show")
+ defaultValue: true
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "Clock BG Color"
+ label: qsTr("Clock Background Color")
+ enabled: cfg_sec_en.value
+ defaultValue: "#ff006a"
+ }
+
+ P.ColorPreference {
+ name: "Clock Font Color"
+ label: qsTr("Clock Font Color")
+ enabled: cfg_sec_en.value
+ defaultValue: "#ffffff"
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "Panel BG Color"
+ label: qsTr("Panel Background Color")
+ enabled: cfg_sec_en.value
+ defaultValue: "#ff006a"
+ }
+
+ P.ColorPreference {
+ name: "Panel Font Color"
+ label: qsTr("Panel Font Color")
+ enabled: cfg_sec_en.value
+ defaultValue: "#ffffff"
+ }
+ }
+
+ Component.onCompleted: {
+ if(!widget.settings.styles) {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ }
+ rootPreference.load(widget.settings.styles);
+ configuration = widget.settings.styles;
+ }
+ }
+ }
+ }
+ }
+
+ onClosing: {
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+ }
+}
diff --git a/round_clock.qml b/round_clock.qml
new file mode 100644
index 0000000..1657a82
--- /dev/null
+++ b/round_clock.qml
@@ -0,0 +1,463 @@
+import QtQuick 2.12
+
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+
+import NERvGear 1.0 as NVG
+import NERvGear.Templates 1.0 as T
+import NERvGear.Preferences 1.0 as P
+
+
+
+T.Widget {
+ id: widget
+ solid: true
+ title: qsTr("Round Clock")
+ resizable: true
+
+ property real maxr: Math.min(width/2, height/2) -10
+ property real thour: 0
+ property real tmin: 0
+ property real tsec: 0
+
+ property var configs: widget.settings.styles ? widget.settings.styles : {"Sec Continue":true,"BG Color":"#2196f3","BG Alpha":50,"HGRID Color":"#ffffff","MGRID Color":"#ffffff","Hhand Color":"#ffffff","Mhand Color":"#ffffff","Shand Color":"#f3a829"}
+
+ onConfigsChanged: {
+ background.requestPaint();
+ hour.requestPaint();
+ min.requestPaint();
+ sec.requestPaint();
+ sec_tail.requestPaint();
+ sec_center.requestPaint();
+ }
+
+ function colorToRGBA(color, alpha) {
+ var color1, color2, color3;
+ color = ""+color;
+ if (typeof color !== "string") return;
+ if (color.charAt(0) === "#") {
+ color = color.substring(1);
+ }
+ var not16num = color.split("").filter(function (item, index) {
+ return isNaN(parseInt(item, 16))
+ });
+ if(not16num.length) return;
+ switch (color.length) {
+ case 3:
+ color1 = color.substr(0,1);
+ color2 = color.substr(1,1);
+ color3 = color.substr(2,1);
+ color1 = color1 + color1;
+ color2 = color2 + color2;
+ color3 = color3 + color3;
+ break;
+ case 6:
+ color1 = color.substr(0,2);
+ color2 = color.substr(2,2);
+ color3 = color.substr(4,2);
+ break;
+ default:
+ return false;
+ }
+ color1 = parseInt(color1, 16);
+ color2 = parseInt(color2, 16);
+ color3 = parseInt(color3, 16);
+ return "rgba("+color1+","+color2+","+color3+","+alpha+")";
+ }
+
+
+ Timer {
+ interval: configs["Sec Continue"] ? 50 : 250
+ running: widget.NVG.View.exposed
+ repeat: true
+ onTriggered: {
+ var now = new Date();
+ tsec = now.getSeconds() + (configs["Sec Continue"] ? now.getMilliseconds()/1000 : 0);
+ tmin = now.getMinutes();
+ thour = now.getHours();
+ thour = thour % 12;
+ }
+ }
+
+ Canvas {
+ id: background
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2); //将坐标原点移到画布中心
+ context.rotate(-Math.PI/2); //将坐标轴逆时针旋转90度,x轴正方向对准12点方向
+
+ context.fillStyle = colorToRGBA(configs["BG Color"], configs["BG Alpha"]/100);
+ context.beginPath();
+ context.arc(0, 0, maxr, 0, Math.PI * 2, true);
+ context.fill();
+
+ context.strokeStyle = configs["HGRID Color"];
+ context.lineWidth = maxr*0.04;
+ context.lineCap = "round";
+ for (var i = 0; i < 12; i++) {
+ context.beginPath();
+ context.rotate(Math.PI / 6);
+ context.moveTo(maxr*0.92, 0);
+ context.lineTo(maxr*0.78, 0);
+ context.stroke();
+ }
+
+ context.strokeStyle = configs["MGRID Color"];
+ context.lineWidth = maxr*0.015;
+ for (i = 0; i < 60; i++) {
+ if (i % 5 !== 0) { //去掉与小时刻度重叠的部分
+ context.beginPath();
+ context.moveTo(maxr*0.92, 0);
+ context.lineTo(maxr*0.86, 0);
+ context.stroke();
+ }
+ context.rotate(Math.PI / 30);
+ }
+ }
+ }
+
+ Canvas {
+ id: hour
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ rotation: thour*30+tmin*0.5+tsec*0.6/60
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.03;
+ context.lineCap = "round";
+ context.strokeStyle = configs["Hhand Color"];
+
+ context.lineWidth = maxr*0.08;
+ context.beginPath();
+ context.moveTo(0,0);
+ context.lineTo(0, -maxr*0.56);
+ context.stroke();
+ }
+ }
+
+ Canvas {
+ id: min
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ rotation: tmin*6+tsec*0.1
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.04;
+ context.lineCap = "round";
+ context.strokeStyle = configs["Mhand Color"];
+
+ context.lineWidth = maxr*0.045;
+ context.beginPath();
+ context.moveTo(0,0);
+ context.lineTo(0, -maxr*0.82);
+ context.stroke();
+ }
+ }
+
+ Canvas {
+ id: sec
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+ rotation: widget.tsec*6
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.05;
+ context.lineCap = "round";
+ context.strokeStyle = configs["Shand Color"];
+
+ context.lineWidth = maxr*0.016;
+ context.beginPath();
+ context.moveTo(0,0);
+ context.lineTo(0, -maxr*0.9);
+ context.stroke();
+ }
+ }
+
+
+ Canvas {
+ id: sec_tail
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+ rotation: widget.tsec*6
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.05;
+
+ context.lineCap = "round";
+ context.strokeStyle = configs["Shand Color"];
+ context.beginPath();
+ context.moveTo(0,0);
+ context.lineTo(0, maxr*0.07);
+ context.lineWidth = maxr*0.07;
+ context.stroke();
+ }
+ }
+
+ Canvas {
+ id: sec_center
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.1;
+ context.shadowOffsetX = maxr*0.05/2.5;
+ context.shadowOffsetY = maxr*0.05/2.5;
+
+ context.beginPath();
+ context.arc(0, 0, maxr*0.07, 0, Math.PI * 2, true);
+ context.fillStyle = configs["Shand Color"];
+ context.fill();
+ }
+ }
+
+ menu: Menu {
+ Action {
+ text: qsTr("Settings") + "..."
+ onTriggered: styleDialog.active = true
+ }
+ }
+
+ Loader {
+ id: styleDialog
+ active: false
+ sourceComponent: NVG.Window {
+ id: window
+ title: qsTr("Clock Settings")
+ visible: true
+ minimumWidth: 380
+ minimumHeight: 540
+ maximumWidth: minimumWidth
+ maximumHeight: minimumHeight
+ width: minimumWidth
+ height: minimumHeight
+
+ transientParent: widget.NVG.View.window
+
+ property var configuration
+
+ ColumnLayout {
+ id: root
+ anchors.fill: parent
+ anchors.margins: 16
+ anchors.topMargin: 0
+
+ Row {
+ spacing: 234
+
+ ToolButton {
+ text: qsTr("Save")
+ onClicked: {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+
+ ToolButton {
+ text: qsTr("Reset")
+ onClicked: {
+ rootPreference.load();
+ let cfg = rootPreference.save();
+ widget.settings.styles = cfg;
+ }
+ }
+ }
+
+ Label {
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Settings")
+ font.pixelSize: 24
+ }
+
+ Flickable {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ clip: true
+ contentWidth: preferenceLayout.implicitWidth
+ contentHeight: preferenceLayout.implicitHeight
+
+ ColumnLayout {
+ id: preferenceLayout
+ width: root.width
+
+ P.PreferenceGroup {
+ id: rootPreference
+ Layout.fillWidth: true
+
+ label: qsTr("Configuration")
+
+ onPreferenceEdited: {
+ widget.settings.styles = rootPreference.save();
+ }
+
+ P.SwitchPreference {
+ name: "Sec Continue"
+ label: qsTr("Continuous Second Hand")
+ defaultValue: true
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "BG Color"
+ label: qsTr("Background Color")
+ defaultValue: "#2196f3"
+ }
+
+ P.SliderPreference {
+ name: "BG Alpha"
+ label: qsTr("Background transparency")
+ from: 0
+ to: 100
+ stepSize: 1
+ defaultValue: 50
+ displayValue: value + "%"
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "HGRID Color"
+ label: qsTr("Hour Scale Color")
+ defaultValue: "#fff"
+ }
+
+ P.ColorPreference {
+ name: "MGRID Color"
+ label: qsTr("Minute Scale Color")
+ defaultValue: "#fff"
+ }
+
+ P.Separator {}
+
+ P.ColorPreference {
+ name: "Hhand Color"
+ label: qsTr("Hour Hand Color")
+ defaultValue: "#fff"
+ }
+
+ P.ColorPreference {
+ name: "Mhand Color"
+ label: qsTr("Minute Hand Color")
+ defaultValue: "#fff"
+ }
+
+ P.ColorPreference {
+ name: "Shand Color"
+ label: qsTr("Second Hand Color")
+ defaultValue: "#F3A829"
+ }
+
+ Component.onCompleted: {
+ if(!widget.settings.styles) {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ }
+ rootPreference.load(widget.settings.styles);
+ configuration = widget.settings.styles;
+ }
+ }
+ }
+ }
+ }
+
+ onClosing: {
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+ }
+}
diff --git a/solars_clock.qml b/solars_clock.qml
new file mode 100644
index 0000000..34bdc32
--- /dev/null
+++ b/solars_clock.qml
@@ -0,0 +1,687 @@
+import QtQuick 2.12
+
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+
+import NERvGear 1.0 as NVG
+import NERvGear.Templates 1.0 as T
+import NERvGear.Preferences 1.0 as P
+
+
+
+T.Widget {
+ id: widget
+ solid: true
+ title: qsTr("Solar Clock")
+ resizable: true
+
+ editing: styleDialog.active
+
+ property real maxr: Math.min(width/2, height/2) -10
+ readonly property real rhour: maxr*0.9
+ readonly property real rmin: maxr*0.72
+ readonly property real rsec: maxr*0.5
+ property real thour: 0
+ property real tmin: 0
+ property real tsec: 0
+ property real tmsec: 0
+
+ property var configs: widget.settings.styles ? widget.settings.styles : {"BG Settings":{"BG Color":"#212121","BG Alpha":100,"Show HGrid":true,"HGRID Color":"#616161","Show Center":true,"Center Color":"#ffeb3b","Center Radius":85,"Show Clock":true,"Clock Color":"#616161","Font Size":100},"Hour Settings":{"Hstar Color":"#ffa000","Show Orbit":true,"Horbit Color":"#616161"},"Min Settings":{"Mstar Color":"#ff5722","Show Orbit":true,"Morbit Color":"#616161"},"Sec Settings":{"Sstar Color":"#2196f3","Show Orbit":true,"Sorbit Color":"#616161"},"MSec Settings":{"MSstar Color":"#9e9e9e","Show Orbit":true,"MSorbit Color":"#9e9e9e"}}
+
+ onConfigsChanged: {
+ background.requestPaint();
+ hour.requestPaint();
+ min.requestPaint();
+ sec.requestPaint();
+ millisec_orbit.requestPaint();
+ millisec_star.requestPaint();
+ center.requestPaint();
+ }
+
+ function colorToRGBA(color, alpha) {
+ var color1, color2, color3;
+ color = ""+color;
+ if (typeof color !== "string") return;
+ if (color.charAt(0) === "#") {
+ color = color.substring(1);
+ }
+ var not16num = color.split("").filter(function (item, index) {
+ return isNaN(parseInt(item, 16))
+ });
+ if(not16num.length) return;
+ switch (color.length) {
+ case 3:
+ color1 = color.substr(0,1);
+ color2 = color.substr(1,1);
+ color3 = color.substr(2,1);
+ color1 = color1 + color1;
+ color2 = color2 + color2;
+ color3 = color3 + color3;
+ break;
+ case 6:
+ color1 = color.substr(0,2);
+ color2 = color.substr(2,2);
+ color3 = color.substr(4,2);
+ break;
+ default:
+ return false;
+ }
+ color1 = parseInt(color1, 16);
+ color2 = parseInt(color2, 16);
+ color3 = parseInt(color3, 16);
+ return "rgba("+color1+","+color2+","+color3+","+alpha+")";
+ }
+
+
+ Timer {
+ interval: 50
+ running: widget.NVG.View.exposed
+ repeat: true
+ onTriggered: {
+ var now = new Date();
+ tmsec = now.getMilliseconds();
+ tsec = now.getSeconds();
+ tmin = now.getMinutes();
+ thour = now.getHours();
+ main_time.text = (thour<10 ? "0"+thour : thour) + ":" + (tmin<10 ? "0"+tmin : tmin) + ":" + (tsec<10 ? "0"+tsec : tsec);
+ thour = thour > 12 ? thour - 12 : thour;
+ tsec += tmsec/1000;
+ }
+ }
+
+ Canvas {
+ id: background
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2); //将坐标原点移到画布中心
+ context.rotate(-Math.PI/2); //将坐标轴逆时针旋转90度,x轴正方向对准12点方向
+
+ context.fillStyle = colorToRGBA(configs["BG Settings"]["BG Color"], configs["BG Settings"]["BG Alpha"]/100);
+ context.beginPath();
+ context.arc(0, 0, maxr, 0, Math.PI * 2, true);
+ context.fill();
+
+ if (configs["Hour Settings"]["Show Orbit"]) {
+ context.strokeStyle = configs["Hour Settings"]["Horbit Color"];
+ context.lineWidth = maxr*0.01;
+ context.beginPath();
+ context.arc(0, 0, rhour, 0, Math.PI * 2, true);
+ context.stroke();
+ }
+
+ if (configs["Min Settings"]["Show Orbit"]) {
+ context.strokeStyle = configs["Min Settings"]["Morbit Color"];
+ context.lineWidth = maxr*0.01;
+ context.beginPath();
+ context.arc(0, 0, rmin, 0, Math.PI * 2, true);
+ context.stroke();
+ }
+
+ if (configs["Sec Settings"]["Show Orbit"]) {
+ context.strokeStyle = configs["Sec Settings"]["Sorbit Color"];
+ context.lineWidth = maxr*0.01;
+ context.beginPath();
+ context.arc(0, 0, rsec, 0, Math.PI * 2, true);
+ context.stroke();
+ }
+
+ if (configs["BG Settings"]["Show HGrid"]) {
+ context.strokeStyle = configs["BG Settings"]["HGRID Color"];
+ context.lineWidth = maxr*0.016;
+ context.lineCap = "round";
+ for (var i = 0; i < 12; i++) {
+ context.beginPath();
+ if (!(i%3)) {
+ context.moveTo(rmin+maxr*0.07, 0);
+ } else {
+ context.moveTo(rmin+maxr*0.035, 0);
+ }
+ context.lineTo(rmin, 0);
+ context.stroke();
+ context.rotate(Math.PI / 6);
+ }
+ }
+ }
+ }
+
+ Canvas {
+ id: hour
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ rotation: thour*30+tmin*0.5+tsec*0.6/60
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.03;
+ context.lineCap = "round";
+ context.fillStyle = configs["Hour Settings"]["Hstar Color"];
+
+ context.beginPath();
+ context.arc(0, -rhour, maxr*0.075, 0, Math.PI * 2, true);
+ context.fill();
+ }
+ }
+
+ Canvas {
+ id: min
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ rotation: tmin*6+tsec*0.1
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.04;
+ context.lineCap = "round";
+ context.fillStyle = configs["Min Settings"]["Mstar Color"];
+ context.beginPath();
+ context.arc(0, -rmin, maxr*0.06, 0, Math.PI * 2, true);
+ context.fill();
+ }
+ }
+
+ Canvas {
+ id: sec
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+ rotation: widget.tsec*6
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.04;
+ context.lineCap = "round";
+ context.fillStyle = configs["Sec Settings"]["Sstar Color"];
+ context.beginPath();
+ context.arc(0, -rsec, maxr*0.045, 0, Math.PI * 2, true);
+ context.fill();
+ }
+ }
+
+ Canvas {
+ id: millisec_orbit
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+ rotation: widget.tsec*6
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ if (configs["MSec Settings"]["Show Orbit"]) {
+ context.translate(width/2, height/2);
+ context.strokeStyle = configs["MSec Settings"]["MSorbit Color"];
+ context.lineWidth = maxr*0.005;
+ context.beginPath();
+ context.arc(0, -rsec, maxr*0.1, 0, Math.PI * 2, true);
+ context.stroke();
+ }
+ }
+
+ Canvas {
+ id: millisec_star
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ transform: Rotation {
+ //设置图像原点
+ origin.x: width/2
+ origin.y: height/2-rsec
+ axis{
+ x: 0
+ y: 0
+ z: 1
+ }
+ angle: tmsec*0.360
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = 'rgba(0,0,0,.5)';
+ context.shadowBlur = maxr*0.05;
+ context.lineCap = "round";
+ context.fillStyle = configs["MSec Settings"]["MSstar Color"];
+ context.beginPath();
+ context.arc(0, -rsec-maxr*0.1, maxr*0.025, 0, Math.PI * 2, true);
+ context.fill();
+ }
+ }
+ }
+
+ Canvas {
+ id: center
+ width: widget.width;
+ height: widget.height;
+ contextType: "2d";
+ renderTarget: Canvas.FramebufferObject
+ renderStrategy: Canvas.Cooperative
+
+ visible: configs["BG Settings"]["Show Center"]
+
+ onWidthChanged: {
+ requestPaint();
+ }
+
+ onHeightChanged: {
+ requestPaint();
+ }
+
+ onPaint: {
+ context.resetTransform();
+ context.clearRect(0,0,widget.width,widget.height);
+ context.translate(width/2, height/2);
+ context.shadowColor = colorToRGBA(configs["BG Settings"]["Center Color"], 0.5);
+ context.shadowBlur = maxr*0.1;
+ context.shadowOffsetX = maxr*0.05/2.5;
+ context.shadowOffsetY = maxr*0.05/2.5;
+
+ context.beginPath();
+ context.arc(0, 0, maxr*0.003*configs["BG Settings"]["Center Radius"], 0, Math.PI * 2, true);
+ context.fillStyle = configs["BG Settings"]["Center Color"];
+ context.fill();
+ }
+ }
+
+ menu: Menu {
+ Action {
+ text: qsTr("Settings") + "..."
+ onTriggered: styleDialog.active = true
+ }
+ }
+
+ Loader {
+ id: styleDialog
+ active: false
+ sourceComponent: NVG.Window {
+ id: window
+ title: qsTr("Clock Settings")
+ visible: true
+ minimumWidth: 400
+ minimumHeight: 660
+ maximumWidth: minimumWidth
+ maximumHeight: minimumHeight
+ width: minimumWidth
+ height: minimumHeight
+
+ transientParent: widget.NVG.View.window
+
+ property var configuration
+
+ ColumnLayout {
+ id: root
+ anchors.fill: parent
+ anchors.margins: 16
+ anchors.topMargin: 0
+
+ Row {
+ spacing: 270
+
+ ToolButton {
+ text: qsTr("Save")
+ onClicked: {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+
+ ToolButton {
+ text: qsTr("Reset")
+ onClicked: {
+ rootPreference.load();
+ let cfg = rootPreference.save();
+ widget.settings.styles = cfg;
+ }
+ }
+ }
+
+ Label {
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Settings")
+ font.pixelSize: 24
+ }
+
+ Flickable {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ clip: true
+ contentWidth: preferenceLayout.implicitWidth
+ contentHeight: preferenceLayout.implicitHeight
+
+ ColumnLayout {
+ id: preferenceLayout
+ width: root.width
+
+ P.PreferenceGroup {
+ id: rootPreference
+ Layout.fillWidth: true
+
+ label: qsTr("Configuration")
+
+ onPreferenceEdited: {
+ widget.settings.styles = rootPreference.save();
+ }
+
+ P.DialogPreference {
+ name: "BG Settings"
+ label: qsTr("Background Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.ColorPreference {
+ name: "BG Color"
+ label: qsTr("Color")
+ defaultValue: "#212121"
+ }
+
+ P.SliderPreference {
+ name: "BG Alpha"
+ label: qsTr("Transparency")
+ from: 0
+ to: 100
+ stepSize: 1
+ defaultValue: 100
+ displayValue: value + "%"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: show_hgrid
+ name: "Show HGrid"
+ label: qsTr("Show Scale")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "HGRID Color"
+ label: qsTr("Scale Color")
+ enabled: show_hgrid.value
+ defaultValue: "#616161"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: showCenter
+ name: "Show Center"
+ label: qsTr("Show Center")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "Center Color"
+ label: qsTr("Center Color")
+ enabled: showCenter.value
+ defaultValue: "#ffeb3b"
+ }
+
+ P.SliderPreference {
+ name: "Center Radius"
+ label: qsTr("Center Radius")
+ enabled: showCenter.value
+ from: 30
+ to: 100
+ stepSize: 1
+ defaultValue: 85
+ displayValue: value + "%"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: showClock
+ name: "Show Clock"
+ label: qsTr("Display Time")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "Clock Color"
+ label: qsTr("Font Color")
+ enabled: showClock.value
+ defaultValue: "#616161"
+ }
+
+ P.SliderPreference {
+ name: "Font Size"
+ label: qsTr("Font Size")
+ enabled: showClock.value
+ from: 50
+ to: 100
+ stepSize: 1
+ defaultValue: 100
+ displayValue: value + "%"
+ }
+ }
+
+ P.Separator {}
+
+ P.DialogPreference {
+ name: "Hour Settings"
+ label: qsTr("Hour Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.ColorPreference {
+ name: "Hstar Color"
+ label: qsTr("Star Color")
+ defaultValue: "#ffa000"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: hour_settings_show_orbit
+ name: "Show Orbit"
+ label: qsTr("Show Orbit")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "Horbit Color"
+ label: qsTr("Orbit Color")
+ enabled: hour_settings_show_orbit.value
+ defaultValue: "#616161"
+ }
+ }
+
+ P.DialogPreference {
+ name: "Min Settings"
+ label: qsTr("Minute Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.ColorPreference {
+ name: "Mstar Color"
+ label: qsTr("Star Color")
+ defaultValue: "#ff5722"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: min_settings_show_orbit
+ name: "Show Orbit"
+ label: qsTr("Show Orbit")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "Morbit Color"
+ label: qsTr("Orbit Color")
+ enabled: min_settings_show_orbit.value
+ defaultValue: "#616161"
+ }
+ }
+
+ P.DialogPreference {
+ name: "Sec Settings"
+ label: qsTr("Second Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.ColorPreference {
+ name: "Sstar Color"
+ label: qsTr("Star Color")
+ defaultValue: "#2196f3"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: sec_settings_show_orbit
+ name: "Show Orbit"
+ label: qsTr("Show Orbit")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "Sorbit Color"
+ label: qsTr("Orbit Color")
+ enabled: sec_settings_show_orbit.value
+ defaultValue: "#616161"
+ }
+ }
+
+ P.DialogPreference {
+ name: "MSec Settings"
+ label: qsTr("Millisecond Settings")
+ live: true
+ icon.name: "regular:\uf1de"
+
+ P.ColorPreference {
+ name: "MSstar Color"
+ label: qsTr("Star Color")
+ defaultValue: "#9e9e9e"
+ }
+
+ P.Separator {}
+
+ P.SwitchPreference {
+ id: msec_settings_show_orbit
+ name: "Show Orbit"
+ label: qsTr("Show Orbit")
+ defaultValue: true
+ }
+
+ P.ColorPreference {
+ name: "MSorbit Color"
+ label: qsTr("Orbit Color")
+ enabled: msec_settings_show_orbit.value
+ defaultValue: "#9e9e9e"
+ }
+ }
+
+ Component.onCompleted: {
+ if(!widget.settings.styles) {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ }
+ rootPreference.load(widget.settings.styles);
+ configuration = widget.settings.styles;
+ }
+ }
+ }
+ }
+ }
+
+ onClosing: {
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+ }
+
+ Text {
+ id: main_time
+ text: ""
+ visible: configs["BG Settings"]["Show Clock"]
+ color: configs["BG Settings"]["Clock Color"]
+ anchors.centerIn: parent
+ font.pointSize: 0.0009*configs["BG Settings"]["Center Radius"]*maxr*configs["BG Settings"]["Font Size"]/100
+ font.weight: Font.Normal
+ font.family: "Microsoft YaHei"
+ }
+}
diff --git a/text_clock.qml b/text_clock.qml
new file mode 100644
index 0000000..45fe1ca
--- /dev/null
+++ b/text_clock.qml
@@ -0,0 +1,312 @@
+import QtQuick 2.12
+
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+import QtGraphicalEffects 1.0
+
+import NERvGear 1.0 as NVG
+import NERvGear.Templates 1.0 as T
+import NERvGear.Preferences 1.0 as P
+
+
+
+T.Widget {
+ id: widget
+ solid: true
+ title: qsTr("Text Clock")
+ resizable: true
+
+ property real day: 1
+ property real hours: 0
+ property string minutes: ""
+ property string seconds: ""
+
+ readonly property string hlight_color: widget.settings.styles["HighLight Color"]
+ readonly property string normal_color: widget.settings.styles["Normal Color"]
+ readonly property string rfulltext: "ITAISSL" + ((day===5) ? "TGIF" : "GTFI") + "
" +
+ "FJLVZGABOUT
" +
+ "ACQUARTERBS
" +
+ "TWENTYFIVEX
" +
+ "HALFBTENFTO
" +
+ "PASTERUNINE
" +
+ "ONESIXTHREE
" +
+ "FOURFIVETWO
" +
+ "EIGHTELEVEN
" +
+ "SEVENTNOONE
" +
+ "TENSEOCLOCK
" +
+ "AMIDNIGHTVW
"
+
+
+ property var rcolors: [hlight_color, hlight_color, hlight_color, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
+ readonly property var rcindex: {"M15": 3, "M20": 4, "M5": 5, "M30": 6, "M10": 7, "TO": 8, "PAST": 9,
+ "9": 10, "1": 11, "13": 11, "6": 12, "3": 13, "4": 14, "5": 15, "2": 16,
+ "8": 17, "11": 18, "23": 18, "7": 19, "12": 20, "10": 21, "OCLOCK": 22, "0": 23, "24": 23}
+
+ readonly property var fonts: Qt.fontFamilies()
+ readonly property var fontweight: [Font.Light, Font.Normal, Font.DemiBold, Font.Bold, Font.Black]
+ readonly property var sfontweight: ["Light", "Normal", "DemiBold", "Bold", "Black"]
+
+ function stringFormat(rtext, format) {
+ if (!rtext)
+ return null;
+ var str = rtext;
+ for (var i = 0; i < format.length; i++)
+ {
+ var re = new RegExp('\\{' + i + '\\}', 'gm');
+ str = str.replace(re, format[i]);
+ }
+ return str;
+ }
+
+ function clearHLColors() {
+ for(let i=3; i<24; i++) {
+ rcolors[i] = "";
+ }
+ }
+
+ function updateHLColors(){
+ for(let i=0; i 12 && hours !== 23) {
+ hours = hours - 12;
+ }
+
+ if (minutes < 10) {
+ minutes = 0 + minutes;
+ }
+ if (seconds < 10) {
+ seconds = 0 + seconds;
+ }
+
+ var minsSecs = minutes + seconds;
+ if (minsSecs > 3230) {
+ hours++;
+ }
+
+ clearHLColors();
+ updateHLColors(hours);
+
+ if ((minsSecs >= 5730 && minsSecs < 6000) || (minsSecs >= 0 && minsSecs < 230)) {
+ if (hours !== 24 && hours !== 0) {
+ updateHLColors("OCLOCK");
+ }
+ } else if (minsSecs >= 230 && minsSecs < 730) {
+ updateHLColors("M5","PAST");
+ } else if (minsSecs >= 730 && minsSecs < 1230) {
+ updateHLColors("M10", "PAST");
+ } else if (minsSecs >= 1230 && minsSecs < 1730) {
+ updateHLColors("M15","PAST");
+ } else if (minsSecs >= 1730 && minsSecs < 2230) {
+ updateHLColors("M20", "PAST");
+ } else if (minsSecs >= 2230 && minsSecs < 2730) {
+ updateHLColors("M20", "M5", "PAST");
+ } else if (minsSecs >= 2730 && minsSecs < 3230) {
+ updateHLColors("M30", "PAST");
+ } else if (minsSecs >= 3230 && minsSecs < 3730) {
+ updateHLColors("M20", "M5", "TO");
+ } else if (minsSecs >= 3730 && minsSecs < 4230) {
+ updateHLColors("M20", "TO");
+ } else if (minsSecs >= 4230 && minsSecs < 4730) {
+ updateHLColors("M15", "TO");
+ } else if (minsSecs >= 4730 && minsSecs < 5230) {
+ updateHLColors("M10", "TO");
+ } else if (minsSecs >= 5230 && minsSecs < 5730) {
+ updateHLColors("M5", "TO");
+ }
+ main.text = stringFormat(rfulltext, rcolors);
+ }
+ }
+
+ menu: Menu {
+ Action {
+ text: qsTr("Settings") + "..."
+ onTriggered: styleDialog.active = true
+ }
+ }
+
+ Loader {
+ id: styleDialog
+ active: false
+ sourceComponent: NVG.Window {
+ id: window
+ title: qsTr("Clock Settings")
+ visible: true
+ minimumWidth: 380
+ minimumHeight: 580
+ maximumWidth: minimumWidth
+ maximumHeight: minimumHeight
+ width: minimumWidth
+ height: minimumHeight
+
+ transientParent: widget.NVG.View.window
+
+ property var configuration
+
+ ColumnLayout {
+ id: root
+ anchors.fill: parent
+ anchors.margins: 16
+ anchors.topMargin: 0
+
+ Row {
+ spacing: 234
+
+ ToolButton {
+ text: qsTr("Save")
+ onClicked: {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+
+ ToolButton {
+ text: qsTr("Reset")
+ onClicked: {
+ rootPreference.load();
+ let cfg = rootPreference.save();
+ widget.settings.styles = cfg;
+ }
+ }
+ }
+
+ Label {
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Settings")
+ font.pixelSize: 24
+ }
+
+ Flickable {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ clip: true
+ contentWidth: preferenceLayout.implicitWidth
+ contentHeight: preferenceLayout.implicitHeight
+
+ ColumnLayout {
+ id: preferenceLayout
+ width: root.width
+
+ P.PreferenceGroup {
+ id: rootPreference
+ Layout.fillWidth: true
+
+ label: qsTr("Configuration")
+
+ onPreferenceEdited: {
+ widget.settings.styles = rootPreference.save();
+ }
+
+ P.SelectPreference {
+ name: "Font Name"
+ label: qsTr("Font Style")
+ icon.name: "solid:\uf1fc"
+ defaultValue: 408
+ model: fonts
+ }
+
+ P.SelectPreference {
+ name: "Font Weight"
+ label: qsTr("Font Weight")
+ icon.name: "solid:\uf1fc"
+ defaultValue: 0
+ model: sfontweight
+ }
+
+ P.ColorPreference {
+ name: "HighLight Color"
+ label: qsTr("HighLight Color")
+ defaultValue: "#FFF"
+ }
+
+ P.ColorPreference {
+ name: "Normal Color"
+ label: qsTr("Normal Color")
+ defaultValue: "#333333"
+ }
+
+ P.SliderPreference {
+ name: "Font Size"
+ label: qsTr("Font Size")
+ from: 1
+ to: 40
+ stepSize: 1
+ defaultValue: 20
+ displayValue: value
+ }
+
+ P.SliderPreference {
+ name: "Letter Space"
+ label: qsTr("Letter Space")
+ from: 1
+ to: 40
+ stepSize: 1
+ defaultValue: 20
+ displayValue: value
+ }
+
+ P.SliderPreference {
+ name: "Line Height"
+ label: qsTr("Line Spacing")
+ from: 0.8
+ to: 2
+ stepSize: 0.1
+ defaultValue: 1.5
+ displayValue: value.toFixed(1)
+ }
+
+ Component.onCompleted: {
+ if(!widget.settings.styles) {
+ configuration = rootPreference.save();
+ widget.settings.styles = configuration;
+ }
+ rootPreference.load(widget.settings.styles);
+ configuration = widget.settings.styles;
+ }
+ }
+ }
+ }
+ }
+
+ onClosing: {
+ widget.settings.styles = configuration;
+ styleDialog.active = false;
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ if (!widget.settings.styles) {
+ widget.settings.styles = {"Font Name": fonts.length-1, "Font Weight": 0, "Normal Color": "#333333", "HighLight Color": "#FFF", "Font Size": 20, "Letter Space": 20, "Line Height": 1.5};
+ }
+ }
+}