You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Fix KeyPad focus handling on devices without touch screen
This commit is contained in:
@@ -210,7 +210,7 @@ group.set_default()
|
||||
indev = lv.indev_create()
|
||||
indev.set_type(lv.INDEV_TYPE.KEYPAD)
|
||||
indev.set_read_cb(keypad_read_cb)
|
||||
indev.set_group(group)
|
||||
indev.set_group(group) # is this needed? maybe better to move the default group creation to main.py so it's available everywhere...
|
||||
disp = lv.display_get_default() # NOQA
|
||||
indev.set_display(disp) # different from display
|
||||
indev.enable(True) # NOQA
|
||||
|
||||
@@ -334,10 +334,7 @@ class ActivityNavigator:
|
||||
activity.intent = intent
|
||||
activity._result_callback = result_callback # Pass callback to activity
|
||||
start_time = utime.ticks_ms()
|
||||
# Remove objects from previous screens from the focus group:
|
||||
focusgroup = lv.group_get_default()
|
||||
if focusgroup: # on esp32 this may not be set
|
||||
focusgroup.remove_all_objs() # might be better to save and restore the group for "back" actions
|
||||
mpos.ui.save_and_clear_current_focusgroup()
|
||||
activity.onCreate()
|
||||
end_time = utime.ticks_diff(utime.ticks_ms(), start_time)
|
||||
print(f"apps.py _launch_activity: activity.onCreate took {end_time}ms")
|
||||
|
||||
@@ -4,6 +4,7 @@ import mpos.time
|
||||
import mpos.wifi
|
||||
from mpos.ui.anim import WidgetAnimator
|
||||
import mpos.ui.topmenu
|
||||
import mpos.util
|
||||
|
||||
th = None
|
||||
|
||||
@@ -172,30 +173,44 @@ def close_top_layer_msgboxes():
|
||||
print(f"Top layer still has {child_count} children")
|
||||
|
||||
|
||||
screen_stack = [] # Stack of (activity, screen) tuples
|
||||
screen_stack = [] # Stack of (activity, screen, focusgroup) tuples
|
||||
|
||||
def empty_screen_stack():
|
||||
global screen_stack
|
||||
screen_stack.clear()
|
||||
|
||||
def move_focusgroup_objects(fromgroup, togroup):
|
||||
print(f"Moving {fromgroup.get_obj_count()} focused objects")
|
||||
for objnr in range(fromgroup.get_obj_count()):
|
||||
#print(f"saving object {objnr} from default focusgroup to current_focusgroup")
|
||||
next = fromgroup.get_obj_by_index(0)
|
||||
mpos.util.print_lvgl_widget(next)
|
||||
if next:
|
||||
togroup.add_obj(next)
|
||||
print("Done moving focused objects")
|
||||
|
||||
|
||||
# Saves all objects from the default focus group in the activity's focus group
|
||||
def save_and_clear_current_focusgroup():
|
||||
global screen_stack
|
||||
if len(screen_stack) > 0:
|
||||
current_activity, current_screen, current_focusgroup = screen_stack[-1]
|
||||
move_focusgroup_objects(lv.group_get_default(), current_focusgroup)
|
||||
|
||||
# new_activity might be None for compatibility, can be removed if compatibility is no longer needed
|
||||
def setContentView(new_activity, new_screen):
|
||||
global screen_stack
|
||||
|
||||
# Get current activity and screen
|
||||
current_activity, current_screen = None, None
|
||||
if len(screen_stack) > 0:
|
||||
current_activity, current_screen = screen_stack[-1]
|
||||
|
||||
if current_activity and current_screen:
|
||||
current_activity, current_screen, current_focusgroup = screen_stack[-1]
|
||||
# Notify current activity that it's being backgrounded:
|
||||
current_activity.onPause(current_screen)
|
||||
current_activity.onStop(current_screen)
|
||||
# don't destroy because the user might go back to it
|
||||
|
||||
# Start the new one:
|
||||
print("Appending screen to screen_stack")
|
||||
screen_stack.append((new_activity, new_screen))
|
||||
print("Appending new activity, new screen and new focusgroup to screen_stack")
|
||||
screen_stack.append((new_activity, new_screen, lv.group_create()))
|
||||
close_top_layer_msgboxes() # otherwise they remain
|
||||
if new_activity:
|
||||
#start_time = utime.ticks_ms()
|
||||
@@ -215,11 +230,13 @@ def setContentView(new_activity, new_screen):
|
||||
#print(f"ui.py setContentView: new_activity.onResume took {end_time}ms")
|
||||
|
||||
def remove_and_stop_current_activity():
|
||||
current_activity, current_screen = screen_stack.pop() # Get current activity and its screen
|
||||
current_activity, current_screen, current_focusgroup = screen_stack.pop() # Get current activity and its screen
|
||||
if current_activity:
|
||||
current_activity.onPause(current_screen)
|
||||
current_activity.onStop(current_screen)
|
||||
current_activity.onDestroy(current_screen)
|
||||
if current_screen:
|
||||
current_screen.clean() # should free up memory
|
||||
|
||||
def back_screen():
|
||||
print("back_screen() running")
|
||||
@@ -229,11 +246,14 @@ def back_screen():
|
||||
return False # No previous screen
|
||||
#close_top_layer_msgboxes() # would be nicer to "cancel" all input events
|
||||
remove_and_stop_current_activity()
|
||||
prev_activity, prev_screen = screen_stack[-1] # load previous screen
|
||||
prev_activity, prev_screen, prev_focusgroup = screen_stack[-1] # load previous screen
|
||||
print("loading prev_screen with animation")
|
||||
lv.screen_load_anim(prev_screen, lv.SCR_LOAD_ANIM.OVER_RIGHT, 500, 0, True) # True means delete the old screen, which is fine as we're going back and current_activity.onDestroy() was called
|
||||
# Restore the focused objects
|
||||
move_focusgroup_objects(prev_focusgroup, lv.group_get_default())
|
||||
if prev_activity:
|
||||
prev_activity.onResume(prev_screen)
|
||||
print(f"5 default focus group has {lv.group_get_default().get_obj_count()} items")
|
||||
if len(screen_stack) == 1:
|
||||
mpos.ui.topmenu.open_bar()
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import lvgl as lv
|
||||
|
||||
def urldecode(s):
|
||||
result = ""
|
||||
i = 0
|
||||
@@ -9,3 +11,13 @@ def urldecode(s):
|
||||
result += s[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def print_lvgl_widget(obj, depth=0):
|
||||
if obj:
|
||||
label = ""
|
||||
if isinstance(obj,lv.label):
|
||||
label = f"has label {obj.get_text()}"
|
||||
padding = " " * depth
|
||||
print(f"{padding}{obj} with size {obj.get_width()}x{obj.get_height()} {label}")
|
||||
for childnr in range(obj.get_child_count()):
|
||||
print_lvgl_widget(obj.get_child(childnr), depth+1)
|
||||
|
||||
@@ -36,6 +36,11 @@ mpos.ui.topmenu.create_notification_bar()
|
||||
mpos.ui.topmenu.create_drawer(display)
|
||||
mpos.ui.handle_back_swipe()
|
||||
mpos.ui.handle_top_swipe()
|
||||
# Clear top menu, notification bar, swipe back and swipe down buttons
|
||||
# Ideally, these would be stored in a different focusgroup that is used when the user opens the drawer
|
||||
focusgroup = lv.group_get_default()
|
||||
if focusgroup: # on esp32 this may not be set
|
||||
focusgroup.remove_all_objs() # might be better to save and restore the group for "back" actions
|
||||
mpos.ui.th = task_handler.TaskHandler(duration=5) # 5ms is recommended for MicroPython+LVGL on desktop
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user