Skip to content

Commit 49dc270

Browse files
Fix KeyPad focus handling on devices without touch screen
1 parent 6ae1778 commit 49dc270

File tree

5 files changed

+49
-15
lines changed

5 files changed

+49
-15
lines changed

internal_filesystem/boot_fri3d-2024.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def keypad_read_cb(indev, data):
210210
indev = lv.indev_create()
211211
indev.set_type(lv.INDEV_TYPE.KEYPAD)
212212
indev.set_read_cb(keypad_read_cb)
213-
indev.set_group(group)
213+
indev.set_group(group) # is this needed? maybe better to move the default group creation to main.py so it's available everywhere...
214214
disp = lv.display_get_default() # NOQA
215215
indev.set_display(disp) # different from display
216216
indev.enable(True) # NOQA

internal_filesystem/lib/mpos/apps.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,7 @@ def _launch_activity(intent, result_callback=None):
334334
activity.intent = intent
335335
activity._result_callback = result_callback # Pass callback to activity
336336
start_time = utime.ticks_ms()
337-
# Remove objects from previous screens from the focus group:
338-
focusgroup = lv.group_get_default()
339-
if focusgroup: # on esp32 this may not be set
340-
focusgroup.remove_all_objs() # might be better to save and restore the group for "back" actions
337+
mpos.ui.save_and_clear_current_focusgroup()
341338
activity.onCreate()
342339
end_time = utime.ticks_diff(utime.ticks_ms(), start_time)
343340
print(f"apps.py _launch_activity: activity.onCreate took {end_time}ms")

internal_filesystem/lib/mpos/ui/__init__.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import mpos.wifi
55
from mpos.ui.anim import WidgetAnimator
66
import mpos.ui.topmenu
7+
import mpos.util
78

89
th = None
910

@@ -172,30 +173,44 @@ def close_top_layer_msgboxes():
172173
print(f"Top layer still has {child_count} children")
173174

174175

175-
screen_stack = [] # Stack of (activity, screen) tuples
176+
screen_stack = [] # Stack of (activity, screen, focusgroup) tuples
176177

177178
def empty_screen_stack():
178179
global screen_stack
179180
screen_stack.clear()
180181

182+
def move_focusgroup_objects(fromgroup, togroup):
183+
print(f"Moving {fromgroup.get_obj_count()} focused objects")
184+
for objnr in range(fromgroup.get_obj_count()):
185+
#print(f"saving object {objnr} from default focusgroup to current_focusgroup")
186+
next = fromgroup.get_obj_by_index(0)
187+
mpos.util.print_lvgl_widget(next)
188+
if next:
189+
togroup.add_obj(next)
190+
print("Done moving focused objects")
191+
192+
193+
# Saves all objects from the default focus group in the activity's focus group
194+
def save_and_clear_current_focusgroup():
195+
global screen_stack
196+
if len(screen_stack) > 0:
197+
current_activity, current_screen, current_focusgroup = screen_stack[-1]
198+
move_focusgroup_objects(lv.group_get_default(), current_focusgroup)
199+
181200
# new_activity might be None for compatibility, can be removed if compatibility is no longer needed
182201
def setContentView(new_activity, new_screen):
183202
global screen_stack
184203

185204
# Get current activity and screen
186-
current_activity, current_screen = None, None
187205
if len(screen_stack) > 0:
188-
current_activity, current_screen = screen_stack[-1]
189-
190-
if current_activity and current_screen:
206+
current_activity, current_screen, current_focusgroup = screen_stack[-1]
191207
# Notify current activity that it's being backgrounded:
192208
current_activity.onPause(current_screen)
193209
current_activity.onStop(current_screen)
194210
# don't destroy because the user might go back to it
195211

196-
# Start the new one:
197-
print("Appending screen to screen_stack")
198-
screen_stack.append((new_activity, new_screen))
212+
print("Appending new activity, new screen and new focusgroup to screen_stack")
213+
screen_stack.append((new_activity, new_screen, lv.group_create()))
199214
close_top_layer_msgboxes() # otherwise they remain
200215
if new_activity:
201216
#start_time = utime.ticks_ms()
@@ -215,11 +230,13 @@ def setContentView(new_activity, new_screen):
215230
#print(f"ui.py setContentView: new_activity.onResume took {end_time}ms")
216231

217232
def remove_and_stop_current_activity():
218-
current_activity, current_screen = screen_stack.pop() # Get current activity and its screen
233+
current_activity, current_screen, current_focusgroup = screen_stack.pop() # Get current activity and its screen
219234
if current_activity:
220235
current_activity.onPause(current_screen)
221236
current_activity.onStop(current_screen)
222237
current_activity.onDestroy(current_screen)
238+
if current_screen:
239+
current_screen.clean() # should free up memory
223240

224241
def back_screen():
225242
print("back_screen() running")
@@ -229,11 +246,14 @@ def back_screen():
229246
return False # No previous screen
230247
#close_top_layer_msgboxes() # would be nicer to "cancel" all input events
231248
remove_and_stop_current_activity()
232-
prev_activity, prev_screen = screen_stack[-1] # load previous screen
249+
prev_activity, prev_screen, prev_focusgroup = screen_stack[-1] # load previous screen
233250
print("loading prev_screen with animation")
234251
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
252+
# Restore the focused objects
253+
move_focusgroup_objects(prev_focusgroup, lv.group_get_default())
235254
if prev_activity:
236255
prev_activity.onResume(prev_screen)
256+
print(f"5 default focus group has {lv.group_get_default().get_obj_count()} items")
237257
if len(screen_stack) == 1:
238258
mpos.ui.topmenu.open_bar()
239259

internal_filesystem/lib/mpos/util.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import lvgl as lv
2+
13
def urldecode(s):
24
result = ""
35
i = 0
@@ -9,3 +11,13 @@ def urldecode(s):
911
result += s[i]
1012
i += 1
1113
return result
14+
15+
def print_lvgl_widget(obj, depth=0):
16+
if obj:
17+
label = ""
18+
if isinstance(obj,lv.label):
19+
label = f"has label {obj.get_text()}"
20+
padding = " " * depth
21+
print(f"{padding}{obj} with size {obj.get_width()}x{obj.get_height()} {label}")
22+
for childnr in range(obj.get_child_count()):
23+
print_lvgl_widget(obj.get_child(childnr), depth+1)

internal_filesystem/main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
mpos.ui.topmenu.create_drawer(display)
3737
mpos.ui.handle_back_swipe()
3838
mpos.ui.handle_top_swipe()
39+
# Clear top menu, notification bar, swipe back and swipe down buttons
40+
# Ideally, these would be stored in a different focusgroup that is used when the user opens the drawer
41+
focusgroup = lv.group_get_default()
42+
if focusgroup: # on esp32 this may not be set
43+
focusgroup.remove_all_objs() # might be better to save and restore the group for "back" actions
3944
mpos.ui.th = task_handler.TaskHandler(duration=5) # 5ms is recommended for MicroPython+LVGL on desktop
4045

4146
try:

0 commit comments

Comments
 (0)