// 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; private var _screen as String; private var _lines as Array? = 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, 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; 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); } 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; } }