Skip to content

Commit 3a2bcbc

Browse files
committed
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
1 parent 577d53d commit 3a2bcbc

File tree

8 files changed

+220
-165
lines changed

8 files changed

+220
-165
lines changed

locale/circuitpython.pot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,10 @@ msgstr ""
863863
msgid "Display rotation must be in 90 degree increments"
864864
msgstr ""
865865

866+
#: main.c
867+
msgid "Done"
868+
msgstr ""
869+
866870
#: shared-bindings/digitalio/DigitalInOut.c
867871
msgid "Drive mode not used when direction is input."
868872
msgstr ""

main.c

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -204,30 +204,20 @@ STATIC void stop_mp(void) {
204204
gc_deinit();
205205
}
206206

207-
STATIC const char *_last_executing_filename = NULL;
208207
STATIC const char *_current_executing_filename = NULL;
209208

210209
STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0};
211-
STATIC int _last_return_code = 0;
212-
STATIC int _last_exception_line = 0;
213-
214-
bool supervisor_execution_status_dirty(void) {
215-
return _last_executing_filename != _current_executing_filename ||
216-
_last_return_code != _exec_result.return_code ||
217-
_last_exception_line != _exec_result.exception_line;
218-
}
219210

220211
void supervisor_execution_status(void) {
221212
mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception);
222-
if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 &&
223-
exception != NULL) {
224-
mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name);
225-
} else if (_current_executing_filename != NULL) {
213+
if (_current_executing_filename != NULL) {
226214
serial_write(_current_executing_filename);
215+
} else if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 &&
216+
exception != NULL) {
217+
mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name);
218+
} else {
219+
serial_write_compressed(translate("Done"));
227220
}
228-
_last_executing_filename = _current_executing_filename;
229-
_last_return_code = _exec_result.return_code;
230-
_last_exception_line = _exec_result.exception_line;
231221
}
232222

233223
#define STRING_LIST(...) {__VA_ARGS__, ""}
@@ -254,13 +244,13 @@ STATIC bool maybe_run_list(const char *const *filenames) {
254244
}
255245
mp_hal_stdout_tx_str(_current_executing_filename);
256246
serial_write_compressed(translate(" output:\n"));
257-
supervisor_title_bar_request_update(false);
247+
supervisor_title_bar_update();
258248
pyexec_file(_current_executing_filename, &_exec_result);
259249
#if CIRCUITPY_ATEXIT
260250
shared_module_atexit_execute(&_exec_result);
261251
#endif
262-
_current_executing_filename = "Done";
263-
supervisor_title_bar_request_update(false);
252+
_current_executing_filename = NULL;
253+
supervisor_title_bar_update();
264254
return true;
265255
}
266256

@@ -851,7 +841,11 @@ STATIC int run_repl(bool first_run) {
851841
exit_code = pyexec_raw_repl();
852842
supervisor_title_bar_resume();
853843
} else {
844+
_current_executing_filename = "REPL";
845+
supervisor_title_bar_update();
854846
exit_code = pyexec_friendly_repl();
847+
_current_executing_filename = NULL;
848+
supervisor_title_bar_update();
855849
}
856850
#if CIRCUITPY_ATEXIT
857851
pyexec_result_t result;

py/circuitpy_mpconfig.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL)
369369
CIRCUITPY_STAGE ?= 0
370370
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)
371371

372-
CIRCUITPY_STATUS_BAR ?= $(CIRCUITPY_WEB_WORKFLOW)
372+
CIRCUITPY_STATUS_BAR ?= 1
373373
CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR)
374374

375375
CIRCUITPY_STORAGE ?= 1

supervisor/shared/display.c

Lines changed: 18 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "shared-bindings/displayio/Palette.h"
3535
#include "shared-bindings/displayio/TileGrid.h"
3636
#include "supervisor/memory.h"
37+
#include "supervisor/shared/title_bar.h"
3738

3839
#if CIRCUITPY_RGBMATRIX
3940
#include "shared-module/displayio/__init__.h"
@@ -65,7 +66,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
6566
displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid;
6667
bool reset_tiles = false;
6768
uint16_t width_in_tiles = width_px / scroll_area->tile_width;
68-
// determine scale based on h
69+
// determine scale based on width
6970
if (width_in_tiles < 80) {
7071
scale = 1;
7172
}
@@ -103,9 +104,9 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
103104
uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr;
104105

105106
#if CIRCUITPY_REPL_LOGO
106-
title_bar->x = blinka_bitmap.width;
107+
title_bar->x = supervisor_blinka_sprite.pixel_width + 1;
107108
// Align the title bar to the bottom of the logo.
108-
title_bar->y = blinka_bitmap.height - title_bar->tile_height;
109+
title_bar->y = supervisor_blinka_sprite.pixel_height - title_bar->tile_height;
109110
#else
110111
title_bar->x = 0;
111112
title_bar->y = 0;
@@ -120,22 +121,28 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
120121
title_bar->full_change = true;
121122

