Use InputDelegate for separate button/tap handling

InputDelegate separates hardware KEY_ENTER (opens item) from
screen onTap (rotates to tapped icon). Fixes tap always opening
instead of rotating.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
EiSiMo 2026-04-13 19:46:36 +02:00
parent 21a62d79c3
commit 46307e7cb0

View file

@ -1,71 +1,68 @@
import Toybox.Lang; import Toybox.Lang;
import Toybox.WatchUi; import Toybox.WatchUi;
// Routes menu input. UP/DOWN rotate the ring. START/STOP opens // Routes menu input. UP/DOWN rotate the ring. Hardware START/STOP
// the selected item. Tap on an icon rotates to it; tap on the // opens the selected item. Screen tap rotates to tapped icon;
// already-selected icon opens it. // tap on already-selected icon opens it.
class MenuDelegate extends WatchUi.BehaviorDelegate { class MenuDelegate extends WatchUi.InputDelegate {
private var _view as MenuView; private var _view as MenuView;
private var _tapHandled as Boolean = false;
function initialize(view as MenuView) { function initialize(view as MenuView) {
BehaviorDelegate.initialize(); InputDelegate.initialize();
_view = view; _view = view;
} }
function onNextPage() as Boolean { // Hardware buttons.
_view.rotateNext(); function onKey(evt as WatchUi.KeyEvent) as Boolean {
return true; var key = evt.getKey();
} if (key == WatchUi.KEY_ENTER || key == WatchUi.KEY_START) {
return _openSelected();
function onPreviousPage() as Boolean { }
_view.rotatePrev(); if (key == WatchUi.KEY_DOWN) {
return true; _view.rotateNext();
return true;
}
if (key == WatchUi.KEY_UP) {
_view.rotatePrev();
return true;
}
return false;
} }
// Screen tap.
function onTap(evt as WatchUi.ClickEvent) as Boolean { function onTap(evt as WatchUi.ClickEvent) as Boolean {
var coords = evt.getCoordinates(); var coords = evt.getCoordinates();
var tapX = coords[0] as Number; var tapX = coords[0] as Number;
var tapY = coords[1] as Number; var tapY = coords[1] as Number;
var idx = _view.itemIndexAt(tapX, tapY); var idx = _view.itemIndexAt(tapX, tapY);
if (idx >= 0 && idx != _view.selectedIndex()) { if (idx < 0) { return false; }
// Tap on non-selected icon rotate to it, block onSelect.
_view.rotateTo(idx); if (idx == _view.selectedIndex()) {
_tapHandled = true; return _openSelected();
return true;
} }
// Tap on selected icon or empty area let onSelect handle it. _view.rotateTo(idx);
return false; return true;
}
function onSelect() as Boolean {
// If a tap already handled this event, skip.
if (_tapHandled) {
_tapHandled = false;
return true;
}
return _openSelected();
} }
private function _openSelected() as Boolean { private function _openSelected() as Boolean {
var item = _view.selectedItem(); var item = _view.selectedItem();
var key = item[:key] as String; var k = item[:key] as String;
if (key.equals(Config.ACTION_HISTORY)) { if (k.equals(Config.ACTION_HISTORY)) {
var view = new HistoryView(); var view = new HistoryView();
WatchUi.pushView(view, new HistoryDelegate(view), WatchUi.SLIDE_LEFT); WatchUi.pushView(view, new HistoryDelegate(view), WatchUi.SLIDE_LEFT);
return true; return true;
} }
if (key.equals(Config.ACTION_DELETE)) { if (k.equals(Config.ACTION_DELETE)) {
var view = new DeleteView(); var view = new DeleteView();
WatchUi.pushView(view, new DeleteDelegate(view), WatchUi.SLIDE_LEFT); WatchUi.pushView(view, new DeleteDelegate(view), WatchUi.SLIDE_LEFT);
return true; return true;
} }
WatchUi.pushView(new LoadingView(key), new LoadingDelegate(), WatchUi.SLIDE_IMMEDIATE); WatchUi.pushView(new LoadingView(k), new LoadingDelegate(), WatchUi.SLIDE_IMMEDIATE);
return true; return true;
} }
} }