Public Access
Steps 5 and 6 of M0. - lib/ui (host-tested): ListModel, LineEditor (UTF-8, byte-limited), wrapText, ToastQueue, DialogModel - lib/input (host-tested): KeyMapper turns keyboard state into logical keys (Fn arrows, ` Back, Fn+` Home) and composes accents with opt - src/ui: off-screen 16-bit frame pushed in one transfer (fixes the flicker), Status Bar, list, text, line editor, dialog, Toast widgets, Notifier (Toast + beep + LED), vendored public-domain Latin-1 fonts - Apps: minimal Launcher, Widget demo, Diagnostics (SD erase now behind a confirmation dialog) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
33 lines
871 B
C++
33 lines
871 B
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
namespace roro {
|
|
|
|
// Single-line UTF-8 text editing. The cursor is a byte index always on a character boundary,
|
|
// and the text never exceeds maxBytes (protocol fields are limited in bytes, not characters).
|
|
class LineEditor {
|
|
public:
|
|
explicit LineEditor(size_t maxBytes) : max_(maxBytes) {}
|
|
|
|
void setText(const std::string& text); // truncates, cursor to end
|
|
const std::string& text() const { return text_; }
|
|
size_t cursor() const { return cursor_; }
|
|
size_t maxBytes() const { return max_; }
|
|
|
|
bool insert(uint32_t codePoint); // false if it would not fit
|
|
void backspace();
|
|
void left();
|
|
void right();
|
|
void home() { cursor_ = 0; }
|
|
void end() { cursor_ = text_.size(); }
|
|
|
|
private:
|
|
size_t max_;
|
|
std::string text_;
|
|
size_t cursor_ = 0;
|
|
};
|
|
|
|
} // namespace roro
|