- `
+ // ...
})
export class MyComponent {
- onConfirm() {
- console.log('Confirmed!');
+ constructor(private inputService: InputService) {
+ // Define custom actions
+ const jumpAction = this.inputService.defineAction('jump');
+ jumpAction.onDown(() => console.log('Jump pressed!'));
+ jumpAction.onUp(() => console.log('Jump released!'));
+
+ // Create input scheme
+ const gameScheme = this.inputService.defineScheme('game');
+
+ // Listen for device changes
+ this.inputService.deviceListChanged.subscribe(devices => {
+ console.log('Available devices:', devices);
+ });
}
}
```
-### Action Binding Directive
+**Methods:**
+- `defineAction(name: string): InputAction` - Creates a new input action
+- `defineScheme(name: string): InputScheme` - Creates a new input scheme
+- `getDevices(): InputDevice[]` - Returns list of available input devices
+**Properties:**
+- `actions: InputAction[]` - Array of defined actions
+- `schemes: InputScheme[]` - Array of defined schemes
+- `devices: InputDevice[]` - Array of connected devices
+- `deviceListChanged: BehaviorSubject` - Observable for device changes
+
+---
+
+### ControlService (Example Integration)
+
+**Description:** Higher-level service that integrates with InputService to provide common navigation actions.
+
+**Usage:**
```typescript
-import { ActionBindingDirective } from '@ngshack/input';
+import { ControlService } from 'your-app/services/control.service';
@Component({
- imports: [ActionBindingDirective],
- template: `
-
- Back Button
-
- `
+ // ...
})
export class MyComponent {
+ constructor(private controlService: ControlService) {
+ // Service automatically sets up common actions:
+ // - Left, Right, Up, Down navigation
+ // - Accept, Back, Exit actions
+ // - Hint/Help action
+
+ // Get key names for display
+ const keyNames = this.controlService.getKeyNames('Enter', 'Escape');
+ console.log('Key names:', keyNames); // ['Enter', 'Escape'] or themed names
+ }
+}
+```
+
+**Static Properties:**
+- `keyLeft: InputAction` - Left navigation action
+- `keyRight: InputAction` - Right navigation action
+- `keyUp: InputAction` - Up navigation action
+- `keyDown: InputAction` - Down navigation action
+- `keyAccept: InputAction` - Accept/confirm action
+- `keyBack: InputAction` - Back/cancel action
+- `keyExit: InputAction` - Exit action
+- `keyHint: InputAction` - Hint/help action
+
+**Methods:**
+- `getKeyNames(...names): string[]` - Get themed key names for display
+- `clearKeyBindings()` - Clear all key bindings from schemes
+- `bindActionsToScheme(device: InputDevice)` - Bind actions to device scheme
+
+## Directives
+
+### ActionBindingDirective
+
+**Selector:** `[inputActionBinding]`
+**Description:** Binds an action name to an HTML element.
+
+**Usage:**
+```html
+
+
Back
+```
+
+**Properties:**
+- `inputActionBinding: string` - Action name to bind to the element
+
+**Features:**
+- Automatically sets `action` attribute on the element
+- Works with keyboard and gamepad navigation
+
+---
+
+### KeyItemDirective
+
+**Selector:** `[inputKeyItem]`
+**Description:** Makes an element navigable with keyboard/gamepad and handles focus states.
+
+**Usage:**
+```html
+
+```
+
+**Properties:**
+- `active: string` - CSS class name for active/focused state (default: 'active')
+- `actionBindings: ActionBindings` - Object mapping action names to callback functions
+
+**Events:**
+- `activated: EventEmitter` - Emitted when item is activated
+- `deactivated: EventEmitter` - Emitted when item is deactivated
+- `focused: EventEmitter` - Emitted when item receives focus
+- `blurred: EventEmitter` - Emitted when item loses focus
+
+**Static Methods:**
+- `FireAction(action: string): boolean` - Fires action on currently focused item
+- `ActivateCurrentItem()` - Activates the currently focused item
+- `SelectNexItem(fromAngle: number, toAngle: number)` - Selects next item in direction
+
+---
+
+### KeyItemGroupDirective
+
+**Selector:** `[inputKeyItemGroup]`
+**Description:** Groups KeyItem elements for scoped navigation.
+
+**Usage:**
+```html
+
+
+
+
+
+```
+
+**Features:**
+- Navigation is scoped to items within the group
+- Automatically manages focus within the group
+- Supports nested groups
+
+## Models
+
+### InputAction
+
+**Description:** Represents a bindable input action (e.g., "jump", "fire", "menu").
+
+**Usage:**
+```typescript
+const jumpAction = new InputAction('jump');
+
+// Bind callbacks
+jumpAction.onDown((value, data, angle, timePressed) => {
+ console.log('Jump started!', { value, data, angle, timePressed });
+});
+
+jumpAction.onUp((value, data, angle, timePressed) => {
+ console.log('Jump ended!', { value, data, angle, timePressed });
+});
+
+jumpAction.onChange((value, data, angle, timePressed) => {
+ console.log('Jump value changed:', value);
+});
+
+// Fire the action
+jumpAction.fire(1.0); // Press
+jumpAction.fire(0.0); // Release
+```
+
+**Methods:**
+- `onDown(callback: ActionCallback)` - Register callback for action press
+- `onUp(callback: ActionCallback)` - Register callback for action release
+- `onChange(callback: ActionCallback)` - Register callback for value changes
+- `fire(value: number, data?: unknown, angle?: number, timePressed?: number)` - Fire the action
+- `mapKeysToScheme(scheme: InputScheme, keys: (string|number)[])` - Map keys to scheme
+
+---
+
+### InputDevice
+
+**Description:** Base class for input devices (keyboard, gamepad).
+
+**Properties:**
+- `name: string` - Device name
+- `type: string` - Device type ('keyboard', 'gamepad')
+
+**Methods:**
+- `hasScheme(): boolean` - Check if device has an input scheme
+- `mapKey(action: InputAction, keys: (string|number)[])` - Map keys to action
+
+---
+
+### InputKeyboard
+
+**Description:** Keyboard input device implementation.
+
+**Usage:**
+```typescript
+const keyboard = new InputKeyboard('Main Keyboard');
+keyboard.mapKey(jumpAction, ['Space', 'KeyW']);
+```
+
+---
+
+### InputGamepad
+
+**Description:** Gamepad input device implementation with automatic detection.
+
+**Static Properties:**
+- `DeviceConnected: Subject` - Observable for gamepad connections
+- `DeviceDisconnected: Subject` - Observable for gamepad disconnections
+
+**Static Methods:**
+- `Init()` - Initialize gamepad detection
+
+**Usage:**
+```typescript
+// Listen for gamepad events
+InputGamepad.DeviceConnected.subscribe(gamepad => {
+ console.log('Gamepad connected:', gamepad.name);
+ gamepad.mapKey(jumpAction, [0]); // Map to button 0
+});
+
+InputGamepad.DeviceDisconnected.subscribe(gamepad => {
+ console.log('Gamepad disconnected:', gamepad.name);
+});
+
+// Initialize detection
+InputGamepad.Init();
+```
+
+## Complete Example
+
+```typescript
+import { Component, OnInit } from '@angular/core';
+import {
+ InputService,
+ NavigationModule,
+ KeyItemDirective,
+ KeyItemGroupDirective,
+ ActionBindingDirective
+} from '@workshack/input';
+
+@Component({
+ selector: 'app-game-menu',
+ imports: [
+ NavigationModule,
+ KeyItemDirective,
+ KeyItemGroupDirective,
+ ActionBindingDirective
+ ],
+ template: `
+
+
Game Menu
+
+
+
+
+
+
+
+
+ Use arrow keys or gamepad to navigate
+ Press Enter or A to select
+