22import lvgl as lv
33import 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-
185def get_object_center (obj ):
19- """Calculate the center (x, y) of an object."""
6+ """Calculate the center (x, y) of an object based on its position and size ."""
207width = obj .get_width ()
218height = obj .get_height ()
229x = obj .get_x ()
@@ -26,7 +13,10 @@ def get_object_center(obj):
2613return center_x ,center_y
2714
2815def compute_angle_to_object (from_obj ,to_obj ):
29- """Compute the clockwise angle (degrees) from from_obj's center to to_obj's center (0° = UP)."""
16+ """
17+ Compute the clockwise angle (degrees) from from_obj's center to to_obj's center.
18+ Convention: 0° = UP, 90° = RIGHT, 180° = DOWN, 270° = LEFT (clockwise).
19+ """
3020# Get centers
3121from_x ,from_y = get_object_center (from_obj )
3222to_x ,to_y = get_object_center (to_obj )
@@ -35,43 +25,60 @@ def compute_angle_to_object(from_obj, to_obj):
3525dx = to_x - from_x
3626dy = to_y - from_y
3727
38- # Calculate angle (0° = UP, 90° = RIGHT,clockwise )
39- angle_rad = math .atan2 (- dx ,dy )# -dx, dyfor 0° = UP
28+ # Calculate angle (0° = UP, 90° = RIGHT,180° = DOWN, 270° = LEFT )
29+ angle_rad = math .atan2 (- dx ,dy )# -dx, dyaligns UP with 0°, clockwise
4030angle_deg = math .degrees (angle_rad )
4131return (angle_deg + 360 )% 360 # Normalize to [0, 360)
4232
4333def find_closest_obj_in_direction (focus_group ,current_focused ,direction_degrees ,angle_tolerance = 45 ):
34+ """
35+ Find the closest object (including children) in the specified direction from the current focused object.
36+ Direction is in degrees: 0° = UP, 90° = RIGHT, 180° = DOWN, 270° = LEFT (clockwise).
37+ Returns the closest object within ±angle_tolerance of direction_degrees, or None.
38+ """
4439if not current_focused :
4540print ("No current focused object." )
4641return None
47-
42+
43+ print (f"Current focused object:{ current_focused } " )
44+ print (f"Default focus group has{ focus_group .get_obj_count ()} items" )
45+
4846closest_obj = None
4947min_distance = float ('inf' )
48+ current_x ,current_y = get_object_center (current_focused )
5049
51- # Iterate through objects in the focus group
52- for objnr in range ( focus_group . get_obj_count ()):
53- obj = focus_group . get_obj_by_index ( objnr )
54- if obj is current_focused :
55- #print(f"Skipping { obj} because it's the currently focused object.")
56- continue
50+ def process_object ( obj , depth = 0 ):
51+ """Recursively process an object and its children to find the closest indirection."""
52+ nonlocal closest_obj , min_distance
53+
54+ if obj is None or obj is current_focused :
55+ return
5756
5857# Compute angle to the object
5958angle_deg = compute_angle_to_object (current_focused ,obj )
60- #print(f"angle_deg is {angle_deg} for") ; mpos.util.print_lvgl_widget(obj)
61-
59+
6260# Check if object is in the desired direction (within ±angle_tolerance)
6361angle_diff = min ((angle_deg - direction_degrees )% 360 , (direction_degrees - angle_deg )% 360 )
6462if angle_diff <= angle_tolerance :
6563# Calculate Euclidean distance
66- current_x ,current_y = get_object_center (current_focused )
6764obj_x ,obj_y = get_object_center (obj )
6865distance = math .sqrt ((obj_x - current_x )** 2 + (obj_y - current_y )** 2 )
6966
7067# Update closest object if this one is closer
7168if distance < min_distance :
7269min_distance = distance
7370closest_obj = obj
74-
71+
72+ # Process children
73+ for childnr in range (obj .get_child_count ()):
74+ child = obj .get_child (childnr )
75+ process_object (child ,depth + 1 )
76+
77+ # Iterate through objects in the focus group
78+ for objnr in range (focus_group .get_obj_count ()):
79+ obj = focus_group .get_obj_by_index (objnr )
80+ process_object (obj )
81+
7582# Result
7683if closest_obj :
7784print (f"Closest object in direction{ direction_degrees } °:{ closest_obj } " )
@@ -80,6 +87,19 @@ def find_closest_obj_in_direction(focus_group, current_focused, direction_degree
8087
8188return closest_obj
8289
90+
91+ # This function is missing so emulate it using focus_next():
92+ def emulate_focus_obj (focusgroup ,target ):
93+ for objnr in range (focusgroup .get_obj_count ()):
94+ currently_focused = focusgroup .get_focused ()
95+ #print ("emulate_focus_obj: currently focused:") ; mpos.util.print_lvgl_widget(currently_focused)
96+ if currently_focused is target :
97+ print ("emulate_focus_obj: found target, stopping" )
98+ return
99+ else :
100+ focusgroup .focus_next ()
101+ print ("WARNING: emulate_focus_obj failed to find target" )
102+
83103def move_focus_direction (angle ):
84104focus_group = lv .group_get_default ()
85105if not focus_group :