Skip to content

Commit

Permalink
4.4.0 - Implemented meditation preparation time that can be customize…
Browse files Browse the repository at this point in the history
…d in global settings for 0s, 15s, 30s or 60s.
  • Loading branch information
dliedke committed Dec 29, 2022
1 parent fb6e7ad commit 1fafd52
Show file tree
Hide file tree
Showing 19 changed files with 228 additions and 15 deletions.
1 change: 0 additions & 1 deletion HrvAlgorithms/manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<iq:product id="fenix5xplus"/>
<iq:product id="fenix6"/>
<iq:product id="fenix6pro"/>
<iq:product id="fenix6prosystem5preview"/>
<iq:product id="fenix6s"/>
<iq:product id="fenix6spro"/>
<iq:product id="fenix6xpro"/>
Expand Down
3 changes: 1 addition & 2 deletions Meditate/manifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. -->
<iq:manifest xmlns:iq="http://www.garmin.com/xml/connectiq" version="3">
<iq:application entry="MeditateApp" id="9abb375dcf7c4ace87ff66f4f774f6c8" launcherIcon="@Drawables.launcherIcon" minSdkVersion="3.0.0" name="@Strings.AppName" type="watch-app" version="4.3.0">
<iq:application entry="MeditateApp" id="9abb375dcf7c4ace87ff66f4f774f6c8" launcherIcon="@Drawables.launcherIcon" minSdkVersion="3.0.0" name="@Strings.AppName" type="watch-app" version="4.4.0">
<iq:products>
<iq:product id="approachs62"/>
<iq:product id="d2air"/>
Expand All @@ -19,7 +19,6 @@
<iq:product id="fenix5x"/>
<iq:product id="fenix5xplus"/>
<iq:product id="fenix6pro"/>
<iq:product id="fenix6prosystem5preview"/>
<iq:product id="fenix6spro"/>
<iq:product id="fenix6xpro"/>
<iq:product id="fenix7"/>
Expand Down
8 changes: 8 additions & 0 deletions Meditate/resources-por/strings/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<string id="menuGlobalSettings_multiSession">Multi-Sessão</string>
<string id="menuGlobalSettings_singleSession">Sessão Simples</string>
<string id="menuGlobalSettings_respirationRate">Taxa respiração</string>
<string id="menuGlobalSettings_prepareTime">Tempo Preparação</string>
<string id="menuGlobalSettings_respiration">Respiração: </string>
<string id="menuGlobalSettings_save">Salvar: </string>

Expand Down Expand Up @@ -68,6 +69,12 @@
<string id="menuRespirationRateOptions_on">Lig. (Padrão)</string>
<string id="menuRespirationRateOptions_off">Deslig.</string>

<string id="menuPrepareTimeOptions_title">Preparação</string>
<string id="menuPrepareTimeOptions_0">0 segs</string>
<string id="menuPrepareTimeOptions_15">15 segs (Padrão)</string>
<string id="menuPrepareTimeOptions_30">30 segs</string>
<string id="menuPrepareTimeOptions_60">60 segs</string>

<string id="menuIntervalAlertSettings_Title">Intervalo de Alerta</string>
<string id="menuIntervalAlertSettings_addNew">Adicionar</string>
<string id="menuIntervalAlertSettings_edit">Editar</string>
Expand Down Expand Up @@ -120,6 +127,7 @@
<string id="editIntervalAlertsMenu_title">Editar Intervalo Alerta</string>
<string id="activityDelayedFinishingText">Finalizando...</string>
<string id="meditateActivityPaused">[Pausado]</string>
<string id="meditateActivityPrepare">Relaxe para\niniciar meditação\nem</string>

