From b98cc177373cf775b73e269e62fff3ff89d53975 Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Mon, 18 Sep 2023 20:53:40 +0200 Subject: [PATCH 1/8] Fix icons size for some devices --- monkey.jungle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monkey.jungle b/monkey.jungle index 55bc90f..d02b22b 100644 --- a/monkey.jungle +++ b/monkey.jungle @@ -6,6 +6,7 @@ venusq.resourcePath = resources;icons/36x36 venusqm.resourcePath = resources;icons/36x36 venu2.resourcePath = resources;icons/70x70 venu2s.resourcePath = resources;icons/61x61 +venu2plus.resourcePath = resources;icons/70x70 venu3.resourcePath = resources;icons/70x70 venu3s.resourcePath = resources;icons/70x70 @@ -18,6 +19,7 @@ vivoactive4s.resourcePath = resources;icons/30x30 fenix5s.resourcePath = resources;icons/36x36 +epix2.resourcePath = resources;icons/60x60 epix2pro51mm.resourcePath = resources;icons/60x60 epix2pro47mm.resourcePath = resources;icons/60x60 epix2pro42mm.resourcePath = resources;icons/60x60 From 43a22896bbba6b6265a67ffac593a318016ca782 Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Mon, 18 Sep 2023 21:01:08 +0200 Subject: [PATCH 2/8] Drop support for Vivoactive 3. Despite what is said in the documentation online, the Vivoactive 3 does not support API level 3.1.0. The SDK export tool refuses to include the device when exporting the app. --- manifest.xml | 1 - monkey.jungle | 1 - 2 files changed, 2 deletions(-) diff --git a/manifest.xml b/manifest.xml index 210f232..a61645b 100644 --- a/manifest.xml +++ b/manifest.xml @@ -54,7 +54,6 @@ - diff --git a/monkey.jungle b/monkey.jungle index d02b22b..55221d4 100644 --- a/monkey.jungle +++ b/monkey.jungle @@ -10,7 +10,6 @@ venu2plus.resourcePath = resources;icons/70x70 venu3.resourcePath = resources;icons/70x70 venu3s.resourcePath = resources;icons/70x70 -vivoactive3.resourcePath = resources;icons/40x33 vivoactive3m.resourcePath = resources;icons/40x33 vivoactive3mlte.resourcePath = resources;icons/40x33 From 949119061260891f16820d0f8777adfd2f393943 Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Mon, 25 Sep 2023 21:39:09 +0200 Subject: [PATCH 3/8] Add support for Vivoactive 5 --- manifest.xml | 1 + monkey.jungle | 2 ++ 2 files changed, 3 insertions(+) diff --git a/manifest.xml b/manifest.xml index a61645b..a3cf3e5 100644 --- a/manifest.xml +++ b/manifest.xml @@ -58,6 +58,7 @@ + diff --git a/monkey.jungle b/monkey.jungle index 55221d4..9ead1ab 100644 --- a/monkey.jungle +++ b/monkey.jungle @@ -16,6 +16,8 @@ vivoactive3mlte.resourcePath = resources;icons/40x33 vivoactive4.resourcePath = resources;icons/35x35 vivoactive4s.resourcePath = resources;icons/30x30 +vivoactive5.resourcePath = resources;icons/70x70 + fenix5s.resourcePath = resources;icons/36x36 epix2.resourcePath = resources;icons/60x60 From ee321c9fa9273d21197c93b9ed7bbd050cb2b99c Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Mon, 2 Oct 2023 22:48:27 +0200 Subject: [PATCH 4/8] Improve wording in the readme file --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b2f773b..2eb3820 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Badminton -Badminton is an application for Garmin watches that will help you to track your score when you're playing badminton. +Badminton is an application for Garmin watches that will help you track your score when you're playing badminton. It is available on the Garmin store here: [https://apps.garmin.com/en-US/apps/51606451-57e2-4f99-9420-2ba5a80b5df6](https://apps.garmin.com/en-US/apps/51606451-57e2-4f99-9420-2ba5a80b5df6). @@ -8,14 +8,14 @@ It is available on the Garmin store here: ## Features Here are the best features of the app: -- Choose type of match (double or single) -- Choose number of sets -- Choose which player has service (you, opponent, or random) +- Choose the type of match (double or single) +- Choose a number of sets +- Choose which player has service (you, your opponent, or random) - Display the boundaries of the court according to the type of match - Show the service corners and your position - Display match duration - Declares the winner of the match -- Use menu (long press on "Up") to reset scores and start a new match +- Use the menu (long press on "Up") to reset scores and start a new match - Save matches as Garmin Connect activities ## Installation From e890e35c273dcd2017a8239c1850ae1a2585b625 Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Wed, 4 Oct 2023 22:03:38 +0200 Subject: [PATCH 5/8] Add a test to check that there is enough memory to run a very complex match --- source/test/MatchTest.mc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source/test/MatchTest.mc b/source/test/MatchTest.mc index c432ac2..0d1fd5b 100644 --- a/source/test/MatchTest.mc +++ b/source/test/MatchTest.mc @@ -628,4 +628,42 @@ module MatchTest { return true; } + + function scorePoints(match, points) { + for(var i = 0; i < points; i++) { + match.score(YOU); + match.score(OPPONENT); + } + } + + (:test) + function testMemory(logger) { + //create a very complex match + var match = new Match(create_match_config(SINGLE, Match.MAX_SETS, YOU, true, 21, 30)); + //set 1, won by YOU + scorePoints(match, 29); + match.score(YOU); + //set 2, won by OPPONENT + match.nextSet(); + scorePoints(match, 29); + match.score(OPPONENT); + //set 3, won by YOU + match.nextSet(); + scorePoints(match, 29); + match.score(YOU); + //set 4, won by OPPONENT + match.nextSet(); + scorePoints(match, 29); + match.score(OPPONENT); + //set 5, won by YOU + match.nextSet(); + scorePoints(match, 29); + match.score(YOU); + //end of match, won by YOU 3-2 + BetterTest.assertTrue(match.hasEnded(), "Match has ended if all its sets have ended"); + BetterTest.assertEqual(match.getTotalScore(YOU), 148, "Total score of player 1 is 148"); + BetterTest.assertEqual(match.getTotalScore(OPPONENT), 147, "Total score of player 2 is 147"); + + return true; + } } From 44030067ea145b7952b050527a7a4474aaaead1e Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Wed, 4 Oct 2023 22:04:01 +0200 Subject: [PATCH 6/8] Simplify syntax --- source/model/Match.mc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/model/Match.mc b/source/model/Match.mc index 7b2e942..ff5f026 100644 --- a/source/model/Match.mc +++ b/source/model/Match.mc @@ -318,8 +318,7 @@ class Match { } function getPlayerIsServer() as Boolean { - var player_corner = getPlayerCorner(); - return player_corner == getServingCorner(); + return getPlayerCorner() == getServingCorner(); } //methods used from perspective of player 1 (watch carrier) From b3c9c40866486ce5c7c0170bccaebecdfb5a4de4 Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Tue, 10 Oct 2023 22:40:57 +0200 Subject: [PATCH 7/8] Fix many type issues. The following has been done: -fix some types -add missing types -remove useless types -use nested generics -cast nullable objects where they cannot be null -cast dictionary values that cannot be null --- source/BadmintonApp.mc | 4 +- source/MenuDelegate.mc | 2 +- source/UIHelpers.mc | 10 +- source/model/BetterMath.mc | 2 +- source/model/Geometry.mc | 10 +- source/model/Match.mc | 15 ++- source/model/MatchSet.mc | 2 +- source/test/MatchTest.mc | 2 +- source/views/ActivityStatsView.mc | 6 +- source/views/InitialView.mc | 4 +- source/views/MatchView.mc | 149 +++++++++++++++++------------- source/views/ResultView.mc | 4 +- source/views/SetResultView.mc | 6 +- 13 files changed, 118 insertions(+), 98 deletions(-) diff --git a/source/BadmintonApp.mc b/source/BadmintonApp.mc index 0091e8b..8fd55ab 100644 --- a/source/BadmintonApp.mc +++ b/source/BadmintonApp.mc @@ -27,7 +27,7 @@ class BadmintonApp extends Application.AppBase { return BUS; } - function getMatch() as Match { + function getMatch() as Match? { return match; } @@ -46,7 +46,7 @@ class BadmintonApp extends Application.AppBase { } } - function onMatchEnd(payload) as Void { + function onMatchEnd(payload as Dictionary) as Void { var winner = payload["winner"]; if(winner != null && Attention has :playTone && Properties.getValue("enable_sound")) { Attention.playTone(winner == YOU ? Attention.TONE_SUCCESS : Attention.TONE_FAILURE); diff --git a/source/MenuDelegate.mc b/source/MenuDelegate.mc index a8806a7..3f730d4 100644 --- a/source/MenuDelegate.mc +++ b/source/MenuDelegate.mc @@ -9,7 +9,7 @@ class MatchMenuDelegate extends WatchUi.Menu2InputDelegate { function onSelect(item as MenuItem) { var id = item.getId(); - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; if(id == :menu_end_game) { match.end(null); //pop once to close the menu diff --git a/source/UIHelpers.mc b/source/UIHelpers.mc index 403d494..b195323 100644 --- a/source/UIHelpers.mc +++ b/source/UIHelpers.mc @@ -9,7 +9,7 @@ module UIHelpers { //for now consider all drawables are labels and are justified //improve this as soon as a method getJustification exists - function findTappedDrawable(event as ClickEvent, drawables as Array) as Drawable { + function findTappedDrawable(event as ClickEvent, drawables as Array) as Drawable? { var coordinate = event.getCoordinates(); var event_x = coordinate[0]; var event_y = coordinate[1]; @@ -28,8 +28,8 @@ module UIHelpers { } } //second loop to find closest drawable - var closest_distance = null as Float; - var closest_drawable = null; + var closest_distance = null as Float?; + var closest_drawable = null as Drawable?; for(var i = 0; i < drawables.size(); i++) { var drawable = drawables[i]; var drawable_x = drawable.locX; @@ -44,11 +44,11 @@ module UIHelpers { return closest_drawable; } - function drawPolygon(dc as Dc, points as Array) as Void { + function drawPolygon(dc as Dc, points as Array>) as Void { var counts = points.size(); for(var i = 0; i < counts; i++) { var next_index = (i + 1) % counts; - dc.drawLine(points[i][0] as Number, points[i][1] as Number, points[next_index][0] as Number, points[next_index][1] as Number); + dc.drawLine(points[i][0], points[i][1], points[next_index][0], points[next_index][1]); } } diff --git a/source/model/BetterMath.mc b/source/model/BetterMath.mc index 6898e7e..3b2eb73 100644 --- a/source/model/BetterMath.mc +++ b/source/model/BetterMath.mc @@ -19,7 +19,7 @@ module BetterMath { return (number1 - number2).abs() * weight_ratio + min(number1, number2); } - function roundAll(numbers as Array) { + function roundAll(numbers as Array) as Array { var rounded = new [numbers.size()] as Array; for(var i = 0; i < numbers.size(); i++) { rounded[i] = Math.round(numbers[i]); diff --git a/source/model/Geometry.mc b/source/model/Geometry.mc index 3d4ed38..d9feec8 100644 --- a/source/model/Geometry.mc +++ b/source/model/Geometry.mc @@ -27,7 +27,7 @@ class Perspective { function initialize(front_left_corner as Array, back_left_corner as Array, front_right_corner as Array, back_right_corner as Array) { origin = [ - BetterMath.mean(front_right_corner[0], front_left_corner[0]) as Float, + BetterMath.mean(front_right_corner[0], front_left_corner[0]), front_left_corner[1] ] as Array; height = front_left_corner[1] - back_left_corner[1]; @@ -56,10 +56,10 @@ class Perspective { return [origin[0] + adjusted_x, origin[1] - adjusted_y] as Array; } - function transformArray(coordinates as Array) as Array { - var transformed_coordinates = new [coordinates.size()] as Array; + function transformArray(coordinates as Array>) as Array> { + var transformed_coordinates = new [coordinates.size()] as Array>; for(var i = 0; i < coordinates.size(); i++) { - transformed_coordinates[i] = transform(coordinates[i] as Array); + transformed_coordinates[i] = transform(coordinates[i]); } return transformed_coordinates; } @@ -80,7 +80,7 @@ class Perspective { dc.drawLine(beginning[0], beginning[1], end[0], end[1]); } - function fillPolygon(dc as Dc, coordinates as Array) as Void { + function fillPolygon(dc as Dc, coordinates as Array>) as Void { dc.fillPolygon(transformArray(coordinates)); } diff --git a/source/model/Match.mc b/source/model/Match.mc index ff5f026..264ad00 100644 --- a/source/model/Match.mc +++ b/source/model/Match.mc @@ -172,7 +172,7 @@ class Match { sets.push(new MatchSet(beginner as Player)); } - function getMaximumSets() as Number { + function getMaximumSets() as Number? { return maximumSets; } @@ -224,7 +224,7 @@ class Match { if(isEndless()) { return null; } - var winning_sets = maximumSets / 2; + var winning_sets = maximumSets as Number / 2; //if not in endless mode, maximum sets cannot be null var player_1_sets = getSetsWon(YOU); if(player_1_sets > winning_sets) { return YOU; @@ -245,12 +245,9 @@ class Match { } } - function getActivity() as Info { - return Activity.getActivityInfo(); - } - function getDuration() as Duration { - var time = getActivity().elapsedTime; + var info = Activity.getActivityInfo() as Info; + var time = info.elapsedTime; var seconds = time != null ? time / 1000 : 0; return new Time.Duration(seconds); } @@ -300,7 +297,7 @@ class Match { return won; } - function getWinner() as Player { + function getWinner() as Player? { return winner; } @@ -314,7 +311,7 @@ class Match { function getReceivingCorner() as Corner { var serving_corner = getServingCorner(); - return OPPOSITE_CORNER[serving_corner]; + return OPPOSITE_CORNER[serving_corner] as Corner; } function getPlayerIsServer() as Boolean { diff --git a/source/model/MatchSet.mc b/source/model/MatchSet.mc index be7a7b1..0e1ccd3 100644 --- a/source/model/MatchSet.mc +++ b/source/model/MatchSet.mc @@ -56,7 +56,7 @@ class MatchSet { } function getScore(player as Player) as Number { - return scores[player]; + return scores[player] as Number; } function getServerTeam() as Player { diff --git a/source/test/MatchTest.mc b/source/test/MatchTest.mc index 0d1fd5b..c9e4287 100644 --- a/source/test/MatchTest.mc +++ b/source/test/MatchTest.mc @@ -629,7 +629,7 @@ module MatchTest { return true; } - function scorePoints(match, points) { + function scorePoints(match as Match, points as Number) as Void { for(var i = 0; i < points; i++) { match.score(YOU); match.score(OPPONENT); diff --git a/source/views/ActivityStatsView.mc b/source/views/ActivityStatsView.mc index bcf5279..d2c82ae 100644 --- a/source/views/ActivityStatsView.mc +++ b/source/views/ActivityStatsView.mc @@ -1,8 +1,7 @@ import Toybox.Lang; import Toybox.WatchUi; -using Toybox.WatchUi; +import Toybox.Activity; using Toybox.Graphics; -using Toybox.Activity; class ActivityStatsView extends WatchUi.View { @@ -15,9 +14,8 @@ class ActivityStatsView extends WatchUi.View { } function onShow() { - var match = (Application.getApp() as BadmintonApp).getMatch(); //retrieve stats from activity - var activity = match.getActivity(); + var activity = Activity.getActivityInfo() as Info; var stats_available = false; var average_heart_rate = activity.averageHeartRate; diff --git a/source/views/InitialView.mc b/source/views/InitialView.mc index 8a462d7..91bd0a9 100644 --- a/source/views/InitialView.mc +++ b/source/views/InitialView.mc @@ -21,8 +21,8 @@ class InitialView extends WatchUi.View { //if config is valid, start the match else if(config.isValid()) { //adjust match configuration with app configuration - config.maximumPoints = Properties.getValue("maximum_points"); - config.absoluteMaximumPoints = Properties.getValue("absolute_maximum_points"); + config.maximumPoints = Properties.getValue("maximum_points") as Number; + config.absoluteMaximumPoints = Properties.getValue("absolute_maximum_points") as Number; //create match var match = new Match(config); diff --git a/source/views/MatchView.mc b/source/views/MatchView.mc index 0cfa6ef..1244269 100644 --- a/source/views/MatchView.mc +++ b/source/views/MatchView.mc @@ -3,9 +3,9 @@ import Toybox.Timer; import Toybox.Graphics; import Toybox.WatchUi; import Toybox.System; +import Toybox.Activity; using Toybox.Application; using Toybox.Application.Properties; -using Toybox.Activity; using Toybox.UserProfile; class MatchBoundaries { @@ -19,13 +19,13 @@ class MatchBoundaries { [0.5 - COURT_SIDELINE_SIZE, 1], [0.5 - COURT_SIDELINE_SIZE, 0], [-0.5 + COURT_SIDELINE_SIZE, 0] - ] as Array; + ] as Array>; static const COURT_DOUBLE = [ [-0.5, 1], [0.5, 1], [0.5, 0], [-0.5, 0] - ] as Array; + ] as Array>; //corners boundaries coordinate static const COURT_SINGLE_CORNERS = { //OPPONENT_RIGHT is the top left corner @@ -103,9 +103,9 @@ class MatchBoundaries { public var perspective as Perspective; - public var court as Array; - public var corners as Dictionary; - public var board as Array; + public var court as Array>; + public var corners as Dictionary>>; + public var board as Array>; public var hrCoordinates as Dictionary; @@ -188,16 +188,16 @@ class MatchBoundaries { court = perspective.transformArray(match.getType() == SINGLE ? COURT_SINGLE : COURT_DOUBLE); //calculate court corners boundaries coordinates - var corner_coordinates = match.getType() == SINGLE ? COURT_SINGLE_CORNERS : COURT_DOUBLE_CORNERS; + var corner_coordinates = match.getType() == SINGLE ? COURT_SINGLE_CORNERS : COURT_DOUBLE_CORNERS ; corners = { - OPPONENT_RIGHT => perspective.transformArray(corner_coordinates[OPPONENT_RIGHT]) as Array, - OPPONENT_LEFT => perspective.transformArray(corner_coordinates[OPPONENT_LEFT]) as Array, - YOU_LEFT => perspective.transformArray(corner_coordinates[YOU_LEFT]) as Array, - YOU_RIGHT => perspective.transformArray(corner_coordinates[YOU_RIGHT]) as Array - }; + OPPONENT_RIGHT => perspective.transformArray(corner_coordinates[OPPONENT_RIGHT] as Array>), + OPPONENT_LEFT => perspective.transformArray(corner_coordinates[OPPONENT_LEFT] as Array>), + YOU_LEFT => perspective.transformArray(corner_coordinates[YOU_LEFT] as Array>), + YOU_RIGHT => perspective.transformArray(corner_coordinates[YOU_RIGHT] as Array>) + } as Dictionary>>; //calculate set positions - board = new [Match.MAX_SETS] as Array; + board = new [Match.MAX_SETS] as Array>; for(var i = 0; i < Match.MAX_SETS; i++) { var y = 0.1 + 0.7 * i / Match.MAX_SETS; //dot not align the balls using the real perspective @@ -207,7 +207,7 @@ class MatchBoundaries { } //calculate hear rate position - var hr_center = BetterMath.roundAll(perspective.transform([0.75, 0.6])) as Array; + var hr_center = BetterMath.roundAll(perspective.transform([0.75, 0.6] as Array)); //size the icon according to the size of the tiny font var size = Math.round(Graphics.getFontHeight(Graphics.FONT_TINY) * 0.2); var icon_center = [hr_center[0], hr_center[1] - size * 2]; @@ -233,7 +233,7 @@ class MatchBoundaries { [icon_center[0] + size / 2, icon_center[1] + size], [icon_center[0] - size / 2, icon_center[1] + size] ] - }; + } as Dictionary; } } @@ -243,21 +243,25 @@ class MatchView extends WatchUi.View { const REFRESH_TIME_ANIMATION = 50; const REFRESH_TIME_STANDARD = 1000; - const ANIMATION_TIME = 800; + static const ANIMATION_TIME = 800; public var boundaries as MatchBoundaries?; + private var match as Match; + private var clock24Hour as Boolean; private var timeAMLabel as String; private var timePMLabel as String; private var startTime as Number; - private var refreshTime = null as Number?; - private var inAnimation = false; + private var refreshTime as Number = REFRESH_TIME_STANDARD; + private var inAnimation as Boolean = false; private var refreshTimer as Timer.Timer; function initialize() { View.initialize(); + match = (Application.getApp() as BadmintonApp).getMatch() as Match; + clock24Hour = System.getDeviceSettings().is24Hour; timeAMLabel = WatchUi.loadResource(Rez.Strings.time_am) as String; timePMLabel = WatchUi.loadResource(Rez.Strings.time_pm) as String; @@ -267,14 +271,13 @@ class MatchView extends WatchUi.View { } function calculateBoundaries(elapsed_time as Number?) as Void { - var match = (Application.getApp() as BadmintonApp).getMatch(); var device = System.getDeviceSettings(); boundaries = new MatchBoundaries(match, device, elapsed_time); } function onShow() as Void { (Application.getApp() as BadmintonApp).getBus().register(self); - inAnimation = Properties.getValue("enable_animation"); + inAnimation = Properties.getValue("enable_animation") as Boolean; var refresh_time = inAnimation ? REFRESH_TIME_ANIMATION : REFRESH_TIME_STANDARD; setRefreshTime(refresh_time); } @@ -309,50 +312,53 @@ class MatchView extends WatchUi.View { } function drawCourt(dc as Dc, match as Match) as Void { + //boundaries cannot be null at this point + var bd = boundaries as MatchBoundaries; + //draw background dc.setColor(Graphics.COLOR_DK_GREEN, Graphics.COLOR_TRANSPARENT); - dc.fillPolygon(boundaries.court); + dc.fillPolygon(bd.court); //draw serving and receiving corners var serving_corner = match.getServingCorner(); var receiving_corner = match.getReceivingCorner(); dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_TRANSPARENT); - dc.fillPolygon(boundaries.corners[serving_corner] as Array); - dc.fillPolygon(boundaries.corners[receiving_corner] as Array); + dc.fillPolygon(bd.corners[serving_corner] as Array>); + dc.fillPolygon(bd.corners[receiving_corner] as Array>); //draw bounds dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); dc.setPenWidth(1); //draw left sideline for doubles - boundaries.perspective.drawVanishingLine(dc, -0.5); + bd.perspective.drawVanishingLine(dc, -0.5); //draw left sideline for singles - boundaries.perspective.drawVanishingLine(dc, -0.5 + MatchBoundaries.COURT_SIDELINE_SIZE); + bd.perspective.drawVanishingLine(dc, -0.5 + MatchBoundaries.COURT_SIDELINE_SIZE); //draw middle line in two parts - boundaries.perspective.drawPartialVanishingLine(dc, 0f, 0f, 0.4); - boundaries.perspective.drawPartialVanishingLine(dc, 0f, 0.6, 1f); + bd.perspective.drawPartialVanishingLine(dc, 0f, 0f, 0.4); + bd.perspective.drawPartialVanishingLine(dc, 0f, 0.6, 1f); //draw right sideline for singles - boundaries.perspective.drawVanishingLine(dc, 0.5 - MatchBoundaries.COURT_SIDELINE_SIZE); + bd.perspective.drawVanishingLine(dc, 0.5 - MatchBoundaries.COURT_SIDELINE_SIZE); //draw right sideline for doubles - boundaries.perspective.drawVanishingLine(dc, 0.5); + bd.perspective.drawVanishingLine(dc, 0.5); //draw front long service line for singles - boundaries.perspective.drawTransversalLine(dc, 0f); + bd.perspective.drawTransversalLine(dc, 0f); //draw front long service line for doubles - boundaries.perspective.drawTransversalLine(dc, MatchBoundaries.COURT_LONG_SERVICE_SIZE); + bd.perspective.drawTransversalLine(dc, MatchBoundaries.COURT_LONG_SERVICE_SIZE); //draw front short service line - boundaries.perspective.drawTransversalLine(dc, 0.5 - MatchBoundaries.COURT_SHORT_SERVICE_SIZE); + bd.perspective.drawTransversalLine(dc, 0.5 - MatchBoundaries.COURT_SHORT_SERVICE_SIZE); //draw net line - boundaries.perspective.drawTransversalLine(dc, 0.5); + bd.perspective.drawTransversalLine(dc, 0.5); //draw back short service line - boundaries.perspective.drawTransversalLine(dc, 0.5 + MatchBoundaries.COURT_SHORT_SERVICE_SIZE); + bd.perspective.drawTransversalLine(dc, 0.5 + MatchBoundaries.COURT_SHORT_SERVICE_SIZE); //draw back long service line for doubles - boundaries.perspective.drawTransversalLine(dc, 1f - MatchBoundaries.COURT_LONG_SERVICE_SIZE); + bd.perspective.drawTransversalLine(dc, 1f - MatchBoundaries.COURT_LONG_SERVICE_SIZE); //draw back long service line for singles - boundaries.perspective.drawTransversalLine(dc, 1f); + bd.perspective.drawTransversalLine(dc, 1f); //draw a dot for the player 1 (watch carrier) position var player_x = match.getPlayerCorner() == YOU_LEFT ? -0.28 : 0.28 as Float; - var player_coordinates = boundaries.perspective.transform([player_x, 0.12] as Array) as Array; + var player_coordinates = bd.perspective.transform([player_x, 0.12] as Array); dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_TRANSPARENT); dc.fillCircle(player_coordinates[0], player_coordinates[1], 7); } @@ -361,8 +367,11 @@ class MatchView extends WatchUi.View { var set = match.getCurrentSet(); var server_team = set.getServerTeam(); - var player_1_coordinates = boundaries.perspective.transform([0f, 0.25] as Array); - var player_2_coordinates = boundaries.perspective.transform([0f, 0.75] as Array); + //boundaries cannot be null at this point + var bd = boundaries as MatchBoundaries; + + var player_1_coordinates = bd.perspective.transform([0f, 0.25] as Array); + var player_2_coordinates = bd.perspective.transform([0f, 0.75] as Array); var player_1_color = server_team == YOU ? Graphics.COLOR_BLUE : Graphics.COLOR_WHITE; var player_2_color = server_team == OPPONENT ? Graphics.COLOR_BLUE : Graphics.COLOR_WHITE; UIHelpers.drawHighlightedNumber(dc, player_1_coordinates[0], player_1_coordinates[1], SCORE_PLAYER_1_FONT, set.getScore(YOU).toString(), player_1_color, 2, 4); @@ -372,9 +381,14 @@ class MatchView extends WatchUi.View { function drawSets(dc as Dc, match as Match) as Void { //do not draw sets in endless mode if(!match.isEndless()) { - var maximum_sets = match.getMaximumSets(); + //if not in endless mode, maximum sets cannot be null + var maximum_sets = match.getMaximumSets() as Number; if(maximum_sets > 1) { var sets = match.getSets(); + + //boundaries cannot be null at this point + var bd = boundaries as MatchBoundaries; + for(var i = 0; i < maximum_sets; i++) { var color; if(i < sets.size()) { @@ -391,14 +405,15 @@ class MatchView extends WatchUi.View { color = Graphics.COLOR_WHITE; } dc.setColor(color, Graphics.COLOR_TRANSPARENT); - dc.fillCircle(boundaries.board[i][0] as Float, boundaries.board[i][1] as Float, MatchBoundaries.SET_BALL_RADIUS); + dc.fillCircle(bd.board[i][0] as Float, bd.board[i][1] as Float, MatchBoundaries.SET_BALL_RADIUS); } } } } function drawHeartRate(dc as Dc) as Void { - var rate = Activity.getActivityInfo().currentHeartRate; + var activity = Activity.getActivityInfo() as Info; + var rate = activity.currentHeartRate; if(rate != null) { var profile = UserProfile.getCurrentSport(); @@ -415,10 +430,13 @@ class MatchView extends WatchUi.View { } } - var hr_coordinates = boundaries.hrCoordinates; + //boundaries cannot be null at this point + var bd = boundaries as MatchBoundaries; + + var hr_coordinates = bd.hrCoordinates; var size = hr_coordinates["size"] as Numeric; var icon_center = hr_coordinates["icon_center"] as Array; - var circle_y_extension = hr_coordinates["circle_y_extension"]; + var circle_y_extension = hr_coordinates["circle_y_extension"] as Numeric; dc.setColor(color, Graphics.COLOR_TRANSPARENT); //draw half circles by clipping the bottom part of full circles //add a margin on the top and bottom because rounded coordinates may result in bad clipping @@ -433,8 +451,8 @@ class MatchView extends WatchUi.View { var heart_circle_right = hr_coordinates["heart_circle_right"] as Array; dc.fillCircle(heart_circle_right[0] as Numeric, heart_circle_right[1] as Numeric, size); dc.clearClip(); - dc.fillPolygon(hr_coordinates["heart_triangle"] as Array); - dc.fillPolygon(hr_coordinates["heart_rectangle"] as Array); + dc.fillPolygon(hr_coordinates["heart_triangle"] as Array>); + dc.fillPolygon(hr_coordinates["heart_rectangle"] as Array>); dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); var center = hr_coordinates["center"] as Array; dc.drawText(center[0], center[1], Graphics.FONT_TINY, rate.toString(), Graphics.TEXT_JUSTIFY_CENTER); @@ -442,10 +460,13 @@ class MatchView extends WatchUi.View { } function drawTimer(dc as Dc, match as Match) as Void { + //boundaries cannot be null at this point + var bd = boundaries as MatchBoundaries; + dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); dc.drawText( - boundaries.xCenter, - boundaries.yFront + MatchBoundaries.TIME_HEIGHT * 0.1 as Float, + bd.xCenter, + bd.yFront + MatchBoundaries.TIME_HEIGHT * 0.1 as Float, Graphics.FONT_SMALL, Helpers.formatDuration(match.getDuration()), Graphics.TEXT_JUSTIFY_CENTER @@ -453,11 +474,14 @@ class MatchView extends WatchUi.View { } function drawTime(dc as Dc) as Void { + //boundaries cannot be null at this point + var bd = boundaries as MatchBoundaries; + var time_label = Helpers.formatCurrentTime(clock24Hour, timeAMLabel, timePMLabel); dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); dc.drawText( - boundaries.xCenter, - boundaries.marginHeight - MatchBoundaries.TIME_HEIGHT * 0.1 as Float, + bd.xCenter, + bd.marginHeight - MatchBoundaries.TIME_HEIGHT * 0.1 as Float, Graphics.FONT_SMALL, time_label, Graphics.TEXT_JUSTIFY_CENTER @@ -475,9 +499,6 @@ class MatchView extends WatchUi.View { dc.setAntiAlias(true); } - var app = (Application.getApp() as BadmintonApp); - var match = app.getMatch(); - if(inAnimation) { var elapsed_time = getElapsedTime(); if(elapsed_time > ANIMATION_TIME) { @@ -531,7 +552,7 @@ class MatchViewDelegate extends WatchUi.BehaviorDelegate { } function manageScore(player as Player) as Boolean { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; match.score(player); var winner = match.getCurrentSet().getWinner(); if(winner != null) { @@ -555,7 +576,7 @@ class MatchViewDelegate extends WatchUi.BehaviorDelegate { //undo last action function onBack() { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; if(match.getTotalRalliesNumber() > 0) { //undo last rally match.undo(); @@ -570,13 +591,17 @@ class MatchViewDelegate extends WatchUi.BehaviorDelegate { } function onTap(event) { - if(event.getCoordinates()[1] < view.boundaries.yMiddle) { - //score with player 2 (opponent) - manageScore(OPPONENT); - } - else { - //score with player 1 (watch carrier) - manageScore(YOU); + if(view.boundaries != null) { + //boundaries cannot be null at this point + var bd = view.boundaries as MatchBoundaries; + if(event.getCoordinates()[1] < bd.yMiddle) { + //score with player 2 (opponent) + manageScore(OPPONENT); + } + else { + //score with player 1 (watch carrier) + manageScore(YOU); + } } return true; } diff --git a/source/views/ResultView.mc b/source/views/ResultView.mc index c157cca..e6f6acc 100644 --- a/source/views/ResultView.mc +++ b/source/views/ResultView.mc @@ -9,7 +9,7 @@ class SaveMatchConfirmationDelegate extends WatchUi.ConfirmationDelegate { } function onResponse(value) as Boolean { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; if(value == CONFIRM_YES) { match.save(); } @@ -34,7 +34,7 @@ class ResultView extends WatchUi.View { } function onShow() { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; //draw end of match text var winner = match.getWinner(); var won_resource = Rez.Strings.end_draw; diff --git a/source/views/SetResultView.mc b/source/views/SetResultView.mc index c464cd7..de7c2f5 100644 --- a/source/views/SetResultView.mc +++ b/source/views/SetResultView.mc @@ -13,7 +13,7 @@ class SetResultView extends WatchUi.View { } function onShow() { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; var set = match.getCurrentSet(); //draw end of match text var set_winner = set.getWinner(); @@ -47,7 +47,7 @@ class SetResultViewDelegate extends WatchUi.BehaviorDelegate { } function onBack() { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; //undo last point match.undo(); var view = new MatchView(); @@ -56,7 +56,7 @@ class SetResultViewDelegate extends WatchUi.BehaviorDelegate { } function onSelect() as Boolean { - var match = (Application.getApp() as BadmintonApp).getMatch(); + var match = (Application.getApp() as BadmintonApp).getMatch() as Match; if(match.hasEnded()) { WatchUi.switchToView(new ResultView(), new ResultViewDelegate(), WatchUi.SLIDE_IMMEDIATE); } From 84bdcdde7a5e288f8e5082ae3e7f955de6dcda7b Mon Sep 17 00:00:00 2001 From: Matthieu Corageoud Date: Mon, 6 Nov 2023 19:53:36 +0100 Subject: [PATCH 8/8] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3406972..07ff4a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 4.3.0 +- Add support for Vivoactive 5 +- Drop support for Vivoactive 3 +- Fix icons size + ## 4.2.0 - Animate the court - Add support for Venu 3 series