From 2a7246111f6c26d3e517b586730fc444aae4127b Mon Sep 17 00:00:00 2001 From: Gyuri Horak Date: Fri, 22 Sep 2023 17:43:20 +0200 Subject: [PATCH] hr part --- .gitignore | 1 + manifest.xml | 16 ++++ monkey.jungle | 1 + resources/drawables/drawables.xml | 3 + resources/drawables/launcher_icon.png | Bin 0 -> 1292 bytes resources/layouts/layouts.xml | 30 ++++++ resources/strings/strings.xml | 5 + source/RepaFieldApp.mc | 28 ++++++ source/RepaFieldBackground.mc | 28 ++++++ source/RepaFieldHeartRate.mc | 56 +++++++++++ source/RepaFieldStamina.mc | 18 ++++ source/RepaFieldTrack.mc | 18 ++++ source/RepaFieldView.mc | 131 ++++++++++++++++++++++++++ 13 files changed, 335 insertions(+) create mode 100644 .gitignore create mode 100644 manifest.xml create mode 100755 monkey.jungle create mode 100755 resources/drawables/drawables.xml create mode 100755 resources/drawables/launcher_icon.png create mode 100755 resources/layouts/layouts.xml create mode 100644 resources/strings/strings.xml create mode 100644 source/RepaFieldApp.mc create mode 100644 source/RepaFieldBackground.mc create mode 100644 source/RepaFieldHeartRate.mc create mode 100644 source/RepaFieldStamina.mc create mode 100644 source/RepaFieldTrack.mc create mode 100644 source/RepaFieldView.mc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e56e04 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/manifest.xml b/manifest.xml new file mode 100644 index 0000000..8610910 --- /dev/null +++ b/manifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + eng + + + + \ No newline at end of file diff --git a/monkey.jungle b/monkey.jungle new file mode 100755 index 0000000..87796c7 --- /dev/null +++ b/monkey.jungle @@ -0,0 +1 @@ +project.manifest = manifest.xml diff --git a/resources/drawables/drawables.xml b/resources/drawables/drawables.xml new file mode 100755 index 0000000..a22c33c --- /dev/null +++ b/resources/drawables/drawables.xml @@ -0,0 +1,3 @@ + + + diff --git a/resources/drawables/launcher_icon.png b/resources/drawables/launcher_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..d3594e7cb975929fe36f50e5bffde505262c0901 GIT binary patch literal 1292 zcmV+n1@roeP)@WZT1er-h zK~zY`<(A)TmSq^nKiB>IdiTD2w>fi5H+`GV>1^WEG${}%gHBRYgw7JFgHHMnf)0XC zDu^JYjx2~muu?oJVwhw>YA7}ln>v=;+}v#M-k;C=-1ptVv!AZHNrDGn@Eklm&wYQd zU*GR_$&$=Q%OfzwBeF*Z?EbIQ)`B&Nv4F)QpaevL$O8adi&R2T4%T(=3n-NkQ(KQs zrLkTBN`W;HmQlGZlF!BtD77%Ktx6HKZ9;NmID>uhMKetVDVH#{^;A~2618t3YH3F| zuD}LKq+G-q?#Jor#=CY2x2GE^jDs^b2&by9@!iQ6-Lj7Hx8KL4>+rhIBVl*bEu(P;CXR9tpQ{3FZ@in zWhbRwdxcYT+gdtJeCQNz>L=}QFr=||yUz!x64c^6HQ6sl8%QKjU6;pLy zFk*>9bYnBNx)$&H6{K8RyuNro?)3>u8AG(P6_m5sR2yuv8tVth=nz;IRHa!_XGbB5 z;(O9{i;oxtjE)bwJ_vwaw4{pT#b5&H$^#4u$3fj4L5g{FQ%mfKT_8hVfUQb`(L@bR z;0K@_)Sba8HCzDLV*CKN?;0w57n5m4H#E(k>Zn4LX=Ci2BNPt4g-zAq4));;^g$)W z?YRPrrjzI4cArPaMj)4^xbH9|l5=$&!1d6}S7B2%gxhve+;a$1TTk-K52^nAJ)~Ti za(Y^;MKH^j6F$2e=XM|drQeWp5kw(j8PSHQWj%W3YH&TAz8+LD&qUGV3ys0Obput* z5oOwl)^*06-PeQLdv#W0&JTQX8kh-Mm?u`C8=HyRH)EDQi8DGBi-<9ZHL=#a9`0Y4 z5v_@uo+8@t4AyaQ|GqJ6=**VP$@!@iRs@;RoiB>-V`oLCQmGr8NqzAViJy)G#NaQ#h8n$1;`GV5B(s<^aFf(mAEQQx zky0^UWA0f5Y$8c;`ULKk3q)%>&<)MlnkC?R5LJ-e7;gW~_}y9(UEhOpsB~<{xic^& zw=!$JH3kVwvB-P=f{G?#Ii_5?4qP9i3M!ukqp?BNM8j#UpTI0_#Odz^N5wPXq3qSx z#*fH + + + + + 64 + + + + + + + + + + + + + + + diff --git a/resources/strings/strings.xml b/resources/strings/strings.xml new file mode 100644 index 0000000..1e2c6f4 --- /dev/null +++ b/resources/strings/strings.xml @@ -0,0 +1,5 @@ + + RepaField + + My Value + diff --git a/source/RepaFieldApp.mc b/source/RepaFieldApp.mc new file mode 100644 index 0000000..df4bf1f --- /dev/null +++ b/source/RepaFieldApp.mc @@ -0,0 +1,28 @@ +import Toybox.Application; +import Toybox.Lang; +import Toybox.WatchUi; + +class RepaFieldApp extends Application.AppBase { + + function initialize() { + AppBase.initialize(); + } + + // onStart() is called on application start up + function onStart(state as Dictionary?) as Void { + } + + // onStop() is called when your application is exiting + function onStop(state as Dictionary?) as Void { + } + + //! Return the initial view of your application here + function getInitialView() as Array? { + return [ new RepaFieldView() ] as Array; + } + +} + +function getApp() as RepaFieldApp { + return Application.getApp() as RepaFieldApp; +} \ No newline at end of file diff --git a/source/RepaFieldBackground.mc b/source/RepaFieldBackground.mc new file mode 100644 index 0000000..5007272 --- /dev/null +++ b/source/RepaFieldBackground.mc @@ -0,0 +1,28 @@ +import Toybox.Application; +import Toybox.Graphics; +import Toybox.WatchUi; + +class Background extends WatchUi.Drawable { + + hidden var mColor as ColorValue; + + function initialize() { + var dictionary = { + :identifier => "Background" + }; + + Drawable.initialize(dictionary); + + mColor = Graphics.COLOR_BLACK; + } + + function setColor(color as ColorValue) as Void { + mColor = color; + } + + function draw(dc as Dc) as Void { + dc.setColor(Graphics.COLOR_TRANSPARENT, mColor); + dc.clear(); + } + +} diff --git a/source/RepaFieldHeartRate.mc b/source/RepaFieldHeartRate.mc new file mode 100644 index 0000000..6385cdc --- /dev/null +++ b/source/RepaFieldHeartRate.mc @@ -0,0 +1,56 @@ +import Toybox.Application; +import Toybox.Graphics; +import Toybox.WatchUi; +import Toybox.Lang; +import Toybox.System; + +class HeartRate extends WatchUi.Drawable { + + hidden var hrZones as Array; + hidden var hrValue as Numeric; + hidden var aColor as Graphics.ColorValue | Number; + hidden var y as Numeric; + + function initialize(params as Dictionary) { + Drawable.initialize(params); + + hrZones = [100, 120, 140, 160, 180, 200]; + hrValue = 0.0f; + aColor = 0xFF8800; + y = 64; + if (params.hasKey(:y)) { + y = params.get(:y) as Number; + } + } + + function setHRZones(zones as Array) as Void { + hrZones = zones; + } + + function setHRValue(value as Numeric) as Void { + hrValue = value; + } + + function setHRColor(color) as Void { + aColor = color; + } + + function draw(dc as Dc) as Void { + dc.setPenWidth(8); + dc.setColor(0x555555, Graphics.COLOR_TRANSPARENT); + var width = dc.getWidth(); + dc.drawLine(width * .1, 64, width * .9, 64); + + var percentage = 0.0f; + var zoneNr = hrZones.size(); + if (hrValue > hrZones[zoneNr - 1]) { + percentage = 1.0f; + } else if (hrValue < hrZones[0]) { + percentage = .0f; + } else { + percentage = (hrValue - hrZones[0]).toFloat() / (hrZones[zoneNr - 1] - hrZones[0]); + } + dc.setColor(aColor, Graphics.COLOR_TRANSPARENT); + dc.drawLine(width * .1, 64, width * (.1 + .8 * percentage), 64); + } +} diff --git a/source/RepaFieldStamina.mc b/source/RepaFieldStamina.mc new file mode 100644 index 0000000..6fab78a --- /dev/null +++ b/source/RepaFieldStamina.mc @@ -0,0 +1,18 @@ +import Toybox.Application; +import Toybox.Graphics; +import Toybox.WatchUi; + +class Stamina extends WatchUi.Drawable { + + function initialize() { + var dictionary = { + :identifier => "Stamina" + }; + + Drawable.initialize(dictionary); + } + + function draw(dc as Dc) as Void { + dc.setColor(0xFF8800, Graphics.COLOR_TRANSPARENT); + } +} diff --git a/source/RepaFieldTrack.mc b/source/RepaFieldTrack.mc new file mode 100644 index 0000000..3ab8e20 --- /dev/null +++ b/source/RepaFieldTrack.mc @@ -0,0 +1,18 @@ +import Toybox.Application; +import Toybox.Graphics; +import Toybox.WatchUi; + +class Track extends WatchUi.Drawable { + + function initialize() { + var dictionary = { + :identifier => "Track" + }; + + Drawable.initialize(dictionary); + } + + function draw(dc as Dc) as Void { + dc.setColor(0xFF8800, Graphics.COLOR_TRANSPARENT); + } +} diff --git a/source/RepaFieldView.mc b/source/RepaFieldView.mc new file mode 100644 index 0000000..84e4c9f --- /dev/null +++ b/source/RepaFieldView.mc @@ -0,0 +1,131 @@ +import Toybox.Activity; +import Toybox.Graphics; +import Toybox.Lang; +import Toybox.UserProfile; +import Toybox.WatchUi; + +class RepaFieldView extends WatchUi.DataField { + + hidden var hrValue as Numeric; + hidden var ahrValue as Numeric; + hidden var mhrValue as Numeric; + hidden var hrZones as Array; + + function initialize() { + DataField.initialize(); + hrValue = 0; + ahrValue = 0; + mhrValue = 0; + hrZones = UserProfile.getHeartRateZones(UserProfile.getCurrentSport()); + } + + function calculateHRColor(hr as Numeric) as Numeric { + var hrColor = Graphics.COLOR_BLACK; + if (hrZones != null) { + if (hr < hrZones[1]) { + hrColor = Graphics.COLOR_LT_GRAY; + } else if (hr < hrZones[2]) { + hrColor = Graphics.COLOR_BLUE; + } else if (hr < hrZones[3]) { + hrColor = Graphics.COLOR_GREEN; + } else if (hr < hrZones[4]) { + hrColor = Graphics.COLOR_YELLOW; + } else if (hr < hrZones[5]) { + hrColor = Graphics.COLOR_ORANGE; + } else { + hrColor = Graphics.COLOR_RED; + } + } + return hrColor; + } + + // Set your layout here. Anytime the size of obscurity of + // the draw context is changed this will be called. + function onLayout(dc as Dc) as Void { + var obscurityFlags = DataField.getObscurityFlags(); + + // TODO ? + // Top layout + if (obscurityFlags == (OBSCURE_TOP | OBSCURE_LEFT | OBSCURE_RIGHT)) { + View.setLayout(Rez.Layouts.TopLayout(dc)); + + // Bottom layout + } else if (obscurityFlags == (OBSCURE_BOTTOM | OBSCURE_LEFT | OBSCURE_RIGHT)) { + View.setLayout(Rez.Layouts.BottomLayout(dc)); + + // Use the generic, centered layout + } else { + View.setLayout(Rez.Layouts.MainLayout(dc)); + } + + var label = View.findDrawableById("label") as Text; + if (label != null) { + label.setText(Rez.Strings.label); + } + } + + // The given info object contains all the current workout information. + // Calculate a value and save it locally in this method. + // Note that compute() and onUpdate() are asynchronous, and there is no + // guarantee that compute() will be called before onUpdate(). + function compute(info as Activity.Info) as Void { + // See Activity.Info in the documentation for available information. + if (info has :currentHeartRate){ + if(info.currentHeartRate != null){ + hrValue = info.currentHeartRate as Number; + } else { + hrValue = 0; + } + } + if (info has :averageHeartRate){ + if(info.averageHeartRate != null){ + ahrValue = info.averageHeartRate as Number; + } else { + ahrValue = 0; + } + } + if (info has :maxHeartRate){ + if(info.maxHeartRate != null){ + mhrValue = info.maxHeartRate as Number; + } else { + mhrValue = 0; + } + } + } + + // Display the value you computed here. This will be called + // once a second when the data field is visible. + function onUpdate(dc as Dc) as Void { + // Set the background color + (View.findDrawableById("Background") as Background).setColor(getBackgroundColor()); + + // HR value + var hrColor = calculateHRColor(hrValue); + var hr = View.findDrawableById("hr") as Text; + hr.setColor(hrColor); + hr.setText(hrValue.format("%d")); + var ahr = View.findDrawableById("ahr") as Text; + ahr.setText(ahrValue.format("%d")); + var mhr = View.findDrawableById("mhr") as Text; + mhr.setText(mhrValue.format("%d")); + var hrGraph = View.findDrawableById("HeartRate") as HeartRate; + hrGraph.setHRColor(hrColor); + hrGraph.setHRZones(hrZones); + hrGraph.setHRValue(hrValue); + + // Set the foreground color and value + var value = View.findDrawableById("value") as Text; + if (value != null) { + if (getBackgroundColor() == Graphics.COLOR_BLACK) { + value.setColor(Graphics.COLOR_WHITE); + } else { + value.setColor(Graphics.COLOR_BLACK); + } + value.setText(hrValue.format("%d")); + } + + // Call parent's onUpdate(dc) to redraw the layout + View.onUpdate(dc); + } + +}