|
|
|
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 fonts: Qt.fontFamilies()
|
|
|
|
readonly property var fontweight: [Font.Light, Font.Normal, Font.Bold]
|
|
|
|
readonly property var sfontweight: [qsTr("Light"), qsTr("Normal"), qsTr("Bold")]
|
|
|
|
|
|
|
|
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":fonts.length-1,"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
|
|
|
|
|
|
|
|
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: fonts.length-1
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|