From 6fdddee7d45206dc64eacd08700f79566ad9b4a6 Mon Sep 17 00:00:00 2001 From: Suchinton Chakravarty Date: Tue, 15 Oct 2024 23:57:36 +0530 Subject: Fix Visual Bugs and Add options for Keypad input - Fixed spin wheel input alignment for HVAC controls - Minor tweaks to Gauge input, Added new tick marks and improved gradient - Adding option(s) in config to handle Keypad input settings - Reconnect QML signals to enable two way input for Speed, RPM and other QML elements - Refactor and Add CLI option to start and stop playback. - Make Tire Pressure Dock into floating window and align to screen center. - Update resources to include keypad icons. - Add new tile for Keypad inputs Bug-AGL: SPEC-5161 Change-Id: I1ecefdfd114ecad081c138e74c1598907d91fd23 Signed-off-by: Suchinton Chakravarty --- QMLWidgets/Full_Gauge/RPMGauge.qml | 211 ++++++++++++++++++++------------ QMLWidgets/Full_Gauge/SpeedGauge.qml | 175 +++++++++++++------------- QMLWidgets/Half_Gauge/CoolantGauge.qml | 179 +++++++++++++++------------ QMLWidgets/Half_Gauge/FuelGauge.qml | 181 +++++++++++++++------------ QMLWidgets/Temp_Tumbler/TempTumbler.qml | 59 +++++---- 5 files changed, 461 insertions(+), 344 deletions(-) (limited to 'QMLWidgets') diff --git a/QMLWidgets/Full_Gauge/RPMGauge.qml b/QMLWidgets/Full_Gauge/RPMGauge.qml index 382731d..e440a13 100644 --- a/QMLWidgets/Full_Gauge/RPMGauge.qml +++ b/QMLWidgets/Full_Gauge/RPMGauge.qml @@ -2,8 +2,8 @@ import QtQuick 2.9 Item { id: root - width: 400 - height: 400 + width: 300 + height: 300 property real value: 0 property real minValue: 0 @@ -13,7 +13,27 @@ Item { property color primaryColor: "#16CCBA" property color secondaryColor: "#00000000" property int animationDuration: 1000 - property real startAngle: 0 + property real startAngle: Math.PI * 3 / 4 + property real fullAngle: Math.PI * 3 / 2 + + property real gaugeRadius: 0 + property real tickLength: 0 + + signal rpmValueChanged(int value) + + Component.onCompleted: { + calculateGeometry(); + updateGaugeValue(value); // Initialize the gauge display + } + + onWidthChanged: calculateGeometry() + onHeightChanged: calculateGeometry() + + function calculateGeometry() { + const side = Math.min(width, height); + gaugeRadius = (side - side * 0.20) / 2; + tickLength = gaugeRadius * 0.1; + } Rectangle { anchors.fill: parent @@ -29,7 +49,6 @@ Item { sourceSize.height: width fillMode: Image.PreserveAspectFit anchors.fill: parent - anchors.centerIn: parent scale: 1 opacity: 0.7 z: 0 @@ -40,9 +59,8 @@ Item { source: "./assets/Ellipse 1.svg" sourceSize.width: width sourceSize.height: width - anchors.fill: parent - anchors.centerIn: parent fillMode: Image.PreserveAspectFit + anchors.fill: parent scale: 1 opacity: 0.7 z: 1 @@ -52,49 +70,81 @@ Item { id: canvas anchors.fill: parent antialiasing: true - property real degree: 0 - - onDegreeChanged: requestPaint() onPaint: { - var ctx = getContext("2d") - var center = Qt.point(width / 2, height / 2) - var side = Math.min(width, height) - var radius = (side - side * 0.20) / 2 - var startAngle = Math.PI * 3 / 4 - var fullAngle = Math.PI * 3 / 2 - var progressAngle = startAngle + (degree / 270) * fullAngle - - ctx.reset() - ctx.lineCap = 'round' - - ctx.lineWidth = side * 0.1 - ctx.beginPath() - ctx.arc(center.x, center.y, radius, startAngle, progressAngle) - ctx.strokeStyle = secondaryColor - ctx.stroke() - - ctx.lineWidth = 20 - ctx.beginPath() - ctx.arc(center.x, center.y, radius, startAngle, progressAngle) - ctx.strokeStyle = primaryColor - ctx.stroke() - - // draw tick marks - ctx.lineWidth = 10 - ctx.strokeStyle = '#FFFFFF' - ctx.beginPath() - var tickCount = 2; // Number of tick marks - for (var i = 0; i < tickCount; i++) { - var angle = startAngle + (i / (tickCount - 1)) * (progressAngle - startAngle) - var x1 = center.x + radius * Math.cos(angle) - var y1 = center.y + radius * Math.sin(angle) - var x2 = center.x + (radius - 20) * Math.cos(angle) - var y2 = center.y + (radius - 20) * Math.sin(angle) - ctx.moveTo(x1, y1) - ctx.lineTo(x2, y2) + var ctx = getContext("2d"); + var center = Qt.point(width / 2, height / 2); + + ctx.reset(); + ctx.lineCap = 'round'; + + drawBackground(ctx, center); + drawProgress(ctx, center, value); + drawTicks(ctx, center); + drawProgressTick(ctx, center, value); + } + + function drawBackground(ctx, center) { + ctx.lineWidth = gaugeRadius * 0.1; + ctx.beginPath(); + ctx.arc(center.x, center.y, gaugeRadius, startAngle, startAngle + fullAngle); + ctx.strokeStyle = secondaryColor; + ctx.stroke(); + } + + function drawProgress(ctx, center, progress) { + ctx.lineWidth = 20; + + var gradient = ctx.createLinearGradient( + center.x - gaugeRadius, center.y, + center.x + gaugeRadius, center.y + ); + + gradient.addColorStop(0.0, "#00FF00"); + //gradient.addColorStop(0.3, primaryColor); + gradient.addColorStop(0.4, "#FFD700"); + gradient.addColorStop(1, "#FF0000"); + + ctx.beginPath(); + ctx.arc(center.x, center.y, gaugeRadius, startAngle, startAngle + (progress / (maxValue - minValue)) * fullAngle); + ctx.strokeStyle = gradient; + ctx.stroke(); + } + + function drawTicks(ctx, center) { + ctx.lineWidth = tickLength / 2; + ctx.strokeStyle = '#FFFFFF'; + ctx.beginPath(); + + const tickCount = 10; // Adjust the number of ticks as needed + + for (let i = 0; i <= tickCount; i++) { + const angle = startAngle + (i / tickCount) * fullAngle; + const x1 = center.x + gaugeRadius * Math.cos(angle); + const y1 = center.y + gaugeRadius * Math.sin(angle); + const x2 = center.x + (gaugeRadius - tickLength) * Math.cos(angle); + const y2 = center.y + (gaugeRadius - tickLength) * Math.sin(angle); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); } - ctx.stroke() + + ctx.stroke(); + } + + function drawProgressTick(ctx, center, progress) { + ctx.lineWidth = tickLength * 1.5; + ctx.strokeStyle = '#FFFFFF'; + ctx.beginPath(); + + const progressAngle = startAngle + (progress / (maxValue - minValue)) * fullAngle; + const x1 = center.x + gaugeRadius * Math.cos(progressAngle); + const y1 = center.y + gaugeRadius * Math.sin(progressAngle); + const x2 = center.x + (gaugeRadius - tickLength * 1.5) * Math.cos(progressAngle); + const y2 = center.y + (gaugeRadius - tickLength * 1.5) * Math.sin(progressAngle); + + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); } } @@ -111,7 +161,6 @@ Item { id: gaugeUnit anchors.top: gaugeText.bottom anchors.horizontalCenter: gaugeText.horizontalCenter - text: unit font.pixelSize: 18 font.bold: true @@ -125,41 +174,51 @@ Item { onValueChanged: updateGaugeValue(value) function updateGaugeValue(value) { - canvas.degree = value * 270 - gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0) - } + canvas.requestPaint(); // Request a repaint to reflect changes. + gaugeText.text = (value).toFixed(0); // Display the current value directly. + rpmValueChanged(value); // Emit the signal with the current value. + } - MouseArea { - anchors.fill: parent - hoverEnabled: true + MouseArea { + id: dragArea + anchors.fill: parent - property bool isDragging: false - property real initialValue: 0 + property bool isDragging: false - onEntered: cursorShape = Qt.PointingHandCursor - onPressed: { - isDragging = true - initialValue = root.value - } - onReleased: isDragging = false + onEntered: cursorShape = Qt.PointingHandCursor - onMouseXChanged: updateDragValue(mouse.x, mouse.y) - onMouseYChanged: updateDragValue(mouse.x, mouse.y) + onPressed: { + isDragging = true; + updateDragValue(mouseX, mouseY); // Update immediately on press. + } + + onReleased: isDragging = false - function updateDragValue(x, y) { - if (!isDragging) return + onPositionChanged: + if (isDragging) { + updateDragValue(mouseX, mouseY); // Use formal parameters instead of injected ones. + } - var centerX = width / 2 - var centerY = height / 2 - var dx = x - centerX - var dy = centerY - y // Note: y-axis is inverted - var angle = Math.atan2(dy, dx) * (180 / Math.PI) + function updateDragValue(x, y) { + const centerX = width / 2; + const centerY = height / 2; - // Convert angle to gauge value (0 to 1) - var gaugeValue = (angle + 135) / 270 // Adjust based on your gauge's start angle - gaugeValue = Math.max(0, Math.min(gaugeValue, 1)) // Clamp value + // Calculate angle from the center to the mouse position. + const dx = x - centerX; + const dy = centerY - y; // Note that y-axis is inverted in QML. + const angle = Math.atan2(dy, dx); - root.value = gaugeValue - } - } + // Normalize angle to [startAngle .. startAngle + fullAngle] + let normalizedAngle = angle < startAngle ? angle + Math.PI * 2 : angle; + + // Calculate the normalized value based on the angle. + let normalizedValue = ((normalizedAngle - startAngle) / fullAngle) * (maxValue - minValue); + + // Clamp value within min and max range. + normalizedValue = Math.max(minValue, Math.min(maxValue, normalizedValue)); + + // Update the root value. + root.value = normalizedValue; + } + } } diff --git a/QMLWidgets/Full_Gauge/SpeedGauge.qml b/QMLWidgets/Full_Gauge/SpeedGauge.qml index 02531b7..60d7525 100644 --- a/QMLWidgets/Full_Gauge/SpeedGauge.qml +++ b/QMLWidgets/Full_Gauge/SpeedGauge.qml @@ -2,8 +2,8 @@ import QtQuick 2.9 Item { id: root - width: 400 - height: 400 + width: 300 + height: 300 property real value: 0 property real minValue: 0 @@ -19,8 +19,11 @@ Item { property real gaugeRadius: 0 property real tickLength: 0 + signal speedValueChanged(int value) + Component.onCompleted: { calculateGeometry(); + updateGaugeValue(value); // Initialize the gauge display } onWidthChanged: calculateGeometry() @@ -29,7 +32,7 @@ Item { function calculateGeometry() { const side = Math.min(width, height); gaugeRadius = (side - side * 0.20) / 2; - tickLength = gaugeRadius * 0.05; + tickLength = gaugeRadius * 0.1; } Rectangle { @@ -67,9 +70,6 @@ Item { id: canvas anchors.fill: parent antialiasing: true - property real degree: 0 - - onDegreeChanged: requestPaint() onPaint: { var ctx = getContext("2d"); @@ -79,9 +79,9 @@ Item { ctx.lineCap = 'round'; drawBackground(ctx, center); - drawProgress(ctx, center, degree); + drawProgress(ctx, center, value); drawTicks(ctx, center); - drawProgressTick(ctx, center, degree); + drawProgressTick(ctx, center, value); } function drawBackground(ctx, center) { @@ -95,60 +95,56 @@ Item { function drawProgress(ctx, center, progress) { ctx.lineWidth = 20; - // Create a linear gradient var gradient = ctx.createLinearGradient( - center.x + gaugeRadius * Math.cos(startAngle), - center.y + gaugeRadius * Math.sin(startAngle), - center.x + gaugeRadius * Math.cos(startAngle + fullAngle), - center.y + gaugeRadius * Math.sin(startAngle + fullAngle) + center.x - gaugeRadius, center.y, + center.x + gaugeRadius, center.y ); - // Set gradient stops - gradient.addColorStop(0.3, "#00FF00"); // Green color - gradient.addColorStop(0.3, primaryColor); // Primary color - gradient.addColorStop(0.3, "#FFD700"); // Yellow color - gradient.addColorStop(1, "#FF0000"); // Red color + gradient.addColorStop(0.0, "#00FF00"); + //gradient.addColorStop(0.3, primaryColor); + gradient.addColorStop(0.4, "#FFD700"); + gradient.addColorStop(1, "#FF0000"); ctx.beginPath(); - ctx.arc(center.x, center.y, gaugeRadius, startAngle, startAngle + (progress / 270) * fullAngle); - - // Apply the gradient to the stroke style + ctx.arc(center.x, center.y, gaugeRadius, startAngle, startAngle + (progress / (maxValue - minValue)) * fullAngle); ctx.strokeStyle = gradient; ctx.stroke(); } function drawTicks(ctx, center) { - ctx.lineWidth = tickLength * 2 - ctx.strokeStyle = '#FFFFFF' - ctx.beginPath() - const tickCount = 2 - for (let i = 0; i < tickCount; i++) { - const angle = startAngle + (i / (tickCount - 1)) * fullAngle - const x1 = center.x + gaugeRadius * Math.cos(angle) - const y1 = center.y + gaugeRadius * Math.sin(angle) - const x2 = center.x + (gaugeRadius - tickLength) * Math.cos(angle) - const y2 = center.y + (gaugeRadius - tickLength) * Math.sin(angle) - ctx.moveTo(x1, y1) - ctx.lineTo(x2, y2) + ctx.lineWidth = tickLength / 2; + ctx.strokeStyle = '#FFFFFF'; + ctx.beginPath(); + + const tickCount = 10; // Adjust the number of ticks as needed + + for (let i = 0; i <= tickCount; i++) { + const angle = startAngle + (i / tickCount) * fullAngle; + const x1 = center.x + gaugeRadius * Math.cos(angle); + const y1 = center.y + gaugeRadius * Math.sin(angle); + const x2 = center.x + (gaugeRadius - tickLength) * Math.cos(angle); + const y2 = center.y + (gaugeRadius - tickLength) * Math.sin(angle); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); } + ctx.stroke(); } function drawProgressTick(ctx, center, progress) { + ctx.lineWidth = tickLength * 1.5; + ctx.strokeStyle = '#FFFFFF'; + ctx.beginPath(); - ctx.lineWidth = tickLength * 3 - ctx.strokeStyle = '#FFFFFF' - ctx.beginPath() - - const progressAngle = startAngle + (progress / 270) * fullAngle - const x1 = center.x + gaugeRadius * Math.cos(progressAngle) - const y1 = center.y + gaugeRadius * Math.sin(progressAngle) - const x2 = center.x + (gaugeRadius - tickLength * 1.5) * Math.cos(progressAngle) - const y2 = center.y + (gaugeRadius - tickLength * 1.5) * Math.sin(progressAngle) + const progressAngle = startAngle + (progress / (maxValue - minValue)) * fullAngle; + const x1 = center.x + gaugeRadius * Math.cos(progressAngle); + const y1 = center.y + gaugeRadius * Math.sin(progressAngle); + const x2 = center.x + (gaugeRadius - tickLength * 1.5) * Math.cos(progressAngle); + const y2 = center.y + (gaugeRadius - tickLength * 1.5) * Math.sin(progressAngle); - ctx.moveTo(x1, y1) - ctx.lineTo(x2, y2) - ctx.stroke() + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); } } @@ -156,7 +152,7 @@ Item { id: gaugeText anchors.centerIn: parent text: "0" - font.pixelSize: 0.2 * Math.min(root.width, root.height) + font.pixelSize: 0.3 * Math.min(root.width, root.height) font.bold: true color: "#FFFFFF" } @@ -178,42 +174,51 @@ Item { onValueChanged: updateGaugeValue(value) function updateGaugeValue(value) { - canvas.degree = value * 270 - gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0) - } - - MouseArea { - id: dragArea - anchors.fill: parent - hoverEnabled: true - - property bool isDragging: false - property real initialValue: 0 - - onEntered: cursorShape = Qt.PointingHandCursor - onPressed: { - isDragging = true - initialValue = root.value - } - onReleased: isDragging = false - - onMouseXChanged: updateDragValue(mouse.x, mouse.y) - onMouseYChanged: updateDragValue(mouse.x, mouse.y) - - function updateDragValue(x, y) { - if (!isDragging) return - - const centerX = width / 2 - const centerY = height / 2 - const dx = x - centerX - const dy = centerY - y // Note: y-axis is inverted - const angle = Math.atan2(dy, dx) * (180 / Math.PI) - - // Convert angle to gauge value (0 to 1) - let gaugeValue = (angle + 135) / 270 - gaugeValue = Math.max(0, Math.min(gaugeValue, 1)) // Clamp value - - root.value = gaugeValue - } - } -} + canvas.requestPaint(); // Request a repaint to reflect changes. + gaugeText.text = (value).toFixed(0); // Display the current value directly. + speedValueChanged(value); // Emit the signal with the current value. + } + + MouseArea { + id: dragArea + anchors.fill: parent + + property bool isDragging: false + + onEntered: cursorShape = Qt.PointingHandCursor + + onPressed: { + isDragging = true; + updateDragValue(mouseX, mouseY); // Update immediately on press. + } + + onReleased: isDragging = false + + onPositionChanged: + if (isDragging) { + updateDragValue(mouseX, mouseY); // Use formal parameters instead of injected ones. + } + + function updateDragValue(x, y) { + const centerX = width / 2; + const centerY = height / 2; + + // Calculate angle from the center to the mouse position. + const dx = x - centerX; + const dy = centerY - y; // Note that y-axis is inverted in QML. + const angle = Math.atan2(dy, dx); + + // Normalize angle to [startAngle .. startAngle + fullAngle] + let normalizedAngle = angle < startAngle ? angle + Math.PI * 2 : angle; + + // Calculate the normalized value based on the angle. + let normalizedValue = ((normalizedAngle - startAngle) / fullAngle) * (maxValue - minValue); + + // Clamp value within min and max range. + normalizedValue = Math.max(minValue, Math.min(maxValue, normalizedValue)); + + // Update the root value. + root.value = normalizedValue; + } + } +} \ No newline at end of file diff --git a/QMLWidgets/Half_Gauge/CoolantGauge.qml b/QMLWidgets/Half_Gauge/CoolantGauge.qml index 634647d..fe402de 100644 --- a/QMLWidgets/Half_Gauge/CoolantGauge.qml +++ b/QMLWidgets/Half_Gauge/CoolantGauge.qml @@ -13,8 +13,11 @@ Item { property color primaryColor: "#16CCBA" property color secondaryColor: "#00000000" - property int animationDuration: 500 - property real startAngle: 0 + property int animationDuration: 1000 + property real startAngle: Math.PI * 5 / 4 + property real fullAngle: Math.PI * 1 / 2 + + signal coolantTempValueChanged(int value) Rectangle { anchors.fill: parent @@ -26,51 +29,66 @@ Item { id: canvas anchors.fill: parent antialiasing: true - property real degree: 0 - - onDegreeChanged: requestPaint() onPaint: { - var ctx = getContext("2d") - var center = Qt.point(width / 2, height / 2) - var side = Math.min(width, height) - var radius = (side - side * 0.25) / 2 - var startAngle = Math.PI * 5 / 4 - var fullAngle = Math.PI * 1 / 2 - var progressAngle = startAngle + (degree / 270) * fullAngle - - ctx.reset() - ctx.lineCap = 'round' - - // background arc - ctx.lineWidth = 25 - ctx.beginPath() - ctx.arc(center.x, center.y, radius, startAngle, startAngle + fullAngle) - ctx.strokeStyle = '#000000' - ctx.stroke() - - // fill arc - ctx.lineWidth = 15 - ctx.beginPath() - ctx.arc(center.x, center.y, radius, startAngle, progressAngle) - ctx.strokeStyle = primaryColor - ctx.stroke() - - // draw tick marks - ctx.lineWidth = 5 - ctx.strokeStyle = '#FFFFFF' - ctx.beginPath() - var tickCount = 2; // Number of tick marks - for (var i = 0; i < tickCount; i++) { - var angle = startAngle + (i / (tickCount - 1)) * (progressAngle - startAngle) - var x1 = center.x + radius * Math.cos(angle) - var y1 = center.y + radius * Math.sin(angle) - var x2 = center.x + (radius - 10) * Math.cos(angle) - var y2 = center.y + (radius - 10) * Math.sin(angle) - ctx.moveTo(x1, y1) - ctx.lineTo(x2, y2) + var ctx = getContext("2d"); + var center = Qt.point(width / 2, height / 2); + var side = Math.min(width, height); + var radius = (side - side * 0.25) / 2; + var progressAngle = startAngle + (value / (maxValue - minValue)) * fullAngle; + + ctx.reset(); + ctx.lineCap = 'round'; + + // Background arc + ctx.lineWidth = 25; + ctx.beginPath(); + ctx.arc(center.x, center.y, radius, startAngle, startAngle + fullAngle); + ctx.strokeStyle = '#000000'; + ctx.stroke(); + + // Fill arc + ctx.lineWidth = 15; + ctx.beginPath(); + ctx.arc(center.x, center.y, radius, startAngle, progressAngle); + ctx.strokeStyle = primaryColor; + ctx.stroke(); + + // Draw tick marks + ctx.lineWidth = 5; + ctx.strokeStyle = '#FFFFFF'; + ctx.beginPath(); + const tickCount = 2; // Adjust the number of ticks as needed + + for (let i = 0; i <= tickCount; i++) { + const angle = startAngle + (i / tickCount) * fullAngle; + const x1 = center.x + radius * Math.cos(angle); + const y1 = center.y + radius * Math.sin(angle); + const x2 = center.x + (radius - 10) * Math.cos(angle); + const y2 = center.y + (radius - 10) * Math.sin(angle); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); } - ctx.stroke() + + ctx.stroke(); + + // Draw progress tick mark + drawProgressTick(ctx, center, progressAngle, radius); + } + + function drawProgressTick(ctx, center, angle, radius) { + ctx.lineWidth = 8; // Thickness of the progress tick mark + ctx.strokeStyle = '#FFFFFF'; // Color of the progress tick mark + ctx.beginPath(); + + const x1 = center.x + radius * Math.cos(angle); + const y1 = center.y + radius * Math.sin(angle); + const x2 = center.x + (radius - 15) * Math.cos(angle); // Adjust length as needed + const y2 = center.y + (radius - 15) * Math.sin(angle); + + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); } } @@ -84,7 +102,7 @@ Item { } Text { - id: gaugePercentage + id: gaugeUnit anchors.verticalCenter: gaugeText.verticalCenter anchors.left: gaugeText.right text: unit @@ -99,52 +117,61 @@ Item { anchors.horizontalCenter: gaugeText.horizontalCenter width: 0.15 * Math.min(root.width, root.height) fillMode: Image.PreserveAspectFit - // antialiasing: true antialiasing: true } Behavior on value { NumberAnimation { duration: animationDuration } } - + onValueChanged: updateGaugeValue(value) function updateGaugeValue(value) { - canvas.degree = value * 270 - gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0) + canvas.requestPaint(); // Request a repaint to reflect changes. + gaugeText.text = value.toFixed(0); // Display the current value directly. + coolantTempValueChanged(value); // Emit the signal with the current value. } - MouseArea { - anchors.fill: parent - hoverEnabled: true + MouseArea { + id: dragArea + anchors.fill: parent - property bool isDragging: false - property real initialValue: 0 + property bool isDragging: false - onEntered: cursorShape = Qt.PointingHandCursor - onPressed: { - isDragging = true - initialValue = root.value - } - onReleased: isDragging = false + onEntered: cursorShape = Qt.PointingHandCursor - onMouseXChanged: updateDragValue(mouse.x, mouse.y) - onMouseYChanged: updateDragValue(mouse.x, mouse.y) + onPressed: { + isDragging = true; + updateDragValue(mouseX, mouseY); // Update immediately on press. + } + + onReleased: isDragging = false - function updateDragValue(x, y) { - if (!isDragging) return + onPositionChanged: + if (isDragging) { + updateDragValue(mouseX, mouseY); // Use formal parameters instead of injected ones. + } - var centerX = width / 2 - var centerY = height / 2 - var dx = x - centerX - var dy = centerY - y // Note: y-axis is inverted - var angle = Math.atan2(dy, dx) * (180 / Math.PI) + function updateDragValue(x, y) { + const centerX = width / 2; + const centerY = height / 2; - // Convert angle to gauge value (0 to 1) - var gaugeValue = (angle + 135) / 270; // Adjust based on your gauge's start angle - gaugeValue = Math.max(0, Math.min(gaugeValue, 1)); // Clamp value + // Calculate angle from the center to the mouse position. + const dx = x - centerX; + const dy = centerY - y; // Note that y-axis is inverted in QML. + const angle = Math.atan2(dy, dx); - root.value = gaugeValue; - } - } -} + // Normalize angle to [startAngle .. startAngle + fullAngle] + let normalizedAngle = angle < startAngle ? angle + Math.PI * 2 : angle; + + // Calculate the normalized value based on the angle. + let normalizedValue = ((normalizedAngle - startAngle) / fullAngle) * (maxValue - minValue); + + // Clamp value within min and max range. + normalizedValue = Math.max(minValue, Math.min(maxValue, normalizedValue)); + + // Update the root value. + root.value = normalizedValue; + } + } +} \ No newline at end of file diff --git a/QMLWidgets/Half_Gauge/FuelGauge.qml b/QMLWidgets/Half_Gauge/FuelGauge.qml index f0ea7d0..4a768a0 100644 --- a/QMLWidgets/Half_Gauge/FuelGauge.qml +++ b/QMLWidgets/Half_Gauge/FuelGauge.qml @@ -13,10 +13,11 @@ Item { property color primaryColor: "#16CCBA" property color secondaryColor: "#00000000" - property int animationDuration: 500 - property real startAngle: 0 + property int animationDuration: 1000 + property real startAngle: Math.PI * 5 / 4 + property real fullAngle: Math.PI * 1 / 2 - property var exposedFunction: updateGaugeUnit + signal fuelLevelValueChanged(int value) Rectangle { anchors.fill: parent @@ -28,51 +29,66 @@ Item { id: canvas anchors.fill: parent antialiasing: true - property real degree: 0 - - onDegreeChanged: requestPaint() onPaint: { - var ctx = getContext("2d") - var center = Qt.point(width / 2, height / 2) - var side = Math.min(width, height) - var radius = (side - side * 0.25) / 2 - var startAngle = Math.PI * 5 / 4 - var fullAngle = Math.PI * 1 / 2 - var progressAngle = startAngle + (degree / 270) * fullAngle - - ctx.reset() - ctx.lineCap = 'round' - - // background arc - ctx.lineWidth = 25 - ctx.beginPath() - ctx.arc(center.x, center.y, radius, startAngle, startAngle + fullAngle) - ctx.strokeStyle = '#000000' - ctx.stroke() - - // fill arc - ctx.lineWidth = 15 - ctx.beginPath() - ctx.arc(center.x, center.y, radius, startAngle, progressAngle) - ctx.strokeStyle = primaryColor - ctx.stroke() - - // draw tick marks - ctx.lineWidth = 5 - ctx.strokeStyle = '#FFFFFF' - ctx.beginPath() - var tickCount = 2; // Number of tick marks - for (var i = 0; i < tickCount; i++) { - var angle = startAngle + (i / (tickCount - 1)) * (progressAngle - startAngle) - var x1 = center.x + radius * Math.cos(angle) - var y1 = center.y + radius * Math.sin(angle) - var x2 = center.x + (radius - 10) * Math.cos(angle) - var y2 = center.y + (radius - 10) * Math.sin(angle) - ctx.moveTo(x1, y1) - ctx.lineTo(x2, y2) + var ctx = getContext("2d"); + var center = Qt.point(width / 2, height / 2); + var side = Math.min(width, height); + var radius = (side - side * 0.25) / 2; + var progressAngle = startAngle + (value / (maxValue - minValue)) * fullAngle; + + ctx.reset(); + ctx.lineCap = 'round'; + + // Background arc + ctx.lineWidth = 25; + ctx.beginPath(); + ctx.arc(center.x, center.y, radius, startAngle, startAngle + fullAngle); + ctx.strokeStyle = '#000000'; + ctx.stroke(); + + // Fill arc + ctx.lineWidth = 15; + ctx.beginPath(); + ctx.arc(center.x, center.y, radius, startAngle, progressAngle); + ctx.strokeStyle = primaryColor; + ctx.stroke(); + + // Draw tick marks + ctx.lineWidth = 5; + ctx.strokeStyle = '#FFFFFF'; + ctx.beginPath(); + const tickCount = 2; // Adjust the number of ticks as needed + + for (let i = 0; i <= tickCount; i++) { + const angle = startAngle + (i / tickCount) * fullAngle; + const x1 = center.x + radius * Math.cos(angle); + const y1 = center.y + radius * Math.sin(angle); + const x2 = center.x + (radius - 10) * Math.cos(angle); + const y2 = center.y + (radius - 10) * Math.sin(angle); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); } - ctx.stroke() + + ctx.stroke(); + + // Draw progress tick mark + drawProgressTick(ctx, center, progressAngle, radius); + } + + function drawProgressTick(ctx, center, angle, radius) { + ctx.lineWidth = 8; // Thickness of the progress tick mark + ctx.strokeStyle = '#FFFFFF'; // Color of the progress tick mark + ctx.beginPath(); + + const x1 = center.x + radius * Math.cos(angle); + const y1 = center.y + radius * Math.sin(angle); + const x2 = center.x + (radius - 15) * Math.cos(angle); // Adjust length as needed + const y2 = center.y + (radius - 15) * Math.sin(angle); + + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); } } @@ -87,8 +103,6 @@ Item { Text { id: gaugePercentage - // anchor this to the right of the gaugeText such that their baseline is aligned - anchors.verticalCenter: gaugeText.verticalCenter anchors.left: gaugeText.right text: unit @@ -103,56 +117,61 @@ Item { anchors.horizontalCenter: gaugeText.horizontalCenter width: 0.15 * Math.min(root.width, root.height) fillMode: Image.PreserveAspectFit - // antialiasing: true antialiasing: true } Behavior on value { NumberAnimation { duration: animationDuration } } - + onValueChanged: updateGaugeValue(value) function updateGaugeValue(value) { - canvas.degree = value * 270 - gaugeText.text = (value * (maxValue - minValue) + minValue).toFixed(0) + canvas.requestPaint(); // Request a repaint to reflect changes. + gaugeText.text = value.toFixed(0); // Display the current value directly. + fuelLevelValueChanged(value); // Emit the signal with the current value. } - function updateGaugeUnit() { - gaugeUnit.text = unit - } + MouseArea { + id: dragArea + anchors.fill: parent - MouseArea { - anchors.fill: parent - hoverEnabled: true + property bool isDragging: false - property bool isDragging: false - property real initialValue: 0 + onEntered: cursorShape = Qt.PointingHandCursor - onEntered: cursorShape = Qt.PointingHandCursor - onPressed: { - isDragging = true - initialValue = root.value - } - onReleased: isDragging = false + onPressed: { + isDragging = true; + updateDragValue(mouseX, mouseY); // Update immediately on press. + } + + onReleased: isDragging = false - onMouseXChanged: updateDragValue(mouse.x, mouse.y) - onMouseYChanged: updateDragValue(mouse.x, mouse.y) + onPositionChanged: + if (isDragging) { + updateDragValue(mouseX, mouseY); // Use formal parameters instead of injected ones. + } - function updateDragValue(x, y) { - if (!isDragging) return + function updateDragValue(x, y) { + const centerX = width / 2; + const centerY = height / 2; - var centerX = width / 2 - var centerY = height / 2 - var dx = x - centerX - var dy = centerY - y // Note: y-axis is inverted - var angle = Math.atan2(dy, dx) * (180 / Math.PI) + // Calculate angle from the center to the mouse position. + const dx = x - centerX; + const dy = centerY - y; // Note that y-axis is inverted in QML. + const angle = Math.atan2(dy, dx); - // Convert angle to gauge value (0 to 1) - var gaugeValue = (angle + 135) / 270; // Adjust based on your gauge's start angle - gaugeValue = Math.max(0, Math.min(gaugeValue, 1)); // Clamp value + // Normalize angle to [startAngle .. startAngle + fullAngle] + let normalizedAngle = angle < startAngle ? angle + Math.PI * 2 : angle; - root.value = gaugeValue; - } - } -} + // Calculate the normalized value based on the angle. + let normalizedValue = ((normalizedAngle - startAngle) / fullAngle) * (maxValue - minValue); + + // Clamp value within min and max range. + normalizedValue = Math.max(minValue, Math.min(maxValue, normalizedValue)); + + // Update the root value. + root.value = normalizedValue; + } + } +} \ No newline at end of file diff --git a/QMLWidgets/Temp_Tumbler/TempTumbler.qml b/QMLWidgets/Temp_Tumbler/TempTumbler.qml index 612d9a3..351f352 100644 --- a/QMLWidgets/Temp_Tumbler/TempTumbler.qml +++ b/QMLWidgets/Temp_Tumbler/TempTumbler.qml @@ -5,19 +5,24 @@ import QtQuick.Controls 2.2 Rectangle { width: frame.implicitWidth height: frame.implicitHeight - - // save colors in variables + + // Save colors in variables property color backgroundColor: "#131313" property color background_alt: "#2A2827" property color buttonColor: "#6C6C85" property color highlight: "#4BD7D6" - // store icons from qrc in variables + // Store icons from qrc in variables property string iconUp: "qrc:/Carbon_Icons/carbon_icons/temperature--frigid.svg" property string iconDown: "qrc:/Carbon_Icons/carbon_icons/temperature--hot.svg" - color: backgroundColor - + color: "#041F2B" + // Remove rectangular border + border.color: "#041F2B" + border.width: 0 + anchors.fill: parent + anchors.margins: -5 + signal valueChanged(int newValue) FontMetrics { @@ -40,32 +45,31 @@ Rectangle { Frame { id: frame - padding: 0 + padding: 10 anchors.centerIn: parent anchors.fill: parent Rectangle { anchors.fill: parent - color: backgroundColor - radius: 10 + color: "#041F2B" + radius: width / 4 } Column { - spacing: 10 + spacing: 5 anchors.fill: parent - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: 10 + anchors.margins: 2 Button { width: parent.width - height: parent.height / 6 + height: parent.height * 1 / 4 - Rectangle { + background : Rectangle { width: parent.width height: parent.height color: buttonColor - radius: 10 + radius: width / 4 Image { source: iconUp @@ -77,11 +81,10 @@ Rectangle { } } onClicked: { - // if we are at the top of the list, set the index to the last element + // If we are at the top of the list, set the index to the last element if (valueTumbler.currentIndex == 0) { valueTumbler.currentIndex = valueTumbler.model.count - 1; - } - else { + } else { valueTumbler.currentIndex -= 1; } } @@ -90,8 +93,10 @@ Rectangle { Tumbler { id: valueTumbler anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - height: parent.height / 2 + height: parent.height * 2 / 4 + model: ListModel { ListElement { number: 16 } ListElement { number: 17 } @@ -118,23 +123,26 @@ Rectangle { delegate: delegateComponent - Rectangle { + background : Rectangle { width: parent.width height: parent.height - color: background_alt - radius: 10 + color: backgroundColor + border.color: buttonColor + border.width: 2 + radius: width / 4 } } Button { + id: buttonDown width: parent.width - height: parent.height / 6 + height: parent.height * 1 / 4 - Rectangle { + background : Rectangle { width: parent.width height: parent.height color: buttonColor - radius: 10 + radius: width / 4 Image { source: iconDown @@ -148,8 +156,7 @@ Rectangle { onClicked: { if (valueTumbler.currentIndex == 16) { valueTumbler.currentIndex = 0; - } - else { + } else { valueTumbler.currentIndex += 1; } } -- cgit 1.2.3-korg