nClocks/qml/RoundClock.qml
mashiros 6cf739c5eb - 统一接口
- 新增时钟样式vecto
2022-05-23 19:20:51 +08:00

466 lines
14 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("Round Clock")
editing: styleDialog.active
resizable: true
version: "1.0.0"
defaultValues: {
"Sec Continue": true,
"BG Color": "#2196f3",
"BG Alpha": 50,
"HGRID Color": "#ffffff",
"MGRID Color": "#ffffff",
"Hhand Color": "#ffffff",
"Mhand Color": "#ffffff",
"Shand Color": "#f3a829"
}
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
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.01
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
width: minimumWidth
height: minimumHeight
transientParent: widget.NVG.View.window
property var configuration
Page {
id: cfg_page
anchors.fill: parent
header: TitleBar {
text: qsTr("Round 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.SwitchPreference {
name: "Sec Continue"
label: qsTr("Continuous Second Hand")
defaultValue: defaultValues["Sec Continue"]
}
P.Separator {}
P.ColorPreference {
name: "BG Color"
label: qsTr("Background Color")
defaultValue: defaultValues["BG Color"]
}
P.SliderPreference {
name: "BG Alpha"
label: qsTr("Background transparency")
from: 0
to: 100
stepSize: 1
defaultValue: defaultValues["BG Alpha"]
displayValue: value + "%"
}
P.Separator {}
P.ColorPreference {
name: "HGRID Color"
label: qsTr("Hour Scale Color")
defaultValue: defaultValues["HGRID Color"]
}
P.ColorPreference {
name: "MGRID Color"
label: qsTr("Minute Scale Color")
defaultValue: defaultValues["MGRID Color"]
}
P.Separator {}
P.ColorPreference {
name: "Hhand Color"
label: qsTr("Hour Hand Color")
defaultValue: defaultValues["Hhand Color"]
}
P.ColorPreference {
name: "Mhand Color"
label: qsTr("Minute Hand Color")
defaultValue: defaultValues["Mhand Color"]
}
P.ColorPreference {
name: "Shand Color"
label: qsTr("Second Hand Color")
defaultValue: defaultValues["Shand Color"]
}
Component.onCompleted: {
rootPreference.load(widget.settings.styles);
configuration = widget.settings.styles;
}
}
}
}
}
}
onClosing: {
widget.settings.styles = configuration;
styleDialog.active = false;
}
}
}
}