Skip to content

Commit d7bf459

Browse files
Move focus with arrows works on desktop
1 parent e0e87dd commit d7bf459

File tree

4 files changed

+58
-41
lines changed

4 files changed

+58
-41
lines changed

internal_filesystem/boot_fri3d-2024.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
import lvgl as lv
1111
import task_handler
1212

13-
import mpos.ui
1413
import mpos.info
14+
import mpos.ui
15+
import mpos.ui.focus_direction
1516

1617
mpos.info.set_hardware_id("fri3d-2024")
1718

@@ -184,10 +185,11 @@ def keypad_read_cb(indev, data):
184185
current_key = lv.KEY.END
185186
else:
186187
# Check joystick
187-
joystick = read_joystick_angle(0.25)
188-
if joystick:
189-
if time.time() < 60:
190-
print(f"joystick angle: {joystick}")
188+
angle = read_joystick_angle(0.25)
189+
if angle and time.time() < 60:
190+
print(f"joystick angle: {angle}")
191+
mpos.ui.focus_direction.move_focus_direction(angle)
192+
joystick = read_joystick()
191193
if joystick == "LEFT":
192194
current_key = lv.KEY.LEFT
193195
elif joystick == "RIGHT":

internal_filesystem/boot_unix.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import mpos.indev.mpos_sdl_keyboard
1212
import mpos.info
1313
import mpos.ui
14+
import mpos.ui.focus_direction
1415

1516
mpos.info.set_hardware_id("linux-desktop")
1617

@@ -63,9 +64,18 @@ def catch_escape_key(indev, indev_data):
6364
#state = indev_data.state
6465
#print(f"indev_data: {state} and {key}") # this catches the previous key release instead of the next key press
6566
pressed, code = sdlkeyboard._get_key() # get the current key and state
66-
#print(f"catch_escape_key caught: {pressed}, {code}")
67+
print(f"catch_escape_key caught: {pressed}, {code}")
6768
if pressed == 1 and code == 27:
6869
mpos.ui.back_screen()
70+
elif pressed == 1 and code == lv.KEY.RIGHT:
71+
mpos.ui.focus_direction.move_focus_direction(270)
72+
elif pressed == 1 and code == lv.KEY.LEFT:
73+
mpos.ui.focus_direction.move_focus_direction(90)
74+
elif pressed == 1 and code == lv.KEY.UP:
75+
mpos.ui.focus_direction.move_focus_direction(180)
76+
elif pressed == 1 and code == lv.KEY.DOWN:
77+
mpos.ui.focus_direction.move_focus_direction(0)
78+
6979
sdlkeyboard._read(indev, indev_data)
7080

7181
#import sdl_keyboard

internal_filesystem/lib/mpos/ui/__init__.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import mpos.time
44
import mpos.wifi
55
from mpos.ui.anim import WidgetAnimator
6+
import mpos.ui.focus_direction
67
import mpos.ui.topmenu
78
import mpos.util
89

@@ -244,17 +245,6 @@ def remove_and_stop_current_activity():
244245
if current_screen:
245246
current_screen.clean() # should free up memory
246247

247-
# This function is missing so emulate it using focus_next():
248-
def emulate_focus_obj(focusgroup, to_focus):
249-
for objnr in range(focusgroup.get_obj_count()):
250-
obj = focusgroup.get_obj_by_index(objnr)
251-
#print ("checking obj for equality...")
252-
mpos.util.print_lvgl_widget(obj)
253-
if obj is to_focus:
254-
#print("found it!")
255-
break
256-
else:
257-
focusgroup.focus_next()
258248

259249
def back_screen():
260250
print("back_screen() running")
@@ -272,7 +262,7 @@ def back_screen():
272262
move_focusgroup_objects(prev_focusgroup, default_focusgroup)
273263
print("restoring prev_focused_object: ")
274264
mpos.util.print_lvgl_widget(prev_focused_object)
275-
emulate_focus_obj(default_focusgroup, prev_focused_object) # LVGL 9.3 should have: default_focusgroup.focus_obj(prev_focused_object)
265+
mpos.ui.focus_direction.emulate_focus_obj(default_focusgroup, prev_focused_object) # LVGL 9.3 should have: default_focusgroup.focus_obj(prev_focused_object)
276266
if prev_activity:
277267
prev_activity.onResume(prev_screen)
278268
print(f"after onResume, default focus group has {lv.group_get_default().get_obj_count()} items")

