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 WidgetTemplate { id: widget title: qsTr("Solar Clock") resizable: true editing: styleDialog.active version: "1.0.0" defaultValues: { "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 Name": Common.fonts.length-1, "Font Weight": 1, "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" } } 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 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("Solar Clock") 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: defaultValues["BG Settings"]["BG Color"] } P.SliderPreference { name: "BG Alpha" label: qsTr("Transparency") from: 0 to: 100 stepSize: 1 defaultValue: defaultValues["BG Settings"]["BG Alpha"] displayValue: value + "%" } P.Separator {} P.SwitchPreference { id: show_hgrid name: "Show HGrid" label: qsTr("Show Scale") defaultValue: defaultValues["BG Settings"]["Show HGrid"] } P.ColorPreference { name: "HGRID Color" label: qsTr("Scale Color") enabled: show_hgrid.value defaultValue: defaultValues["BG Settings"]["HGRID Color"] } P.Separator {} P.SwitchPreference { id: showCenter name: "Show Center" label: qsTr("Show Center") defaultValue: defaultValues["BG Settings"]["Show Center"] } P.ColorPreference { name: "Center Color" label: qsTr("Center Color") enabled: showCenter.value defaultValue: defaultValues["BG Settings"]["Center Color"] } P.SliderPreference { name: "Center Radius" label: qsTr("Center Radius") enabled: showCenter.value from: 30 to: 100 stepSize: 1 defaultValue: defaultValues["BG Settings"]["Center Radius"] displayValue: value + "%" } P.Separator {} P.SwitchPreference { id: showClock name: "Show Clock" label: qsTr("Display Time") defaultValue: defaultValues["BG Settings"]["Show Clock"] } P.ColorPreference { name: "Clock Color" label: qsTr("Font Color") enabled: showClock.value defaultValue: defaultValues["BG Settings"]["Clock Color"] } P.SelectPreference { name: "Font Name" label: qsTr("Font Style") defaultValue: defaultValues["BG Settings"]["Font Name"] model: Common.fonts } P.SelectPreference { name: "Font Weight" label: qsTr("Font Weight") defaultValue: defaultValues["BG Settings"]["Font Weight"] model: Common.sfontweight } P.SliderPreference { name: "Font Size" label: qsTr("Font Size") enabled: showClock.value from: 50 to: 100 stepSize: 1 defaultValue: defaultValues["BG Settings"]["Font Size"] 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: defaultValues["Hour Settings"]["Hstar Color"] } P.Separator {} P.SwitchPreference { id: hour_settings_show_orbit name: "Show Orbit" label: qsTr("Show Orbit") defaultValue: defaultValues["Hour Settings"]["Show Orbit"] } P.ColorPreference { name: "Horbit Color" label: qsTr("Orbit Color") enabled: hour_settings_show_orbit.value defaultValue: defaultValues["Hour Settings"]["Horbit Color"] } } 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: defaultValues["Min Settings"]["Mstar Color"] } P.Separator {} P.SwitchPreference { id: min_settings_show_orbit name: "Show Orbit" label: qsTr("Show Orbit") defaultValue: defaultValues["Min Settings"]["Show Orbit"] } P.ColorPreference { name: "Morbit Color" label: qsTr("Orbit Color") enabled: min_settings_show_orbit.value defaultValue: defaultValues["Min Settings"]["Morbit Color"] } } 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: defaultValues["Sec Settings"]["Sstar Color"] } P.Separator {} P.SwitchPreference { id: sec_settings_show_orbit name: "Show Orbit" label: qsTr("Show Orbit") defaultValue: defaultValues["Sec Settings"]["Show Orbit"] } P.ColorPreference { name: "Sorbit Color" label: qsTr("Orbit Color") enabled: sec_settings_show_orbit.value defaultValue: defaultValues["Sec Settings"]["Sorbit Color"] } } 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: defaultValues["MSec Settings"]["MSstar Color"] } P.Separator {} P.SwitchPreference { id: msec_settings_show_orbit name: "Show Orbit" label: qsTr("Show Orbit") defaultValue: defaultValues["MSec Settings"]["Show Orbit"] } P.ColorPreference { name: "MSorbit Color" label: qsTr("Orbit Color") enabled: msec_settings_show_orbit.value defaultValue: defaultValues["MSec Settings"]["MSorbit Color"] } } Component.onCompleted: { rootPreference.load(widget.settings.styles); configuration = widget.settings.styles; } } } } } } onClosing: { widget.settings.styles = configuration; styleDialog.active = false; } } } Text { id: main_time text: "" style: Text.Outline styleColor: "transparent" 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: Common.fontweight[configs["BG Settings"]["Font Weight"]] font.family: Common.fonts[configs["BG Settings"]["Font Name"]]//"Microsoft YaHei" } }