aboutsummaryrefslogtreecommitdiff
path: root/source/ui/InfoView.mc
blob: 3b757644831803812f3f29e521b01deeea0d72b3 (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
121
122
// Author:  cirakg & claude ai
// Summary: A scrollable text screen with a title: settings results, entry IDs, clock status, about, errors.

import Toybox.Graphics;
import Toybox.Lang;
import Toybox.WatchUi;

class InfoView extends WatchUi.View {

    private var _title as String;
    private var _text as Array<String>;
    private var _screen as String;
    private var _lines as Array<String>? = null; // wrapped, on first draw
    private var _first as Number = 0;
    private var _visible as Number = 1;
    private var _shownLogged as Boolean = false;

    // screen names the view in "DIAG shown" lines for UI scripts.
    function initialize(title as String, text as Array<String>, screen as String) {
        View.initialize();
        _title = title;
        _text = text;
        _screen = screen;
    }

    function onShow() as Void {
        _shownLogged = false;
    }

    // Scroll by delta lines; returns false when already at that end.
    function scroll(delta as Number) as Boolean {
        var lines = _lines;
        if (lines == null) {
            return false;
        }
        var max = lines.size() - _visible > 0 ? lines.size() - _visible : 0;
        var next = _first + delta;
        next = next < 0 ? 0 : (next > max ? max : next);
        if (next == _first) {
            return false;
        }
        _first = next;
        WatchUi.requestUpdate();
        return true;
    }

    function onUpdate(dc as Graphics.Dc) as Void {
        Ui.clear(dc);
        var w = dc.getWidth();
        var h = dc.getHeight();
        var font = Graphics.FONT_XTINY;
        var lineH = dc.getFontHeight(font);
        var y = Ui.isRound() ? h / 8 : 6;
        dc.setColor(Ui.accent(), Graphics.COLOR_TRANSPARENT);
        dc.drawText(w / 2, y, Graphics.FONT_SMALL, Ui.fit(dc, _title, Graphics.FONT_SMALL, 2 * Ui.halfWidthAt(dc, y)),
            Graphics.TEXT_JUSTIFY_CENTER);
        y += dc.getFontHeight(Graphics.FONT_SMALL) + 4;
        var bottom = Ui.isRound() ? h - h / 10 : h - 4;
        var lines = _lines;
        if (lines == null) {
            // Wrap to the narrowest width the text area has.
            var width = 2 * Ui.halfWidthBetween(dc, y, bottom) - 8;
            lines = [] as Array<String>;
            for (var i = 0; i < _text.size(); i++) {
                lines.addAll(Ui.wrap(dc, _text[i], font, width));
            }
            _lines = lines;
        }
        _visible = (bottom - y) / lineH;
        dc.setColor(Ui.fg(), Graphics.COLOR_TRANSPARENT);
        for (var i = _first; i < lines.size() && i < _first + _visible; i++) {
            dc.drawText(w / 2, y, font, lines[i], Graphics.TEXT_JUSTIFY_CENTER);
            y += lineH;
        }
        if (_first + _visible < lines.size()) {
            var cx = w / 2;
            dc.setColor(Ui.dim(), Graphics.COLOR_TRANSPARENT);
            dc.fillPolygon([[cx - 6, bottom], [cx + 6, bottom], [cx, bottom + 6]] as Array<Graphics.Point2D>);
        }
        if (!_shownLogged) {
            _shownLogged = true;
            Diag.shown(_screen);
        }
    }
}

// Input on a text screen: scroll, BACK closes (and leaves the app when this
// is the only screen, as for start-up errors).
class InfoDelegate extends WatchUi.BehaviorDelegate {

    function initialize() {
        BehaviorDelegate.initialize();
    }

    private function view() as InfoView? {
        var current = WatchUi.getCurrentView()[0];
        return current instanceof InfoView ? current : null;
    }

    function onNextPage() as Boolean {
        AppState.activity();
        var v = view();
        if (v != null) {
            v.scroll(3);
        }
        return true;
    }

    function onPreviousPage() as Boolean {
        AppState.activity();
        var v = view();
        if (v != null) {
            v.scroll(-3);
        }
        return true;
    }

    function onBack() as Boolean {
        AppState.activity();
        return false;
    }
}