Skip to content

Commit 5381310

Browse files
Update InputManager
1 parent a270a94 commit 5381310

File tree

1 file changed

+141
-1
lines changed

1 file changed

+141
-1
lines changed

docs/frameworks/input-manager.md

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# InputManager
22

3-
InputManager is a singleton framework that provides a unified API for managing input device interactions, including pointer/touch coordinates and focus management.
3+
InputManager is a singleton framework that provides a unified API for managing input device interactions, including pointer/touch coordinates, focus management, and input device registration.
44

55
## Overview
66

@@ -11,13 +11,16 @@ InputManager centralizes all input-related operations in a single class with cla
1111
- **Testable** - InputManager can be tested independently
1212
- **Focus Control** - Emulate focus on specific UI objects
1313
- **Pointer Access** - Get current touch/pointer coordinates
14+
- **Device Registration** - Register and query available input devices by type
1415

1516
## Architecture
1617

1718
InputManager is implemented as a singleton using class variables and class methods:
1819

1920
```python
2021
class InputManager:
22+
_registered_indevs = [] # List of registered input devices
23+
2124
@classmethod
2225
def pointer_xy(cls):
2326
"""Get current pointer/touch coordinates."""
@@ -33,6 +36,25 @@ class InputManager:
3336
def emulate_focus_obj(cls, focusgroup, target):
3437
"""Emulate setting focus to a specific object."""
3538
# ... implementation
39+
40+
@classmethod
41+
def register_indev(cls, indev):
42+
"""Register an input device for later querying."""
43+
if indev and indev not in cls._registered_indevs:
44+
cls._registered_indevs.append(indev)
45+
46+
@classmethod
47+
def list_indevs(cls):
48+
"""Get list of all registered input devices."""
49+
return cls._registered_indevs
50+
51+
@classmethod
52+
def has_indev_type(cls, indev_type):
53+
"""Check if any registered input device has the specified type."""
54+
for indev in cls._registered_indevs:
55+
if indev.get_type() == indev_type:
56+
return True
57+
return False
3658
```
3759

3860
No instance creation is needed - all methods are class methods that operate on class variables.
@@ -100,6 +122,55 @@ if focusgroup:
100122
InputManager.emulate_focus_obj(focusgroup, my_button)
101123
```
102124

125+
#### `register_indev(indev)`
126+
Register an input device for later querying by type.
127+
128+
This method is called by board initialization code to register available input devices. Apps can then query these devices without hardcoding hardware IDs.
129+
130+
**Parameters:**
131+
- `indev` (lv.indev): The LVGL input device to register
132+
133+
**Returns:** None
134+
135+
**Example:**
136+
```python
137+
# In board initialization (e.g., fri3d_2024.py)
138+
indev = lv.indev_create()
139+
indev.set_type(lv.INDEV_TYPE.KEYPAD)
140+
indev.set_read_cb(keypad_read_cb)
141+
InputManager.register_indev(indev)
142+
```
143+
144+
#### `list_indevs()`
145+
Get list of all registered input devices.
146+
147+
**Returns:** list - List of registered LVGL input devices
148+
149+
**Example:**
150+
```python
151+
devices = InputManager.list_indevs()
152+
for indev in devices:
153+
print(f"Device type: {indev.get_type()}")
154+
```
155+
156+
#### `has_indev_type(indev_type)`
157+
Check if any registered input device has the specified type.
158+
159+
This is a convenience method for checking device capabilities without iterating through the device list.
160+
161+
**Parameters:**
162+
- `indev_type` (int): LVGL input device type (e.g., `lv.INDEV_TYPE.KEYPAD`, `lv.INDEV_TYPE.POINTER`)
163+
164+
**Returns:** bool - True if a device with the specified type is registered, False otherwise
165+
166+
**Example:**
167+
```python
168+
if InputManager.has_indev_type(lv.INDEV_TYPE.KEYPAD):
169+
print("Device has physical buttons")
170+
else:
171+
print("Device is touch-only")
172+
```
173+
103174
## Practical Examples
104175

105176
### Touch Event Handling
@@ -161,6 +232,49 @@ def navigate_to_button(button):
161232
print(f"Focus moved to {button}")
162233
```
163234

235+
### Input Device Registration (Board Initialization)
236+
237+
```python
238+
# In board initialization file (e.g., fri3d_2024.py)
239+
from mpos import InputManager
240+
import lvgl as lv
241+
242+
# Create and configure input device
243+
indev = lv.indev_create()
244+
indev.set_type(lv.INDEV_TYPE.KEYPAD)
245+
indev.set_read_cb(keypad_read_cb)
246+
247+
# Register with InputManager for app access
248+
InputManager.register_indev(indev)
249+
```
250+
251+
### Querying Input Devices (App Code)
252+
253+
```python
254+
from mpos import InputManager, Activity
255+
import lvgl as lv
256+
257+
class MyGame(Activity):
258+
def onCreate(self):
259+
# Check if device has physical buttons
260+
if InputManager.has_indev_type(lv.INDEV_TYPE.KEYPAD):
261+
# Show button-based controls
262+
self.show_button_controls()
263+
else:
264+
# Show touch-based controls
265+
self.show_touch_controls()
266+
267+
def show_button_controls(self):
268+
"""Display UI optimized for physical buttons."""
269+
helptext = "Press A to start!\nY to reset, B to show FPS"
270+
# ... setup button-based UI ...
271+
272+
def show_touch_controls(self):
273+
"""Display UI optimized for touch."""
274+
helptext = "Tap to start!\nTop left to reset, bottom left for FPS"
275+
# ... setup touch-based UI ...
276+
```
277+
164278
## Implementation Details
165279

166280
### File Structure
@@ -227,6 +341,32 @@ focusgroup = lv.group_get_default()
227341
focusgroup.focus_next()
228342
```
229343

344+
### Device Registration Pattern
345+
346+
InputManager uses a registration pattern to decouple hardware initialization from app code:
347+
348+
**Board Initialization (Hardware Layer):**
349+
```python
350+
# fri3d_2024.py - knows about hardware
351+
InputManager.register_indev(keypad_indev)
352+
InputManager.register_indev(touch_indev)
353+
```
354+
355+
**App Code (Application Layer):**
356+
```python
357+
# quasibird.py - doesn't know about hardware
358+
if InputManager.has_indev_type(lv.INDEV_TYPE.KEYPAD):
359+
# Adapt UI for buttons
360+
else:
361+
# Adapt UI for touch
362+
```
363+
364+
This pattern provides:
365+
- **Hardware Abstraction** - Apps don't hardcode hardware IDs
366+
- **Flexibility** - New boards can register different devices
367+
- **Testability** - Apps can be tested with different device configurations
368+
- **Scalability** - Easy to add new input device types
369+
230370
## Related Frameworks
231371

232372
- **[DisplayMetrics](display-metrics.md)** - Display properties and pointer coordinates (now uses InputManager)

0 commit comments

Comments
 (0)