summaryrefslogtreecommitdiff
path: root/source/ui/ListDelegate.mc
blob: ca7cee91884e9a215001801a32ccd36a23e059be (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// 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 {
        if (!Gesture.recent()) {
            AppState.activity();
            _view.move(1);
        }
        return true;
    }

    function onPreviousPage() as Boolean {
        if (!Gesture.recent()) {
            AppState.activity();
            _view.move(-1);
        }
        return true;
    }

    // The Forerunner 70 sends no page behaviour for a vertical swipe, so the
    // swipe and the drag scroll here; Gesture makes a gesture count once.
    function onSwipe(event as WatchUi.SwipeEvent) as Boolean {
        if (!Gesture.isVertical(event)) {
            return BehaviorDelegate.onSwipe(event);
        }
        var step = Gesture.swipeStep(event);
        if (step != 0) {
            AppState.activity();
            _view.move(step);
        }
        return true;
    }

    // A drag scrolls by the rows it covered, at least one.
    function onDrag(event as WatchUi.DragEvent) as Boolean {
        var step = Gesture.dragStep(event, _view.rowHeight());
        if (step == 0) {
            return false;
        }
        AppState.activity();
        _view.move(step);
        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();
        if (Gesture.tapIgnored()) {
            return true;
        }
        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;
    }
}