<string id="meditateYogaActivityName">Meditação</string>
<string id="meditateBreathActivityName">Meditação</string>
Expand Down
2 changes: 1 addition & 1 deletion Meditate/resources-round-240x240/constants.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<property id="progressBarWidth" type="number">150</property>
<property id="globalSettingsIconsXPos" type="number">50</property>
<property id="globalSettingsValueXPos" type="number">70</property>
<property id="globalSettingsLinesYOffset" type="number">10</property>
<property id="globalSettingsLinesYOffset" type="number">-10</property>
<property id="sessionDetailsIconsXPos" type="number">35</property>
<property id="sessionDetailsValueXPos" type="number">60</property>
<property id="meditateActivityIconsXPos" type="number">90</property>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<menu-item id="hrvTracking" label="@Strings.menuGlobalSettings_newHrvTracking" />
<menu-item id="confirmSaveActivity" label="@Strings.menuGlobalSettings_confirmSaveActivity" />
<menu-item id="multiSession" label="@Strings.menuGlobalSettings_multiSession" />
<menu-item id="newActivityType" label="@Strings.menuGlobalSettings_newActivityType" />
<menu-item id="prepareTime" label="@Strings.menuGlobalSettings_prepareTime" />
<menu-item id="respirationRate" label="@Strings.menuGlobalSettings_respirationRate" />
<menu-item id="newActivityType" label="@Strings.menuGlobalSettings_newActivityType" />
</menu>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<menu id="prepareTimeOptionsMenu" title="@Strings.menuPrepareTimeOptions_title">
<menu-item id="time_0" label="@Strings.menuPrepareTimeOptions_0" />
<menu-item id="time_15" label="@Strings.menuPrepareTimeOptions_15" />
<menu-item id="time_30" label="@Strings.menuPrepareTimeOptions_30" />
<menu-item id="time_60" label="@Strings.menuPrepareTimeOptions_60" />
</menu>
8 changes: 8 additions & 0 deletions Meditate/resources/strings/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<string id="menuGlobalSettings_multiSession">Multi-Session</string>
<string id="menuGlobalSettings_singleSession">Single session</string>
<string id="menuGlobalSettings_respirationRate">Respiration Rate</string>
<string id="menuGlobalSettings_prepareTime">Prepare Time</string>
<string id="menuGlobalSettings_respiration">Respiration: </string>
<string id="menuGlobalSettings_save">Save: </string>

Expand Down Expand Up @@ -68,6 +69,12 @@
<string id="menuRespirationRateOptions_on">On (Default)</string>
<string id="menuRespirationRateOptions_off">Off</string>

<string id="menuPrepareTimeOptions_title">Preparation</string>
<string id="menuPrepareTimeOptions_0">0 secs</string>
<string id="menuPrepareTimeOptions_15">15 secs (Default)</string>
<string id="menuPrepareTimeOptions_30">30 secs</string>
<string id="menuPrepareTimeOptions_60">60 secs</string>

<string id="menuIntervalAlertSettings_Title">Interval Alerts</string>
<string id="menuIntervalAlertSettings_addNew">Add New</string>
<string id="menuIntervalAlertSettings_edit">Edit</string>
Expand Down Expand Up @@ -119,6 +126,7 @@
<string id="editIntervalAlertsMenu_title">Edit Interval Alerts</string>
<string id="activityDelayedFinishingText">Finishing...</string>
<string id="meditateActivityPaused">[Paused]</string>
<string id="meditateActivityPrepare">Relax to start\nmeditate session\nin</string>

<string id="meditateYogaActivityName">Meditating</string>
<string id="meditateBreathActivityName">Meditating</string>
Expand Down
14 changes: 9 additions & 5 deletions Meditate/source/activity/MeditateDelegate.mc
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,19 @@ class MeditateDelegate extends Ui.BehaviorDelegate {

// Touch screen to disable/enable backlight during activity
// This will still respect the backligh timeout configured in the device
backlightOn = !backlightOn;
Attention.backlight(backlightOn);
if ((Attention has :backlight) ) {
backlightOn = !backlightOn;
Attention.backlight(backlightOn);
}

} catch(ex) {

// Just in case we get a BacklightOnTooLongException for OLED display devices,
// Just in case we get a BacklightOnTooLongException for OLED display devices (ex: Venu 2),
// disable backlight
backlightOn = false;
Attention.backlight(backlightOn);
if ((Attention has :backlight) ) {
backlightOn = false;
Attention.backlight(backlightOn);
}
}
}
}
20 changes: 20 additions & 0 deletions Meditate/source/activity/MeditatePrepareDelegate.mc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Toybox.WatchUi as Ui;
using Toybox.Lang;

class MeditatePrepareDelegate extends Ui.BehaviorDelegate {

var mSessionPickerDelegate;

function initialize(sessionPickerDelegate) {
mSessionPickerDelegate = sessionPickerDelegate;
Ui.BehaviorDelegate.initialize();
}

function onBack() {
return true;
}

function onKey(keyEvent) {
return true;
}
}
110 changes: 110 additions & 0 deletions Meditate/source/activity/MeditatePrepareView.mc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using Toybox.Lang;
using Toybox.Timer;
using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.Application as App;

