diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-19 22:28:09 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-19 22:28:09 +0200 |
| commit | 35042ff04ffc50e55ff59a385849442be4429d6b (patch) | |
| tree | 3c142dd9bfb995b7aacdf39128e591dd3f9370de /source/ui/ListDelegate.mc | |
| parent | 871aba901501302586895d266fe4569665d9fe70 (diff) | |
feat(ui): add the list, OTP detail, PIN entry, menu, info screens and glance
List with live codes and countdowns, adaptive rows and lazy headers; OTP
detail with ring or bar, next code and HOTP next; PIN keypad or button
selector with create, unlock, change, lockout display and pending
promotion; native menu; glance with the entry count; self-test after the
first frame; option properties with defaults. Codes are computed one per
timer event, apart from drawing, for the watchdog. A UI-test build
(uitest.jungle) starts with fake entries, PIN 123456 and a frozen clock.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/ui/ListDelegate.mc')
| -rw-r--r-- | source/ui/ListDelegate.mc | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/source/ui/ListDelegate.mc b/source/ui/ListDelegate.mc new file mode 100644 index 0000000..a7c8bf0 --- /dev/null +++ b/source/ui/ListDelegate.mc @@ -0,0 +1,88 @@ +// Author: cirakg & claude ai +// Summary: Input on the list (README 13.4): scroll with UP/DOWN or swipes, open with START or a tap, menu (MENU or long press), back exits. + +import Toybox.Lang; +import Toybox.WatchUi; + +class ListDelegate extends WatchUi.BehaviorDelegate { + + private var _view as ListView; + + function initialize(view as ListView) { + BehaviorDelegate.initialize(); + _view = view; + } + + function onNextPage() as Boolean { + AppState.activity(); + _view.move(1); + return true; + } + + function onPreviousPage() as Boolean { + AppState.activity(); + _view.move(-1); + return true; + } + + // On touch screens a tap arrives as the select behaviour first; returning + // false passes it on to onTap, which opens the row under the finger. The + // START button then comes through onKey. + function onSelect() as Boolean { + if (Ui.isTouch()) { + return false; + } + openFocused(); + return true; + } + + function onKey(event as WatchUi.KeyEvent) as Boolean { + if (Ui.isTouch() && event.getKey() == WatchUi.KEY_ENTER) { + openFocused(); + return true; + } + return false; + } + + private function openFocused() as Void { + AppState.activity(); + var id = _view.focusedId(); + if (id != null) { + Nav.openEntry(id); + } + } + + // A tap opens the row under the finger. + function onTap(event as WatchUi.ClickEvent) as Boolean { + AppState.activity(); + var index = _view.rowAt(event.getCoordinates()[1]); + if (index < 0) { + return true; + } + _view.focus = index; + var id = _view.focusedId(); + if (id != null) { + Nav.openEntry(id); + } + return true; + } + + // A long press opens the menu too: watches without a MENU button + // (Venu X1) have no other way to reach it (README 13.4). + function onHold(event as WatchUi.ClickEvent) as Boolean { + AppState.activity(); + Nav.openMenu(); + return true; + } + + function onMenu() as Boolean { + AppState.activity(); + Nav.openMenu(); + return true; + } + + // BACK leaves the app; onStop locks everything. + function onBack() as Boolean { + return false; + } +} |
