CircleMeter: begin a better design

Design proposed by David.
This commit is contained in:
Louis-Joseph Fournier 2015-12-31 17:12:54 +01:00
parent 4b6ffebea2
commit cdf30d2c3c
3 changed files with 122 additions and 23 deletions

View file

@ -8,14 +8,22 @@ Item {
/// current level /// current level
property double level: 0.5  property double level: 0.5 
/// minimum level /// minimum level
property double min: -1 property double min: -50
/// maximum level /// maximum level
property double max: 1 property double max: 50
/// numbers to write on the scale /// 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 /// theme object
property QtObject theme 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 /// positions helper functions
function angle(level) { function angle(level) {
return (level - min) / (max - min) * Math.PI - Math.PI / 2 return (level - min) / (max - min) * Math.PI - Math.PI / 2
@ -28,38 +36,78 @@ Item {
return height - height * k * Math.cos(angle) 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 /// Ellipse
Canvas { Canvas {
id: ellipse id: ellipse
anchors.fill: parent anchors.fill: parent
property double mark_k_min: 0.90 property double r_text: 0.92
property double mark_k_max: 0.95
property double mark_k_text: 0.85 property double l_marker: 0.035
property int font_size: 16 property double h_marker: 7
property int font_size: 20
onPaint: { onPaint: {
var ctx = getContext('2d'); var ctx = getContext('2d');
ctx.strokeStyle = theme.primaryColor ctx.strokeStyle = theme.primaryColor
ctx.lineWidth = 1 ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(0,height - 1) arc(ctx, r_circle_min)
ctx.bezierCurveTo(0, -height * 0.33, width - 1, -height * 0.33, width - 1, height - 1) arc(ctx, r_circle_max)
//ctx.closePath()
ctx.stroke()
console.log("ellipse done")
ctx.font = font_size + "px sans-serif" ctx.font = font_size + "px sans-serif"
ctx.textAlign = "center" ctx.textAlign = "center"
ctx.lineWidth = h_marker
ctx.strokeStyle = theme.secondaryColor
for (var i = 0; i < marks.length; i++) { 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]) var a = angle(marks[i])
ctx.beginPath() ctx.fillText(marks[i], getx(a, r_text), gety(a, r_text) + 4)
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.strokeText() 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 /// level arrow
id: arrow id: arrow
anchors.fill: parent anchors.fill: parent
property double k: 0.99 property double k: 0.82
property double k_base: 0.1 property double k_base: 0.1
property double angle: parent.angle(level) property double angle: parent.angle(level)
onPaint: { onPaint: {
var ctx = getContext('2d'); var ctx = getContext('2d');
ctx.clearRect(0,0,width,height)
ctx.strokeStyle = theme.primaryColor ctx.strokeStyle = theme.primaryColor
ctx.lineWidth = 1 ctx.lineWidth = 1
ctx.beginPath() ctx.beginPath()
ctx.moveTo(getx(angle, k_base), gety(angle, k_base)) ctx.moveTo(getx(angle, k_base), gety(angle, k_base))
ctx.lineTo(getx(angle, k), gety(angle, k)) ctx.lineTo(getx(angle, k), gety(angle, k))
ctx.stroke() 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
}
}
} }

View file

@ -2,7 +2,7 @@ import QtQuick 2.0
Item { Item {
property color primaryColor: "#000000" property color primaryColor: "#000000"
property color secondaryColor: "#444444" property color secondaryColor: "#777777"
property int paddingSmall: 4 property int paddingSmall: 4
property int paddingLarge: 20 property int paddingLarge: 20
property int fontSizeSmall: 10 property int fontSizeSmall: 10

View file

@ -7,7 +7,7 @@ import QtQuick 2.0
Item { Item {
width: 600 width: 600
height: 400 height: 300
DesktopTheme { DesktopTheme {
id: theme id: theme