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.
 
 

520 lines
20 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
visible: true
title: qsTr("Ordinal Scale Top UI widget")
property real thour: 0
property real t12hour: 0
property real tmin: 0
editing: styleDialog.active
readonly property var configs: widget.settings.styles ? widget.settings.styles : {"Circle Color":"#fffcf9","Line Color":"#fffcf9","Line Width":38,"Shadow Color":"#e0e0e0","Shadow Size":0.5,"Battle UI":false,"Clock Visible":true,"Full Clock":true,"Font Color":"#f5f5f5","Font Size":44,"Font Name":0,"Font Weight":0,"Text Vertical Offset":16}
property string circle_color: configs["Circle Color"]
property string line_color: configs["Line Color"]
property string shadowColor: configs["Shadow Color"]
property real shadowBlur: configs["Shadow Size"]
readonly property real size: 155
readonly property real h: Math.min(widget.width, widget.height)
readonly property real w: widget.width
readonly property real r: (w**2+h**2)/4/h
readonly property var fonts: Qt.fontFamilies()
readonly property var fontweight: [Font.Light, Font.Normal, Font.Bold]
readonly property var sfontweight: [qsTr("Light"), qsTr("Normal"), qsTr("Bold")]
Timer {
interval: 250
running: text_clock.visible
repeat: true
onTriggered: {
var now = new Date();
tmin = now.getMinutes();
thour = now.getHours();
if (!configs["Full Clock"])
t12hour = thour > 12 ? thour - 12 : thour;
}
}
Text {
id: text_clock
anchors.top: parent.top
anchors.topMargin: widget.height/200*configs["Text Vertical Offset"]
anchors.horizontalCenter: parent.horizontalCenter
color: configs["Font Color"]
text: configs["Full Clock"] ? ("0"+thour).slice(-2) + ":" + ("0"+tmin).slice(-2) : ("0"+t12hour).slice(-2) + ":" + ("0"+tmin).slice(-2)
font.pointSize: widget.height/200*configs["Font Size"]
font.family: fonts[configs["Font Name"]]
font.weight: fontweight[configs["Font Weight"]]
visible: widget.NVG.View.exposed && !configs["Battle UI"] && configs["Clock Visible"]
}
Item {
id: circle
anchors.centerIn: parent
anchors.verticalCenterOffset: -2.5
scale: widget.height/size/1.25
visible: widget.NVG.View.exposed && configs["Battle UI"]
Canvas {
id: c1
anchors.centerIn: parent
width: size
height: size
contextType: "2d"
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
onPaint: {
context.reset();
context.clearRect(0,0,size,size);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = size*0.04 - shadowBlur;
context.beginPath();
context.arc(size/2, size/2, size*0.38-shadowBlur/2, -Math.PI/6, -Math.PI/6+Math.PI*2/3 , true);
context.strokeStyle = circle_color;
context.stroke();
}
rotation: -140
SequentialAnimation on rotation {
running: circle.visible
loops: Animation.Infinite
RotationAnimation {
duration: 1250
easing.type: Easing.InOutCubic
from: -140
to: 220
}
RotationAnimation {
duration: 1250
easing.type: Easing.InOutCubic
from: 220
to: -140
direction: RotationAnimation.Counterclockwise
}
}
}
Canvas {
id: c2
anchors.centerIn: parent
width: size
height: size
contextType: "2d"
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
onPaint: {
context.reset();
context.clearRect(0,0,size,size);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = size*0.08 - shadowBlur;
context.beginPath();
context.arc(size/2, size/2, size*0.30-shadowBlur/2, -Math.PI/6, -Math.PI/24+Math.PI*2/3 , true);
context.strokeStyle = circle_color;
context.stroke();
}
rotation: 20
NumberAnimation on rotation {
duration: 2800
easing.type: Easing.Linear
from: 20
to: 380
loops: Animation.Infinite
running: circle.visible
}
}
Canvas {
id: c3
anchors.centerIn: parent
width: size
height: size
contextType: "2d"
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
onPaint: {
context.reset();
context.clearRect(0,0,size,size);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = size*0.03 - shadowBlur;
context.beginPath();
context.arc(size/2, size/2, size*0.23-shadowBlur/2, -Math.PI/6, Math.PI/12+Math.PI*2/3 , true);
context.strokeStyle = circle_color;
context.stroke();
}
rotation: 90
NumberAnimation on rotation {
duration: 2000
easing.type: Easing.Linear
from: 90
to: -270
loops: Animation.Infinite
running: circle.visible
}
}
Canvas {
id: c4
anchors.centerIn: parent
width: size
height: size
contextType: "2d"
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
onPaint: {
context.reset();
context.clearRect(0,0,size,size);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = size*0.06 - shadowBlur;
context.beginPath();
context.arc(size/2, size/2, size*0.17-shadowBlur/2, -Math.PI/6, Math.PI/4+Math.PI*2/3 , true);
context.strokeStyle = circle_color;
context.stroke();
}
rotation: -70
SequentialAnimation on rotation {
running: circle.visible
loops: Animation.Infinite
RotationAnimation {
duration: 1150
easing.type: Easing.InOutCubic
from: -70
to: 290
}
RotationAnimation {
duration: 1150
easing.type: Easing.InOutCubic
from: 290
to: -70
direction: RotationAnimation.Counterclockwise
}
}
}
Canvas {
id: c5
anchors.centerIn: parent
width: size
height: size
contextType: "2d"
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
onPaint: {
context.reset();
context.clearRect(0,0,size,size);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = size*0.1 - shadowBlur;
context.beginPath();
context.arc(size/2, size/2, size*0.05-shadowBlur/2, 0, -Math.PI*2 , true);
context.strokeStyle = circle_color;
context.stroke();
}
}
Canvas {
id: c0
anchors.centerIn: parent
width: size
height: size
contextType: "2d"
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
onPaint: {
context.reset();
context.clearRect(0,0,size,size);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = size*0.16 - shadowBlur;
context.beginPath();
context.arc(size/2, size/2, size*0.38-shadowBlur/2, 0, -Math.PI/3 , true);
context.strokeStyle = circle_color;
context.stroke();
}
NumberAnimation on rotation {
duration: 1500
easing.type: Easing.Linear
from: 0
to: 360
loops: Animation.Infinite
running: circle.visible
}
}
}
Canvas {
id: line
anchors.centerIn: parent
width: widget.width
height: widget.height
contextType: "2d"
onPaint: {
context.reset();
context.clearRect(0,0,width,height);
context.shadowBlur = shadowBlur;
context.shadowColor = shadowColor;
context.lineWidth = Math.max(0.08*configs["Line Width"] - shadowBlur, 0.1);
context.strokeStyle = line_color;
let deg = Math.asin(w/2/r)*0.95;
context.beginPath();
if (circle.visible) {
context.arc(w/2, -r+h/2, r-shadowBlur/2, deg+Math.PI/2, Math.PI/2+circle.scale*size/1.22/r, true);
context.stroke();
context.beginPath();
context.arc(w/2, -r+h/2, r-shadowBlur/2, -deg+Math.PI/2, Math.PI/2-circle.scale*size/1.22/r, false);
context.stroke();
} else {
context.arc(w/2, -r+h/2, r-shadowBlur/2, deg+Math.PI/2, -deg+Math.PI/2, true);
context.stroke();
}
}
}
menu: Menu {
Action {
text: qsTr("Settings") + "..."
onTriggered: styleDialog.active = true
}
}
Loader {
id: styleDialog
active: false
sourceComponent: NVG.Window {
id: window
title: qsTr("Settings")
visible: true
minimumWidth: 380
minimumHeight: 500
width: minimumWidth
height: minimumHeight
transientParent: widget.NVG.View.window
property var configuration
Page {
id: cfg_page
anchors.fill: parent
header: TitleBar {
text: qsTr("UI 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;
line.requestPaint();
c0.requestPaint();
c1.requestPaint();
c2.requestPaint();
c3.requestPaint();
c4.requestPaint();
c5.requestPaint();
}
}
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();
line.requestPaint();
c0.requestPaint();
c1.requestPaint();
c2.requestPaint();
c3.requestPaint();
c4.requestPaint();
c5.requestPaint();
}
P.ColorPreference {
name: "Circle Color"
label: qsTr("Circle Color")
defaultValue: "#fffcf9"
}
P.ColorPreference {
name: "Line Color"
label: qsTr("Line Color")
defaultValue: "#fffcf9"
}
P.SliderPreference {
name: "Line Width"
label: qsTr("Line Width")
from: 1
to: 100
stepSize: 1
defaultValue: 38
displayValue: value + "%"
}
P.ColorPreference {
name: "Shadow Color"
label: qsTr("Shadow Color")
defaultValue: "#e0e0e0"
}
P.SliderPreference {
name: "Shadow Size"
label: qsTr("Shadow Size")
from: 0
to: 3
stepSize: 0.1
defaultValue: 0.5
displayValue: Math.round(value*10)/10 + "px"
}
P.Separator {}
P.SwitchPreference {
id: _cfg_battle_ui
name: "Battle UI"
label: qsTr("Battle UI")
defaultValue: false
}
P.Separator {}
P.SwitchPreference {
id: _cfg_clock_visible
name: "Clock Visible"
label: qsTr("Clock Visible")
visible: !_cfg_battle_ui.value
enabled: visible
defaultValue: true
}
P.SwitchPreference {
name: "Full Clock"
label: qsTr("24 Hour Clock")
visible: !_cfg_battle_ui.value
enabled: visible && _cfg_clock_visible.value
defaultValue: true
}
P.ColorPreference {
name: "Font Color"
label: qsTr("Font Color")
visible: !_cfg_battle_ui.value
enabled: visible && _cfg_clock_visible.value
defaultValue: "#f5f5f5"
}
P.SliderPreference {
name: "Font Size"
label: qsTr("Font Size")
visible: !_cfg_battle_ui.value
enabled: visible && _cfg_clock_visible.value
from: 1
to: 100
stepSize: 1
defaultValue: 44
displayValue: value + "%"
}
P.SelectPreference {
name: "Font Name"
label: qsTr("Font Style")
visible: !_cfg_battle_ui.value
enabled: visible && _cfg_clock_visible.value
icon.name: "solid:\uf1fc"
defaultValue: 0
model: fonts
}
P.SelectPreference {
name: "Font Weight"
label: qsTr("Font Weight")
visible: !_cfg_battle_ui.value
enabled: visible && _cfg_clock_visible.value
icon.name: "solid:\uf1fc"
defaultValue: 0
model: sfontweight
}
P.SliderPreference {
name: "Text Vertical Offset"
label: qsTr("Text Vertical Offset")
visible: !_cfg_battle_ui.value
enabled: visible && _cfg_clock_visible.value
from: -100
to: 100
stepSize: 1
defaultValue: 16
displayValue: value + "%"
}
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;
line.requestPaint();
c0.requestPaint();
c1.requestPaint();
c2.requestPaint();
c3.requestPaint();
c4.requestPaint();
c5.requestPaint();
}
}
}
}