Update "Input-and-Events"
parent
9ce4d4d425
commit
af3c216722
|
|
@ -0,0 +1,162 @@
|
|||
# Input and Events
|
||||
|
||||
McRogueFace provides keyboard, mouse, and window event handling through Python callbacks. Events are dispatched through the scene system, allowing different scenes to have different input handlers.
|
||||
|
||||
**Related Pages:**
|
||||
- [[UI-Widget-Patterns]] - Modal dialogs, buttons, hotbars
|
||||
- [[Grid-Interaction-Patterns]] - Entity selection, movement, context menus
|
||||
- [[Writing-Tests]] - Testing input with automation API
|
||||
|
||||
**Key Files:**
|
||||
- `src/GameEngine.cpp::processEvent()` - Event dispatch
|
||||
- `src/Scene.cpp::sUserInput()` - Scene input handling
|
||||
- `src/McRFPy_API.cpp` - Python callback registration
|
||||
|
||||
---
|
||||
|
||||
## Keyboard Input
|
||||
|
||||
Register a scene-level callback that fires on every key press/release:
|
||||
|
||||
```python
|
||||
import mcrfpy
|
||||
|
||||
def handle_key(key: str, pressed: bool):
|
||||
"""
|
||||
key: Key name (e.g., "W", "Space", "Escape", "Up")
|
||||
pressed: True on press, False on release
|
||||
"""
|
||||
if key == "Escape" and pressed:
|
||||
mcrfpy.setScene("menu")
|
||||
|
||||
mcrfpy.keypressScene(handle_key)
|
||||
```
|
||||
|
||||
### Key Names
|
||||
|
||||
Common key names from SFML:
|
||||
- Letters: `"A"` through `"Z"`
|
||||
- Numbers: `"Num0"` through `"Num9"`
|
||||
- Arrows: `"Up"`, `"Down"`, `"Left"`, `"Right"`
|
||||
- Special: `"Space"`, `"Enter"`, `"Escape"`, `"Tab"`, `"LShift"`, `"RShift"`, `"LControl"`, `"RControl"`
|
||||
- Function: `"F1"` through `"F12"`
|
||||
|
||||
---
|
||||
|
||||
## Mouse Input
|
||||
|
||||
### Element Event Handlers
|
||||
|
||||
All UIDrawables support mouse event callbacks:
|
||||
|
||||
| Property | Signature | When Called |
|
||||
|----------|-----------|-------------|
|
||||
| `on_click` | `(x, y, button) -> None` | Mouse button pressed on element |
|
||||
| `on_enter` | `() -> None` | Mouse enters element bounds |
|
||||
| `on_exit` | `() -> None` | Mouse leaves element bounds |
|
||||
| `on_move` | `(x, y) -> None` | Mouse moves within element |
|
||||
|
||||
```python
|
||||
frame = mcrfpy.Frame(pos=(100, 100), size=(200, 50))
|
||||
|
||||
frame.on_click = lambda x, y, btn: print(f"Clicked at ({x}, {y}) with button {btn}")
|
||||
frame.on_enter = lambda: print("Mouse entered")
|
||||
frame.on_exit = lambda: print("Mouse exited")
|
||||
```
|
||||
|
||||
The `hovered` property (read-only) indicates whether the mouse is currently over an element.
|
||||
|
||||
### Grid Cell Events
|
||||
|
||||
Grids provide cell-level mouse events in addition to element events:
|
||||
|
||||
| Property | Signature | Description |
|
||||
|----------|-----------|-------------|
|
||||
| `on_cell_click` | `(grid_x, grid_y, button) -> None` | Cell clicked |
|
||||
| `on_cell_enter` | `(grid_x, grid_y) -> None` | Mouse enters cell |
|
||||
| `on_cell_exit` | `(grid_x, grid_y) -> None` | Mouse leaves cell |
|
||||
| `hovered_cell` | `(x, y)` or `None` | Currently hovered cell (read-only) |
|
||||
|
||||
See [[Grid-Interaction-Patterns]] for usage examples.
|
||||
|
||||
### Mouse Position
|
||||
|
||||
```python
|
||||
# Window coordinates (pixels)
|
||||
x, y = mcrfpy.getMousePos()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Event Priority
|
||||
|
||||
### Click Dispatch Order
|
||||
|
||||
Clicks are dispatched in reverse render order (front to back):
|
||||
|
||||
1. **UI elements with highest z_index** receive clicks first
|
||||
2. If handled (callback returns truthy), propagation stops
|
||||
3. **Entities on grids** receive clicks next
|
||||
4. **Grid cells** receive clicks last
|
||||
|
||||
### Keyboard Priority
|
||||
|
||||
Keyboard events go only to the current scene's registered callback. There is no concept of "focused" UI elements for keyboard input.
|
||||
|
||||
---
|
||||
|
||||
## Window Events
|
||||
|
||||
### Resize Events
|
||||
|
||||
Window resize events are not currently exposed directly. Workaround using timer polling:
|
||||
|
||||
```python
|
||||
last_size = mcrfpy.getWindowSize()
|
||||
|
||||
def check_resize(dt):
|
||||
global last_size
|
||||
current = mcrfpy.getWindowSize()
|
||||
if current != last_size:
|
||||
on_resize(current)
|
||||
last_size = current
|
||||
|
||||
mcrfpy.setTimer("resize_check", check_resize, 100)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Input
|
||||
|
||||
Use the automation API to simulate input in tests:
|
||||
|
||||
```python
|
||||
from mcrfpy import automation
|
||||
|
||||
automation.keypress("W", True) # Press W
|
||||
automation.keypress("W", False) # Release W
|
||||
automation.click(100, 200, button=0) # Left-click at position
|
||||
```
|
||||
|
||||
See [[Writing-Tests]] for complete testing patterns.
|
||||
|
||||
---
|
||||
|
||||
## API Reference
|
||||
|
||||
**Module Functions:**
|
||||
- `mcrfpy.keypressScene(callback)` - Register keyboard handler
|
||||
- `mcrfpy.getMousePos() -> (int, int)` - Get mouse position
|
||||
- `mcrfpy.getWindowSize() -> (int, int)` - Get window dimensions
|
||||
|
||||
**UIDrawable Properties:**
|
||||
- `on_click`, `on_enter`, `on_exit`, `on_move` - Event handlers
|
||||
- `hovered` - Mouse hover state (read-only)
|
||||
|
||||
**Grid Properties:**
|
||||
- `on_cell_click`, `on_cell_enter`, `on_cell_exit` - Cell event handlers
|
||||
- `hovered_cell` - Currently hovered cell (read-only)
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-11-29*
|
||||
Loading…
Reference in New Issue