122123
scroll_area->x = 0;
123-
#if CIRCUITPY_REPL_LOGO
124-
scroll_area->y = blinka_bitmap.height;
125-
#else
126-
scroll_area->y = scroll_area->tile_height;
127-
#endif
128124
scroll_area->top_left_y = 0;
129125
scroll_area->width_in_tiles = width_in_tiles;
130126
scroll_area->height_in_tiles = height_in_tiles - 1;
131127
assert(width_in_tiles > 0);
132128
assert(height_in_tiles > 1);
133129
scroll_area->pixel_width = width_in_tiles * scroll_area->tile_width;
134130
scroll_area->pixel_height = (height_in_tiles - 1) * scroll_area->tile_height;
131+
#if CIRCUITPY_REPL_LOGO
132+
scroll_area->y = blinka_bitmap.height;
133+
#else
134+
scroll_area->y = title_bar->tile_height;
135+
#endif
136+
int16_t extra_height = (scroll_area->pixel_height + scroll_area->y) - height_px;
137+
// Subtract extra height so that the bottom line fully shows. The top line will be under the
138+
// title bar and Blinka logo.
139+
scroll_area->y -= extra_height;
135140
scroll_area->tiles = tiles + width_in_tiles;
136141
scroll_area->full_change = true;
137142

138143
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, title_bar);
144+
// Update the title bar since we just cleared the terminal.
145+
supervisor_title_bar_update();
139146
}
140147
#endif
141148

@@ -186,134 +193,17 @@ void supervisor_display_move_memory(void) {
186193
#endif
187194
}
188195

