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;
}
}
|