Enable title bar on all builds

* Tweak scroll area position so last line is complete and top is
  under the title bar.
* Pick Blinka size based on the font to minimize unused space in
  title bar. Related to #2791
* Update the title bar after terminal is started. Fixes #6078

Fixes #6668
This commit is contained in:
Scott Shawcroft 2022-08-03 12:13:27 -07:00
parent 577d53dda4
commit 3a2bcbc5c7
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
8 changed files with 222 additions and 167 deletions

View File

@ -863,6 +863,10 @@ msgstr ""
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
#: main.c
msgid "Done"
msgstr ""
#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/digitalio/DigitalInOut.c
msgid "Drive mode not used when direction is input." msgid "Drive mode not used when direction is input."
msgstr "" msgstr ""

32
main.c
View File

@ -204,30 +204,20 @@ STATIC void stop_mp(void) {
gc_deinit(); gc_deinit();
} }
STATIC const char *_last_executing_filename = NULL;
STATIC const char *_current_executing_filename = NULL; STATIC const char *_current_executing_filename = NULL;
STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0}; STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0};
STATIC int _last_return_code = 0;
STATIC int _last_exception_line = 0;
bool supervisor_execution_status_dirty(void) {
return _last_executing_filename != _current_executing_filename ||
_last_return_code != _exec_result.return_code ||
_last_exception_line != _exec_result.exception_line;
}
void supervisor_execution_status(void) { void supervisor_execution_status(void) {
mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception); mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception);
if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 && if (_current_executing_filename != NULL) {
exception != NULL) {
mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name);
} else if (_current_executing_filename != NULL) {
serial_write(_current_executing_filename); serial_write(_current_executing_filename);
} else if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 &&
exception != NULL) {
mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name);
} else {
serial_write_compressed(translate("Done"));
} }
_last_executing_filename = _current_executing_filename;
_last_return_code = _exec_result.return_code;
_last_exception_line = _exec_result.exception_line;
} }
#define STRING_LIST(...) {__VA_ARGS__, ""} #define STRING_LIST(...) {__VA_ARGS__, ""}
@ -254,13 +244,13 @@ STATIC bool maybe_run_list(const char *const *filenames) {
} }
mp_hal_stdout_tx_str(_current_executing_filename); mp_hal_stdout_tx_str(_current_executing_filename);
serial_write_compressed(translate(" output:\n")); serial_write_compressed(translate(" output:\n"));
supervisor_title_bar_request_update(false); supervisor_title_bar_update();
pyexec_file(_current_executing_filename, &_exec_result); pyexec_file(_current_executing_filename, &_exec_result);
#if CIRCUITPY_ATEXIT #if CIRCUITPY_ATEXIT
shared_module_atexit_execute(&_exec_result); shared_module_atexit_execute(&_exec_result);
#endif #endif
_current_executing_filename = "Done"; _current_executing_filename = NULL;
supervisor_title_bar_request_update(false); supervisor_title_bar_update();
return true; return true;
} }
@ -851,7 +841,11 @@ STATIC int run_repl(bool first_run) {
exit_code = pyexec_raw_repl(); exit_code = pyexec_raw_repl();
supervisor_title_bar_resume(); supervisor_title_bar_resume();
} else { } else {
_current_executing_filename = "REPL";
supervisor_title_bar_update();
exit_code = pyexec_friendly_repl(); exit_code = pyexec_friendly_repl();
_current_executing_filename = NULL;
supervisor_title_bar_update();
} }
#if CIRCUITPY_ATEXIT #if CIRCUITPY_ATEXIT
pyexec_result_t result; pyexec_result_t result;

View File

@ -369,7 +369,7 @@ CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL)
CIRCUITPY_STAGE ?= 0 CIRCUITPY_STAGE ?= 0
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)
CIRCUITPY_STATUS_BAR ?= $(CIRCUITPY_WEB_WORKFLOW) CIRCUITPY_STATUS_BAR ?= 1
CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR) CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR)
CIRCUITPY_STORAGE ?= 1 CIRCUITPY_STORAGE ?= 1

