You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

681 lines
25 KiB

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import NERvGear 1.0 as NVG
import NERvGear.Controls 1.0
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
width: minimumWidth
height: minimumHeight
transientParent: widget.NVG.View.window
property var configuration
Page {
id: cfg_page
anchors.fill: parent
header: TitleBar {
text: qsTr("Settings")
standardButtons: Dialog.Save | Dialog.Reset
onAccepted: {
configuration = rootPreference.save();
widget.settings.styles = configuration;
styleDialog.active = false;
}
onReset: {
rootPreference.load();
let cfg = rootPreference.save();
widget.settings.styles = cfg;
}
}
ColumnLayout {
id: root
anchors.fill: parent
anchors.margins: 16
anchors.topMargin: 0
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"
}
}