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.

463 lines
14 KiB

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;
}
}
}
}