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.
465 lines
14 KiB
465 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.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; |
|
} |
|
} |
|
} |
|
}
|
|
|