status bar control
This commit is contained in:
parent
aa5f892a11
commit
52080e24eb
52
main.c
52
main.c
@ -57,7 +57,6 @@
|
||||
#include "supervisor/shared/stack.h"
|
||||
#include "supervisor/shared/status_leds.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
#include "supervisor/shared/traceback.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
#include "supervisor/shared/workflow.h"
|
||||
@ -106,6 +105,10 @@
|
||||
#include "shared-bindings/socketpool/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
#include "shared-module/usb_hid/__init__.h"
|
||||
#endif
|
||||
@ -208,6 +211,7 @@ STATIC const char *_current_executing_filename = NULL;
|
||||
|
||||
STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0};
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
void supervisor_execution_status(void) {
|
||||
mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception);
|
||||
if (_current_executing_filename != NULL) {
|
||||
@ -220,6 +224,7 @@ void supervisor_execution_status(void) {
|
||||
serial_write_compressed(translate("Done"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define STRING_LIST(...) {__VA_ARGS__, ""}
|
||||
|
||||
@ -245,13 +250,23 @@ STATIC bool maybe_run_list(const char *const *filenames) {
|
||||
}
|
||||
mp_hal_stdout_tx_str(_current_executing_filename);
|
||||
serial_write_compressed(translate(" output:\n"));
|
||||
supervisor_title_bar_update();
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_update();
|
||||
#endif
|
||||
|
||||
pyexec_file(_current_executing_filename, &_exec_result);
|
||||
|
||||
#if CIRCUITPY_ATEXIT
|
||||
shared_module_atexit_execute(&_exec_result);
|
||||
#endif
|
||||
|
||||
_current_executing_filename = NULL;
|
||||
supervisor_title_bar_update();
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_update();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -749,8 +764,10 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
|
||||
if (ok_to_run) {
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
// Turn off title bar updates when writing out to boot_out.txt.
|
||||
supervisor_title_bar_suspend();
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// Turn off status bar updates when writing out to boot_out.txt.
|
||||
supervisor_status_bar_suspend();
|
||||
#endif
|
||||
vstr_t boot_text;
|
||||
vstr_init(&boot_text, 512);
|
||||
boot_output = &boot_text;
|
||||
@ -778,7 +795,9 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
FATFS *fs = &vfs->fatfs;
|
||||
|
||||
boot_output = NULL;
|
||||
supervisor_title_bar_resume();
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_resume();
|
||||
#endif
|
||||
bool write_boot_output = true;
|
||||
FIL boot_output_file;
|
||||
if (f_open(fs, &boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) {
|
||||
@ -854,15 +873,23 @@ STATIC int run_repl(bool first_run) {
|
||||
status_led_deinit();
|
||||
#endif
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
supervisor_title_bar_suspend();
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_suspend();
|
||||
#endif
|
||||
exit_code = pyexec_raw_repl();
|
||||
supervisor_title_bar_resume();
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_resume();
|
||||
#endif
|
||||
} else {
|
||||
_current_executing_filename = "REPL";
|
||||
supervisor_title_bar_update();
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_update();
|
||||
#endif
|
||||
exit_code = pyexec_friendly_repl();
|
||||
_current_executing_filename = NULL;
|
||||
supervisor_title_bar_update();
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_update();
|
||||
#endif
|
||||
}
|
||||
#if CIRCUITPY_ATEXIT
|
||||
pyexec_result_t result;
|
||||
@ -959,7 +986,10 @@ int __attribute__((used)) main(void) {
|
||||
run_boot_py(safe_mode);
|
||||
|
||||
supervisor_workflow_start();
|
||||
supervisor_title_bar_start();
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_start();
|
||||
#endif
|
||||
|
||||
// Boot script is finished, so now go into REPL or run code.py.
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
|
@ -44,9 +44,12 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
|
||||
#include "components/log/include/esp_log.h"
|
||||
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
#include "supervisor/workflow.h"
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
#endif
|
||||
|
||||
#include "esp_ipc.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
@ -56,7 +59,9 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
|
||||
static const char *TAG = "CP wifi";
|
||||
|
||||
STATIC void schedule_background_on_cp_core(void *arg) {
|
||||
supervisor_title_bar_request_update(false);
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_request_update(false);
|
||||
#endif
|
||||
|
||||
// CircuitPython's VM is run in a separate FreeRTOS task from wifi callbacks. So, we have to
|
||||
// notify the main task every time in case it's waiting for us.
|
||||
|
@ -101,6 +101,7 @@ endif
|
||||
|
||||
###
|
||||
# Select which builtin modules to compile and include.
|
||||
# Keep alphabetical.
|
||||
|
||||
ifeq ($(CIRCUITPY_AESIO),1)
|
||||
SRC_PATTERNS += aesio/%
|
||||
@ -175,11 +176,8 @@ endif
|
||||
ifeq ($(CIRCUITPY_DOTENV),1)
|
||||
SRC_PATTERNS += dotenv/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_PARALLELDISPLAY),1)
|
||||
SRC_PATTERNS += paralleldisplay/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_VECTORIO),1)
|
||||
SRC_PATTERNS += vectorio/%
|
||||
ifeq ($(CIRCUITPY__EVE),1)
|
||||
SRC_PATTERNS += _eve/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_FLOPPYIO),1)
|
||||
SRC_PATTERNS += floppyio/%
|
||||
@ -187,17 +185,12 @@ endif
|
||||
ifeq ($(CIRCUITPY_FRAMEBUFFERIO),1)
|
||||
SRC_PATTERNS += framebufferio/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY__EVE),1)
|
||||
SRC_PATTERNS += _eve/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_FREQUENCYIO),1)
|
||||
SRC_PATTERNS += frequencyio/%
|
||||
endif
|
||||
|
||||
ifeq ($(CIRCUITPY_FUTURE),1)
|
||||
SRC_PATTERNS += __future__/%
|
||||
endif
|
||||
|
||||
ifeq ($(CIRCUITPY_GETPASS),1)
|
||||
SRC_PATTERNS += getpass/%
|
||||
endif
|
||||
@ -237,6 +230,9 @@ endif
|
||||
ifeq ($(CIRCUITPY_MDNS),1)
|
||||
SRC_PATTERNS += mdns/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_MSGPACK),1)
|
||||
SRC_PATTERNS += msgpack/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_NEOPIXEL_WRITE),1)
|
||||
SRC_PATTERNS += neopixel_write/%
|
||||
endif
|
||||
@ -252,6 +248,12 @@ endif
|
||||
ifeq ($(CIRCUITPY_DUALBANK),1)
|
||||
SRC_PATTERNS += dualbank/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_PARALLELDISPLAY),1)
|
||||
SRC_PATTERNS += paralleldisplay/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_PEW),1)
|
||||
SRC_PATTERNS += _pew/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_PIXELBUF),1)
|
||||
SRC_PATTERNS += adafruit_pixelbuf/%
|
||||
endif
|
||||
@ -351,8 +353,8 @@ endif
|
||||
ifeq ($(CIRCUITPY_USTACK),1)
|
||||
SRC_PATTERNS += ustack/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_ZLIB),1)
|
||||
SRC_PATTERNS += zlib/%
|
||||
ifeq ($(CIRCUITPY_VECTORIO),1)
|
||||
SRC_PATTERNS += vectorio/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_VIDEOCORE),1)
|
||||
SRC_PATTERNS += videocore/%
|
||||
@ -363,11 +365,8 @@ endif
|
||||
ifeq ($(CIRCUITPY_WIFI),1)
|
||||
SRC_PATTERNS += wifi/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_PEW),1)
|
||||
SRC_PATTERNS += _pew/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_MSGPACK),1)
|
||||
SRC_PATTERNS += msgpack/%
|
||||
ifeq ($(CIRCUITPY_ZLIB),1)
|
||||
SRC_PATTERNS += zlib/%
|
||||
endif
|
||||
|
||||
# All possible sources are listed here, and are filtered by SRC_PATTERNS in SRC_COMMON_HAL
|
||||
@ -511,6 +510,7 @@ $(filter $(SRC_PATTERNS), \
|
||||
qrio/PixelPolicy.c \
|
||||
qrio/QRInfo.c \
|
||||
supervisor/RunReason.c \
|
||||
supervisor/StatusBar.c \
|
||||
wifi/AuthMode.c \
|
||||
wifi/Packet.c \
|
||||
)
|
||||
@ -611,6 +611,8 @@ SRC_SHARED_MODULE_ALL = \
|
||||
socket/__init__.c \
|
||||
storage/__init__.c \
|
||||
struct/__init__.c \
|
||||
supervisor/__init__.c \
|
||||
supervisor/StatusBar.c \
|
||||
synthio/MidiTrack.c \
|
||||
synthio/__init__.c \
|
||||
terminalio/Terminal.c \
|
||||
|
126
shared-bindings/supervisor/StatusBar.c
Normal file
126
shared-bindings/supervisor/StatusBar.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 by Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/enum.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
|
||||
//| class StatusBar:
|
||||
//| """Current status of runtime objects.
|
||||
//|
|
||||
//| Usage::
|
||||
//|
|
||||
//| import supervisor
|
||||
//|
|
||||
//| supervisor.status_bar.console = False
|
||||
//| """
|
||||
//|
|
||||
|
||||
//| def __init__(self) -> None:
|
||||
//| """You cannot create an instance of `supervisor.StatusBar`.
|
||||
//| Use `supervisor.status_bar` to access the sole instance available."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
//| console: bool
|
||||
//| """Whether status bar information is sent over the console (REPL) serial connection,
|
||||
//| using OSC terminal escape codes that change the terminal's title. Default is ``True``.
|
||||
//| If set to ``False``, status bar will be cleared and then disabled.
|
||||
//| May be set in ``boot.py`` or later.
|
||||
//| """
|
||||
//|
|
||||
STATIC mp_obj_t supervisor_status_bar_get_console(mp_obj_t self_in) {
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(shared_module_supervisor_status_bar_get_console(self));
|
||||
#else
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
#endif
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(supervisor_status_bar_get_console_obj, supervisor_status_bar_get_console);
|
||||
|
||||
STATIC mp_obj_t supervisor_status_bar_set_console(mp_obj_t self_in, mp_obj_t state_in) {
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
shared_module_supervisor_status_bar_set_console(self, mp_obj_is_true(state_in));
|
||||
return mp_const_none;
|
||||
#else
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
#endif
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(supervisor_status_bar_set_console_obj, supervisor_status_bar_set_console);
|
||||
|
||||
MP_PROPERTY_GETSET(supervisor_status_bar_console_obj,
|
||||
(mp_obj_t)&supervisor_status_bar_get_console_obj,
|
||||
(mp_obj_t)&supervisor_status_bar_set_console_obj);
|
||||
|
||||
//| display: bool
|
||||
//| """Whether status bar information is displayed on the top line of the display.
|
||||
//| Default is ``True``. If set to ``False``, status bar will be cleared and then disabled.
|
||||
//| May be set in ``boot.py`` or later. Not available if `terminalio` is not available.
|
||||
//| """
|
||||
//|
|
||||
STATIC mp_obj_t supervisor_status_bar_get_display(mp_obj_t self_in) {
|
||||
#if CIRCUITPY_STATUS_BAR && CIRCUITPY_TERMINALIO
|
||||
supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(shared_module_supervisor_status_bar_get_display(self));
|
||||
#else
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
#endif
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(supervisor_status_bar_get_display_obj, supervisor_status_bar_get_display);
|
||||
|
||||
STATIC mp_obj_t supervisor_status_bar_set_display(mp_obj_t self_in, mp_obj_t state_in) {
|
||||
#if CIRCUITPY_STATUS_BAR && CIRCUITPY_TERMINALIO
|
||||
supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
shared_module_supervisor_status_bar_set_display(self, mp_obj_is_true(state_in));
|
||||
return mp_const_none;
|
||||
#else
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
#endif
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(supervisor_status_bar_set_display_obj, supervisor_status_bar_set_display);
|
||||
|
||||
MP_PROPERTY_GETSET(supervisor_status_bar_display_obj,
|
||||
(mp_obj_t)&supervisor_status_bar_get_display_obj,
|
||||
(mp_obj_t)&supervisor_status_bar_set_display_obj);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t supervisor_status_bar_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_console), MP_ROM_PTR(&supervisor_status_bar_console_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_display), MP_ROM_PTR(&supervisor_status_bar_display_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(supervisor_status_bar_locals_dict, supervisor_status_bar_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t supervisor_status_bar_type = {
|
||||
.base = { &mp_type_type },
|
||||
.name = MP_QSTR_Status_Bar,
|
||||
.locals_dict = (mp_obj_dict_t *)&supervisor_status_bar_locals_dict,
|
||||
};
|
42
shared-bindings/supervisor/StatusBar.h
Normal file
42
shared-bindings/supervisor/StatusBar.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 by Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_STATUS_BAR_STATUS_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_STATUS_BAR_STATUS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "py/obj.h"
|
||||
#include "shared-module/supervisor/StatusBar.h"
|
||||
|
||||
extern const mp_obj_type_t supervisor_status_bar_type;
|
||||
|
||||
bool shared_module_supervisor_status_bar_get_console(supervisor_status_bar_obj_t *self);
|
||||
void shared_module_supervisor_status_bar_set_console(supervisor_status_bar_obj_t *self, bool enabled);
|
||||
|
||||
bool shared_module_supervisor_status_bar_get_display(supervisor_status_bar_obj_t *self);
|
||||
void shared_module_supervisor_status_bar_set_display(supervisor_status_bar_obj_t *self, bool enabled);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR_STATUS_BAR_H
|
@ -43,6 +43,7 @@
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
#include "shared-bindings/supervisor/Runtime.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
|
||||
//| """Supervisor settings"""
|
||||
//|
|
||||
@ -53,6 +54,14 @@
|
||||
//| This object is the sole instance of `supervisor.Runtime`."""
|
||||
//|
|
||||
|
||||
//| status_bar: StatusBar
|
||||
//| """The status bar, shown on an attached display, and also sent to
|
||||
//| an attached terminal via OSC escape codes over the REPL serial connection.
|
||||
//| The status bar reports the current IP or BLE connection, what file is running,
|
||||
//| the last exception name and location, and firmware version information.
|
||||
//| This object is the sole instance of `supervisor.StatusBar`."""
|
||||
//|
|
||||
|
||||
//| def set_rgb_status_brightness(brightness: int) -> None:
|
||||
//| """Set brightness of status RGB LED from 0-255. This will take effect
|
||||
//| after the current code finishes and the status LED is used to show
|
||||
@ -301,6 +310,7 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_previous_traceback), MP_ROM_PTR(&supervisor_get_previous_traceback_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_disable_ble_workflow), MP_ROM_PTR(&supervisor_disable_ble_workflow_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset_terminal), MP_ROM_PTR(&supervisor_reset_terminal_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_status_bar), MP_ROM_PTR(&shared_module_supervisor_status_bar_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(supervisor_module_globals, supervisor_module_globals_table);
|
||||
|
@ -31,8 +31,10 @@
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "common-hal/supervisor/Runtime.h"
|
||||
#include "shared-module/supervisor/StatusBar.h"
|
||||
|
||||
extern const super_runtime_obj_t common_hal_supervisor_runtime_obj;
|
||||
extern supervisor_status_bar_obj_t shared_module_supervisor_status_bar_obj;
|
||||
extern mp_obj_t supervisor_ticks_ms(void);
|
||||
|
||||
|
||||
|
@ -56,26 +56,26 @@
|
||||
//| * ``ESC [ nnnn ; mmmm H`` - Move the cursor to mmmm, nnnn.
|
||||
//| """
|
||||
//|
|
||||
//| def __init__(self, scroll_area: displayio.TileGrid, font: fontio.BuiltinFont, *, title_bar: displayio.TileGrid = None) -> None:
|
||||
//| def __init__(self, scroll_area: displayio.TileGrid, font: fontio.BuiltinFont, *, status_bar: displayio.TileGrid = None) -> None:
|
||||
//| """Terminal manages tile indices and cursor position based on VT100 commands. The font should be
|
||||
//| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_scroll_area, ARG_font, ARG_title_bar };
|
||||
enum { ARG_scroll_area, ARG_font, ARG_status_bar };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_scroll_area, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_font, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_title_bar, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
{ MP_QSTR_status_bar, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
displayio_tilegrid_t *scroll_area = mp_arg_validate_type(args[ARG_scroll_area].u_obj, &displayio_tilegrid_type, MP_QSTR_scroll_area);
|
||||
displayio_tilegrid_t *title_bar = NULL;
|
||||
if (args[ARG_title_bar].u_obj != mp_const_none) {
|
||||
title_bar = mp_arg_validate_type(args[ARG_title_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_title_bar);
|
||||
displayio_tilegrid_t *status_bar = NULL;
|
||||
if (args[ARG_status_bar].u_obj != mp_const_none) {
|
||||
status_bar = mp_arg_validate_type(args[ARG_status_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_status_bar);
|
||||
}
|
||||
|
||||
fontio_builtinfont_t *font = mp_arg_validate_type(args[ARG_font].u_obj, &fontio_builtinfont_type, MP_QSTR_font);
|
||||
@ -83,7 +83,7 @@ STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n
|
||||
terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t);
|
||||
self->base.type = &terminalio_terminal_type;
|
||||
|
||||
common_hal_terminalio_terminal_construct(self, scroll_area, font, title_bar);
|
||||
common_hal_terminalio_terminal_construct(self, scroll_area, font, status_bar);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
extern const mp_obj_type_t terminalio_terminal_type;
|
||||
|
||||
extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *title_bar);
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *status_bar);
|
||||
|
||||
// Write characters. len is in characters NOT bytes!
|
||||
extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self,
|
||||
|
74
shared-module/supervisor/StatusBar.c
Normal file
74
shared-module/supervisor/StatusBar.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "py/obj.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#include "supervisor/shared/display.h"
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
#include "shared-module/terminalio/Terminal.h"
|
||||
#endif
|
||||
|
||||
bool shared_module_supervisor_status_bar_get_console(supervisor_status_bar_obj_t *self) {
|
||||
return self->console;
|
||||
}
|
||||
|
||||
void shared_module_supervisor_status_bar_set_console(supervisor_status_bar_obj_t *self, bool enabled) {
|
||||
// Clear before changing state. If disabling, will remain cleared.
|
||||
supervisor_status_bar_clear();
|
||||
|
||||
self->console = enabled;
|
||||
|
||||
// Update may be ignored.
|
||||
supervisor_status_bar_update();
|
||||
}
|
||||
|
||||
bool shared_module_supervisor_status_bar_get_display(supervisor_status_bar_obj_t *self) {
|
||||
return self->display;
|
||||
}
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
void shared_module_supervisor_status_bar_set_display(supervisor_status_bar_obj_t *self, bool enabled) {
|
||||
terminalio_terminal_clear_status_bar(&supervisor_terminal);
|
||||
// Clear before changing state. If disabling, will remain cleared.
|
||||
|
||||
self->display = enabled;
|
||||
|
||||
// Update may be ignored.
|
||||
supervisor_status_bar_update();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool supervisor_status_bar_get_update_in_progress(supervisor_status_bar_obj_t *self) {
|
||||
return self->update_in_progress;
|
||||
}
|
||||
|
||||
void supervisor_status_bar_set_update_in_progress(supervisor_status_bar_obj_t *self, bool update_in_progress) {
|
||||
self->update_in_progress = update_in_progress;
|
||||
}
|
42
shared-module/supervisor/StatusBar.h
Normal file
42
shared-module/supervisor/StatusBar.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_MODULE_SUPERVISOR_STATUS_BAR_H
|
||||
#define MICROPY_INCLUDED_SHARED_MODULE_SUPERVISOR_STATUS_BAR_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
bool console;
|
||||
bool display;
|
||||
bool update_in_progress;
|
||||
} supervisor_status_bar_obj_t;
|
||||
|
||||
extern bool supervisor_status_bar_get_update_in_progress(supervisor_status_bar_obj_t *self);
|
||||
extern void supervisor_status_bar_set_update_in_progress(supervisor_status_bar_obj_t *self, bool in_progress);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_MODULE_SUPERVISOR_STATUS_BAR_H
|
39
shared-module/supervisor/__init__.c
Normal file
39
shared-module/supervisor/__init__.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "py/obj.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
|
||||
// The singleton supervisor.StatusBar object, bound to supervisor.status_bar
|
||||
supervisor_status_bar_obj_t shared_module_supervisor_status_bar_obj = {
|
||||
.base = {
|
||||
.type = &supervisor_status_bar_type,
|
||||
},
|
||||
.console = true,
|
||||
.display = true,
|
||||
};
|
@ -30,20 +30,31 @@
|
||||
#include "shared-bindings/displayio/TileGrid.h"
|
||||
#include "shared-bindings/terminalio/Terminal.h"
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
#endif
|
||||
|
||||
void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self) {
|
||||
if (self->status_bar) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
|
||||
displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font,
|
||||
displayio_tilegrid_t *title_bar) {
|
||||
displayio_tilegrid_t *status_bar) {
|
||||
self->cursor_x = 0;
|
||||
self->cursor_y = 0;
|
||||
self->font = font;
|
||||
self->scroll_area = scroll_area;
|
||||
self->title_bar = title_bar;
|
||||
self->title_x = 0;
|
||||
self->title_y = 0;
|
||||
self->status_bar = status_bar;
|
||||
self->status_x = 0;
|
||||
self->status_y = 0;
|
||||
self->first_row = 0;
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
|
||||
if (self->title_bar) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->title_bar, 0);
|
||||
if (self->status_bar) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
|
||||
}
|
||||
|
||||
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 1);
|
||||
@ -54,6 +65,14 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
if (self->scroll_area == NULL) {
|
||||
return len;
|
||||
}
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// Skip the status bar OSC sequence if it's disabled for the display.
|
||||
const bool status_bar_write_ok =
|
||||
shared_module_supervisor_status_bar_get_display(&shared_module_supervisor_status_bar_obj) ||
|
||||
!supervisor_status_bar_get_update_in_progress(&shared_module_supervisor_status_bar_obj);
|
||||
#endif
|
||||
|
||||
const byte *i = data;
|
||||
uint16_t start_y = self->cursor_y;
|
||||
while (i < data + len) {
|
||||
@ -62,21 +81,27 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
if (self->in_osc_command) {
|
||||
if (c == 0x1b && i[0] == '\\') {
|
||||
self->in_osc_command = false;
|
||||
self->title_x = 0;
|
||||
self->title_y = 0;
|
||||
self->status_x = 0;
|
||||
self->status_y = 0;
|
||||
i += 1;
|
||||
} else if (self->osc_command == 0 && self->title_bar != NULL && self->title_y < self->title_bar->height_in_tiles) {
|
||||
} else if (
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
status_bar_write_ok &&
|
||||
#endif
|
||||
self->osc_command == 0 &&
|
||||
self->status_bar != NULL &&
|
||||
self->status_y < self->status_bar->height_in_tiles) {
|
||||
uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c);
|
||||
if (tile_index != 0xff) {
|
||||
// Clear the tile grid before we start putting new info.
|
||||
if (self->title_x == 0 && self->title_y == 0) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->title_bar, 0);
|
||||
if (self->status_x == 0 && self->status_y == 0) {
|
||||
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
|
||||
}
|
||||
common_hal_displayio_tilegrid_set_tile(self->title_bar, self->title_x, self->title_y, tile_index);
|
||||
self->title_x++;
|
||||
if (self->title_x >= self->title_bar->width_in_tiles) {
|
||||
self->title_y++;
|
||||
self->title_x %= self->title_bar->width_in_tiles;
|
||||
common_hal_displayio_tilegrid_set_tile(self->status_bar, self->status_x, self->status_y, tile_index);
|
||||
self->status_x++;
|
||||
if (self->status_x >= self->status_bar->width_in_tiles) {
|
||||
self->status_y++;
|
||||
self->status_x %= self->status_bar->width_in_tiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,7 +123,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
|
||||
self->cursor_x--;
|
||||
}
|
||||
} else if (c == 0x1b) {
|
||||
// Handle commands of the form \x1b.####D where . is ignored.
|
||||
// Handle commands of the form [ESC].<digits><command-char> where . is not yet known.
|
||||
uint16_t n = 0;
|
||||
uint8_t j = 1;
|
||||
for (; j < 6; j++) {
|
||||
|
@ -40,12 +40,14 @@ typedef struct {
|
||||
uint16_t cursor_x;
|
||||
uint16_t cursor_y;
|
||||
displayio_tilegrid_t *scroll_area;
|
||||
displayio_tilegrid_t *title_bar;
|
||||
uint16_t title_x;
|
||||
uint16_t title_y;
|
||||
displayio_tilegrid_t *status_bar;
|
||||
uint16_t status_x;
|
||||
uint16_t status_y;
|
||||
uint16_t first_row;
|
||||
uint16_t osc_command;
|
||||
bool in_osc_command;
|
||||
} terminalio_terminal_obj_t;
|
||||
|
||||
extern void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self);
|
||||
|
||||
#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "supervisor/serial.h"
|
||||
#include "supervisor/shared/status_leds.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
@ -57,6 +56,10 @@
|
||||
#include "bluetooth/ble_drv.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
#endif
|
||||
|
||||
// This standard advertisement advertises the CircuitPython editing service and a CIRCUITPY short name.
|
||||
const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags
|
||||
0x02, 0x0a, 0xec, // 3-5 TX power level -20
|
||||
@ -94,16 +97,21 @@ STATIC bool ble_started = false;
|
||||
STATIC uint8_t workflow_state = WORKFLOW_UNSET;
|
||||
STATIC bool was_connected = false;
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// To detect when the title bar changes.
|
||||
STATIC bool _last_connected = false;
|
||||
STATIC bool _last_advertising = false;
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// Title bar status
|
||||
bool supervisor_bluetooth_status_dirty(void) {
|
||||
return _last_advertising != advertising ||
|
||||
_last_connected != was_connected;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
void supervisor_bluetooth_status(void) {
|
||||
serial_write("BLE:");
|
||||
if (advertising) {
|
||||
@ -123,6 +131,7 @@ void supervisor_bluetooth_status(void) {
|
||||
_last_connected = was_connected;
|
||||
_last_advertising = advertising;
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC void supervisor_bluetooth_start_advertising(void) {
|
||||
if (workflow_state != WORKFLOW_ENABLED) {
|
||||
@ -273,9 +282,13 @@ void supervisor_bluetooth_background(void) {
|
||||
supervisor_bluetooth_file_transfer_disconnected();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
if (was_connected != is_connected) {
|
||||
supervisor_title_bar_request_update(false);
|
||||
supervisor_status_bar_request_update(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
was_connected = is_connected;
|
||||
if (!is_connected) {
|
||||
supervisor_bluetooth_start_advertising();
|
||||
@ -312,7 +325,10 @@ void supervisor_start_bluetooth(void) {
|
||||
|
||||
// Kick off advertisements
|
||||
supervisor_bluetooth_background();
|
||||
supervisor_title_bar_request_update(false);
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
supervisor_status_bar_request_update(false);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "shared-bindings/displayio/Palette.h"
|
||||
#include "shared-bindings/displayio/TileGrid.h"
|
||||
#include "supervisor/memory.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
|
||||
#if CIRCUITPY_RGBMATRIX
|
||||
#include "shared-module/displayio/__init__.h"
|
||||
@ -46,6 +45,10 @@
|
||||
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
extern uint32_t blinka_bitmap_data[];
|
||||
extern displayio_bitmap_t blinka_bitmap;
|
||||
@ -63,7 +66,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid;
|
||||
displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid;
|
||||
displayio_tilegrid_t *status_bar = &supervisor_terminal_status_bar_text_grid;
|
||||
bool reset_tiles = false;
|
||||
uint16_t width_in_tiles = width_px / scroll_area->tile_width;
|
||||
// determine scale based on width
|
||||
@ -104,21 +107,21 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
uint8_t *tiles = (uint8_t *)tilegrid_tiles->ptr;
|
||||
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
title_bar->x = supervisor_blinka_sprite.pixel_width + 1;
|
||||
// Align the title bar to the bottom of the logo.
|
||||
title_bar->y = supervisor_blinka_sprite.pixel_height - title_bar->tile_height;
|
||||
status_bar->x = supervisor_blinka_sprite.pixel_width + 1;
|
||||
// Align the status bar to the bottom of the logo.
|
||||
status_bar->y = supervisor_blinka_sprite.pixel_height - status_bar->tile_height;
|
||||
#else
|
||||
title_bar->x = 0;
|
||||
title_bar->y = 0;
|
||||
status_bar->x = 0;
|
||||
status_bar->y = 0;
|
||||
#endif
|
||||
title_bar->top_left_y = 0;
|
||||
title_bar->width_in_tiles = width_in_tiles;
|
||||
title_bar->height_in_tiles = 1;
|
||||
status_bar->top_left_y = 0;
|
||||
status_bar->width_in_tiles = width_in_tiles;
|
||||
status_bar->height_in_tiles = 1;
|
||||
assert(width_in_tiles > 0);
|
||||
title_bar->pixel_width = width_in_tiles * title_bar->tile_width;
|
||||
title_bar->pixel_height = title_bar->tile_height;
|
||||
title_bar->tiles = tiles;
|
||||
title_bar->full_change = true;
|
||||
status_bar->pixel_width = width_in_tiles * status_bar->tile_width;
|
||||
status_bar->pixel_height = status_bar->tile_height;
|
||||
status_bar->tiles = tiles;
|
||||
status_bar->full_change = true;
|
||||
|
||||
scroll_area->x = 0;
|
||||
scroll_area->top_left_y = 0;
|
||||
@ -131,7 +134,7 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
scroll_area->y = blinka_bitmap.height;
|
||||
#else
|
||||
scroll_area->y = title_bar->tile_height;
|
||||
scroll_area->y = status_bar->tile_height;
|
||||
#endif
|
||||
int16_t extra_height = (scroll_area->pixel_height + scroll_area->y) - (height_px / scale);
|
||||
// Subtract extra height so that the bottom line fully shows. The top line will be under the
|
||||
@ -140,9 +143,11 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
|
||||
scroll_area->tiles = tiles + width_in_tiles;
|
||||
scroll_area->full_change = true;
|
||||
|
||||
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();
|
||||
common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, status_bar);
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// Update the status bar since we just cleared the terminal.
|
||||
supervisor_status_bar_update();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -155,9 +160,9 @@ void supervisor_stop_terminal(void) {
|
||||
free_memory(tilegrid_tiles);
|
||||
tilegrid_tiles = NULL;
|
||||
supervisor_terminal_scroll_area_text_grid.tiles = NULL;
|
||||
supervisor_terminal_title_bar_text_grid.tiles = NULL;
|
||||
supervisor_terminal_status_bar_text_grid.tiles = NULL;
|
||||
supervisor_terminal.scroll_area = NULL;
|
||||
supervisor_terminal.title_bar = NULL;
|
||||
supervisor_terminal.status_bar = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -165,13 +170,13 @@ void supervisor_stop_terminal(void) {
|
||||
void supervisor_display_move_memory(void) {
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid;
|
||||
displayio_tilegrid_t *title_bar = &supervisor_terminal_title_bar_text_grid;
|
||||
displayio_tilegrid_t *status_bar = &supervisor_terminal_status_bar_text_grid;
|
||||
if (tilegrid_tiles != NULL) {
|
||||
title_bar->tiles = (uint8_t *)tilegrid_tiles->ptr;
|
||||
status_bar->tiles = (uint8_t *)tilegrid_tiles->ptr;
|
||||
scroll_area->tiles = (uint8_t *)tilegrid_tiles->ptr + scroll_area->width_in_tiles;
|
||||
} else {
|
||||
scroll_area->tiles = NULL;
|
||||
title_bar->tiles = NULL;
|
||||
status_bar->tiles = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -195,7 +200,7 @@ void supervisor_display_move_memory(void) {
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
#if CIRCUITPY_REPL_LOGO
|
||||
mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_blinka_sprite, &supervisor_terminal_title_bar_text_grid, };
|
||||
mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_blinka_sprite, &supervisor_terminal_status_bar_text_grid, };
|
||||
mp_obj_list_t splash_children = {
|
||||
.base = {.type = &mp_type_list },
|
||||
.alloc = 3,
|
||||
@ -203,7 +208,7 @@ mp_obj_list_t splash_children = {
|
||||
.items = members,
|
||||
};
|
||||
#else
|
||||
mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_title_bar_text_grid,};
|
||||
mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_status_bar_text_grid,};
|
||||
mp_obj_list_t splash_children = {
|
||||
.base = {.type = &mp_type_list },
|
||||
.alloc = 2,
|
||||
|
@ -45,7 +45,7 @@ extern const fontio_builtinfont_t supervisor_terminal_font;
|
||||
// These will change so they must live in RAM.
|
||||
extern displayio_bitmap_t supervisor_terminal_font_bitmap;
|
||||
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_status_bar_text_grid;
|
||||
extern terminalio_terminal_obj_t supervisor_terminal;
|
||||
#endif
|
||||
|
||||
|
@ -41,6 +41,11 @@
|
||||
#include "supervisor/shared/bluetooth/serial.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
@ -276,11 +281,22 @@ void serial_write_substring(const char *text, uint32_t length) {
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
int errcode;
|
||||
// We might be writing
|
||||
// If the status bar is disabled for the display, common_hal_terminalio_terminal_write() will not write it.
|
||||
common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t *)text, length, &errcode);
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// If the status bar is disabled for the console, skip writing out the OSC sequence.
|
||||
if (supervisor_status_bar_get_update_in_progress(&shared_module_supervisor_status_bar_obj) &&
|
||||
!shared_module_supervisor_status_bar_get_console(&shared_module_supervisor_status_bar_obj)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_VENDOR
|
||||
if (tud_vendor_connected()) {
|
||||
tud_vendor_write(text, length);
|
||||
|
@ -27,9 +27,15 @@
|
||||
#include <stdbool.h>
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#include "shared-bindings/supervisor/StatusBar.h"
|
||||
#include "supervisor/background_callback.h"
|
||||
#include "supervisor/serial.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
#include "shared-module/terminalio/Terminal.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_WEB_WORKFLOW
|
||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||
@ -39,46 +45,56 @@
|
||||
#include "supervisor/shared/bluetooth/bluetooth.h"
|
||||
#endif
|
||||
|
||||
static background_callback_t title_bar_background_cb;
|
||||
static background_callback_t status_bar_background_cb;
|
||||
|
||||
static bool _forced_dirty = false;
|
||||
static bool _suspended = false;
|
||||
|
||||
// Clear if possible, but give up if we can't do it now.
|
||||
void supervisor_status_bar_clear(void) {
|
||||
if (!_suspended) {
|
||||
supervisor_status_bar_set_update_in_progress(&shared_module_supervisor_status_bar_obj, true);
|
||||
serial_write("\x1b" "]0;" "\x1b" "\\");
|
||||
supervisor_status_bar_set_update_in_progress(&shared_module_supervisor_status_bar_obj, false);
|
||||
}
|
||||
}
|
||||
|
||||
void supervisor_title_bar_update(void) {
|
||||
#if !CIRCUITPY_STATUS_BAR
|
||||
return;
|
||||
#endif
|
||||
void supervisor_status_bar_update(void) {
|
||||
if (_suspended) {
|
||||
supervisor_title_bar_request_update(true);
|
||||
supervisor_status_bar_request_update(true);
|
||||
return;
|
||||
}
|
||||
_forced_dirty = false;
|
||||
|
||||
supervisor_status_bar_set_update_in_progress(&shared_module_supervisor_status_bar_obj, true);
|
||||
|
||||
// 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
|
||||
|
||||
#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE
|
||||
supervisor_bluetooth_status();
|
||||
serial_write(" | ");
|
||||
#endif
|
||||
|
||||
supervisor_execution_status();
|
||||
serial_write(" | ");
|
||||
serial_write(MICROPY_GIT_TAG);
|
||||
// Send string terminator
|
||||
serial_write("\x1b" "\\");
|
||||
|
||||
supervisor_status_bar_set_update_in_progress(&shared_module_supervisor_status_bar_obj, false);
|
||||
}
|
||||
|
||||
static void title_bar_background(void *data) {
|
||||
#if !CIRCUITPY_STATUS_BAR
|
||||
return;
|
||||
#endif
|
||||
static void status_bar_background(void *data) {
|
||||
if (_suspended) {
|
||||
return;
|
||||
}
|
||||
@ -92,42 +108,29 @@ static void title_bar_background(void *data) {
|
||||
dirty = dirty || supervisor_bluetooth_status_dirty();
|
||||
#endif
|
||||
|
||||
if (!dirty) {
|
||||
return;
|
||||
if (dirty) {
|
||||
supervisor_status_bar_update();
|
||||
}
|
||||
supervisor_title_bar_update();
|
||||
}
|
||||
|
||||
void supervisor_title_bar_start(void) {
|
||||
#if !CIRCUITPY_STATUS_BAR
|
||||
return;
|
||||
#endif
|
||||
title_bar_background_cb.fun = title_bar_background;
|
||||
title_bar_background_cb.data = NULL;
|
||||
supervisor_title_bar_request_update(true);
|
||||
void supervisor_status_bar_start(void) {
|
||||
status_bar_background_cb.fun = status_bar_background;
|
||||
status_bar_background_cb.data = NULL;
|
||||
supervisor_status_bar_request_update(true);
|
||||
}
|
||||
|
||||
void supervisor_title_bar_request_update(bool force_dirty) {
|
||||
#if !CIRCUITPY_STATUS_BAR
|
||||
return;
|
||||
#endif
|
||||
void supervisor_status_bar_request_update(bool force_dirty) {
|
||||
if (force_dirty) {
|
||||
_forced_dirty = true;
|
||||
}
|
||||
background_callback_add_core(&title_bar_background_cb);
|
||||
background_callback_add_core(&status_bar_background_cb);
|
||||
}
|
||||
|
||||
void supervisor_title_bar_suspend(void) {
|
||||
#if !CIRCUITPY_STATUS_BAR
|
||||
return;
|
||||
#endif
|
||||
void supervisor_status_bar_suspend(void) {
|
||||
_suspended = true;
|
||||
}
|
||||
|
||||
void supervisor_title_bar_resume(void) {
|
||||
#if !CIRCUITPY_STATUS_BAR
|
||||
return;
|
||||
#endif
|
||||
void supervisor_status_bar_resume(void) {
|
||||
_suspended = false;
|
||||
supervisor_title_bar_request_update(false);
|
||||
supervisor_status_bar_request_update(false);
|
||||
}
|
@ -28,17 +28,19 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void supervisor_title_bar_start(void);
|
||||
void supervisor_title_bar_suspend(void);
|
||||
void supervisor_title_bar_resume(void);
|
||||
void supervisor_status_bar_start(void);
|
||||
void supervisor_status_bar_suspend(void);
|
||||
void supervisor_status_bar_resume(void);
|
||||
|
||||
void supervisor_status_bar_clear(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);
|
||||
void supervisor_status_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_status_bar_request_update(bool force_dirty);
|
||||
|
||||
// Provided by main.c
|
||||
void supervisor_execution_status(void);
|
@ -31,11 +31,14 @@
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/serial.h"
|
||||
#include "supervisor/usb.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
#include "supervisor/shared/workflow.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "shared/readline/readline.h"
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STORAGE
|
||||
#include "shared-module/storage/__init__.h"
|
||||
#endif
|
||||
@ -244,8 +247,10 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
||||
reset_to_bootloader();
|
||||
}
|
||||
} else {
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// We are connected, let's request a title bar update.
|
||||
supervisor_title_bar_request_update(true);
|
||||
supervisor_status_bar_request_update(true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,12 @@ typedef struct {
|
||||
|
||||
static wifi_radio_error_t _wifi_status = WIFI_RADIO_ERROR_NONE;
|
||||
|
||||
// Store last status state to compute dirty.
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// Store various last states to compute if status bar needs an update.
|
||||
static bool _last_enabled = false;
|
||||
static uint32_t _last_ip = 0;
|
||||
static wifi_radio_error_t _last_wifi_status = WIFI_RADIO_ERROR_NONE;
|
||||
#endif
|
||||
|
||||
static mdns_server_obj_t mdns;
|
||||
static uint32_t web_api_port = 80;
|
||||
@ -193,12 +195,15 @@ STATIC void _update_encoded_ip(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
bool supervisor_web_workflow_status_dirty(void) {
|
||||
return common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) != _last_enabled ||
|
||||
_encoded_ip != _last_ip ||
|
||||
_last_wifi_status != _wifi_status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
void supervisor_web_workflow_status(void) {
|
||||
_last_enabled = common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj);
|
||||
if (_last_enabled) {
|
||||
@ -231,6 +236,7 @@ void supervisor_web_workflow_status(void) {
|
||||
serial_write_compressed(translate("off"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void supervisor_start_web_workflow(void) {
|
||||
#if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI
|
||||
|
@ -29,9 +29,12 @@
|
||||
#include "py/ringbuf.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "supervisor/shared/title_bar.h"
|
||||
#include "supervisor/shared/web_workflow/web_workflow.h"
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
#include "supervisor/shared/status_bar.h"
|
||||
#endif
|
||||
|
||||
// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server.
|
||||
#include "esp_log.h"
|
||||
|
||||
@ -73,8 +76,10 @@ void websocket_handoff(socketpool_socket_obj_t *socket) {
|
||||
socket->connected = false;
|
||||
socket->num = -1;
|
||||
|
||||
#if CIRCUITPY_STATUS_BAR
|
||||
// Send the title bar for the new client.
|
||||
supervisor_title_bar_request_update(true);
|
||||
supervisor_status_bar_request_update(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool websocket_connected(void) {
|
||||
|
@ -15,7 +15,6 @@ SRC_SUPERVISOR = \
|
||||
supervisor/shared/stack.c \
|
||||
supervisor/shared/status_leds.c \
|
||||
supervisor/shared/tick.c \
|
||||
supervisor/shared/title_bar.c \
|
||||
supervisor/shared/traceback.c \
|
||||
supervisor/shared/translate/translate.c \
|
||||
supervisor/shared/workflow.c \
|
||||
@ -98,6 +97,12 @@ ifneq ($(wildcard supervisor/serial.c),)
|
||||
SRC_SUPERVISOR += supervisor/serial.c
|
||||
endif
|
||||
|
||||
ifeq ($(CIRCUITPY_STATUS_BAR),1)
|
||||
SRC_SUPERVISOR += \
|
||||
supervisor/shared/status_bar.c \
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(CIRCUITPY_USB),1)
|
||||
SRC_SUPERVISOR += \
|
||||
lib/tinyusb/src/class/cdc/cdc_device.c \
|
||||
|
@ -324,7 +324,7 @@ displayio_tilegrid_t supervisor_terminal_scroll_area_text_grid = {{
|
||||
|
||||
c_file.write(
|
||||
"""\
|
||||
displayio_tilegrid_t supervisor_terminal_title_bar_text_grid = {{
|
||||
displayio_tilegrid_t supervisor_terminal_status_bar_text_grid = {{
|
||||
.base = {{ .type = &displayio_tilegrid_type }},
|
||||
.bitmap = (displayio_bitmap_t*) &supervisor_terminal_font_bitmap,
|
||||
.pixel_shader = &supervisor_terminal_color,
|
||||
@ -414,7 +414,7 @@ terminalio_terminal_obj_t supervisor_terminal = {
|
||||
.cursor_x = 0,
|
||||
.cursor_y = 0,
|
||||
.scroll_area = NULL,
|
||||
.title_bar = NULL
|
||||
.status_bar = NULL
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user