24 inline constexpr
DrawArg arg_ptr(
const void* x) {
27 inline constexpr
DrawArg arg_color(u32 x) {
30 inline constexpr
DrawArg arg_count(u32 x) {
33 inline constexpr
DrawArg arg_rc(u16 r, u16 c) {
36 inline constexpr
DrawArg arg_scroll(s16 x) {
52 bool DrawCmd::rc(u16 r, u16 c)
const {
67 return icon8()->
rc(r / m_arg1, c / m_arg1);
69 return icon16()->
rc(r / m_arg1, c / m_arg1);
71 return icon32()->
rc(r / m_arg1, c / m_arg1);
82 return icon8()->
h() * m_arg1;
84 return icon16()->
h() * m_arg1;
86 return icon32()->
h() * m_arg1;
97 return icon8()->
w() * m_arg1;
99 return icon16()->
w() * m_arg1;
101 return icon32()->
w() * m_arg1;
116 cursor.
r = m_arg2.
rc[0];
117 cursor.
c = m_arg2.
rc[1];
126 , m_cursor_draw{0, 0, 0, 0}
127 , m_cursor_user{0, 0, 0, 0}
135 , m_cursor_draw{0, 0, 0, 0}
136 , m_cursor_user{0, 0, 0, 0}
137 , m_buffer(buffer, bsize)
143 if (m_cursor_user.
fg == color)
return true;
144 DrawCmd cmd(CMD_COLOR_FG, 0, arg_color(color));
145 return enqueue(cmd) && finalize();
149 if (m_cursor_user.
bg == color)
return true;
150 DrawCmd cmd(CMD_COLOR_BG, 0, arg_color(color));
151 return enqueue(cmd) && finalize();
154 bool Canvas::cursor(u16 r, u16 c) {
155 if (m_cursor_user.
r == r && m_cursor_user.
c == c)
return true;
156 DrawCmd cmd(CMD_MOVE, 0, arg_rc(r, c));
157 return enqueue(cmd) && finalize();
166 DrawCmd cmd(CMD_ICON8, mag, arg_ptr(icon));
167 return enqueue(cmd) && finalize();
171 DrawCmd cmd(CMD_ICON16, mag, arg_ptr(icon));
172 return enqueue(cmd) && finalize();
176 DrawCmd cmd(CMD_ICON32, mag, arg_ptr(icon));
177 return enqueue(cmd) && finalize();
181 DrawCmd cmd(CMD_RECT, fg ? 1 : 0, arg_rc(h, w));
182 return enqueue(cmd) && finalize();
186 u16 rows =
raw_text(msg, font, mag);
187 return (draw_eol(8*mag, rows) && finalize()) ? rows : 0;
191 u16 rows =
raw_text(msg, font, mag);
192 return (draw_eol(16*mag, rows) && finalize()) ? rows : 0;
196 u16 rows =
raw_text(msg, font, mag);
197 return (draw_eol(32*mag, rows) && finalize()) ? rows : 0;
203 DrawCmd cmd(CMD_ICON8, mag, arg_ptr(font.
icon(*msg)));
204 if (!draw_char(*msg++, cmd, rows))
return 0;
212 DrawCmd cmd(CMD_ICON16, mag, arg_ptr(font.
icon(*msg)));
213 if (!draw_char(*msg++, cmd, rows))
return 0;
221 DrawCmd cmd(CMD_ICON32, mag, arg_ptr(font.
icon(*msg)));
222 if (!draw_char(*msg++, cmd, rows))
return 0;
228 DrawCmd cmd(CMD_SCROLL, 0, arg_scroll(rows));
229 return enqueue(cmd) && finalize();
232 bool Canvas::cmd_retry() {
234 bool done = execute(m_cmd_retry);
235 if (done) m_cmd_retry.m_opcode = CMD_NONE;
242 bool Canvas::draw_char(
char ch,
const DrawCmd& cmd, u16& total_rows) {
245 u16 rem_cols = width() - m_cursor_user.
c;
247 if ((ch ==
'\n') || (cmd.
width() > rem_cols))
248 ok = ok && draw_eol(cmd.
height(), total_rows);
250 if (cmd.m_arg2.
ptr) {
251 ok = ok && enqueue(cmd);
252 }
else if (ch ==
'\t') {
254 ok = ok && enqueue(tab);
259 bool Canvas::draw_eol(u16 height, u16& total_rows) {
261 total_rows += height;
262 u16 rem_cols = width() - m_cursor_user.
c;
263 DrawCmd fill(CMD_RECT, 0, arg_rc(height, rem_cols));
264 DrawCmd wrap(CMD_MOVE, 0, arg_rc(m_cursor_user.
r + height, 0));
265 return (!rem_cols || enqueue(fill)) && enqueue(wrap);
268 bool Canvas::enqueue(
const DrawCmd& cmd) {
274 if (ok) cmd.
update(m_cursor_user);
278 bool Canvas::execute(
const DrawCmd& cmd) {
281 if (cmd.m_opcode == CMD_SCROLL) {
284 ok = m_display->
draw(m_cursor_draw, cmd);
288 if (ok) cmd.
update(m_cursor_draw);
292 bool Canvas::finalize() {
308 u16 row_min, u16 row_count)
312 , m_row_count(row_count ? row_count : (canvas->height() - row_min))
322 m_canvas->
cursor(m_row_next + m_row_min, 0);
325 if (priority <= satcat5::log::DEBUG) {
326 m_canvas->
color_bg(m_colors.bg_debug);
327 m_canvas->
color_fg(m_colors.fg_debug);
329 }
else if (priority <= satcat5::log::INFO) {
330 m_canvas->
color_bg(m_colors.bg_info);
331 m_canvas->
color_fg(m_colors.fg_info);
333 }
else if (priority <= satcat5::log::WARNING) {
334 m_canvas->
color_fg(m_colors.fg_warn);
335 m_canvas->
color_bg(m_colors.bg_warn);
338 m_canvas->
color_bg(m_colors.bg_error);
339 m_canvas->
color_fg(m_colors.fg_error);
344 m_canvas->
color_bg(m_colors.bg_text);
345 m_canvas->
color_fg(m_colors.fg_text);
349 m_canvas->
scroll(new_rows);
350 m_row_next = (m_row_next + new_rows) % m_row_count;
User-facing interface for drawing graphical elements on a screen.
u16 raw_text(const char *msg, const satcat5::gui::Font8x8 &font=BASIC_FONT, u8 mag=1)
Draw a partial line of text with the designated font.
bool clear(u32 color)
Clear the entire display contents.
bool cursor(u16 r, u16 c)
Set cursor position for subsequent commands.
bool draw_rect(u16 h, u16 w, bool fg=true)
Draw a solid rectangle using the specified color.
bool draw_icon(const satcat5::gui::Icon8x8 *icon, u8 mag=1)
Draw icon with the designated location and color.
bool color_bg(u32 color)
Set background color for subsequent commands.
bool scroll(s16 rows)
On supported displays, scroll the designated scrollable window.
void poll_demand() override
Deferred event handler, called after request().
u16 draw_text(const char *msg, const satcat5::gui::Font8x8 &font=BASIC_FONT, u8 mag=1)
Draw a full line of text with the designated font.
bool color_fg(u32 color)
Set foreground color for subsequent commands.
Canvas(satcat5::gui::Display *display)
Link this object to a Display in immediate mode.
Required API for display devices.
virtual bool draw(const satcat5::gui::Cursor &cursor, const satcat5::gui::DrawCmd &cmd)=0
Draw pixels to the screen at the designated location.
u16 width() const
Total size of the display, in pixels.
virtual bool scroll(s16 rows)
Optional: Advance the predefined viewport by N pixels.
u16 height() const
Total size of the display, in pixels.
Each "draw command" updates a rectangular region of pixels.
u16 width() const
Size of the rectangular update region.
u16 height() const
Size of the rectangular update region.
void update(Cursor &cursor) const
Update cursor-state automatically for easier chaining.
The Font class maps characters to fixed-size icons.
const T * icon(char c) const
Fetch the icon associated with a given character.
Service for forwarding Log events to a display adapter.
void log_event(s8 priority, unsigned nbytes, const char *msg) override
Implement the required API from log::EventHandler.
LogToDisplay(satcat5::gui::Canvas *canvas, const satcat5::gui::LogColors &colors, u16 row_min=0, u16 row_count=0)
Link this log service to the designated display/canvas.
bool write_finalize() override
Mark end of frame and release temporary working data.
bool read_bytes(unsigned nbytes, void *dst) override
Read 0 or more bytes into a buffer.
void write_bytes(unsigned nbytes, const void *src) override
Write 0 or more bytes from a buffer.
unsigned get_read_ready() const override
How many bytes can be read without blocking?
unsigned get_buff_size() const
Accessor for children that need to delete underlying buffer.
void request_poll()
Call this method to request polling at a later time.
"Display" and "Canvas" API for rendering text and graphics
Cursor object tracks position and foreground/background colors.
u32 fg
Foreground color (format defined by display)
u16 r
Row coordinate (0 = top)
u32 bg
Background color (format defined by display)
u16 c
Column coordinate (0 = left)
Plain-old-data struct for a 16x16 monochrome image.
bool rc(u16 r, u16 c) const
Get pixel value at designated row and column.
u16 w() const
Height of this icon.
u16 h() const
Width of this icon.
Plain-old-data struct for a 32x32 monochrome image.
u16 h() const
Width of this icon.
bool rc(u16 r, u16 c) const
Get pixel value at designated row and column.
u16 w() const
Height of this icon.
Plain-old-data struct for an 8x8 monochrome image.
bool rc(u16 r, u16 c) const
Get pixel value at designated row and column.
u16 w() const
Height of this icon.
u16 h() const
Width of this icon.
Color parameters for the LogToDisplay class.
Argument for a draw command (see below).
const void * ptr
Pointer to an icon or other object.
u32 color
Display-specific color argument.
s16 scroll
Scrolling parameter (signed)
u16 rc[2]
A row and column (coordinate or size)
u32 count
Any other counter.