View File

@ -34,6 +34,7 @@
#include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/Palette.h"
#include "shared-bindings/displayio/TileGrid.h" #include "shared-bindings/displayio/TileGrid.h"
#include "supervisor/memory.h" #include "supervisor/memory.h"
#include "supervisor/shared/title_bar.h"
#if CIRCUITPY_RGBMATRIX #if CIRCUITPY_RGBMATRIX
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
@ -65,7 +66,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid; displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid;
bool reset_tiles = false; bool reset_tiles = false;
uint16_t width_in_tiles = width_px / scroll_area->tile_width; uint16_t width_in_tiles = width_px / scroll_area->tile_width;
// determine scale based on h // determine scale based on width
if (width_in_tiles < 80) { if (width_in_tiles < 80) {
scale = 1; scale = 1;
} }
@ -103,9 +104,9 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr; uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr;
#if CIRCUITPY_REPL_LOGO #if CIRCUITPY_REPL_LOGO
title_bar->x = blinka_bitmap.width; title_bar->x = supervisor_blinka_sprite.pixel_width + 1;
// Align the title bar to the bottom of the logo. // Align the title bar to the bottom of the logo.
title_bar->y = blinka_bitmap.height - title_bar->tile_height; title_bar->y = supervisor_blinka_sprite.pixel_height - title_bar->tile_height;
#else #else
title_bar->x = 0; title_bar->x = 0;
title_bar->y = 0; title_bar->y = 0;
@ -120,11 +121,6 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
title_bar->full_change = true; title_bar->full_change = true;
scroll_area->x = 0; scroll_area->x = 0;
#if CIRCUITPY_REPL_LOGO
scroll_area->y = blinka_bitmap.height;
#else
scroll_area->y = scroll_area->tile_height;
#endif
scroll_area->top_left_y = 0; scroll_area->top_left_y = 0;
scroll_area->width_in_tiles = width_in_tiles; scroll_area->width_in_tiles = width_in_tiles;
scroll_area->height_in_tiles = height_in_tiles - 1; scroll_area->height_in_tiles = height_in_tiles - 1;
@ -132,10 +128,21 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
assert(height_in_tiles > 1); assert(height_in_tiles > 1);
scroll_area->pixel_width = width_in_tiles * scroll_area->tile_width; scroll_area->pixel_width = width_in_tiles * scroll_area->tile_width;
scroll_area->pixel_height = (height_in_tiles - 1) * scroll_area->tile_height; scroll_area->pixel_height = (height_in_tiles - 1) * scroll_area->tile_height;
#if CIRCUITPY_REPL_LOGO
scroll_area->y = blinka_bitmap.height;
#else
scroll_area->y = title_bar->tile_height;
#endif
int16_t extra_height = (scroll_area->pixel_height + scroll_area->y) - height_px;
// Subtract extra height so that the bottom line fully shows. The top line will be under the
// title bar and Blinka logo.
scroll_area->y -= extra_height;
scroll_area->tiles = tiles + width_in_tiles; scroll_area->tiles = tiles + width_in_tiles;
scroll_area->full_change = true; scroll_area->full_change = true;
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, title_bar); common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, title_bar);
// Update the title bar since we just cleared the terminal.
supervisor_title_bar_update();
} }
#endif #endif
@ -186,126 +193,9 @@ void supervisor_display_move_memory(void) {
#endif #endif
} }
#if CIRCUITPY_REPL_LOGO
uint32_t blinka_bitmap_data[32] = {
0x00000011, 0x11000000,
0x00000111, 0x53100000,
0x00000111, 0x56110000,
0x00000111, 0x11140000,
0x00000111, 0x20002000,
0x00000011, 0x13000000,
0x00000001, 0x11200000,
0x00000000, 0x11330000,
0x00000000, 0x01122000,
0x00001111, 0x44133000,
0x00032323, 0x24112200,
0x00111114, 0x44113300,
0x00323232, 0x34112200,
0x11111144, 0x44443300,
0x11111111, 0x11144401,
0x23232323, 0x21111110
};
displayio_bitmap_t blinka_bitmap = {
.base = {.type = &displayio_bitmap_type },
.width = 16,
.height = 16,
.data = blinka_bitmap_data,
.stride = 2,
.bits_per_value = 4,
.x_shift = 3,
.x_mask = 0x7,
.bitmask = 0xf,
.read_only = true
};
_displayio_color_t blinka_colors[7] = {
{
.rgb888 = 0x000000,
.rgb565 = 0x0000,
.luma = 0x00,
.chroma = 0,
.transparent = true
},
{
.rgb888 = 0x8428bc,
.rgb565 = 0x8978,
.luma = 0xff, // We cheat the luma here. It is actually 0x60
.hue = 184,
.chroma = 148
},
{
.rgb888 = 0xff89bc,
.rgb565 = 0xFCB8,
.luma = 0xb5,
.hue = 222,
.chroma = 118
},
{
.rgb888 = 0x7beffe,
.rgb565 = 0x869F,
.luma = 0xe0,
.hue = 124,
.chroma = 131
},
{
.rgb888 = 0x51395f,
.rgb565 = 0x5A0D,
.luma = 0x47,
.hue = 185,
.chroma = 38
},
{
.rgb888 = 0xffffff,
.rgb565 = 0xffff,
.luma = 0xff,
.chroma = 0
},
{
.rgb888 = 0x0736a0,
.rgb565 = 0x01f5,
.luma = 0x44,
.hue = 147,
.chroma = 153
},
};
displayio_palette_t blinka_palette = {
.base = {.type = &displayio_palette_type },
.colors = blinka_colors,
.color_count = 7,
.needs_refresh = false
};
displayio_tilegrid_t blinka_sprite = {
.base = {.type = &displayio_tilegrid_type },
.bitmap = &blinka_bitmap,
.pixel_shader = &blinka_palette,
.x = 0,
.y = 0,
.pixel_width = 16,
.pixel_height = 16,
.bitmap_width_in_tiles = 1,
.width_in_tiles = 1,
.height_in_tiles = 1,
.tile_width = 16,
.tile_height = 16,
.top_left_x = 16,
.top_left_y = 16,
.tiles = 0,
.partial_change = false,
.full_change = false,
.hidden = false,
.hidden_by_parent = false,
.moved = false,
.inline_tiles = true,
.in_group = true
};
#endif
#if CIRCUITPY_TERMINALIO #if CIRCUITPY_TERMINALIO
#if CIRCUITPY_REPL_LOGO #if CIRCUITPY_REPL_LOGO
mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, }; mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_blinka_sprite, &supervisor_terminal_title_bar_text_grid, };
mp_obj_list_t splash_children = { mp_obj_list_t splash_children = {
.base = {.type = &mp_type_list }, .base = {.type = &mp_type_list },
.alloc = 3, .alloc = 3,
@ -313,7 +203,7 @@ mp_obj_list_t splash_children = {
.items = members, .items = members,
}; };
#else #else
mp_obj_t members[] = { &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, }; mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_title_bar_text_grid,};
mp_obj_list_t splash_children = { mp_obj_list_t splash_children = {
.base = {.type = &mp_type_list }, .base = {.type = &mp_type_list },
.alloc = 2, .alloc = 2,
@ -323,7 +213,7 @@ mp_obj_list_t splash_children = {
#endif #endif
#else #else
#if CIRCUITPY_REPL_LOGO #if CIRCUITPY_REPL_LOGO
mp_obj_t members[] = { &blinka_sprite }; mp_obj_t members[] = { &supervisor_blinka_sprite };
mp_obj_list_t splash_children = { mp_obj_list_t splash_children = {
.base = {.type = &mp_type_list }, .base = {.type = &mp_type_list },
.alloc = 1, .alloc = 1,

View File

@ -42,6 +42,7 @@
extern const fontio_builtinfont_t supervisor_terminal_font; extern const fontio_builtinfont_t supervisor_terminal_font;
// These will change so they must live in RAM. // These will change so they must live in RAM.
extern displayio_tilegrid_t supervisor_blinka_sprite;
extern displayio_bitmap_t supervisor_terminal_font_bitmap; extern displayio_bitmap_t supervisor_terminal_font_bitmap;
extern displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid; extern displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid;
extern displayio_tilegrid_t supervisor_terminal_title_bar_text_grid; extern displayio_tilegrid_t supervisor_terminal_title_bar_text_grid;

View File

@ -39,6 +39,29 @@ static background_callback_t title_bar_background_cb;
static bool _forced_dirty = false; static bool _forced_dirty = false;
static bool _suspended = false; static bool _suspended = false;
void supervisor_title_bar_update(void) {
#if !CIRCUITPY_STATUS_BAR
return;
#endif
_forced_dirty = false;
// Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code
// doesn't get terminated after two following characters and the value is invalid.
// This is the OSC command to set the title and the icon text. It can be up to 255 characters
// but some may be cut off.
serial_write("\x1b" "]0;");
serial_write("🐍");
#if CIRCUITPY_WEB_WORKFLOW
supervisor_web_workflow_status();
serial_write(" | ");
#endif
supervisor_execution_status();
serial_write(" | ");
serial_write(MICROPY_GIT_TAG);
// Send string terminator
serial_write("\x1b" "\\");
}
static void title_bar_background(void *data) { static void title_bar_background(void *data) {
#if !CIRCUITPY_STATUS_BAR #if !CIRCUITPY_STATUS_BAR
return; return;
@ -52,27 +75,10 @@ static void title_bar_background(void *data) {
dirty = dirty || supervisor_web_workflow_status_dirty(); dirty = dirty || supervisor_web_workflow_status_dirty();
#endif #endif
dirty = dirty || supervisor_execution_status_dirty();
if (!dirty) { if (!dirty) {
return; return;
} }
_forced_dirty = false; supervisor_title_bar_update();
// Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code
// doesn't get terminated after two following characters and the value is invalid.
// This is the OSC command to set the title and the icon text. It can be up to 255 characters
// but some may be cut off.
serial_write("\x1b" "]0;");
serial_write("🐍 ");
#if CIRCUITPY_WEB_WORKFLOW
supervisor_web_workflow_status();
serial_write(" | ");
#endif
supervisor_execution_status();
serial_write(" | ");
serial_write(MICROPY_GIT_TAG);
// Send string terminator
serial_write("\x1b" "\\");
} }
void supervisor_title_bar_start(void) { void supervisor_title_bar_start(void) {

View File

@ -31,8 +31,14 @@
void supervisor_title_bar_start(void); void supervisor_title_bar_start(void);
void supervisor_title_bar_suspend(void); void supervisor_title_bar_suspend(void);
void supervisor_title_bar_resume(void); void supervisor_title_bar_resume(void);
// Update the title bar immediately. Useful from main.c where we know state has changed and the code
// will only be run once.
void supervisor_title_bar_update(void);
// Use this if requesting from the background, as code is executing or if the status may not have
// changed.
void supervisor_title_bar_request_update(bool force_dirty); void supervisor_title_bar_request_update(bool force_dirty);
// Provided by main.c // Provided by main.c
bool supervisor_execution_status_dirty(void);
void supervisor_execution_status(void); void supervisor_execution_status(void);

View File

@ -110,6 +110,160 @@ c_file.write(
""" """
) )
c_file.write(
"""\
#if CIRCUITPY_REPL_LOGO
"""
)
if tile_y == 16:
blinka_size = 16
c_file.write(
"""\
uint32_t blinka_bitmap_data[32] = {
0x00000011, 0x11000000,
0x00000111, 0x53100000,
0x00000111, 0x56110000,
0x00000111, 0x11140000,
0x00000111, 0x20002000,
0x00000011, 0x13000000,
0x00000001, 0x11200000,
0x00000000, 0x11330000,
0x00000000, 0x01122000,
0x00001111, 0x44133000,
0x00032323, 0x24112200,
0x00111114, 0x44113300,
0x00323232, 0x34112200,
0x11111144, 0x44443300,
0x11111111, 0x11144401,
0x23232323, 0x21111110
};
"""
)
else:
blinka_size = 12
c_file.write(
"""\
uint32_t blinka_bitmap_data[28] = {
0x00000111, 0x00000000,
0x00001153, 0x10000000,
0x00001156, 0x11000000,
0x00001111, 0x14000000,
0x00000112, 0x00200000,
0x00000011, 0x30000000,
0x00000011, 0x20000000,
0x00011144, 0x13000000,
0x00232324, 0x12000000,
0x01111444, 0x13000000,
0x32323234, 0x12010000,
0x11111144, 0x44100000
};
"""
)
c_file.write(
"""\
displayio_bitmap_t blinka_bitmap = {{
.base = {{.type = &displayio_bitmap_type }},
.width = {0},
.height = {0},
.data = blinka_bitmap_data,
.stride = 2,
.bits_per_value = 4,
.x_shift = 3,
.x_mask = 0x7,
.bitmask = 0xf,
.read_only = true
}};
_displayio_color_t blinka_colors[7] = {{
{{
.rgb888 = 0x000000,
.rgb565 = 0x0000,
.luma = 0x00,
.chroma = 0,
.transparent = true
}},
{{
.rgb888 = 0x8428bc,
.rgb565 = 0x8978,
.luma = 0xff, // We cheat the luma here. It is actually 0x60
.hue = 184,
.chroma = 148
}},
{{
.rgb888 = 0xff89bc,
.rgb565 = 0xFCB8,
.luma = 0xb5,
.hue = 222,
.chroma = 118
}},
{{
.rgb888 = 0x7beffe,
.rgb565 = 0x869F,
.luma = 0xe0,
.hue = 124,
.chroma = 131
}},
{{
.rgb888 = 0x51395f,
.rgb565 = 0x5A0D,
.luma = 0x47,
.hue = 185,
.chroma = 38
}},
{{
.rgb888 = 0xffffff,
.rgb565 = 0xffff,
.luma = 0xff,
.chroma = 0
}},
{{
.rgb888 = 0x0736a0,
.rgb565 = 0x01f5,
.luma = 0x44,
.hue = 147,
.chroma = 153
}},
}};
displayio_palette_t blinka_palette = {{
.base = {{.type = &displayio_palette_type }},
.colors = blinka_colors,
.color_count = 7,
.needs_refresh = false
}};
displayio_tilegrid_t supervisor_blinka_sprite = {{
.base = {{.type = &displayio_tilegrid_type }},
.bitmap = &blinka_bitmap,
.pixel_shader = &blinka_palette,
.x = 0,
.y = 0,
.pixel_width = {0},
.pixel_height = {0},
.bitmap_width_in_tiles = 1,
.width_in_tiles = 1,
.height_in_tiles = 1,
.tile_width = {0},
.tile_height = {0},
.top_left_x = {0},
.top_left_y = {0},
.tiles = 0,
.partial_change = false,
.full_change = false,
.hidden = false,
.hidden_by_parent = false,
.moved = false,
.inline_tiles = true,
.in_group = true
}};
#endif
""".format(
blinka_size
)
)
c_file.write( c_file.write(
"""\ """\
_displayio_color_t terminal_colors[2] = { _displayio_color_t terminal_colors[2] = {