internal_filesystem/lib/mpos/ui/focus_direction.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
import lvgl as lv
33
import mpos.util
44

5+
6+
# This function is missing so emulate it using focus_next():
7+
def emulate_focus_obj(focusgroup, target):
8+
for objnr in range(focusgroup.get_obj_count()):
9+
currently_focused = focusgroup.get_focused()
10+
#print ("emulate_focus_obj: currently focused:") ; mpos.util.print_lvgl_widget(currently_focused)
11+
if currently_focused is target:
12+
print("emulate_focus_obj: found target, stopping")
13+
return
14+
else:
15+
focusgroup.focus_next()
16+
print("WARNING: emulate_focus_obj failed to find target")
17+
518
def get_object_center(obj):
619
"""Calculate the center (x, y) of an object."""
720
width = obj.get_width()
@@ -27,42 +40,25 @@ def compute_angle_to_object(from_obj, to_obj):
2740
angle_deg = math.degrees(angle_rad)
2841
return (angle_deg + 360) % 360 # Normalize to [0, 360)
2942

30-
def find_closest_obj_in_direction(direction_degrees, angle_tolerance=45):
31-
print(f"default focus group has {lv.group_get_default().get_obj_count()} items")
32-
focusgroup = lv.group_get_default()
33-
for objnr in range(focusgroup.get_obj_count()):
34-
obj = focusgroup.get_obj_by_index(objnr)
35-
print ("checking obj for equality...")
36-
mpos.util.print_lvgl_widget(obj)
37-
print(f"current focus object: {lv.group_get_default().get_focused()}")
38-
39-
"""Find the closest object in the specified direction from the current focused object."""
40-
# Get focus group and current focused object
41-
focus_group = lv.group_get_default()
42-
current_focused = focus_group.get_focused()
43-
43+
def find_closest_obj_in_direction(focus_group, current_focused, direction_degrees, angle_tolerance=45):
4444
if not current_focused:
4545
print("No current focused object.")
4646
return None
47-
48-
print(f"Current focused object: {current_focused}")
49-
print(f"Default focus group has {focus_group.get_obj_count()} items")
50-
47+
5148
closest_obj = None
5249
min_distance = float('inf')
5350

5451
# Iterate through objects in the focus group
5552
for objnr in range(focus_group.get_obj_count()):
5653
obj = focus_group.get_obj_by_index(objnr)
5754
if obj is current_focused:
58-
print(f"Skipping {obj} because it's the currently focused object.")
55+
#print(f"Skipping {obj} because it's the currently focused object.")
5956
continue
6057

6158
# Compute angle to the object
6259
angle_deg = compute_angle_to_object(current_focused, obj)
63-
print(f"angle_deg is {angle_deg} for")
64-
mpos.util.print_lvgl_widget(obj)
65-
60+
#print(f"angle_deg is {angle_deg} for") ; mpos.util.print_lvgl_widget(obj)
61+
6662
# Check if object is in the desired direction (within ±angle_tolerance)
6763
angle_diff = min((angle_deg - direction_degrees) % 360, (direction_degrees - angle_deg) % 360)
6864
if angle_diff <= angle_tolerance:
@@ -75,11 +71,30 @@ def find_closest_obj_in_direction(direction_degrees, angle_tolerance=45):
7571
if distance < min_distance:
7672
min_distance = distance
7773
closest_obj = obj
78-
74+
7975
# Result
8076
if closest_obj:
8177
print(f"Closest object in direction {direction_degrees}°: {closest_obj}")
8278
else:
8379
print(f"No object found in direction {direction_degrees}°")
8480

8581
return closest_obj
82+
83+
def move_focus_direction(angle):
84+
focus_group = lv.group_get_default()
85+
if not focus_group:
86+
print("move_focus_direction: no default focus_group found, returning...")
87+
return
88+
current_focused = focus_group.get_focused()
89+
if not current_focused:
90+
print("move_focus_direction: nothing is focused, choosing the next thing")
91+
focus_group.focus_next()
92+
current_focused = focus_group.get_focused()
93+
if isinstance(current_focused, lv.keyboard):
94+
print("focus is on a keyboard, which has its own move_focus_direction: NOT moving")
95+
return
96+
o = find_closest_obj_in_direction(focus_group, current_focused, angle)
97+
if o:
98+
print("move_focus_direction: moving focus to:")
99+
mpos.util.print_lvgl_widget(o)
100+
emulate_focus_obj(focus_group, o)

0 commit comments

Comments
 (0)