class MeditatePrepareView extends Ui.View {
private var mOnShow;
private var mMainDurationRenderer;
private var mSeconds;
private var mTotalSeconds;

function initialize(onShow) {
View.initialize();
me.mOnShow = onShow;
mSeconds = 0;
mTotalSeconds = GlobalSettings.loadPrepareTime();
}

function onViewDrawn() {

if (mSeconds >= mTotalSeconds+1) {
return;
}

mSeconds += 1;
Ui.requestUpdate();

// Start the meditation session after XX seconds
if (mSeconds == mTotalSeconds+1) {

// Vibrate short to notify session starts
Vibe.vibrate(VibePattern.Blip);

// Starts the meditation session
me.mOnShow.invoke();

return;
}

// Try to keep backlight on during preparation time
try {

if ((Attention has :backlight) ) {
if (mSeconds == 1 || (mSeconds % 8 == 0)) {
Attention.backlight(true);
}
}

} catch(ex) {

// Just in case we get a BacklightOnTooLongException for OLED display devices (ex: Venu2)
if ((Attention has :backlight) ) {
Attention.backlight(false);
}
}
}

function onLayout(dc) {

// Clear the screen
renderBackground(dc);

var durationArcRadius = dc.getWidth() / 2;
var mainDurationArcWidth = dc.getWidth() / 4;

// For rectangle screens we need to set this manually
var mainDurationArcWidthConfig = App.getApp().getProperty("meditateActivityDurationArcWidth");
if (mainDurationArcWidthConfig != null) {
mainDurationArcWidth = mainDurationArcWidthConfig;
}

// Configure the arc render for progress
me.mMainDurationRenderer = new ElapsedDurationRenderer(Gfx.COLOR_BLUE, durationArcRadius, mainDurationArcWidth);
}

private function renderBackground(dc) {

// Clear the screen
dc.setColor(Gfx.COLOR_TRANSPARENT, Gfx.COLOR_BLACK);
dc.clear();
}

function onShow() {
var viewDrawnTimer = new Timer.Timer();
viewDrawnTimer.start(method(:onViewDrawn), 1000, true);
}

function onUpdate(dc) {
View.onUpdate(dc);

// Draw arc with the progress
me.mMainDurationRenderer.drawOverallElapsedTime(dc, mSeconds, mTotalSeconds);

// Calculate center of the screen
var centerX = dc.getWidth()/2;
var centerY = dc.getHeight()/2;

// Render main text with number of seconds remaining to start the session
dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT);
dc.drawText(centerX,
centerY-centerY/3,
Gfx.FONT_SYSTEM_TINY,
Ui.loadResource(Rez.Strings.meditateActivityPrepare) + " " + (mTotalSeconds-mSeconds).toString() + "s",
Graphics.TEXT_JUSTIFY_CENTER);
}

function onHide() {
}
}
16 changes: 16 additions & 0 deletions Meditate/source/globalSettings/GlobalSettings.mc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ class GlobalSettings {
static function saveRespirationRate(respirationRate) {
App.Storage.setValue(RespirationRateKey, respirationRate);
}

private static const PrepareTimeKey = "globalSettings_prapareTime";

static function loadPrepareTime() {
var prepareTime = App.Storage.getValue(PrepareTimeKey);
if (prepareTime == null) {
return 15;
}
else {
return prepareTime;
}
}

static function savePrepareTime(prepareTime) {
App.Storage.setValue(PrepareTimeKey, prepareTime);
}
}