189-
#if CIRCUITPY_REPL_LOGO
190-
uint32_t blinka_bitmap_data[32] = {
191-
0x00000011, 0x11000000,
192-
0x00000111, 0x53100000,
193-
0x00000111, 0x56110000,
194-
0x00000111, 0x11140000,
195-
0x00000111, 0x20002000,
196-
0x00000011, 0x13000000,
197-
0x00000001, 0x11200000,
198-
0x00000000, 0x11330000,
199-
0x00000000, 0x01122000,
200-
0x00001111, 0x44133000,
201-
0x00032323, 0x24112200,
202-
0x00111114, 0x44113300,
203-
0x00323232, 0x34112200,
204-
0x11111144, 0x44443300,
205-
0x11111111, 0x11144401,
206-
0x23232323, 0x21111110
207-
};
208-
209-
displayio_bitmap_t blinka_bitmap = {
210-
.base = {.type = &displayio_bitmap_type },
211-
.width = 16,
212-
.height = 16,
213-
.data = blinka_bitmap_data,
214-
.stride = 2,
215-
.bits_per_value = 4,
216-
.x_shift = 3,
217-
.x_mask = 0x7,
218-
.bitmask = 0xf,
219-
.read_only = true
220-
};
221-
222-
_displayio_color_t blinka_colors[7] = {
223-
{
224-
.rgb888 = 0x000000,
225-
.rgb565 = 0x0000,
226-
.luma = 0x00,
227-
.chroma = 0,
228-
.transparent = true
229-
},
230-
{
231-
.rgb888 = 0x8428bc,
232-
.rgb565 = 0x8978,
233-
.luma = 0xff, // We cheat the luma here. It is actually 0x60
234-
.hue = 184,
235-
.chroma = 148
236-
},
237-
{
238-
.rgb888 = 0xff89bc,
239-
.rgb565 = 0xFCB8,
240-
.luma = 0xb5,
241-
.hue = 222,
242-
.chroma = 118
243-
},
244-
{
245-
.rgb888 = 0x7beffe,
246-
.rgb565 = 0x869F,
247-
.luma = 0xe0,
248-
.hue = 124,
249-
.chroma = 131
250-
},
251-
{
252-
.rgb888 = 0x51395f,
253-
.rgb565 = 0x5A0D,
254-
.luma = 0x47,
255-
.hue = 185,
256-
.chroma = 38
257-
},
258-
{
259-
.rgb888 = 0xffffff,
260-
.rgb565 = 0xffff,
261-
.luma = 0xff,
262-
.chroma = 0
263-
},
264-
{
265-
.rgb888 = 0x0736a0,
266-
.rgb565 = 0x01f5,
267-
.luma = 0x44,
268-
.hue = 147,
269-
.chroma = 153
270-
},
271-
};
272-
273-
displayio_palette_t blinka_palette = {
274-
.base = {.type = &displayio_palette_type },
275-
.colors = blinka_colors,
276-
.color_count = 7,
277-
.needs_refresh = false
278-
};
279-
280-
displayio_tilegrid_t blinka_sprite = {
281-
.base = {.type = &displayio_tilegrid_type },
282-
.bitmap = &blinka_bitmap,
283-
.pixel_shader = &blinka_palette,
284-
.x = 0,
285-
.y = 0,
286-
.pixel_width = 16,
287-
.pixel_height = 16,
288-
.bitmap_width_in_tiles = 1,
289-
.width_in_tiles = 1,
290-
.height_in_tiles = 1,
291-
.tile_width = 16,
292-
.tile_height = 16,
293-
.top_left_x = 16,
294-
.top_left_y = 16,
295-
.tiles = 0,
296-
.partial_change = false,
297-
.full_change = false,
298-
.hidden = false,
299-
.hidden_by_parent = false,
300-
.moved = false,
301-
.inline_tiles = true,
302-
.in_group = true
303-
};
304-
#endif
305-
306196
#if CIRCUITPY_TERMINALIO
307197
#if CIRCUITPY_REPL_LOGO
308-
mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, };
198+
mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_blinka_sprite, &supervisor_terminal_title_bar_text_grid, };
309199
mp_obj_list_t splash_children = {
310200
.base = {.type = &mp_type_list },
311201
.alloc = 3,
312202
.len = 3,
313203
.items = members,
314204
};
315205
#else
316-
mp_obj_t members[] = { &supervisor_terminal_title_bar_text_grid, &supervisor_terminal_scroll_area_text_grid, };
206+
mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_title_bar_text_grid,};
317207
mp_obj_list_t splash_children = {
318208
.base = {.type = &mp_type_list },
319209
.alloc = 2,
@@ -323,7 +213,7 @@ mp_obj_list_t splash_children = {
323213
#endif
324214
#else
325215
#if CIRCUITPY_REPL_LOGO
326-
mp_obj_t members[] = { &blinka_sprite };
216+
mp_obj_t members[] = { &supervisor_blinka_sprite };
327217
mp_obj_list_t splash_children = {
328218
.base = {.type = &mp_type_list },
329219
.alloc = 1,

supervisor/shared/display.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
extern const fontio_builtinfont_t supervisor_terminal_font;
4343

4444
// These will change so they must live in RAM.
45+
extern displayio_tilegrid_t supervisor_blinka_sprite;
4546
extern displayio_bitmap_t supervisor_terminal_font_bitmap;
4647
extern displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid;
4748
extern displayio_tilegrid_t supervisor_terminal_title_bar_text_grid;

supervisor/shared/title_bar.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,31 +39,18 @@ static background_callback_t title_bar_background_cb;
3939
static bool _forced_dirty = false;
4040
static bool _suspended = false;
4141

42-
static void title_bar_background(void *data) {
42+
43+
void supervisor_title_bar_update(void) {
4344
#if !CIRCUITPY_STATUS_BAR
4445
return;
4546
#endif
46-
if (_suspended) {
47-
return;
48-
}
49-
bool dirty = _forced_dirty;
50-
51-
#if CIRCUITPY_WEB_WORKFLOW
52-
dirty = dirty || supervisor_web_workflow_status_dirty();
53-
#endif
54-
55-
dirty = dirty || supervisor_execution_status_dirty();
56-
57-
if (!dirty) {
58-
return;
59-
}
6047
_forced_dirty = false;
6148
// Neighboring "" "" are concatenated by the compiler. Without this separation, the hex code
6249
// doesn't get terminated after two following characters and the value is invalid.
6350
// This is the OSC command to set the title and the icon text. It can be up to 255 characters
6451
// but some may be cut off.
6552
serial_write("\x1b" "]0;");
66-
serial_write("🐍 ");
53+
serial_write("🐍");
6754
#if CIRCUITPY_WEB_WORKFLOW
6855
supervisor_web_workflow_status();
6956
serial_write(" | ");
@@ -75,6 +62,25 @@ static void title_bar_background(void *data) {
7562
serial_write("\x1b" "\\");
7663
}
7764

65+
static void title_bar_background(void *data) {
66+
#if !CIRCUITPY_STATUS_BAR
67+
return;
68+
#endif
69+
if (_suspended) {
70+
return;
71+
}
72+
bool dirty = _forced_dirty;
73+
74+
#if CIRCUITPY_WEB_WORKFLOW
75+
dirty = dirty || supervisor_web_workflow_status_dirty();
76+
#endif
77+
78+
if (!dirty) {
79+
return;
80+
}
81+
supervisor_title_bar_update();
82+
}
83+
7884
void supervisor_title_bar_start(void) {
7985
#if !CIRCUITPY_STATUS_BAR
8086
return;

supervisor/shared/title_bar.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,14 @@
3131
void supervisor_title_bar_start(void);
3232
void supervisor_title_bar_suspend(void);
3333
void supervisor_title_bar_resume(void);
34+
35+
// Update the title bar immediately. Useful from main.c where we know state has changed and the code
36+
// will only be run once.
37+
void supervisor_title_bar_update(void);
38+
39+
// Use this if requesting from the background, as code is executing or if the status may not have
40+
// changed.
3441
void supervisor_title_bar_request_update(bool force_dirty);
3542

3643
// Provided by main.c
37-
bool supervisor_execution_status_dirty(void);
3844
void supervisor_execution_status(void);

0 commit comments

Comments
 (0)