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 ."""
207 width = obj .get_width ()
218 height = obj .get_height ()
229 x = obj .get_x ()
@@ -26,7 +13,10 @@ def get_object_center(obj):
2613 return 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
3121 from_x , from_y = get_object_center (from_obj )
3222 to_x , to_y = get_object_center (to_obj )
@@ -35,43 +25,60 @@ def compute_angle_to_object(from_obj, to_obj):
3525 dx = to_x - from_x
3626 dy = to_y - from_y
3727
38- # Calculate angle (0° = UP, 90° = RIGHT, clockwise )
39- angle_rad = math .atan2 (- dx , dy ) # -dx, dy for 0° = UP
28+ # Calculate angle (0° = UP, 90° = RIGHT, 180° = DOWN, 270° = LEFT )
29+ angle_rad = math .atan2 (- dx , dy ) # -dx, dy aligns UP with 0°, clockwise
4030 angle_deg = math .degrees (angle_rad )
4131 return (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+ """
4439 if not current_focused :
4540 print ("No current focused object." )
4641 return 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+
4846 closest_obj = None
4947 min_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 in direction."""
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
5958 angle_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)
6361 angle_diff = min ((angle_deg - direction_degrees ) % 360 , (direction_degrees - angle_deg ) % 360 )
6462 if angle_diff <= angle_tolerance :
6563 # Calculate Euclidean distance
66- current_x , current_y = get_object_center (current_focused )
6764 obj_x , obj_y = get_object_center (obj )
6865 distance = math .sqrt ((obj_x - current_x )** 2 + (obj_y - current_y )** 2 )
6966
7067 # Update closest object if this one is closer
7168 if distance < min_distance :
7269 min_distance = distance
7370 closest_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
7683 if closest_obj :
7784 print (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
8188 return 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 ):
84104 focus_group = lv .group_get_default ()
85105 if not focus_group :
0 commit comments