From b46756bf03518a7cc7c81f1a3843935354d541a5 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sun, 4 May 2025 21:51:54 +0200 Subject: [PATCH] Fullscreen all apps - no more subwindow --- draft_code/animations.py | 238 ++++++++++++++++++ draft_code/screen_capture.py | 80 ++++++ .../assets/bitcoin_price.py | 4 +- .../assets/bitcoin_transactions.py | 212 ---------------- .../com.example.camtest/assets/camtest.py | 4 +- .../com.example.cputest/assets/cputest.py | 4 +- .../com.example.imutest/assets/imutest.py | 16 +- .../com.example.lvgltest/assets/lvgltest.py | 12 +- .../com.example.memtest/assets/memtest.py | 4 +- .../com.example.launcher/assets/launcher.py | 4 +- .../com.example.osupdate/assets/osupdate.py | 6 +- .../com.example.wificonf/assets/wificonf.py | 33 ++- internal_filesystem/lib/display_driver.py | 4 + internal_filesystem/main.py | 20 +- scripts/build_lvgl_micropython.sh | 3 + 15 files changed, 387 insertions(+), 257 deletions(-) create mode 100644 draft_code/animations.py create mode 100644 draft_code/screen_capture.py delete mode 100644 internal_filesystem/apps/com.example.btcticker/assets/bitcoin_transactions.py create mode 100644 internal_filesystem/lib/display_driver.py diff --git a/draft_code/animations.py b/draft_code/animations.py new file mode 100644 index 00000000..386ebfba --- /dev/null +++ b/draft_code/animations.py @@ -0,0 +1,238 @@ + +# Initialize + +import display_driver +import lvgl as lv + +import lvgl + +label = lvgl.label( lvgl.screen_active() ) +label.set_text( 'hi' ) + +animation = lvgl.anim_t() +animation.init() +animation.set_var( label ) +animation.set_values( 0, 100 ) +animation.set_time( 1000 ) + +animation.set_custom_exec_cb( lambda not_used, value : label.set_x( value )) + +#wait half a second before starting animation +animation.set_delay( 500 ) + +#play animation backward for 1 second after first play +animation.set_playback_time( 1000 ) +#repeat animation infinitely +animation.set_repeat_count( 10 ) +#animation.set_repeat_count( lvgl.ANIM_REPEAT.INFINITE ) +animation.set_repeat_delay( 500 ) + +animation.start() + + + +****************************** + + + +# Initialize + +import display_driver +import lvgl as lv + +import lvgl + +#create the slow short label +label1 = lvgl.label( lvgl.screen_active() ) +label1.set_text( 'hello 1' ) +label1.align( lvgl.ALIGN.CENTER, 0, -50 ) + +anim1 = lvgl.anim_t() +anim1.init() +anim1.set_var( label1 ) +#anim1.set_time( lvgl.anim_speed_to_time( 20, 0, 100 )) +anim1.set_time( 2000 ) +anim1.set_values( 0, 100 ) +anim1.set_repeat_count( 10 ) +anim1.set_repeat_delay( 2000 ) +anim1.set_custom_exec_cb( lambda not_used, value : label1.set_x( value )) + + +#create the fast long label +label2 = lvgl.label( lvgl.screen_active() ) +label2.set_text('hello 2') +label2.align(lvgl.ALIGN.CENTER,-100,0) + +anim2 = lvgl.anim_t() +anim2.init() +anim2.set_var( label2 ) +#anim2.set_time( lvgl.anim_speed_to_time( 40, -100, 100 )) +anim2.set_time( 40 * 200 ) +anim2.set_values( -100, 100 ) +anim2.set_custom_exec_cb( lambda not_used, value : label2.set_x( value )) +anim2.set_repeat_count( 10) +anim2.set_repeat_delay( 2000 ) + + +#Create the fast short label +label3 = lvgl.label( lvgl.screen_active() ) +label3.set_text( 'hello 3' ) +label3.align( lvgl.ALIGN.CENTER, -100, 50 ) + + +anim3 = lvgl.anim_t() +anim3.init() +anim3.set_var( label3 ) +#anim3.set_time( lvgl.anim_speed_to_time( 40, -100, 0 )) +anim3.set_time( 40 * 100) +anim3.set_values( -100, 0) +anim3.set_custom_exec_cb( lambda not_used, value : label3.set_x( value )) +anim3.set_repeat_count( 10 ) +anim3.set_repeat_delay( 40 * 100 + 2000 ) +#anim3.set_repeat_delay( lvgl.anim_speed_to_time( 40, -100, 0) + 2000 ) +#lvgl.anim_speed_to_time( 1, 2, 3) +#anim3.set_repeat_delay( 5000) +#lvgl.anim + +anim1.start() +anim2.start() +anim3.start() + + + + + + + + + +****************** + + + + +# Initialize + +import display_driver +import lvgl as lv + +import lvgl + +import lvgl + +#normal animation +label1 = lvgl.label( lvgl.screen_active() ) +label1.set_text( 'hello 1' ) +label1.align( lvgl.ALIGN.CENTER, -70, -60 ) + +anim1 = lvgl.anim_t() +anim1.init() +anim1.set_var( label1 ) +anim1.set_time( 1000 ) +anim1.set_values( -70, 20 ) +anim1.set_repeat_count( 100 ) +anim1.set_repeat_delay( 2000 ) +anim1.set_custom_exec_cb( lambda not_used, value : label1.set_x( value )) + + +#this animation bounces the label when it ends +label2 = lvgl.label( lvgl.screen_active() ) +label2.set_text( 'hello 2' ) +label2.align( lvgl.ALIGN.CENTER, 30, -60 ) + +anim2 = lvgl.anim_t() +anim2.init() +anim2.set_var( label2 ) +anim2.set_time( 1000 ) +anim2.set_values( 30, 120 ) +anim2.set_custom_exec_cb( lambda not_used, value : label2.set_x( value )) +anim2.set_repeat_count( 100) +anim2.set_repeat_delay( 2000 ) +anim2.set_path_cb( lvgl.anim_t.path_bounce ) + + +#this animation goes past the end point then comes back +label3 = lvgl.label( lvgl.screen_active() ) +label3.set_text( 'hello 3' ) +label3.align( lvgl.ALIGN.CENTER, -70, 60 ) + +anim3 = lvgl.anim_t() +anim3.init() +anim3.set_var( label3 ) +anim3.set_time( 1000 ) +anim3.set_values( -70, 20 ) +anim3.set_custom_exec_cb( lambda not_used, value : label3.set_x( value )) +anim3.set_repeat_count( 100 ) +anim3.set_repeat_delay( 2000 ) +anim3.set_path_cb( lvgl.anim_t.path_overshoot ) + + +#this animation slowly starts and then slowly ends +label4 = lvgl.label( lvgl.screen_active() ) +label4.set_text( 'hello 4' ) +label4.align( lvgl.ALIGN.CENTER, 30, 60 ) + +anim4 = lvgl.anim_t() +anim4.init() +anim4.set_var( label4 ) +anim4.set_time( 1000 ) +anim4.set_values( 30, 120 ) +anim4.set_custom_exec_cb( lambda not_used, value : label4.set_x( value )) +anim4.set_repeat_count( 100 ) +anim4.set_repeat_delay( 2000 ) +anim4.set_path_cb( lvgl.anim_t.path_ease_in_out ) + + +anim1.start() +anim2.start() +anim3.start() +anim4.start() + + + +******************** + + + + +# Initialize + +import display_driver +import lvgl as lv + +import lvgl + +button = lvgl.button( lvgl.screen_active() ) +button.set_size( 50, 20 ) +button.center() + +anim1 = lvgl.anim_t() +anim1.init() +anim1.set_var( button ) +anim1.set_time( 1000 ) +anim1.set_values( -100, 100 ) +anim1.set_custom_exec_cb( lambda not_used, value : button.set_x( value )) + +anim2 = lvgl.anim_t() +anim2.init() +anim2.set_var( button ) +anim2.set_time( 150 ) +anim2.set_values( 100, 30 ) +anim2.set_custom_exec_cb( lambda not_used, value : button.set_x( value )) + +anim3 = lvgl.anim_t() +anim3.init() +anim3.set_var( button ) +anim3.set_time( 2000 ) +anim3.set_values( 30, -100 ) +anim3.set_custom_exec_cb( lambda not_used, value : button.set_x( value )) + +time = lvgl.anim_timeline_create() + +# somehow this doesn't work: +#lvgl.anim_timeline_add( time, 0, anim1 ) +#lvgl.anim_timeline_add( time, 1000, anim2 ) +#lvgl.anim_timeline_add( time, 1150, anim3 ) + +#lvgl.anim_timeline_start( time ) + diff --git a/draft_code/screen_capture.py b/draft_code/screen_capture.py new file mode 100644 index 00000000..abac2afa --- /dev/null +++ b/draft_code/screen_capture.py @@ -0,0 +1,80 @@ +import ustruct +import os +#os.mkdir("/flash") + +import lvgl as lv +import micropython +import ustruct + +# Capture the screen to a buffer +snapshot_buf = lv.snapshot_take(lv.screen_active(), lv.COLOR_FORMAT.NATIVE) +if snapshot_buf is None: + print("Failed to capture snapshot") +else: + print("Snapshot captured successfully") + +# Assuming snapshot_buf is from lv.snapshot_take(scr, lv.COLOR_FORMAT.NATIVE) +if snapshot_buf: + # Verify metadata + print("Width:", snapshot_buf.header.w) # Should be 320 + print("Height:", snapshot_buf.header.h) # Should be 240 + print("Data size:", snapshot_buf.data_size) # Should be 153600 + # Get the raw buffer pointer + data_ptr = snapshot_buf.data + data_size = snapshot_buf.data_size + # Use memoryview to access the full buffer + try: + # Create a memoryview of the C buffer + buffer = memoryview(data_ptr)[:data_size] + print("Buffer length:", len(buffer)) # Should be 153600 + # Save to flash storage + with open("/flash/snapshot.bin", "wb") as f: + f.write(buffer) + print("Snapshot saved to /flash/snapshot.bin") + except Exception as e: + print("Error accessing or saving buffer:", e) + # Free the snapshot to avoid memory leaks + lv.snapshot_free(snapshot_buf) +else: + print("Snapshot capture failed") + + + + + +# Assuming snapshot_buf is the lv_img_dsc_t from lv.snapshot_take +if snapshot_buf: + # Get image data and metadata + img_data = snapshot_buf.data # Raw buffer (bytearray) + img_width = snapshot_buf.header.w + img_height = snapshot_buf.header.h + img_data_size = snapshot_buf.data_size + # Save to flash storage + try: + with open("/flash/snapshot.bin", "wb") as f: + f.write(img_data, img_data_size) + print("Snapshot saved to /flash/snapshot.bin") + except OSError as e: + print("Failed to save snapshot:", e) +else: + print("No snapshot to save") + + + + + +if False: + img_data = snapshot_buf.data + img_width = snapshot_buf.header.w + img_height = snapshot_buf.header.h + img_data_size = snapshot_buf.data_size + color_format = lv.COLOR_FORMAT.NATIVE # Store format for reference + try: + with open("/flash/snapshot.bin", "wb") as f: + # Write header: width (4 bytes), height (4 bytes), format (4 bytes) + f.write(ustruct.pack("III", img_width, img_height, color_format)) + # Write image data + f.write(img_data, img_data_size) + print("Snapshot with header saved to /flash/snapshot.bin") + except OSError as e: + print("Failed to save snapshot:", e) diff --git a/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_price.py b/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_price.py index a22cc773..43413a42 100644 --- a/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_price.py +++ b/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_price.py @@ -1,3 +1,5 @@ +appscreen = lv.screen_active() + import usocket import ssl import ubinascii @@ -175,7 +177,7 @@ def get_price(json_str): print(f"Error: An unexpected error occurred - {str(e)}") return None -status = lv.label(subwindow) +status = lv.label(appscreen) status.align(lv.ALIGN.TOP_LEFT, 5, 10) status.set_style_text_color(lv.color_hex(0xFFFFFF), 0) diff --git a/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_transactions.py b/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_transactions.py deleted file mode 100644 index 08b07f99..00000000 --- a/internal_filesystem/apps/com.example.btcticker/assets/bitcoin_transactions.py +++ /dev/null @@ -1,212 +0,0 @@ -import usocket -import ssl -import ubinascii -import ujson -import urandom -import uhashlib -import time - -def compute_accept_key(key): - GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - hash_obj = uhashlib.sha1(key + GUID) - return ubinascii.b2a_base64(hash_obj.digest())[:-1].decode() - -def ws_handshake(host, port, path="/"): - print(f"Connecting to {host}:{port}") - sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM) - addr = usocket.getaddrinfo(host, port)[0][-1] - print(f"Resolved: {addr}") - sock.connect(addr) - - ssl_sock = ssl.wrap_socket(sock, server_hostname=host) - print("SSL handshake complete") - - key_bytes = bytearray() - for _ in range(4): - key_bytes.extend(urandom.getrandbits(32).to_bytes(4, 'big')) - key = ubinascii.b2a_base64(key_bytes)[:-1].decode() - expected_accept = compute_accept_key(key) - print(f"Key: {key}") - print(f"Expected Sec-WebSocket-Accept: {expected_accept}") - - handshake = ( - f"GET {path} HTTP/1.1\r\n" - f"Host: {host}\r\n" - f"Upgrade: websocket\r\n" - f"Connection: Upgrade\r\n" - f"Sec-WebSocket-Key: {key}\r\n" - f"Sec-WebSocket-Version: 13\r\n" - f"\r\n" - ) - print(f"Handshake:\n{handshake}") - ssl_sock.write(handshake.encode()) - - response = ssl_sock.readline() - print(f"Response: {response.decode()}") - if b"101" not in response: - ssl_sock.close() - raise ValueError(f"Handshake failed: {response.decode()}") - - accept_key = None - while True: - line = ssl_sock.readline() - print(f"Header: {line.decode()}") - if line == b"\r\n": - break - if line.lower().startswith(b"sec-websocket-accept:"): - accept_key = line.decode().split(":")[1].strip() - - if not accept_key: - ssl_sock.close() - raise ValueError("No Sec-WebSocket-Accept header received") - if accept_key != expected_accept: - ssl_sock.close() - raise ValueError(f"Invalid Sec-WebSocket-Accept: got {accept_key}, expected {expected_accept}") - - # Set non-blocking read - ssl_sock.setblocking(False) - return ssl_sock - -def ws_send_text(sock, message): - print(f"Sending: {message}") - data = message.encode() - print(f"Data: {data}") - length = len(data) - - frame = bytearray() - frame.append(0x81) # FIN=1, opcode=0x1 (text) - mask_bit = 0x80 - mask_key = bytearray(urandom.getrandbits(32).to_bytes(4, 'big')) - print(f"Mask key: {mask_key}") - - if length <= 125: - frame.append(mask_bit | length) - elif length <= 65535: - frame.append(mask_bit | 126) - frame.extend(length.to_bytes(2, 'big')) - else: - frame.append(mask_bit | 127) - frame.extend(length.to_bytes(8, 'big')) - - frame.extend(mask_key) - masked_data = bytearray(data) - for i in range(len(data)): - masked_data[i] ^= mask_key[i % 4] - frame.extend(masked_data) - print(f"Frame: {frame}") - sock.write(frame) - -def ws_read_frame(sock): - try: - data = sock.read(2) # Read header (FIN/opcode, length) - except OSError as e: - print(f"Read error: {e}") - return None - if not data: - print("Read: empty") - return None - print(f"Raw header: {data}") - - if len(data) < 2: - print("Frame too short") - return None - - fin = (data[0] & 0x80) >> 7 - opcode = data[0] & 0x0F - masked = (data[1] & 0x80) >> 7 - payload_len = data[1] & 0x7F - print(f"FIN: {fin} Opcode: {opcode} Masked: {masked} Len: {payload_len}") - - if payload_len == 126: - len_data = sock.read(2) - payload_len = int.from_bytes(len_data, 'big') - print(f"Extended len: {payload_len}") - elif payload_len == 127: - len_data = sock.read(8) - payload_len = int.from_bytes(len_data, 'big') - print(f"Extended len: {payload_len}") - - mask_key = None - if masked: - mask_key = sock.read(4) - print(f"Mask key: {mask_key}") - - payload = sock.read(payload_len) - print(f"Raw payload: {payload}") - if masked and mask_key: - payload = bytearray(payload) - for i in range(len(payload)): - payload[i] ^= mask_key[i % 4] - print(f"Payload: {payload}") - - if opcode == 0x1: - return payload.decode() - elif opcode == 0x9: - print("Ping frame received") - return None - elif opcode == 0xA: - print("Pong frame received") - return None - elif opcode == 0x8: - print("Close frame received") - return None - else: - print(f"Unknown opcode: {opcode}") - return None - - - -status = lv.label(subwindow) -status.align(lv.ALIGN.TOP_LEFT, 5, 10) -status.set_style_text_color(lv.color_hex(0xFFFFFF), 0) - -summary = "Websocket sends:\n\n" -status.set_text(summary) - -port = 443 -#host = "echo.websocket.org" -#path = "/" -host = "ws.blockchain.info" -path = "/inv" - -try: - sock = ws_handshake(host, port, path) - - print("Reading a bit...") # echo.websocket.org sends a reply - for _ in range(3): - time.sleep(1) - data = ws_read_frame(sock) - if data: - print(f"Response: {data}") - break - - print("Sending JSON ping...") - ws_send_text(sock, ujson.dumps({"op": "ping"})) - for _ in range(10): - time.sleep(2) - data = ws_read_frame(sock) - if data: - print(f"Response: {data}") - summary += f"{data}\n" - status.set_text(summary) - break - - print("Subscribing unconfirmed transactions...") - ws_send_text(sock, ujson.dumps({"op": "unconfirmed_sub"})) - while appscreen == lv.screen_active(): - time.sleep(1) - data = ws_read_frame(sock) # Bug: when a giant response comes in, it cuts off after 5470 bytes and then the rest is read as a new (garbled) response - if data: - print(f"Response: {data}") - summary += f"{data}\n" - status.set_text(summary) - - sock.close() -except Exception as e: - print(f"Error: {str(e)}") - try: - sock.close() - except: - pass - - diff --git a/internal_filesystem/apps/com.example.camtest/assets/camtest.py b/internal_filesystem/apps/com.example.camtest/assets/camtest.py index 980e7107..6f2edba8 100644 --- a/internal_filesystem/apps/com.example.camtest/assets/camtest.py +++ b/internal_filesystem/apps/com.example.camtest/assets/camtest.py @@ -1,3 +1,5 @@ +appscreen = lv.screen_active() + #define PWDN_GPIO_NUM 17 //power down is not used #define RESET_GPIO_NUM -1 //software reset will be performed #define XCLK_GPIO_NUM 8 @@ -40,7 +42,7 @@ width = 240 height = 240 -cont = lv.obj(subwindow) +cont = lv.obj(appscreen) cont.set_style_pad_all(0, 0) cont.set_style_border_width(0, 0) cont.set_size(lv.pct(100), lv.pct(100)) diff --git a/internal_filesystem/apps/com.example.cputest/assets/cputest.py b/internal_filesystem/apps/com.example.cputest/assets/cputest.py index 284ef41b..300a3bd9 100644 --- a/internal_filesystem/apps/com.example.cputest/assets/cputest.py +++ b/internal_filesystem/apps/com.example.cputest/assets/cputest.py @@ -10,6 +10,8 @@ # Busy loop with yield: 15923 iterations/second # SHA-256 (1KB): 5269 iterations/second +appscreen = lv.screen_active() + import time import hashlib import os @@ -60,7 +62,7 @@ def stress_test_sha256(): return iterations_per_second -status = lv.label(subwindow) +status = lv.label(appscreen) status.align(lv.ALIGN.TOP_LEFT, 5, 10) status.set_style_text_color(lv.color_hex(0xFFFFFF), 0) diff --git a/internal_filesystem/apps/com.example.imutest/assets/imutest.py b/internal_filesystem/apps/com.example.imutest/assets/imutest.py index 06695505..b1fabdfc 100644 --- a/internal_filesystem/apps/com.example.imutest/assets/imutest.py +++ b/internal_filesystem/apps/com.example.imutest/assets/imutest.py @@ -1,24 +1,26 @@ +appscreen = lv.screen_active() + from machine import Pin, I2C from qmi8658 import QMI8658 import machine sensor = QMI8658(I2C(0, sda=machine.Pin(48), scl=machine.Pin(47))) -templabel = lv.label(subwindow) +templabel = lv.label(appscreen) templabel.align(lv.ALIGN.TOP_MID, 0, 10) -sliderx = lv.slider(subwindow) +sliderx = lv.slider(appscreen) sliderx.align(lv.ALIGN.CENTER, 0, -60) -slidery = lv.slider(subwindow) +slidery = lv.slider(appscreen) slidery.align(lv.ALIGN.CENTER, 0, -30) -sliderz = lv.slider(subwindow) +sliderz = lv.slider(appscreen) sliderz.align(lv.ALIGN.CENTER, 0, 0) -slidergx = lv.slider(subwindow) +slidergx = lv.slider(appscreen) slidergx.align(lv.ALIGN.CENTER, 0, 30) -slidergy = lv.slider(subwindow) +slidergy = lv.slider(appscreen) slidergy.align(lv.ALIGN.CENTER, 0, 60) -slidergz = lv.slider(subwindow) +slidergz = lv.slider(appscreen) slidergz.align(lv.ALIGN.CENTER, 0, 90) def map_nonlinear(value: float) -> int: diff --git a/internal_filesystem/apps/com.example.lvgltest/assets/lvgltest.py b/internal_filesystem/apps/com.example.lvgltest/assets/lvgltest.py index 58bdb065..95529eec 100644 --- a/internal_filesystem/apps/com.example.lvgltest/assets/lvgltest.py +++ b/internal_filesystem/apps/com.example.lvgltest/assets/lvgltest.py @@ -1,3 +1,5 @@ +appscreen == lv.screen_active() + import time import random @@ -8,14 +10,16 @@ SPINNER_SIZE = 40 # Size of each spinner in pixels spinner_count = 0 metrics_label = None + + def add_spinner_and_update(): global spinner_count, metrics_label try: - spinner = lv.spinner(subwindow) + spinner = lv.spinner(appscreen) spinner.set_size(SPINNER_SIZE, SPINNER_SIZE) spinner.set_pos( - random.randint(0, subwindow.get_width() - SPINNER_SIZE), - random.randint(0, subwindow.get_height() - SPINNER_SIZE) + random.randint(0, appscreen.get_width() - SPINNER_SIZE), + random.randint(0, appscreen.get_height() - SPINNER_SIZE) ) spinner_count += 1 except Exception as e: @@ -29,7 +33,7 @@ def run_benchmark(): global spinner_count, metrics_label print("Starting LVGL spinner benchmark...") - scr = subwindow + scr = appscreen scr.set_style_bg_color(lv.color_black(), 0) metrics_label = lv.label(scr) diff --git a/internal_filesystem/apps/com.example.memtest/assets/memtest.py b/internal_filesystem/apps/com.example.memtest/assets/memtest.py index d07fcd60..f3011857 100644 --- a/internal_filesystem/apps/com.example.memtest/assets/memtest.py +++ b/internal_filesystem/apps/com.example.memtest/assets/memtest.py @@ -26,6 +26,8 @@ # 2097152 | 0 #===================================== +appscreen = lv.screen_active() + import gc import time @@ -71,7 +73,7 @@ def test_allocation(buffer_size, n): # Test buffer sizes of 2^n, starting from n=1 (2 bytes) n = 1 -status = lv.label(subwindow) +status = lv.label(appscreen) status.align(lv.ALIGN.TOP_LEFT, 5, 10) status.set_style_text_color(lv.color_hex(0xFFFFFF), 0) status.set_style_text_font(lv.font_unscii_8, 0) diff --git a/internal_filesystem/builtin/apps/com.example.launcher/assets/launcher.py b/internal_filesystem/builtin/apps/com.example.launcher/assets/launcher.py index 25d3e9c7..c3236927 100644 --- a/internal_filesystem/builtin/apps/com.example.launcher/assets/launcher.py +++ b/internal_filesystem/builtin/apps/com.example.launcher/assets/launcher.py @@ -9,11 +9,13 @@ # All icons took: 1250ms # Most of this time is actually spent reading and parsing manifests. +appscreen = lv.screen_active() + import uos import lvgl as lv # Create a container for the grid -cont = lv.obj(subwindow) +cont = lv.obj(appscreen) cont.set_size(lv.pct(100), lv.pct(100)) cont.set_style_pad_all(10, 0) cont.set_flex_flow(lv.FLEX_FLOW.ROW_WRAP) diff --git a/internal_filesystem/builtin/apps/com.example.osupdate/assets/osupdate.py b/internal_filesystem/builtin/apps/com.example.osupdate/assets/osupdate.py index 64be820f..08a06e0c 100644 --- a/internal_filesystem/builtin/apps/com.example.osupdate/assets/osupdate.py +++ b/internal_filesystem/builtin/apps/com.example.osupdate/assets/osupdate.py @@ -1,3 +1,5 @@ +appscreen = lv.screen_active() + import lvgl as lv import ota.update from esp32 import Partition @@ -10,11 +12,11 @@ current next_partition = current.get_next_update() next_partition -label = lv.label(subwindow) +label = lv.label(appwindow) label.set_text("OS Update: 0.00%") label.align(lv.ALIGN.CENTER, 0, -30) -progress_bar = lv.bar(subwindow) +progress_bar = lv.bar(appwindow) progress_bar.set_size(200, 20) progress_bar.align(lv.ALIGN.BOTTOM_MID, 0, -50) progress_bar.set_range(0, 100) diff --git a/internal_filesystem/builtin/apps/com.example.wificonf/assets/wificonf.py b/internal_filesystem/builtin/apps/com.example.wificonf/assets/wificonf.py index ce8a3877..db625beb 100644 --- a/internal_filesystem/builtin/apps/com.example.wificonf/assets/wificonf.py +++ b/internal_filesystem/builtin/apps/com.example.wificonf/assets/wificonf.py @@ -1,3 +1,5 @@ +appscreen = lv.screen_active() + import network import ujson import os @@ -12,7 +14,6 @@ selected_ssid=None list=None password_ta=None password_page=None -main_subwindow=None keyboard=None error_label=None scanning_label=None @@ -197,8 +198,8 @@ def connect_cb(event): save_config() print("connect_cb: Deleting password page") password_page.delete() - print("connect_cb: Restoring main subwindow") - lv.screen_load(main_subwindow) + print("connect_cb: Restoring main appscreen") + lv.screen_load(appscreen) print(f"connect_cb: Attempting connection to {selected_ssid}") success=attempt_connecting(selected_ssid,password) print(f"connect_cb: Connection {'succeeded' if success else 'failed'}") @@ -208,27 +209,27 @@ def cancel_cb(event): print("cancel_cb: Cancel button clicked") print("Deleting password screen...") password_page.delete() - print("cancel_cb: Restoring main subwindow") - lv.screen_load(main_subwindow) + print("cancel_cb: Restoring main appscreen") + lv.screen_load(appscreen) -def create_ui(subwindow): - global list,main_subwindow,error_label,scanning_label +def create_ui(): + global list,appscreen,error_label,scanning_label print("create_ui: Creating list widget") - list=lv.list(subwindow) + list=lv.list(appscreen) list.set_size(lv.pct(100),180) list.align(lv.ALIGN.TOP_MID,0,0) print("create_ui: Creating error label") - error_label=lv.label(subwindow) + error_label=lv.label(appscreen) error_label.set_text("") error_label.align(lv.ALIGN.BOTTOM_MID,0,-40) error_label.add_flag(lv.obj.FLAG.HIDDEN) print("create_ui: Creating scanning label") - scanning_label=lv.label(subwindow) + scanning_label=lv.label(appscreen) scanning_label.set_text("Scanning...") scanning_label.align(lv.ALIGN.CENTER,0,0) scanning_label.add_flag(lv.obj.FLAG.HIDDEN) print("create_ui: Creating Scan button") - scan_button=lv.button(subwindow) + scan_button=lv.button(appscreen) scan_button.set_size(80,30) scan_button.align(lv.ALIGN.BOTTOM_MID,0,-5) label=lv.label(scan_button) @@ -242,11 +243,9 @@ def create_ui(subwindow): load_config() -main_subwindow=appscreen -#create_ui(subwindow) -create_ui(appscreen) +create_ui() -import time -while appscreen == lv.screen_active() or password_page == lv.screen_active(): - time.sleep_ms(100) # not too long, otherwise touch events get lost +#import time +#while appscreen == lv.screen_active() or password_page == lv.screen_active(): +# time.sleep_ms(100) # not too long, otherwise touch events get lost diff --git a/internal_filesystem/lib/display_driver.py b/internal_filesystem/lib/display_driver.py new file mode 100644 index 00000000..9dc1e63e --- /dev/null +++ b/internal_filesystem/lib/display_driver.py @@ -0,0 +1,4 @@ +print("There's no need to import a display_driver module, as the display has already been initialized.") +print("But since the LVGL simulator at https://sim.lvgl.io/v9.0/micropython/ports/webassembly/ requires it,") +print("we've included this empty module just to avoid an ImportError if you're copy-pasting from there.") +print("Happy coding!") diff --git a/internal_filesystem/main.py b/internal_filesystem/main.py index 4c458915..8a5fda65 100644 --- a/internal_filesystem/main.py +++ b/internal_filesystem/main.py @@ -48,9 +48,9 @@ drawer_open=False rootscreen = lv.screen_active() -rootscreen.set_style_bg_color(lv.color_hex(0x444444), 0) +#rootscreen.set_style_bg_color(lv.color_hex(0x444444), 0) rootlabel = lv.label(rootscreen) -rootlabel.set_text("Welcome to PiggyOS!") +rootlabel.set_text("Welcome!") rootlabel.align(lv.ALIGN.CENTER, 0, 0) def open_drawer(): @@ -295,17 +295,17 @@ def execute_script(script_source, is_file, is_launcher, is_graphical): prevscreen = lv.screen_active() newscreen=lv.obj() newscreen.set_size(lv.pct(100),lv.pct(100)) - timer1, timer2, timer3, timer4 = add_notification_bar(newscreen) - subwindow = lv.obj(newscreen) - subwindow.set_size(TFT_HOR_RES, TFT_VER_RES - NOTIFICATION_BAR_HEIGHT) - subwindow.set_pos(0, NOTIFICATION_BAR_HEIGHT) - subwindow.set_style_border_width(0, 0) - subwindow.set_style_pad_all(0, 0) + #timer1, timer2, timer3, timer4 = add_notification_bar(newscreen) + #subwindow = lv.obj(newscreen) + #subwindow.set_size(TFT_HOR_RES, TFT_VER_RES - NOTIFICATION_BAR_HEIGHT) + #subwindow.set_pos(0, NOTIFICATION_BAR_HEIGHT) + #subwindow.set_style_border_width(0, 0) + #subwindow.set_style_pad_all(0, 0) lv.screen_load(newscreen) script_globals = { 'lv': lv, 'appscreen': newscreen, - 'subwindow': subwindow, + #'subwindow': subwindow, 'start_app': start_app, # for launcher apps 'parse_manifest': parse_manifest, # for launcher apps 'restart_launcher': restart_launcher, # for appstore apps @@ -322,7 +322,7 @@ def execute_script(script_source, is_file, is_launcher, is_graphical): tb = getattr(e, '__traceback__', None) traceback.print_exception(type(e), e, tb) print(f"Thread {thread_id}: script {compile_name} finished") - if is_graphical and prevscreen and not is_launcher: + if False and is_graphical and prevscreen and not is_launcher: # disabled this for now print("/main.py: execute_script(): deleting timers...") timer1.delete() timer2.delete() diff --git a/scripts/build_lvgl_micropython.sh b/scripts/build_lvgl_micropython.sh index 9d15f81d..81de7e13 100755 --- a/scripts/build_lvgl_micropython.sh +++ b/scripts/build_lvgl_micropython.sh @@ -7,4 +7,7 @@ pushd ~/sources/lvgl_micropython python3 make.py --ota --partition-size=4194304 --flash-size=16 esp32 BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT DISPLAY=st7789 INDEV=cst816s USER_C_MODULE="/home/user/sources/micropython-camera-API/src/micropython.cmake" FROZEN_MANIFEST=~/sources/PiggyOS/manifest.py +# dev build: +#python3 make.py --ota --partition-size=4194304 --flash-size=16 esp32 BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT DISPLAY=st7789 INDEV=cst816s USER_C_MODULE="/home/user/sources/micropython-camera-API/src/micropython.cmake" + popd