mirror of
https://github.com/house-of-abbey/GarminHomeAssistant.git
synced 2025-06-16 19:38:34 +00:00
Merge branch 'main' into 22-add-internationalisation-for-application-settings
This commit is contained in:
@ -18,6 +18,15 @@
|
||||
// should not happen of course... but they do, so best make sure errors can be
|
||||
// reported.
|
||||
//
|
||||
// Designed so that a single ErrorView is used for all errors and hence can ensure
|
||||
// that only the first call to display is honoured until the view is dismissed.
|
||||
// This compensates for older devices not being able to call WatchUi.getCurrentView()
|
||||
// due to not supporting API level 3.4.0.
|
||||
//
|
||||
// Usage:
|
||||
// 1) ErrorView.show("Error message");
|
||||
// 2) return ErrorView.create("Error message"); // as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Graphics;
|
||||
@ -26,18 +35,22 @@ using Toybox.WatchUi;
|
||||
using Toybox.Communications;
|
||||
|
||||
class ErrorView extends ScalableView {
|
||||
private const cSettings as Lang.Dictionary = {
|
||||
private var mText as Lang.String = "";
|
||||
private var mDelegate as ErrorDelegate;
|
||||
private const cSettings as Lang.Dictionary = {
|
||||
:errorIconMargin => 7f
|
||||
};
|
||||
// Vertical spacing between the top of the face and the error icon
|
||||
private var mErrorIconMargin;
|
||||
private var mText as Lang.String;
|
||||
private var mErrorIconMargin as Lang.Number;
|
||||
private var mErrorIcon;
|
||||
private var mTextArea;
|
||||
|
||||
function initialize(text as Lang.String) {
|
||||
private static var instance;
|
||||
private static var mShown as Lang.Boolean = false;
|
||||
|
||||
function initialize() {
|
||||
ScalableView.initialize();
|
||||
mText = text;
|
||||
mDelegate = new ErrorDelegate(self);
|
||||
// Convert the settings from % of screen size to pixels
|
||||
mErrorIconMargin = pixelsForScreen(cSettings.get(:errorIconMargin) as Lang.Float);
|
||||
}
|
||||
@ -65,25 +78,66 @@ class ErrorView extends ScalableView {
|
||||
function onUpdate(dc as Graphics.Dc) as Void {
|
||||
var w = dc.getWidth();
|
||||
var hw = w/2;
|
||||
var bg = 0x3B444C;
|
||||
if(dc has :setAntiAlias) {
|
||||
dc.setAntiAlias(true);
|
||||
}
|
||||
dc.setColor(Graphics.COLOR_WHITE, bg);
|
||||
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLUE);
|
||||
dc.clear();
|
||||
dc.drawBitmap(hw - mErrorIcon.getWidth()/2, mErrorIconMargin, mErrorIcon);
|
||||
mTextArea.draw(dc);
|
||||
}
|
||||
|
||||
function getDelegate() as ErrorDelegate {
|
||||
return mDelegate;
|
||||
}
|
||||
|
||||
static function create(text as Lang.String) as Lang.Array<ErrorView or ErrorDelegate> {
|
||||
if (instance == null) {
|
||||
instance = new ErrorView();
|
||||
}
|
||||
if (!mShown) {
|
||||
instance.setText(text);
|
||||
}
|
||||
return [instance, instance.getDelegate()];
|
||||
}
|
||||
|
||||
// Create or reuse an existing ErrorView, and pass on the text.
|
||||
static function show(text as Lang.String) as Void {
|
||||
create(text); // Ignore returned values
|
||||
if (!mShown) {
|
||||
WatchUi.pushView(instance, instance.getDelegate(), WatchUi.SLIDE_UP);
|
||||
mShown = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal show now we're not a static method like 'show()'.
|
||||
function setText(text as Lang.String) as Void {
|
||||
mText = text;
|
||||
if (mTextArea != null) {
|
||||
mTextArea.setText(text);
|
||||
requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
static function unShow() as Void {
|
||||
if (mShown) {
|
||||
mShown = false;
|
||||
WatchUi.popView(WatchUi.SLIDE_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ErrorDelegate extends WatchUi.BehaviorDelegate {
|
||||
function initialize() {
|
||||
|
||||
function initialize(view as ErrorView) {
|
||||
WatchUi.BehaviorDelegate.initialize();
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
getApp().getQuitTimer().reset();
|
||||
WatchUi.popView(WatchUi.SLIDE_DOWN);
|
||||
ErrorView.unShow();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
@ -24,24 +24,71 @@ using Toybox.WatchUi;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantApp extends Application.AppBase {
|
||||
private var mHaMenu;
|
||||
private var quitTimer as QuitTimer;
|
||||
private var strNoApiKey as Lang.String;
|
||||
private var strNoApiUrl as Lang.String;
|
||||
private var strNoConfigUrl as Lang.String;
|
||||
private var strNoPhone as Lang.String;
|
||||
private var strNoInternet as Lang.String;
|
||||
private var strNoResponse as Lang.String;
|
||||
private var strNoMenu as Lang.String;
|
||||
private var strApiFlood as Lang.String;
|
||||
private var strConfigUrlNotFound as Lang.String;
|
||||
private var strUnhandledHttpErr as Lang.String;
|
||||
private var strTrailingSlashErr as Lang.String;
|
||||
private var mHaMenu as HomeAssistantView or Null;
|
||||
private var mQuitTimer as QuitTimer or Null;
|
||||
private var strNoApiKey as Lang.String or Null;
|
||||
private var strNoApiUrl as Lang.String or Null;
|
||||
private var strNoConfigUrl as Lang.String or Null;
|
||||
private var strNoPhone as Lang.String or Null;
|
||||
private var strNoInternet as Lang.String or Null;
|
||||
private var strNoResponse as Lang.String or Null;
|
||||
private var strNoMenu as Lang.String or Null;
|
||||
private var strApiFlood as Lang.String or Null;
|
||||
private var strConfigUrlNotFound as Lang.String or Null;
|
||||
private var strUnhandledHttpErr as Lang.String or Null;
|
||||
private var strTrailingSlashErr as Lang.String or Null;
|
||||
private var mItemsToUpdate; // Array initialised by onReturnFetchMenuConfig()
|
||||
private var mNextItemToUpdate = 0; // Index into the above array
|
||||
|
||||
function initialize() {
|
||||
AppBase.initialize();
|
||||
|
||||
// ATTENTION when adding stuff into this block:
|
||||
// Because of the >>GlanceView<<, it should contain only
|
||||
// code, which is used as well for the glance:
|
||||
// - https://developer.garmin.com/connect-iq/core-topics/glances/
|
||||
//
|
||||
// Also dealing with resources "Rez" needs attention, too. See
|
||||
// "Resource Scopes":
|
||||
// - https://developer.garmin.com/connect-iq/core-topics/resources/
|
||||
//
|
||||
// Classes which are used for the glance view, needed to be tagged
|
||||
// with "(:glance)".
|
||||
}
|
||||
|
||||
// onStart() is called on application start up
|
||||
function onStart(state as Lang.Dictionary?) as Void {
|
||||
// ATTENTION when adding stuff into this block:
|
||||
// Because of the >>GlanceView<<, it should contain only
|
||||
// code, which is used as well for the glance:
|
||||
// - https://developer.garmin.com/connect-iq/core-topics/glances/
|
||||
//
|
||||
// Also dealing with resources "Rez" needs attention, too. See
|
||||
// "Resource Scopes":
|
||||
// - https://developer.garmin.com/connect-iq/core-topics/resources/
|
||||
//
|
||||
// Classes which are used for the glance view, needed to be tagged
|
||||
// with "(:glance)".
|
||||
}
|
||||
|
||||
// onStop() is called when your application is exiting
|
||||
function onStop(state as Lang.Dictionary?) as Void {
|
||||
// ATTENTION when adding stuff into this block:
|
||||
// Because of the >>GlanceView<<, it should contain only
|
||||
// code, which is used as well for the glance:
|
||||
// - https://developer.garmin.com/connect-iq/core-topics/glances/
|
||||
//
|
||||
// Also dealing with resources "Rez" needs attention, too. See
|
||||
// "Resource Scopes":
|
||||
// - https://developer.garmin.com/connect-iq/core-topics/resources/
|
||||
//
|
||||
// Classes which are used for the glance view, needed to be tagged
|
||||
// with "(:glance)".
|
||||
}
|
||||
|
||||
// Return the initial view of your application here
|
||||
function getInitialView() as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>? {
|
||||
|
||||
strNoApiKey = WatchUi.loadResource($.Rez.Strings.NoAPIKey);
|
||||
strNoApiUrl = WatchUi.loadResource($.Rez.Strings.NoApiUrl);
|
||||
strNoConfigUrl = WatchUi.loadResource($.Rez.Strings.NoConfigUrl);
|
||||
@ -53,56 +100,43 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
strConfigUrlNotFound = WatchUi.loadResource($.Rez.Strings.ConfigUrlNotFound);
|
||||
strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
|
||||
strTrailingSlashErr = WatchUi.loadResource($.Rez.Strings.TrailingSlashErr);
|
||||
quitTimer = new QuitTimer();
|
||||
}
|
||||
mQuitTimer = new QuitTimer();
|
||||
|
||||
// onStart() is called on application start up
|
||||
function onStart(state as Lang.Dictionary?) as Void {
|
||||
quitTimer.begin();
|
||||
}
|
||||
|
||||
// onStop() is called when your application is exiting
|
||||
function onStop(state as Lang.Dictionary?) as Void {
|
||||
quitTimer.stop();
|
||||
}
|
||||
|
||||
// Return the initial view of your application here
|
||||
function getInitialView() as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>? {
|
||||
var api_url = Properties.getValue("api_url") as Lang.String;
|
||||
|
||||
if ((Properties.getValue("api_key") as Lang.String).length() == 0) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp getInitialView(): No API key in the application settings.");
|
||||
}
|
||||
return [new ErrorView(strNoApiKey + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return ErrorView.create(strNoApiKey + ".");
|
||||
} else if (api_url.length() == 0) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp getInitialView(): No API URL in the application settings.");
|
||||
}
|
||||
return [new ErrorView(strNoApiUrl + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return ErrorView.create(strNoApiUrl + ".");
|
||||
} else if (api_url.substring(-1, api_url.length()).equals("/")) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp getInitialView(): API URL must not have a trailing slash '/'.");
|
||||
}
|
||||
return [new ErrorView(strTrailingSlashErr + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return ErrorView.create(strTrailingSlashErr + ".");
|
||||
} else if ((Properties.getValue("config_url") as Lang.String).length() == 0) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp getInitialView(): No configuration URL in the application settings.");
|
||||
}
|
||||
return [new ErrorView(strNoConfigUrl + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return ErrorView.create(strNoConfigUrl + ".");
|
||||
} else if (! System.getDeviceSettings().phoneConnected) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp fetchMenuConfig(): No Phone connection, skipping API call.");
|
||||
}
|
||||
return [new ErrorView(strNoPhone + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return ErrorView.create(strNoPhone + ".");
|
||||
} else if (! System.getDeviceSettings().connectionAvailable) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp fetchMenuConfig(): No Internet connection, skipping API call.");
|
||||
}
|
||||
return [new ErrorView(strNoInternet + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return ErrorView.create(strNoInternet + ".");
|
||||
} else {
|
||||
fetchMenuConfig();
|
||||
return [new WatchUi.View(), new WatchUi.BehaviorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
return [new RootView(self), new RootViewDelegate(self)] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,28 +151,27 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
} else if (responseCode == Communications.BLE_QUEUE_FULL) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
// Don't need to worry about multiple ErrorViews here as the fetch does not happen a second time.
|
||||
ErrorView.show(strApiFlood);
|
||||
} else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoResponse), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoResponse);
|
||||
} else if (responseCode == 404) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp onReturnFetchMenuConfig() Response Code: 404, page not found. Check Configuration URL setting.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strConfigUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strConfigUrlNotFound);
|
||||
} else if (responseCode == 200) {
|
||||
mHaMenu = new HomeAssistantView(data, null);
|
||||
WatchUi.switchToView(mHaMenu, new HomeAssistantViewDelegate(), WatchUi.SLIDE_IMMEDIATE);
|
||||
mQuitTimer.begin();
|
||||
pushHomeAssistantMenuView();
|
||||
mItemsToUpdate = mHaMenu.getItemsToUpdate();
|
||||
// Start the continuous update process that continues for as long as the application is running.
|
||||
// The chain of functions from 'updateNextMenuItem()' calls 'updateNextMenuItem()' on completion.
|
||||
@ -149,12 +182,12 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp onReturnFetchMenuConfig(): Network request timeout.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoMenu + ". " + strNoInternet + "?"), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoMenu + ". " + strNoInternet + "?");
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantApp onReturnFetchMenuConfig(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strUnhandledHttpErr + responseCode );
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,6 +204,14 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
);
|
||||
}
|
||||
|
||||
function homeAssistantMenuIsLoaded() as Lang.Boolean{
|
||||
return mHaMenu!=null;
|
||||
}
|
||||
|
||||
function pushHomeAssistantMenuView() as Void{
|
||||
WatchUi.pushView(mHaMenu, new HomeAssistantViewDelegate(true), WatchUi.SLIDE_IMMEDIATE);
|
||||
}
|
||||
|
||||
// We need to spread out the API calls so as not to overload the results queue and cause Communications.BLE_QUEUE_FULL (-101) error.
|
||||
// This function is called by a timer every Globals.menuItemUpdateInterval ms.
|
||||
function updateNextMenuItem() as Void {
|
||||
@ -180,9 +221,13 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
}
|
||||
|
||||
function getQuitTimer() as QuitTimer{
|
||||
return quitTimer;
|
||||
return mQuitTimer;
|
||||
}
|
||||
|
||||
(:glance)
|
||||
function getGlanceView() {
|
||||
return [new HomeAssistantGlanceView()];
|
||||
}
|
||||
}
|
||||
|
||||
function getApp() as HomeAssistantApp {
|
||||
|
@ -26,6 +26,7 @@ using Toybox.Timer;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantConfirmation extends WatchUi.Confirmation {
|
||||
|
||||
function initialize() {
|
||||
WatchUi.Confirmation.initialize(WatchUi.loadResource($.Rez.Strings.Confirm));
|
||||
}
|
||||
@ -33,32 +34,32 @@ class HomeAssistantConfirmation extends WatchUi.Confirmation {
|
||||
}
|
||||
|
||||
class HomeAssistantConfirmationDelegate extends WatchUi.ConfirmationDelegate {
|
||||
private var confirmMethod;
|
||||
private var timeout;
|
||||
private var mConfirmMethod;
|
||||
private var mTimer;
|
||||
|
||||
function initialize(callback as Method() as Void) {
|
||||
WatchUi.ConfirmationDelegate.initialize();
|
||||
confirmMethod = callback;
|
||||
mConfirmMethod = callback;
|
||||
var timeoutSeconds = Properties.getValue("confirm_timeout") as Lang.Number;
|
||||
if (timeoutSeconds > 0) {
|
||||
timeout = new Timer.Timer();
|
||||
timeout.start(method(:onTimeout), timeoutSeconds * 1000, true);
|
||||
mTimer = new Timer.Timer();
|
||||
mTimer.start(method(:onTimeout), timeoutSeconds * 1000, true);
|
||||
}
|
||||
}
|
||||
|
||||
function onResponse(response) as Lang.Boolean {
|
||||
getApp().getQuitTimer().reset();
|
||||
if (timeout) {
|
||||
timeout.stop();
|
||||
if (mTimer) {
|
||||
mTimer.stop();
|
||||
}
|
||||
if (response == WatchUi.CONFIRM_YES) {
|
||||
confirmMethod.invoke();
|
||||
mConfirmMethod.invoke();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function onTimeout() as Void {
|
||||
timeout.stop();
|
||||
mTimer.stop();
|
||||
WatchUi.popView(WatchUi.SLIDE_RIGHT);
|
||||
}
|
||||
}
|
||||
|
42
source/HomeAssistantGlanceView.mc
Normal file
42
source/HomeAssistantGlanceView.mc
Normal file
@ -0,0 +1,42 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 23 November 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Glance view for GarminHomeAssistant
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
using Toybox.Graphics;
|
||||
|
||||
(:glance)
|
||||
class HomeAssistantGlanceView extends WatchUi.GlanceView {
|
||||
|
||||
private var mText as Lang.String;
|
||||
|
||||
function initialize() {
|
||||
GlanceView.initialize();
|
||||
|
||||
mText = WatchUi.loadResource($.Rez.Strings.AppName);
|
||||
}
|
||||
|
||||
function onUpdate(dc) as Void {
|
||||
GlanceView.onUpdate(dc);
|
||||
|
||||
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
|
||||
dc.drawText(0, dc.getHeight() / 2, Graphics.FONT_TINY, mText, Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER);
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
|
@ -54,25 +54,23 @@ class HomeAssistantService {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
} else if (responseCode == Communications.BLE_QUEUE_FULL) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
// Don't need to worry about multiple ErrorViews here as the call is not on a repeat timer.
|
||||
ErrorView.show(strApiFlood);
|
||||
} else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoResponse), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoResponse);
|
||||
} else if (responseCode == 404) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: 404, page not found. Check API URL setting.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strApiUrlNotFound);
|
||||
} else if (responseCode == 200) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall(): Service executed.");
|
||||
@ -99,7 +97,7 @@ class HomeAssistantService {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strUnhandledHttpErr + responseCode );
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,14 +115,15 @@ class HomeAssistantService {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService call(): No Phone connection, skipping API call.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
} else if (! System.getDeviceSettings().connectionAvailable) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService call(): No Internet connection, skipping API call.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoInternet + ".");
|
||||
} else {
|
||||
var url = (Properties.getValue("api_url") as Lang.String) + "/services/" + service.substring(0, service.find(".")) + "/" + service.substring(service.find(".")+1, null);
|
||||
// Can't use null for substring() parameters due to API version level.
|
||||
var url = (Properties.getValue("api_url") as Lang.String) + "/services/" + service.substring(0, service.find(".")) + "/" + service.substring(service.find(".")+1, service.length());
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService call() URL=" + url);
|
||||
System.println("HomeAssistantService call() service=" + service);
|
||||
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
@ -77,56 +77,68 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
}
|
||||
// Provide the ability to terminate updating chain of calls for a permanent network error.
|
||||
var keepUpdating = true;
|
||||
if (responseCode == Communications.BLE_HOST_TIMEOUT || responseCode == Communications.BLE_CONNECTION_UNAVAILABLE) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
} else if (responseCode == Communications.BLE_QUEUE_FULL) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
} else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strNoResponse), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
} else if (responseCode == 404) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404, page not found. Check API URL setting.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
keepUpdating = false;
|
||||
} else if (responseCode == 200) {
|
||||
var state = data.get("state") as Lang.String;
|
||||
if (Globals.scDebug) {
|
||||
System.println((data.get("attributes") as Lang.Dictionary).get("friendly_name") + " State=" + state);
|
||||
}
|
||||
if (getLabel().equals("...")) {
|
||||
setLabel((data.get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String);
|
||||
}
|
||||
setUiToggle(state);
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
switch (responseCode) {
|
||||
case Communications.BLE_HOST_TIMEOUT:
|
||||
case Communications.BLE_CONNECTION_UNAVAILABLE:
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
break;
|
||||
case Communications.BLE_QUEUE_FULL:
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
ErrorView.show(strApiFlood);
|
||||
break;
|
||||
case Communications.NETWORK_REQUEST_TIMED_OUT:
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
ErrorView.show(strNoResponse);
|
||||
break;
|
||||
case 404:
|
||||
var msg = null;
|
||||
if (data != null) {
|
||||
msg = data.get("message");
|
||||
}
|
||||
if (msg != null) {
|
||||
// Should be an HTTP 405 according to curl queries
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404. " + mIdentifier + " " + msg);
|
||||
}
|
||||
ErrorView.show("HTTP 405, " + mIdentifier + ". " + data.get("message"));
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 404, page not found. Check API URL setting.");
|
||||
}
|
||||
ErrorView.show(strApiUrlNotFound);
|
||||
}
|
||||
keepUpdating = false;
|
||||
break;
|
||||
case 405:
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState() Response Code: 405. " + mIdentifier + " " + data.get("message"));
|
||||
}
|
||||
ErrorView.show("HTTP 405, " + mIdentifier + ". " + data.get("message"));
|
||||
keepUpdating = false;
|
||||
break;
|
||||
case 200:
|
||||
var state = data.get("state") as Lang.String;
|
||||
if (Globals.scDebug) {
|
||||
System.println((data.get("attributes") as Lang.Dictionary).get("friendly_name") + " State=" + state);
|
||||
}
|
||||
if (getLabel().equals("...")) {
|
||||
setLabel((data.get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String);
|
||||
}
|
||||
setUiToggle(state);
|
||||
ErrorView.unShow();
|
||||
break;
|
||||
default:
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
ErrorView.show(strUnhandledHttpErr + responseCode);
|
||||
}
|
||||
if (keepUpdating) {
|
||||
// Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
|
||||
@ -147,18 +159,12 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem getState(): No Phone connection, skipping API call.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
} else if (! System.getDeviceSettings().connectionAvailable) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
ErrorView.show(strNoInternet + ".");
|
||||
} else {
|
||||
var url = Properties.getValue("api_url") + "/states/" + mIdentifier;
|
||||
if (Globals.scDebug) {
|
||||
@ -180,7 +186,9 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
var myTimer = new Timer.Timer();
|
||||
// Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
|
||||
myTimer.start(getApp().method(:updateNextMenuItem), 500, false);
|
||||
System.println("HomeAssistantToggleMenuItem getState(): Updated failed " + mIdentifier);
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem getState(): Updated failed " + mIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,22 +203,22 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
} else if (responseCode == Communications.BLE_QUEUE_FULL) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strApiFlood);
|
||||
} else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoResponse), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoResponse);
|
||||
} else if (responseCode == 404) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnSetState() Response Code: 404, page not found. Check API URL setting.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strApiUrlNotFound);
|
||||
} else if (responseCode == 200) {
|
||||
var state;
|
||||
var d = data as Lang.Array;
|
||||
@ -227,7 +235,7 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem onReturnSetState(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strUnhandledHttpErr + responseCode );
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,14 +254,14 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
}
|
||||
// Toggle the UI back
|
||||
setEnabled(!isEnabled());
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoPhone + ".");
|
||||
} else if (! System.getDeviceSettings().connectionAvailable) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantToggleMenuItem getState(): No Internet connection, skipping API call.");
|
||||
}
|
||||
// Toggle the UI back
|
||||
setEnabled(!isEnabled());
|
||||
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
ErrorView.show(strNoInternet + ".");
|
||||
} else {
|
||||
// Updated SDK and got a new error
|
||||
// ERROR: venu: Cannot find symbol ':substring' on type 'PolyType<Null or $.Toybox.Lang.Object>'.
|
||||
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
@ -21,6 +21,7 @@
|
||||
using Toybox.Application;
|
||||
using Toybox.Lang;
|
||||
using Toybox.Graphics;
|
||||
using Toybox.System;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class HomeAssistantView extends WatchUi.Menu2 {
|
||||
@ -103,12 +104,23 @@ class HomeAssistantView extends WatchUi.Menu2 {
|
||||
//
|
||||
class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate {
|
||||
|
||||
function initialize() {
|
||||
private var mIsRootMenuView = false;
|
||||
|
||||
function initialize(isRootMenuView as Lang.Boolean) {
|
||||
Menu2InputDelegate.initialize();
|
||||
mIsRootMenuView = isRootMenuView;
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
getApp().getQuitTimer().reset();
|
||||
|
||||
if (mIsRootMenuView){
|
||||
// If its started from glance or as an activity, directly exit the widget/app
|
||||
// (on widgets without glance, this exit() won`t do anything,
|
||||
// so the base view will be shown instead, through the popView below this "if body")
|
||||
System.exit();
|
||||
}
|
||||
|
||||
WatchUi.popView(WatchUi.SLIDE_RIGHT);
|
||||
}
|
||||
|
||||
@ -147,15 +159,13 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate {
|
||||
if (Globals.scDebug) {
|
||||
System.println("Menu: " + haMenuItem.getLabel() + " " + haMenuItem.getId());
|
||||
}
|
||||
// No delegate state to be amended, so re-use 'self'.
|
||||
WatchUi.pushView(haMenuItem.getMenuView(), self, WatchUi.SLIDE_LEFT);
|
||||
WatchUi.pushView(haMenuItem.getMenuView(), new HomeAssistantViewDelegate(false), WatchUi.SLIDE_LEFT);
|
||||
} else if (item instanceof HomeAssistantViewIconMenuItem) {
|
||||
var haMenuItem = item as HomeAssistantViewIconMenuItem;
|
||||
if (Globals.scDebug) {
|
||||
System.println("IconMenu: " + haMenuItem.getLabel() + " " + haMenuItem.getId());
|
||||
}
|
||||
// No delegate state to be amended, so re-use 'self'.
|
||||
WatchUi.pushView(haMenuItem.getMenuView(), self, WatchUi.SLIDE_LEFT);
|
||||
WatchUi.pushView(haMenuItem.getMenuView(), new HomeAssistantViewDelegate(false), WatchUi.SLIDE_LEFT);
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println(item.getLabel() + " " + item.getId());
|
||||
|
@ -9,7 +9,7 @@
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
|
129
source/RootView.mc
Normal file
129
source/RootView.mc
Normal file
@ -0,0 +1,129 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 5 December 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Application root view for GarminHomeAssistant
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Graphics;
|
||||
using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class RootView extends ScalableView {
|
||||
|
||||
// ATTENTION when the app is running as a "widget" (that means, it runs on devices
|
||||
// without glance view support), the input events in this view are limited, as
|
||||
// described under "Base View and the Widget Carousel" on:
|
||||
//
|
||||
// https://developer.garmin.com/connect-iq/connect-iq-basics/app-types/
|
||||
//
|
||||
// Also the view type of the base view is limited too (for example "WatchUi.Menu2"
|
||||
// is not possible)).
|
||||
//
|
||||
// Also System.exit() is not working/do nothing when running as a widget: A widget will be
|
||||
// terminated automatically by OS after some time or can be quit manually, when on the base
|
||||
// view a swipe to left / "back button" press is done.
|
||||
|
||||
private var mApp as HomeAssistantApp;
|
||||
private var strFetchingMenuConfig as Lang.String;
|
||||
private var strExit as Lang.String;
|
||||
private var mTextAreaExit as WatchUi.TextArea or Null;
|
||||
private var mTextAreaFetching as WatchUi.TextArea or Null;
|
||||
|
||||
function initialize(app as HomeAssistantApp) {
|
||||
ScalableView.initialize();
|
||||
mApp=app;
|
||||
|
||||
strFetchingMenuConfig = WatchUi.loadResource($.Rez.Strings.FetchingMenuConfig);
|
||||
|
||||
if (System.getDeviceSettings().isTouchScreen){
|
||||
strExit = WatchUi.loadResource($.Rez.Strings.ExitViewTouch);
|
||||
} else {
|
||||
strExit = WatchUi.loadResource($.Rez.Strings.ExitViewButtons);
|
||||
}
|
||||
}
|
||||
|
||||
function onLayout(dc as Graphics.Dc) as Void {
|
||||
var w = dc.getWidth();
|
||||
var h = dc.getHeight();
|
||||
|
||||
mTextAreaExit = new WatchUi.TextArea({
|
||||
:text => strExit,
|
||||
:color => Graphics.COLOR_WHITE,
|
||||
:font => Graphics.FONT_XTINY,
|
||||
:justification => Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER,
|
||||
:locX => 0,
|
||||
:locY => 83,
|
||||
:width => w,
|
||||
:height => h - 166
|
||||
});
|
||||
|
||||
mTextAreaFetching = new WatchUi.TextArea({
|
||||
:text => strFetchingMenuConfig,
|
||||
:color => Graphics.COLOR_WHITE,
|
||||
:font => Graphics.FONT_XTINY,
|
||||
:justification => Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER,
|
||||
:locX => 0,
|
||||
:locY => 83,
|
||||
:width => w,
|
||||
:height => h - 166
|
||||
});
|
||||
}
|
||||
|
||||
function onUpdate(dc as Graphics.Dc) as Void {
|
||||
if(dc has :setAntiAlias) {
|
||||
dc.setAntiAlias(true);
|
||||
}
|
||||
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
|
||||
dc.clear();
|
||||
|
||||
if(mApp.homeAssistantMenuIsLoaded()) {
|
||||
mTextAreaExit.draw(dc);
|
||||
} else {
|
||||
mTextAreaFetching.draw(dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RootViewDelegate extends WatchUi.BehaviorDelegate {
|
||||
|
||||
var mApp as HomeAssistantApp;
|
||||
|
||||
function initialize(app as HomeAssistantApp ) {
|
||||
BehaviorDelegate.initialize();
|
||||
mApp=app;
|
||||
}
|
||||
|
||||
function onTap(evt as WatchUi.ClickEvent) as Lang.Boolean {
|
||||
return backToMainMenu();
|
||||
}
|
||||
|
||||
function onSelect() as Lang.Boolean {
|
||||
return backToMainMenu();
|
||||
}
|
||||
|
||||
function onMenu() as Lang.Boolean{
|
||||
return backToMainMenu();
|
||||
}
|
||||
|
||||
private function backToMainMenu() as Lang.Boolean{
|
||||
if(mApp.homeAssistantMenuIsLoaded()){
|
||||
mApp.pushHomeAssistantMenuView();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user