aboutsummaryrefslogtreecommitdiff
path: root/source/ui/InfoView.mc
diff options
context:
space:
mode:
Diffstat (limited to 'source/ui/InfoView.mc')
-rw-r--r--source/ui/InfoView.mc122
1 files changed, 122 insertions, 0 deletions
diff --git a/source/ui/InfoView.mc b/source/ui/InfoView.mc
new file mode 100644
index 0000000..3b75764
--- /dev/null
+++ b/source/ui/InfoView.mc
@@ -0,0 +1,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;
+ }
+}