mirror of
https://github.com/dyuri/garmin-repafield.git
synced 2025-12-16 19:24:01 +00:00
hr part
This commit is contained in:
parent
071336d246
commit
2a7246111f
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/bin
|
||||||
16
manifest.xml
Normal file
16
manifest.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. -->
|
||||||
|
<iq:manifest version="3" xmlns:iq="http://www.garmin.com/xml/connectiq">
|
||||||
|
<iq:application id="d0f125e7-b43a-46ab-927e-87396eda74a0" type="datafield" name="@Strings.AppName" entry="RepaFieldApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="4.2.0">
|
||||||
|
<iq:products>
|
||||||
|
<iq:product id="epix2"/>
|
||||||
|
</iq:products>
|
||||||
|
<iq:permissions>
|
||||||
|
<iq:uses-permission id="UserProfile"/>
|
||||||
|
</iq:permissions>
|
||||||
|
<iq:languages>
|
||||||
|
<iq:language>eng</iq:language>
|
||||||
|
</iq:languages>
|
||||||
|
<iq:barrels/>
|
||||||
|
</iq:application>
|
||||||
|
</iq:manifest>
|
||||||
1
monkey.jungle
Executable file
1
monkey.jungle
Executable file
@ -0,0 +1 @@
|
|||||||
|
project.manifest = manifest.xml
|
||||||
3
resources/drawables/drawables.xml
Executable file
3
resources/drawables/drawables.xml
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
<drawables>
|
||||||
|
<bitmap id="LauncherIcon" filename="launcher_icon.png" />
|
||||||
|
</drawables>
|
||||||
BIN
resources/drawables/launcher_icon.png
Executable file
BIN
resources/drawables/launcher_icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
30
resources/layouts/layouts.xml
Executable file
30
resources/layouts/layouts.xml
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
<layouts>
|
||||||
|
<!-- A generic, centered layout. -->
|
||||||
|
<layout id="MainLayout">
|
||||||
|
<drawable class="Background" />
|
||||||
|
<drawable class="HeartRate" id="HeartRate">
|
||||||
|
<param name="y">64</param>
|
||||||
|
</drawable>
|
||||||
|
<drawable class="Stamina" />
|
||||||
|
<drawable class="Track" />
|
||||||
|
|
||||||
|
<!-- hr labels -->
|
||||||
|
<label id="hr" x="center" y="6" color="Graphics.COLOR_WHITE" justification="Graphics.TEXT_JUSTIFY_CENTER" font="Graphics.FONT_MEDIUM" />
|
||||||
|
<label id="ahr" x="32%" y="18" color="0x888888" justification="Graphics.TEXT_JUSTIFY_CENTER" font="Graphics.FONT_TINY" />
|
||||||
|
<label id="mhr" x="68%" y="18" color="0x888888" justification="Graphics.TEXT_JUSTIFY_CENTER" font="Graphics.FONT_TINY" />
|
||||||
|
|
||||||
|
<!-- TODO distance, pace, avg pace, time, timer, elevation, egain, calories -->
|
||||||
|
</layout>
|
||||||
|
|
||||||
|
<!-- Layouts used for the for the four quadrants. -->
|
||||||
|
<layout id="TopLayout">
|
||||||
|
<drawable class="Background" />
|
||||||
|
<label id="label" x="14" y="75" color="0x888888" justification="Graphics.TEXT_JUSTIFY_LEFT" font="Graphics.FONT_TINY" />
|
||||||
|
<label id="value" x="14" y="42" color="Graphics.COLOR_WHITE" justification="Graphics.TEXT_JUSTIFY_LEFT" font="Graphics.FONT_LARGE" />
|
||||||
|
</layout>
|
||||||
|
<layout id="BottomLayout">
|
||||||
|
<drawable class="Background" />
|
||||||
|
<label id="label" x="95" y="10" color="0x888888" justification="Graphics.TEXT_JUSTIFY_RIGHT" font="Graphics.FONT_TINY" />
|
||||||
|
<label id="value" x="95" y="27" color="Graphics.COLOR_WHITE" justification="Graphics.TEXT_JUSTIFY_RIGHT" font="Graphics.FONT_LARGE" />
|
||||||
|
</layout>
|
||||||
|
</layouts>
|
||||||
5
resources/strings/strings.xml
Normal file
5
resources/strings/strings.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<strings>
|
||||||
|
<string id="AppName">RepaField</string>
|
||||||
|
|
||||||
|
<string id="label">My Value</string>
|
||||||
|
</strings>
|
||||||
28
source/RepaFieldApp.mc
Normal file
28
source/RepaFieldApp.mc
Normal file
@ -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<Views or InputDelegates>? {
|
||||||
|
return [ new RepaFieldView() ] as Array<Views or InputDelegates>;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getApp() as RepaFieldApp {
|
||||||
|
return Application.getApp() as RepaFieldApp;
|
||||||
|
}
|
||||||
28
source/RepaFieldBackground.mc
Normal file
28
source/RepaFieldBackground.mc
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
56
source/RepaFieldHeartRate.mc
Normal file
56
source/RepaFieldHeartRate.mc
Normal file
@ -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<Numeric>;
|
||||||
|
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<Numeric>) 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
source/RepaFieldStamina.mc
Normal file
18
source/RepaFieldStamina.mc
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
source/RepaFieldTrack.mc
Normal file
18
source/RepaFieldTrack.mc
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
131
source/RepaFieldView.mc
Normal file
131
source/RepaFieldView.mc
Normal file
@ -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<Numeric>;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user