diff --git a/qml/CircleMeter.qml b/qml/CircleMeter.qml index 6a8a086..9d01f7f 100644 --- a/qml/CircleMeter.qml +++ b/qml/CircleMeter.qml @@ -8,14 +8,22 @@ Item { /// current level property double level: 0.5  /// minimum level - property double min: -1 + property double min: -50 /// maximum level - property double max: 1 + property double max: 50 /// numbers to write on the scale - property variant marks: [-1, -0.5, 0, 0.5, 1, -0.2, 0.2, -0.8, 0.8] + property variant marks: [-40, -20, 0, 20, 40] + /// marks regions colors + property variant region_color: ["red", "yellow", "green", "yellow", "red"] /// theme object property QtObject theme + property double r_circle_min: 0.85 + property double r_circle_max: 1 + + property double amin: angle(min) + property double amax: angle(max) + /// positions helper functions function angle(level) { return (level - min) / (max - min) * Math.PI - Math.PI / 2 @@ -28,38 +36,78 @@ Item { return height - height * k * Math.cos(angle) } + /// objects draw + + function arc(ctx, k) { + ctx.beginPath() + ctx.moveTo(getx(amin, k), gety(amin, k)) + for (var i = amin + 0.01; i <= amax; i+=0.01) { + ctx.lineTo(getx(i,k), gety(i,k)) + } + ctx.stroke() + } + + function arc_part(ctx, k, a1, a2) { + ctx.lineTo(getx(a1,k), gety(a1,k)) + var eps = 0.01 + if (a2 > a1) { + for (var i = a1 + eps; i < a2; i+=eps) { + ctx.lineTo(getx(i,k), gety(i,k)) + } + } + else { + for (var i = a1 - eps; i > a2; i-=eps) { + ctx.lineTo(getx(i,k), gety(i,k)) + } + } + ctx.lineTo(getx(a2,k), gety(a2,k)) + } + + function line_mark(ctx, value, r_min, r_max) { + var a = angle(value) + ctx.beginPath() + ctx.moveTo(getx(a, r_min), gety(a, r_min)) + ctx.lineTo(getx(a, r_max), gety(a, r_max)) + ctx.stroke() + } + /// Ellipse Canvas { id: ellipse anchors.fill: parent - property double mark_k_min: 0.90 - property double mark_k_max: 0.95 - property double mark_k_text: 0.85 - property int font_size: 16 + property double r_text: 0.92 + + property double l_marker: 0.035 + property double h_marker: 7 + property int font_size: 20 onPaint: { var ctx = getContext('2d'); ctx.strokeStyle = theme.primaryColor ctx.lineWidth = 1 - ctx.beginPath() - ctx.moveTo(0,height - 1) - ctx.bezierCurveTo(0, -height * 0.33, width - 1, -height * 0.33, width - 1, height - 1) - //ctx.closePath() - ctx.stroke() - console.log("ellipse done") + + arc(ctx, r_circle_min) + arc(ctx, r_circle_max) + ctx.font = font_size + "px sans-serif" ctx.textAlign = "center" + ctx.lineWidth = h_marker + ctx.strokeStyle = theme.secondaryColor for (var i = 0; i < marks.length; i++) { + line_mark(ctx, marks[i], r_circle_min - l_marker, r_circle_min + l_marker) var a = angle(marks[i]) - ctx.beginPath() - ctx.moveTo(getx(a, mark_k_min), gety(a, mark_k_min)) - ctx.lineTo(getx(a, mark_k_max), gety(a, mark_k_max)) - ctx.stroke() - ctx.fillText(marks[i], getx(a, mark_k_text), gety(a, mark_k_text)) + ctx.fillText(marks[i], getx(a, r_text), gety(a, r_text) + 4) ctx.strokeText() } + + // "beetween" marks + ctx.lineWidth = 1 + ctx.strokeStyle = theme.primaryColor + for (var i = 0; i < marks.length - 1; i++) { + line_mark(ctx, (marks[i] + marks[i+1])/2, r_circle_min, r_circle_max) + } } } @@ -67,20 +115,71 @@ Item { /// level arrow id: arrow anchors.fill: parent - property double k: 0.99 + property double k: 0.82 property double k_base: 0.1 property double angle: parent.angle(level) onPaint: { var ctx = getContext('2d'); + ctx.clearRect(0,0,width,height) ctx.strokeStyle = theme.primaryColor ctx.lineWidth = 1 ctx.beginPath() ctx.moveTo(getx(angle, k_base), gety(angle, k_base)) ctx.lineTo(getx(angle, k), gety(angle, k)) ctx.stroke() - - console.log("angle: " + angle) } } + + Canvas { + /// region colors + id: regions + anchors.fill: parent + z: -4 + onPaint: { + var ctx = getContext('2d'); + ctx.clearRect(0,0,width,height) + + var l1 = min + var l2 + + for (var i = 0; i < marks.length; i++) { + if (i == marks.length - 1) l2 = max + else l2 = (marks[i] + marks[i+1]) / 2 + + if (level <= l2) { + var a1 = angle(l1) + var a2 = angle(l2) + ctx.fillStyle = region_color[i] + ctx.beginPath() + ctx.moveTo(getx(a1, r_circle_min), gety(a1, r_circle_min)) + arc_part(ctx, r_circle_min, a1, a2) + arc_part(ctx, r_circle_max, a2, a1) + ctx.lineTo(getx(a1, r_circle_min), gety(a1, r_circle_min)) + ctx.fill() + break; + } + l1 = l2 + } + } + } + + Behavior on level { + NumberAnimation { + duration: 50 + easing.amplitude: max - min + } + } + + onLevelChanged: { + arrow.requestPaint() + regions.requestPaint() + } + + MouseArea { + anchors.fill: parent + onClicked: { + level = Math.random() * (max - min) + min + } + } } diff --git a/qml/DesktopTheme.qml b/qml/DesktopTheme.qml index 059b272..24cadce 100644 --- a/qml/DesktopTheme.qml +++ b/qml/DesktopTheme.qml @@ -2,7 +2,7 @@ import QtQuick 2.0 Item { property color primaryColor: "#000000" - property color secondaryColor: "#444444" + property color secondaryColor: "#777777" property int paddingSmall: 4 property int paddingLarge: 20 property int fontSizeSmall: 10 diff --git a/qml/Scene.qml b/qml/Scene.qml index 0e3baeb..f06fb10 100644 --- a/qml/Scene.qml +++ b/qml/Scene.qml @@ -7,7 +7,7 @@ import QtQuick 2.0 Item { width: 600 - height: 400 + height: 300 DesktopTheme { id: theme