Skip to content

Commit 46d51ab

Browse files
Also think about the children of objects
1 parent d7bf459 commit 46d51ab

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

internal_filesystem/lib/mpos/ui/focus_direction.py

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,8 @@
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-
185
def 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

2815
def 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

4333
def 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+
83103
def move_focus_direction(angle):
84104
focus_group = lv.group_get_default()
85105
if not focus_group:

0 commit comments

Comments
 (0)