Fix tap-to-rotate and GPS cancel crash

- Tap on non-selected icon rotates instead of opening, flag
  prevents onSelect from double-firing
- GpsService.stop() for clean cancellation
- LoadingView stops GPS on hide (BACK button)
- LoadingDelegate allows BACK to cancel GPS acquisition

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
EiSiMo 2026-04-13 19:41:57 +02:00
parent a45f1b5215
commit 21a62d79c3
4 changed files with 42 additions and 8 deletions

View file

@ -60,6 +60,14 @@ class GpsService {
}
}
function stop() as Void {
if (_finished) { return; }
_finished = true;
_timer.stop();
_pollTimer.stop();
Position.enableLocationEvents(Position.LOCATION_DISABLE, method(:_onPosition));
}
function _onTimeout() as Void {
_finish(_bestFix);
}

15
source/LoadingDelegate.mc Normal file
View file

@ -0,0 +1,15 @@
import Toybox.Lang;
import Toybox.WatchUi;
// Allows the user to cancel GPS acquisition by pressing BACK.
class LoadingDelegate extends WatchUi.BehaviorDelegate {
function initialize() {
BehaviorDelegate.initialize();
}
function onBack() as Boolean {
WatchUi.popView(WatchUi.SLIDE_RIGHT);
return true;
}
}

View file

@ -30,6 +30,10 @@ class LoadingView extends WatchUi.View {
function onHide() as Void {
_animTimer.stop();
if (_gps != null) {
_gps.stop();
_gps = null;
}
}
function _tick() as Void {

View file

@ -7,6 +7,7 @@ import Toybox.WatchUi;
class MenuDelegate extends WatchUi.BehaviorDelegate {
private var _view as MenuView;
private var _tapHandled as Boolean = false;
function initialize(view as MenuView) {
BehaviorDelegate.initialize();
@ -28,18 +29,24 @@ class MenuDelegate extends WatchUi.BehaviorDelegate {
var tapX = coords[0] as Number;
var tapY = coords[1] as Number;
var idx = _view.itemIndexAt(tapX, tapY);
if (idx < 0) { return false; }
if (idx == _view.selectedIndex()) {
// Tap on already-selected item open it.
return _openSelected();
if (idx >= 0 && idx != _view.selectedIndex()) {
// Tap on non-selected icon rotate to it, block onSelect.
_view.rotateTo(idx);
_tapHandled = true;
return true;
}
// Tap on another item rotate to it.
_view.rotateTo(idx);
return true;
// Tap on selected icon or empty area let onSelect handle it.
return false;
}
function onSelect() as Boolean {
// If a tap already handled this event, skip.
if (_tapHandled) {
_tapHandled = false;
return true;
}
return _openSelected();
}
@ -58,7 +65,7 @@ class MenuDelegate extends WatchUi.BehaviorDelegate {
return true;
}
WatchUi.pushView(new LoadingView(key), null, WatchUi.SLIDE_IMMEDIATE);
WatchUi.pushView(new LoadingView(key), new LoadingDelegate(), WatchUi.SLIDE_IMMEDIATE);
return true;
}
}