From 2a70e32375444ffe289aafa80b091ad8116f4528 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sun, 25 Jan 2026 21:17:20 +0100 Subject: [PATCH] Add InputManager framework --- .../com.micropythonos.draw/assets/draw.py | 7 +-- internal_filesystem/lib/mpos/__init__.py | 4 +- .../lib/mpos/ui/display_metrics.py | 10 ---- .../lib/mpos/ui/focus_direction.py | 21 +-------- .../lib/mpos/ui/input_manager.py | 47 +++++++++++++++++++ internal_filesystem/lib/mpos/ui/keyboard.py | 5 +- internal_filesystem/lib/mpos/ui/topmenu.py | 3 +- internal_filesystem/lib/mpos/ui/view.py | 4 +- 8 files changed, 61 insertions(+), 40 deletions(-) create mode 100644 internal_filesystem/lib/mpos/ui/input_manager.py diff --git a/internal_filesystem/apps/com.micropythonos.draw/assets/draw.py b/internal_filesystem/apps/com.micropythonos.draw/assets/draw.py index 8740bbca..30f48b97 100644 --- a/internal_filesystem/apps/com.micropythonos.draw/assets/draw.py +++ b/internal_filesystem/apps/com.micropythonos.draw/assets/draw.py @@ -1,5 +1,5 @@ import lvgl as lv -from mpos import Activity, DisplayMetrics +from mpos import Activity, DisplayMetrics, InputManager indev_error_x = 160 indev_error_y = 120 @@ -35,11 +35,8 @@ class Draw(Activity): def touch_cb(self, event): event_code=event.get_code() if event_code not in [19,23,25,26,27,28,29,30,49]: - #name = ui.get_event_name(event_code) - #print(f"lv_event_t: code={event_code}, name={name}") # target={event.get_target()}, user_data={event.get_user_data()}, param={event.get_param()} if event_code == lv.EVENT.PRESSING: # this is probably enough - #if event_code in [lv.EVENT.PRESSED, lv.EVENT.PRESSING, lv.EVENT.LONG_PRESSED, lv.EVENT.LONG_PRESSED_REPEAT]: - x, y = DisplayMetrics.pointer_xy() + x, y = InputManager.pointer_xy() #canvas.set_px(x,y,lv.color_black(),lv.OPA.COVER) # draw a tiny point self.draw_rect(x,y) #self.draw_line(x,y) diff --git a/internal_filesystem/lib/mpos/__init__.py b/internal_filesystem/lib/mpos/__init__.py index fdef8adf..770a074c 100644 --- a/internal_filesystem/lib/mpos/__init__.py +++ b/internal_filesystem/lib/mpos/__init__.py @@ -35,6 +35,7 @@ from .ui.testing import ( # UI utility functions from .ui.display_metrics import DisplayMetrics +from .ui.input_manager import InputManager from .ui.appearance_manager import AppearanceManager from .ui.event import get_event_name, print_event from .ui.view import setContentView, back_screen @@ -73,8 +74,9 @@ __all__ = [ "SettingActivity", "SettingsActivity", "CameraActivity", # UI components "MposKeyboard", - # UI utility - DisplayMetrics and AppearanceManager + # UI utility - DisplayMetrics, InputManager and AppearanceManager "DisplayMetrics", + "InputManager", "AppearanceManager", "get_event_name", "print_event", "setContentView", "back_screen", diff --git a/internal_filesystem/lib/mpos/ui/display_metrics.py b/internal_filesystem/lib/mpos/ui/display_metrics.py index 94e3940c..a01502f4 100644 --- a/internal_filesystem/lib/mpos/ui/display_metrics.py +++ b/internal_filesystem/lib/mpos/ui/display_metrics.py @@ -69,13 +69,3 @@ class DisplayMetrics: """Get maximum dimension (width or height).""" return max(cls._width, cls._height) - @classmethod - def pointer_xy(cls): - """Get current pointer/touch coordinates.""" - import lvgl as lv - indev = lv.indev_active() - if indev: - p = lv.point_t() - indev.get_point(p) - return p.x, p.y - return -1, -1 diff --git a/internal_filesystem/lib/mpos/ui/focus_direction.py b/internal_filesystem/lib/mpos/ui/focus_direction.py index bfed35fe..af439908 100644 --- a/internal_filesystem/lib/mpos/ui/focus_direction.py +++ b/internal_filesystem/lib/mpos/ui/focus_direction.py @@ -144,25 +144,8 @@ def find_closest_obj_in_direction(focus_group, current_focused, direction_degree return closest_obj -# This function is missing so emulate it using focus_next(): -def emulate_focus_obj(focusgroup, target): - if not focusgroup: - print("emulate_focus_obj needs a focusgroup, returning...") - return - if not target: - print("emulate_focus_obj needs a target, returning...") - return - 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 move_focus_direction(angle): + from .input_manager import InputManager focus_group = lv.group_get_default() if not focus_group: print("move_focus_direction: no default focus_group found, returning...") @@ -191,4 +174,4 @@ def move_focus_direction(angle): if o: #print("move_focus_direction: moving focus to:") #mpos.util.print_lvgl_widget(o) - emulate_focus_obj(focus_group, o) + InputManager.emulate_focus_obj(focus_group, o) diff --git a/internal_filesystem/lib/mpos/ui/input_manager.py b/internal_filesystem/lib/mpos/ui/input_manager.py new file mode 100644 index 00000000..4c9574ff --- /dev/null +++ b/internal_filesystem/lib/mpos/ui/input_manager.py @@ -0,0 +1,47 @@ +# lib/mpos/ui/input_manager.py +""" +InputManager - Framework for managing input device interactions. + +Provides a clean API for accessing input device data like pointer/touch coordinates +and focus management. +All methods are class methods, so no instance creation is needed. +""" + + +class InputManager: + """ + Input manager singleton for handling input device interactions. + + Provides static/class methods for accessing input device properties and data. + """ + + @classmethod + def pointer_xy(cls): + """Get current pointer/touch coordinates.""" + import lvgl as lv + indev = lv.indev_active() + if indev: + p = lv.point_t() + indev.get_point(p) + return p.x, p.y + return -1, -1 + + @classmethod + def emulate_focus_obj(cls, focusgroup, target): + """ + Emulate setting focus to a specific object in the focus group. + This function is needed because LVGL doesn't have a direct set_focus method. + """ + if not focusgroup: + print("emulate_focus_obj needs a focusgroup, returning...") + return + if not target: + print("emulate_focus_obj needs a target, returning...") + return + for objnr in range(focusgroup.get_obj_count()): + currently_focused = focusgroup.get_focused() + if currently_focused is target: + return + else: + focusgroup.focus_next() + print("WARNING: emulate_focus_obj failed to find target") diff --git a/internal_filesystem/lib/mpos/ui/keyboard.py b/internal_filesystem/lib/mpos/ui/keyboard.py index 05d90a2d..6ee72d6c 100644 --- a/internal_filesystem/lib/mpos/ui/keyboard.py +++ b/internal_filesystem/lib/mpos/ui/keyboard.py @@ -240,8 +240,9 @@ class MposKeyboard: def focus_on_keyboard(self, timer=None): default_group = lv.group_get_default() if default_group: - from .focus_direction import emulate_focus_obj, move_focus_direction - emulate_focus_obj(default_group, self._keyboard) + from .input_manager import InputManager + from .focus_direction import move_focus_direction + InputManager.emulate_focus_obj(default_group, self._keyboard) def scroll_back_after_hide(self, timer): self._parent.scroll_to_y(self._saved_scroll_y, True) diff --git a/internal_filesystem/lib/mpos/ui/topmenu.py b/internal_filesystem/lib/mpos/ui/topmenu.py index 236f54e4..40deaf85 100644 --- a/internal_filesystem/lib/mpos/ui/topmenu.py +++ b/internal_filesystem/lib/mpos/ui/topmenu.py @@ -5,6 +5,7 @@ import mpos.battery_voltage from .display_metrics import DisplayMetrics from .appearance_manager import AppearanceManager from .util import (get_foreground_app) +from .input_manager import InputManager from . import focus_direction from .widget_animator import WidgetAnimator from mpos.content.app_manager import AppManager @@ -372,7 +373,7 @@ def create_drawer(): def drawer_scroll_callback(event): global scroll_start_y event_code=event.get_code() - x, y = DisplayMetrics.pointer_xy() + x, y = InputManager.pointer_xy() #name = mpos.ui.get_event_name(event_code) #print(f"drawer_scroll: code={event_code}, name={name}, ({x},{y})") if event_code == lv.EVENT.SCROLL_BEGIN and scroll_start_y == None: diff --git a/internal_filesystem/lib/mpos/ui/view.py b/internal_filesystem/lib/mpos/ui/view.py index 5de70666..aced0765 100644 --- a/internal_filesystem/lib/mpos/ui/view.py +++ b/internal_filesystem/lib/mpos/ui/view.py @@ -86,8 +86,8 @@ def back_screen(): if default_group: from .focus import move_focusgroup_objects move_focusgroup_objects(prev_focusgroup, default_group) - from .focus_direction import emulate_focus_obj - emulate_focus_obj(default_group, prev_focused) + from .input_manager import InputManager + InputManager.emulate_focus_obj(default_group, prev_focused) if prev_activity: prev_activity.onResume(prev_screen)