module ConfirmSaveActivity {
Expand Down
11 changes: 10 additions & 1 deletion Meditate/source/globalSettings/GlobalSettingsDelegate.mc
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ class GlobalSettingsDelegate extends ScreenPicker.ScreenPickerDelegate {
}
details.detailLines[3].value.text = multiSessionSetting;

// Activity type settings
// Activity type settings (not enough screen space for everything)
/*
details.detailLines[4].icon = new ScreenPicker.Icon({
:font => StatusIconFonts.fontMeditateIcons,
:symbol => StatusIconFonts.Rez.Strings.meditateFontYoga
Expand All @@ -131,6 +132,14 @@ class GlobalSettingsDelegate extends ScreenPicker.ScreenPickerDelegate {
if (newActivityType == ActivityType.Yoga) {
details.detailLines[4].value.text = Ui.loadResource(Rez.Strings.menuNewActivityTypeOptions_yoga);
}
*/

// Preparation time settings
details.detailLines[4].icon = new ScreenPicker.Icon({
:font => StatusIconFonts.fontMeditateIcons,
:symbol => StatusIconFonts.Rez.Strings.meditateFontYoga
});
details.detailLines[4].value.text = Ui.loadResource(Rez.Strings.menuPrepareTimeOptions_title) + ": " + GlobalSettings.loadPrepareTime().toString() + "s";

// Show Respiration rate settings if supported
if (HrvAlgorithms.RrActivity.isRespirationRateSupported()) {
Expand Down
20 changes: 20 additions & 0 deletions Meditate/source/globalSettings/GlobalSettingsMenuDelegate.mc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class GlobalSettingsMenuDelegate extends Ui.MenuInputDelegate {
Ui.pushView(new Rez.Menus.respirationRateOptionsDisabledMenu(), respirationRateDelegate, Ui.SLIDE_LEFT);
}
}
else if (item ==:prepareTime) {
var prepareTimeDelegate = new MenuOptionsDelegate(method(:onPrepareTimePicked));
Ui.pushView(new Rez.Menus.prepareTimeOptionsMenu(), prepareTimeDelegate, Ui.SLIDE_LEFT);
}
}

function onConfirmSaveActivityPicked(item) {
Expand Down Expand Up @@ -72,6 +76,22 @@ class GlobalSettingsMenuDelegate extends Ui.MenuInputDelegate {
mOnGlobalSettingsChanged.invoke();
}

function onPrepareTimePicked(item) {
if (item == :time_0) {
GlobalSettings.savePrepareTime(0);
}
else if (item == :time_15) {
GlobalSettings.savePrepareTime(15);
}
else if (item == :time_30) {
GlobalSettings.savePrepareTime(30);
}
else if (item == :time_60) {
GlobalSettings.savePrepareTime(60);
}
mOnGlobalSettingsChanged.invoke();
}

function onRespirationRateDisabledPicked(item) {
mOnGlobalSettingsChanged.invoke();
}
Expand Down
15 changes: 15 additions & 0 deletions Meditate/source/sessionSettings/SessionPickerDelegate.mc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ class SessionPickerDelegate extends ScreenPicker.ScreenPickerDelegate {
}

private function startActivity() {

// If there is no preparation time, start the meditate activity
if (GlobalSettings.loadPrepareTime()==0) {
startMeditationSession();
return;
}

// Show preparation time view and start meditation session once the time is over
var meditatePrepareView = new MeditatePrepareView(method(:startMeditationSession));
var meditatePrepareDelegate = new MeditatePrepareDelegate(me);
Ui.switchToView(meditatePrepareView, meditatePrepareDelegate, Ui.SLIDE_IMMEDIATE);
}

function startMeditationSession() {

var selectedSession = me.mSessionStorage.loadSelectedSession();
var meditateModel = new MeditateModel(selectedSession);
var meditateView = new MeditateView(meditateModel);
Expand Down
1 change: 0 additions & 1 deletion ScreenPicker/manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<iq:product id="fenix5xplus"/>
<iq:product id="fenix6"/>
<iq:product id="fenix6pro"/>
<iq:product id="fenix6prosystem5preview"/>
<iq:product id="fenix6s"/>
<iq:product id="fenix6spro"/>
<iq:product id="fenix6xpro"/>
Expand Down
2 changes: 1 addition & 1 deletion ScreenPicker/sources/DetailsModel.mc
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ module ScreenPicker {

private var lineHeight;
private var iconHeight;
private const InitialPosY = 30;
private const InitialPosY = 20;
}

class DetailsModel{
Expand Down
2 changes: 1 addition & 1 deletion ScreenPicker/sources/DetailsViewRenderer.mc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using Toybox.Application as App;

module ScreenPicker {
class DetailsViewRenderer {
private const TitlePosY = 25;
private const TitlePosY = 15;

private var mDetailsModel;

Expand Down
Loading

0 comments on commit 1fafd52

Please sign in to comment.