From 4e67739c268ac401671098c6397b8ab5427d0fe6 Mon Sep 17 00:00:00 2001 From: cos Date: Wed, 18 Mar 2020 01:43:48 +0100 Subject: Show battery status in hour and minute hands Garmin do not provide all too many tools, so this uses the only imaginable way to get partially red and partially white hands with the graphics primitives available. They idea is that there is a loop over each angle mapping to new pixels of the hands, setting the clipping region while using red, to get a battery level indication along the hands. --- Makefile | 2 +- manifest.xml | 2 +- source/MazarineApp.mc | 4 + source/MazarineView.mc | 289 +++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 262 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 2f80eb5..852367d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ DEVICE=vivoactive3 SDK=3.1.7 -VERSION="0.0.1" +VERSION="0.0.2" OUTPUT=bin/mazarine_$(VERSION).prg MONKEY_SDK=~/CONNECTIQ CONNIQ=$(MONKEY_SDK)/bin/connectiq diff --git a/manifest.xml b/manifest.xml index 39df2e7..5638436 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,5 +1,5 @@ - + diff --git a/source/MazarineApp.mc b/source/MazarineApp.mc index b334540..afe8049 100644 --- a/source/MazarineApp.mc +++ b/source/MazarineApp.mc @@ -6,6 +6,10 @@ // This software may be modified and distributed under the terms // of the BSD license. See the LICENSE file for details. +// Settings are not possible: +// https://stackoverflow.com/q/34583358/how-to-have-settings-for-connectiq-watch-app +// https://forums.garmin.com/developer/connect-iq/f/discussion/2810/watch-face-settings-for-watch-faces-uploaded-directly + using Toybox.Application; using Toybox.WatchUi; diff --git a/source/MazarineView.mc b/source/MazarineView.mc index 3a684c2..d0c5228 100644 --- a/source/MazarineView.mc +++ b/source/MazarineView.mc @@ -11,9 +11,14 @@ using Toybox.Graphics; using Toybox.System; using Toybox.Math; using Toybox.Application; +using Toybox.Time; using Toybox.Time.Gregorian; +using Toybox.SensorHistory; +using Toybox.Lang; class MazarineView extends WatchUi.WatchFace { + var background; + var width_minute_mark = 3; function initialize() { WatchUi.WatchFace.initialize(); @@ -27,6 +32,10 @@ class MazarineView extends WatchUi.WatchFace { var width = dc.getWidth(); var height = dc.getHeight(); + dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT); + dc.fillRectangle(0, 0, width, height); + dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_TRANSPARENT); + var min; if (width > height) { min = height; @@ -42,7 +51,7 @@ class MazarineView extends WatchUi.WatchFace { dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_TRANSPARENT); // minute marks - dc.setPenWidth(2); + dc.setPenWidth(width_minute_mark); for (var x = 0; x <= 60; x += 1) { var angle = x * (Math.PI / 30.0); @@ -239,9 +248,246 @@ class MazarineView extends WatchUi.WatchFace { // draw the hand dc.setPenWidth(4); dc.drawLine(pix, piy, pox, poy); + } + + function debug_clip_circle(dc) { + var width = dc.getWidth(); + var height = dc.getHeight(); + + var min; + if (width > height) { + min = height; + } else { + min = width; + } + + var iX, iY, oX, oY; + var furtherOuterRad = min * 0.46; + var outerRad = min * 0.48; + var innerRad = min * 0.52; + + // minute marks + dc.setPenWidth(width_minute_mark); + var resolution = 275; + var stats = System.getSystemStats(); + var warning_level = 33.0; + if (stats.battery < warning_level) { + + var battery = (stats.battery/warning_level); + var time = System.getClockTime(); + + var start = (time.min - 1) * resolution/60; + var end = (time.min + 2) * resolution/60; + for (var x = start; x <= end; x += 1) { + var angle = x * (2.0 * Math.PI / resolution); + + var x0 = width/2.0 + (Math.sin(angle)*outerRad * (1.0 - + battery)); + var y0 = height/2.0 - (Math.cos(angle)*outerRad * (1.0 - + battery)); + + var x1 = width/2.0; + var y1 = height/2.0; + if (time.min <= 30) { + x1 -= 10; + } else { + x1 += 10; + } + if ((time.min > 45) || (time.min <= 15)) { + y1 += 10; + } else { + y1 -= 10; + } + + if (x0 > x1) { + var tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + var tmp = y0; + y0 = y1; + y1 = tmp; + } + dc.setClip(x0, y0, x1-x0, y1-y0); + dc.fillRectangle(0, 0, width, height); + dc.clearClip(); + } + + start = ((time.hour + time.min/60.0 - 0.3) * resolution/12) + .toNumber(); + end = ((time.hour + time.min/60.0 + 0.3) * resolution/12) + .toNumber()+1; + for (var x = start; x <= end; x += 1) { + var angle = x * (2.0 * Math.PI / resolution); + + var x0 = width/2.0 + (Math.sin(angle)*outerRad * (1.0 - + battery)); + var y0 = height/2.0 - (Math.cos(angle)*outerRad * (1.0 - + battery)); + + var x1 = width/2.0; + var y1 = height/2.0; + if (time.hour % 12 < 6) { + x1 -= 10; + } else { + x1 += 10; + } + if ((time.hour % 12 >= 9) || (time.hour % 12 < 3)) { + y1 += 10; + } else { + y1 -= 10; + } + + + if (x0 > x1) { + var tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + var tmp = y0; + y0 = y1; + y1 = tmp; + } + dc.setClip(x0, y0, x1-x0, y1-y0); + dc.fillRectangle(0, 0, width, height); + dc.clearClip(); + } + } + } + + function draw_clip_circle(dc) { + var width = dc.getWidth(); + var height = dc.getHeight(); + + var min; + if (width > height) { + min = height; + } else { + min = width; + } - // draw the arbor - dc.fillCircle(width/2.0, height/2.0, min*0.03); + var iX, iY, oX, oY; + var furtherOuterRad = min * 0.46; + var outerRad = min * 0.48; + var innerRad = min * 0.52; + + // minute marks + dc.setPenWidth(width_minute_mark); + var resolution = 275; + var stats = System.getSystemStats(); + var warning_level = 33.0; + if (stats.battery >= warning_level) { + dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); + dc.fillCircle(width/2.0, height/2.0, 7.5); + } else { + dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_TRANSPARENT); + dc.fillCircle(width/2.0, height/2.0, 7.5); + + var battery = (stats.battery/warning_level); + var time = System.getClockTime(); + + var start = (time.min - 1) * resolution/60; + var end = (time.min + 2) * resolution/60; + for (var x = start; x <= end; x += 1) { + var angle = x * (2.0 * Math.PI / resolution); + + var x0 = width/2.0 + (Math.sin(angle)*outerRad * (1.0 - + battery)); + var y0 = height/2.0 - (Math.cos(angle)*outerRad * (1.0 - + battery)); + + var x1 = width/2.0; + var y1 = height/2.0; + if (time.min <= 30) { + x1 -= 10; + } else { + x1 += 10; + } + if ((time.min > 45) || (time.min <= 15)) { + y1 += 10; + } else { + y1 -= 10; + } + + if (x0 > x1) { + var tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + var tmp = y0; + y0 = y1; + y1 = tmp; + } + dc.setClip(x0, y0, x1-x0, y1-y0); + // dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT); + // dc.fillRectangle(0, 0, width, height); + // dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); + draw_minute_hand(dc); + dc.clearClip(); + } + + start = ((time.hour + time.min/60.0 - 0.3) * resolution/12) + .toNumber(); + end = ((time.hour + time.min/60.0 + 0.3) * resolution/12) + .toNumber()+1; + for (var x = start; x <= end; x += 1) { + var angle = x * (2.0 * Math.PI / resolution); + + var x0 = width/2.0 + (Math.sin(angle)*outerRad * (1.0 - + battery)); + var y0 = height/2.0 - (Math.cos(angle)*outerRad * (1.0 - + battery)); + + var x1 = width/2.0; + var y1 = height/2.0; + if (time.hour % 12 < 6) { + x1 -= 10; + } else { + x1 += 10; + } + if ((time.hour % 12 >= 9) || (time.hour % 12 < 3)) { + y1 += 10; + } else { + y1 -= 10; + } + + + if (x0 > x1) { + var tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + var tmp = y0; + y0 = y1; + y1 = tmp; + } + dc.setClip(x0, y0, x1-x0, y1-y0); + // dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT); + // dc.fillRectangle(0, 0, width, height); + // dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); + draw_hour_hand(dc); + dc.clearClip(); + } + } + } + + function draw_analog(dc) { + var stats = System.getSystemStats(); + + if (stats.battery < 25.0) { + // dc.fillRectangle(battery_meter_x, battery_meter_y, + // battery_meter_width*stats.battery/100.0, battery_meter_height); + } + // dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT); + // debug_clip_circle(dc); + dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); + draw_hour_hand(dc); + draw_minute_hand(dc); + draw_clip_circle(dc); } function draw_hour_hand(dc) { @@ -258,7 +504,7 @@ class MazarineView extends WatchUi.WatchFace { var clockTime = System.getClockTime(); var hourRad = min * 0.13; - var pointerOut = min * 0.34; + var pointerOut = min * 0.24; var pointerIn = min * 0.00; // get the angle for the hour @@ -268,10 +514,6 @@ class MazarineView extends WatchUi.WatchFace { // add the minutes angle -= (clockTime.min / 60.0) * (Math.PI / 6); - // center of the circle - var cX = width/2.0 + Math.sin(angle)*hourRad; - var cY = height/2.0 + Math.cos(angle)*hourRad; - // points for the nub var pox = width/2.0 + Math.sin(angle)*pointerOut; var poy = height/2.0 + Math.cos(angle)*pointerOut; @@ -297,8 +539,6 @@ class MazarineView extends WatchUi.WatchFace { var clockTime = System.getClockTime(); - // var secondRad = min * 0.52; - // var secondRadBack = min * 0.0; var furtherOuterRad = min * 0.46; var outerRad = min * 0.48; var innerRad = min * 0.52; @@ -306,7 +546,7 @@ class MazarineView extends WatchUi.WatchFace { // get the angle for seconds var angle = (clockTime.sec / 60.0) * (-2.0 * Math.PI); - for (var x = clockTime.sec - 1; x <= clockTime.sec + 1; x += 1) { + for (var x = clockTime.sec - 1; x <= clockTime.sec; x += 1) { var angle = x * (Math.PI / 30.0); dc.setPenWidth(4); oX = width/2.0 + Math.sin(angle)*furtherOuterRad; @@ -321,7 +561,7 @@ class MazarineView extends WatchUi.WatchFace { dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT); dc.drawLine(iX, iY, oX, oY); dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_TRANSPARENT); - dc.setPenWidth(2); + dc.setPenWidth(width_minute_mark); // make the 5 minute marks longer if (x % 5 == 0) { @@ -337,12 +577,11 @@ class MazarineView extends WatchUi.WatchFace { } } - // update event handler function onUpdate(dc) { + dc.clearClip(); + var width = dc.getWidth(); var height = dc.getHeight(); - // dc.setClip(0, 0, width, height); - dc.clearClip(); var min; if (width > height) { @@ -351,30 +590,14 @@ class MazarineView extends WatchUi.WatchFace { min = width; } - // bg - dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT); - dc.fillRectangle(0, 0, width, height); - - // minute rings with marks - dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_TRANSPARENT); draw_root_window(dc); draw_digital_time(dc); draw_dayday(dc); draw_timezones(dc); + draw_analog(dc); - draw_battery_meter(dc); - // draw hour hand - dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); - draw_hour_hand(dc); - - // draw minute hand - dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); - draw_minute_hand(dc); - - dc.setColor(Graphics.COLOR_LT_GRAY, Graphics.COLOR_TRANSPARENT); - - dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_TRANSPARENT); draw_second_hand(dc); + draw_clip_circle(dc); } function onPartialUpdate(dc) { -- cgit v1.2.3