Move focus with arrows works on desktop

This commit is contained in:
Thomas Farstrike
2025-10-20 09:18:15 +02:00
parent e0e87dd5df
commit d7bf4594d8
4 changed files with 58 additions and 41 deletions
+7 -5
View File
@@ -10,8 +10,9 @@ import math
import lvgl as lv
import task_handler
import mpos.ui
import mpos.info
import mpos.ui
import mpos.ui.focus_direction
mpos.info.set_hardware_id("fri3d-2024")
@@ -184,10 +185,11 @@ def keypad_read_cb(indev, data):
current_key = lv.KEY.END
else:
# Check joystick
joystick = read_joystick_angle(0.25)
if joystick:
if time.time() < 60:
print(f"joystick angle: {joystick}")
angle = read_joystick_angle(0.25)
if angle and time.time() < 60:
print(f"joystick angle: {angle}")
mpos.ui.focus_direction.move_focus_direction(angle)
joystick = read_joystick()
if joystick == "LEFT":
current_key = lv.KEY.LEFT
elif joystick == "RIGHT":
+11 -1
View File
@@ -11,6 +11,7 @@ import mpos.clipboard
import mpos.indev.mpos_sdl_keyboard
import mpos.info
import mpos.ui
import mpos.ui.focus_direction
mpos.info.set_hardware_id("linux-desktop")
@@ -63,9 +64,18 @@ def catch_escape_key(indev, indev_data):
#state = indev_data.state
#print(f"indev_data: {state} and {key}") # this catches the previous key release instead of the next key press
pressed, code = sdlkeyboard._get_key() # get the current key and state
#print(f"catch_escape_key caught: {pressed}, {code}")
print(f"catch_escape_key caught: {pressed}, {code}")
if pressed == 1 and code == 27:
mpos.ui.back_screen()
elif pressed == 1 and code == lv.KEY.RIGHT:
mpos.ui.focus_direction.move_focus_direction(270)
elif pressed == 1 and code == lv.KEY.LEFT:
mpos.ui.focus_direction.move_focus_direction(90)
elif pressed == 1 and code == lv.KEY.UP:
mpos.ui.focus_direction.move_focus_direction(180)
elif pressed == 1 and code == lv.KEY.DOWN:
mpos.ui.focus_direction.move_focus_direction(0)
sdlkeyboard._read(indev, indev_data)
#import sdl_keyboard
+2 -12
View File
@@ -3,6 +3,7 @@ import mpos.apps
import mpos.time
import mpos.wifi
from mpos.ui.anim import WidgetAnimator
import mpos.ui.focus_direction
import mpos.ui.topmenu
import mpos.util
@@ -244,17 +245,6 @@ def remove_and_stop_current_activity():
if current_screen:
current_screen.clean() # should free up memory
# This function is missing so emulate it using focus_next():
def emulate_focus_obj(focusgroup, to_focus):
for objnr in range(focusgroup.get_obj_count()):
obj = focusgroup.get_obj_by_index(objnr)
#print ("checking obj for equality...")
mpos.util.print_lvgl_widget(obj)
if obj is to_focus:
#print("found it!")
break
else:
focusgroup.focus_next()
def back_screen():
print("back_screen() running")
@@ -272,7 +262,7 @@ def back_screen():
move_focusgroup_objects(prev_focusgroup, default_focusgroup)
print("restoring prev_focused_object: ")
mpos.util.print_lvgl_widget(prev_focused_object)
emulate_focus_obj(default_focusgroup, prev_focused_object) # LVGL 9.3 should have: default_focusgroup.focus_obj(prev_focused_object)
mpos.ui.focus_direction.emulate_focus_obj(default_focusgroup, prev_focused_object) # LVGL 9.3 should have: default_focusgroup.focus_obj(prev_focused_object)
if prev_activity:
prev_activity.onResume(prev_screen)
print(f"after onResume, default focus group has {lv.group_get_default().get_obj_count()} items")
@@ -2,6 +2,19 @@ import math
import lvgl as lv
import mpos.util
# This function is missing so emulate it using focus_next():
def emulate_focus_obj(focusgroup, target):
for objnr in range(focusgroup.get_obj_count()):
currently_focused = focusgroup.get_focused()
#print ("emulate_focus_obj: currently focused:") ; mpos.util.print_lvgl_widget(currently_focused)
if currently_focused is target:
print("emulate_focus_obj: found target, stopping")
return
else:
focusgroup.focus_next()
print("WARNING: emulate_focus_obj failed to find target")
def get_object_center(obj):
"""Calculate the center (x, y) of an object."""
width = obj.get_width()
@@ -27,27 +40,11 @@ def compute_angle_to_object(from_obj, to_obj):
angle_deg = math.degrees(angle_rad)
return (angle_deg + 360) % 360 # Normalize to [0, 360)
def find_closest_obj_in_direction(direction_degrees, angle_tolerance=45):
print(f"default focus group has {lv.group_get_default().get_obj_count()} items")
focusgroup = lv.group_get_default()
for objnr in range(focusgroup.get_obj_count()):
obj = focusgroup.get_obj_by_index(objnr)
print ("checking obj for equality...")
mpos.util.print_lvgl_widget(obj)
print(f"current focus object: {lv.group_get_default().get_focused()}")
"""Find the closest object in the specified direction from the current focused object."""
# Get focus group and current focused object
focus_group = lv.group_get_default()
current_focused = focus_group.get_focused()
def find_closest_obj_in_direction(focus_group, current_focused, direction_degrees, angle_tolerance=45):
if not current_focused:
print("No current focused object.")
return None
print(f"Current focused object: {current_focused}")
print(f"Default focus group has {focus_group.get_obj_count()} items")
closest_obj = None
min_distance = float('inf')
@@ -55,14 +52,13 @@ def find_closest_obj_in_direction(direction_degrees, angle_tolerance=45):
for objnr in range(focus_group.get_obj_count()):
obj = focus_group.get_obj_by_index(objnr)
if obj is current_focused:
print(f"Skipping {obj} because it's the currently focused object.")
#print(f"Skipping {obj} because it's the currently focused object.")
continue
# Compute angle to the object
angle_deg = compute_angle_to_object(current_focused, obj)
print(f"angle_deg is {angle_deg} for")
mpos.util.print_lvgl_widget(obj)
#print(f"angle_deg is {angle_deg} for") ; mpos.util.print_lvgl_widget(obj)
# Check if object is in the desired direction (within ±angle_tolerance)
angle_diff = min((angle_deg - direction_degrees) % 360, (direction_degrees - angle_deg) % 360)
if angle_diff <= angle_tolerance:
@@ -75,7 +71,7 @@ def find_closest_obj_in_direction(direction_degrees, angle_tolerance=45):
if distance < min_distance:
min_distance = distance
closest_obj = obj
# Result
if closest_obj:
print(f"Closest object in direction {direction_degrees}°: {closest_obj}")
@@ -83,3 +79,22 @@ def find_closest_obj_in_direction(direction_degrees, angle_tolerance=45):
print(f"No object found in direction {direction_degrees}°")
return closest_obj
def move_focus_direction(angle):
focus_group = lv.group_get_default()
if not focus_group:
print("move_focus_direction: no default focus_group found, returning...")
return
current_focused = focus_group.get_focused()
if not current_focused:
print("move_focus_direction: nothing is focused, choosing the next thing")
focus_group.focus_next()
current_focused = focus_group.get_focused()
if isinstance(current_focused, lv.keyboard):
print("focus is on a keyboard, which has its own move_focus_direction: NOT moving")
return
o = find_closest_obj_in_direction(focus_group, current_focused, angle)
if o:
print("move_focus_direction: moving focus to:")
mpos.util.print_lvgl_widget(o)
emulate_focus_obj(focus_group, o)