-
Notifications
You must be signed in to change notification settings - Fork 6
ViewModels
Every ViewModel class in PadForge: what it backs, what it exposes, and how state flows between the UI and the services layer.
v3 (2026-04-26): Rewritten for v3. The HIDMaestro SDK surface, OpenXInput shim, thread-pool lifecycle, and bubble-up cascade live on HIDMaestro Deep Dive. If anything here drifts from the live source, the live source wins.
All ViewModels live in PadForge.App/ViewModels/ (PadForge.ViewModels namespace). Built on CommunityToolkit.Mvvm (ObservableObject, RelayCommand).
File: ViewModelBase.cs
Abstract base class for all ViewModels. Extends ObservableObject (INotifyPropertyChanged, SetProperty).
public abstract class ViewModelBase : ObservableObject
{
private string _title = string.Empty;
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
}| Property | Type | Description |
|---|---|---|
Title |
string |
Display title for the view. Used by navigation and page headers. |
The constructor subscribes to Strings.CultureChanged for live language switching. When the UI language changes, every ViewModel's OnCultureChanged() runs, letting derived classes refresh culture-dependent text.
Strings.CultureChanged uses a weak event pattern. Instance-method subscribers are stored as (WeakReference<Target>, MethodInfo) pairs, so short-lived ViewModels can be garbage-collected without unsubscribing. Dead entries are pruned on each raise. Static-method subscribers use strong references.
protected ViewModelBase()
{
Strings.CultureChanged += OnCultureChanged; // weak. No GC leak
}
protected virtual void OnCultureChanged() { }File: MainViewModel.cs (defined alongside MainViewModel)
Sidebar entry for one virtual controller. Shows controller type icon, slot number, and per-type instance label.
| Property | Type | Description |
|---|---|---|
PadIndex |
int |
Zero-based pad slot index (0–15). Read-only. |
Tag |
string |
Navigation tag ("Pad1"–"Pad16"). Computed as $"Pad{PadIndex + 1}". |
SlotNumber |
int |
1-based controller number among active slots. |
InstanceLabel |
string |
Per-type instance label (e.g., "1", "2"). |
IconKey |
string |
Resource key for controller type icon (e.g., "XboxControllerIcon", "DS4ControllerIcon", "ExtendedControllerIcon", "MidiControllerIcon", "KeyboardMouseControllerIcon"). |
IsEnabled |
bool |
Virtual controller enabled. |
ConnectedDeviceCount |
int |
Mapped physical devices connected. |
IsInitializing |
bool |
Virtual controller initializing. |
IsVirtualControllerConnected |
bool |
Live virtual controller is alive (created + reporting IsConnected). Drives the sidebar green-vs-yellow indicator so the slot stays green through the HM-inactivity grace window and only turns yellow once the timeout tears the VC down. |
XAML binding: Sidebar ListBox binds to MainViewModel.NavControllerItems. Each template binds SlotNumber, InstanceLabel, IconKey (via DynamicResource), and IsEnabled.
File: MainViewModel.cs
DataContext for: MainWindow
Root ViewModel. Manages navigation state, 16 pad ViewModels, sidebar controller entries, and app-wide status.
| Property | Type | Description |
|---|---|---|
Pads |
ObservableCollection<PadViewModel> |
16 pad ViewModels (one per slot). Created in constructor. |
NavControllerItems |
ObservableCollection<NavControllerItemViewModel> |
Sidebar items for created slots. Rebuilt by RefreshNavControllerItems(). |
Dashboard |
DashboardViewModel |
Dashboard overview ViewModel. |
Devices |
DevicesViewModel |
Devices list ViewModel. |
Settings |
SettingsViewModel |
Application settings ViewModel. |
| Property | Type | Description |
|---|---|---|
SelectedNavTag |
string |
Current nav tag: "Dashboard", "Pad1"–"Pad16", "Devices", "Settings", "About". Also notifies IsPadPageSelected and SelectedPadIndex. |
IsPadPageSelected |
bool |
True if a Pad page (Pad1–Pad16) is selected. Computed. |
SelectedPadIndex |
int |
Zero-based pad index for the selected Pad page, or -1. Computed. |
SelectedPad |
PadViewModel |
PadViewModel for the selected Pad page, or null. Computed. |
| Property | Type | Default | Description |
|---|---|---|---|
StatusText |
string |
"Ready" |
Status bar text. |
IsEngineRunning |
bool |
false |
Polling loop active. Calls RefreshEngineStatus(). |
HasActiveSlots |
bool |
false |
Any virtual controller slots exist. Calls RefreshEngineStatus(). |
EngineStatusText |
string |
- | Computed: "Running" / "Idle" / "Stopped" based on engine and slot state. |
EngineStatusBrush |
Brush |
- | Computed: Red (#F44336) = Stopped, Amber (#FFB300) = Idle (engine running, no created slots), Green (#4CAF50) = Running with active slots. Frozen (thread-safe). |
PollingFrequency |
double |
0 |
Current polling frequency in Hz. |
ConnectedDeviceCount |
int |
0 |
Connected input device count. |
| Command | CanExecute | Description |
|---|---|---|
StartEngineCommand |
!IsEngineRunning |
Raises StartEngineRequested. Wired by MainWindow code-behind. |
StopEngineCommand |
IsEngineRunning |
Raises StopEngineRequested. |
| Event | Args | Description |
|---|---|---|
StartEngineRequested |
EventArgs |
Start engine. |
StopEngineRequested |
EventArgs |
Stop engine. |
NavControllerItemsRefreshed |
EventArgs |
Raised after RefreshNavControllerItems() completes. MainWindow uses this instead of CollectionChanged to avoid rapid sidebar rebuilds. |
| Method | Description |
|---|---|
RefreshNavControllerItems() |
Rebuilds sidebar entries from SettingsManager.SlotCreated[]. Computes per-type instance numbers and updates each pad's Title, SlotLabel, TypeInstanceLabel. Raises NavControllerItemsRefreshed only on slot add/remove. |
ForceNavControllerItemsRefreshed() |
Forces NavControllerItemsRefreshed even when slot count is unchanged. Used after reorder/swap. |
RefreshEngineStatus() |
Notifies EngineStatusText and EngineStatusBrush. |
RefreshCommands() |
Notifies CanExecuteChanged on start/stop commands. Call after IsEngineRunning changes. |
File: DashboardViewModel.cs
DataContext for: Dashboard page
Overview of all controller slots, engine status, connected devices, and driver status.
| Property | Type | Description |
|---|---|---|
SlotSummaries |
ObservableCollection<SlotSummary> |
Cards for created slots. Rebuilt by RefreshActiveSlots(). |
ShowAddController |
bool |
"Add Controller" visible (any type has capacity). |
| Property | Type | Default | Description |
|---|---|---|---|
EngineStatus |
string |
"Stopped" |
Localized engine status. |
EngineStateKey |
string |
"Stopped" |
Non-localized state key ("Running", "Stopped", "Idle") for XAML DataTriggers. |
PollingFrequency |
double |
0 |
Polling frequency in Hz. Also notifies PollingFrequencyText. |
PollingFrequencyText |
string |
- | Computed: formatted frequency (e.g., "987.3 Hz") or dash when zero. |
| Property | Type | Description |
|---|---|---|
TotalDevices |
int |
Total detected devices (online + offline). |
OnlineDevices |
int |
Currently connected devices. |
MappedDevices |
int |
Devices with an active slot mapping. |
HIDMaestro is bundled with PadForge as a managed SDK and ships with the executable, so the dashboard does not surface an install/uninstall row for it. HidHide and Windows MIDI Services are optional system drivers and have their own rows.
| Property | Type | Description |
|---|---|---|
IsHidHideInstalled |
bool |
HidHide installed. Notifies HidHideStatusText. |
HidHideStatusText |
string |
Computed: "Installed" / "Not installed". |
IsMidiServicesInstalled |
bool |
Windows MIDI Services installed. Notifies MidiServicesStatusText. |
MidiServicesStatusText |
string |
Computed: "Installed" / "Not installed". |
| Property | Type | Default | Description |
|---|---|---|---|
EnableDsuMotionServer |
bool |
false |
DSU (cemuhook) motion server enabled. |
DsuMotionServerPort |
int |
26760 |
UDP port. Clamped to 1024–65535. |
DsuServerStatus |
string |
"Stopped" |
DSU server status. |
| Property | Type | Default | Description |
|---|---|---|---|
EnableWebController |
bool |
false |
Web controller server enabled. |
WebControllerPort |
int |
8080 |
HTTP/WebSocket port. Clamped to 1024–65535. |
WebControllerStatus |
string |
"Stopped" |
Web controller server status. |
WebControllerClientCount |
int |
0 |
Connected web controller clients. |
On-screen transparent touchpad window that drives the DS4 / DualSense touchpad on the assigned PlayStation slot.
| Property | Type | Default | Description |
|---|---|---|---|
EnableTouchpadOverlay |
bool |
false |
Overlay visible. |
TouchpadOverlayOpacity |
double |
0.25 |
Surface opacity 0.0–1.0. Notifies TouchpadOverlayOpacityPercent. |
TouchpadOverlayOpacityPercent |
int |
25 |
0–100 integer view of opacity for NumberBox binding. |
TouchpadOverlayMonitor |
int |
0 |
Monitor index the overlay is pinned to (0 = primary). |
TouchpadOverlayLeft / Top
|
double |
-1 |
Window position. -1 = centered on the chosen monitor. |
TouchpadOverlayWidth / Height
|
double |
500 / 250
|
Window size. Clamped to >= 150 and >= 80 respectively. |
IsTouchpadOverlayRunning |
bool |
false |
Overlay window currently shown. Drives TouchpadOverlayStatus. |
TouchpadOverlayStatus |
string |
- | Localized status string ("Running" / "Stopped"). |
| Command | Description |
|---|---|
ResetOpacityCommand |
Resets opacity to default 0.25. |
ResetTouchpadOverlayPositionCommand |
Raises ResetTouchpadOverlayPositionRequested. InputService recenters the live overlay (or seeds defaults if not open) and clears persisted Left / Top. |
| Event | Description |
|---|---|
ResetTouchpadOverlayPositionRequested |
Recenter request from the UI. |
| Method | Description |
|---|---|
RefreshActiveSlots(IList<int>, bool) |
Rebuilds SlotSummaries for active slots. Updates display labels, sets ShowAddController. Called by InputService. |
File: DashboardViewModel.cs (nested class)
Summary card for one virtual controller slot on the Dashboard.
| Property | Type | Default | Description |
|---|---|---|---|
PadIndex |
int |
- | Zero-based slot index. Read-only. |
SlotLabel |
string |
- | Display label (e.g., "Virtual Controller 1"). |
DeviceName |
string |
"No device" |
Primary mapped device name. |
IsActive |
bool |
false |
Has at least one online mapped device. |
IsVirtualControllerConnected |
bool |
false |
Virtual controller connected. |
IsInitializing |
bool |
false |
Virtual controller initializing. |
MappedDeviceCount |
int |
0 |
Devices mapped to this slot. |
ConnectedDeviceCount |
int |
0 |
Mapped devices connected. |
StatusText |
string |
"Idle" |
Status: "Active", "Idle", "No mapping", or "Disabled". |
IsEnabled |
bool |
true |
Slot enabled for output. |
SlotNumber |
int |
1 |
1-based controller number among active slots. |
TypeInstanceLabel |
string |
"1" |
Per-type instance label. |
OutputType |
VirtualControllerType |
Xbox |
Virtual controller output type. (XML on-disk name is "Microsoft" via [XmlEnum] for v2/early-v3 back-compat; in-code identifier is Xbox.) |
File: SettingsViewModel.cs
DataContext for: Settings page
Application-level settings: theme, language, drivers, profiles, and engine configuration.
| Property | Type | Default | Description |
|---|---|---|---|
SelectedThemeIndex |
int |
0 |
0 = System, 1 = Light, 2 = Dark. Raises ThemeChanged. |
| Event | Args | Description |
|---|---|---|
ThemeChanged |
int |
Raised when theme selection changes. Arg = theme index. |
| Property | Type | Description |
|---|---|---|
AvailableLanguages |
ObservableCollection<CultureInfo> |
UI languages: en, de, fr, ja, ko, zh-Hans, pt-BR, es, it, nl. |
SelectedLanguage |
CultureInfo |
Current UI language. Applies immediately via Strings.ChangeCulture(). Defaults to current culture or English. |
| Member | Type | Description |
|---|---|---|
LanguageCode |
string |
Persisted language code for serialization. |
SetLanguageFromCode(string) |
method | Sets language from persisted code on startup without raising CultureChanged. |
HIDMaestro is shipped as an embedded managed SDK (HIDMaestro.Core, bundled at Resources/HIDMaestro/HIDMaestro.Core.dll). The user-mode driver still needs to be registered with Windows once. That happens inside the engine via HMContext.InstallDriver() (called from InputManager.Step5.VirtualDevices.cs:EnsureHMaestroContext), not through DriverInstaller. The SettingsViewModel exposes a read-only version string read from the bundled assembly at startup.
| Property | Type | Description |
|---|---|---|
HIDMaestroVersion |
string |
HIDMaestro SDK version. Initialized from the embedded HIDMaestro.Core assembly via GetEmbeddedHidMaestroVersion(). |
| Property | Type | Description |
|---|---|---|
IsHidHideInstalled |
bool |
HidHide installed. |
HidHideStatusText |
string |
Computed: "Installed" / "Not installed". |
HidHideVersion |
string |
HidHide version. |
HidHideWhitelistPaths |
ObservableCollection<string> |
Whitelisted application paths. |
SelectedWhitelistPath |
string |
Selected whitelist path. Refreshes RemoveWhitelistPathCommand. |
| Command | CanExecute | Description |
|---|---|---|
InstallHidHideCommand |
!IsHidHideInstalled |
Raises InstallHidHideRequested. |
UninstallHidHideCommand |
IsHidHideInstalled && !HasAnyHidHideDevices() |
Raises UninstallHidHideRequested. |
AddWhitelistPathCommand |
IsHidHideInstalled |
Raises AddWhitelistPathRequested. |
RemoveWhitelistPathCommand |
SelectedWhitelistPath != null |
Removes selected path, raises WhitelistChanged. |
| Event | Description |
|---|---|
InstallHidHideRequested |
Install HidHide. |
UninstallHidHideRequested |
Uninstall HidHide. |
AddWhitelistPathRequested |
Add whitelist path (opens file dialog). |
WhitelistChanged |
Whitelist was modified (add or remove). |
| Property | Type | Description |
|---|---|---|
IsMidiServicesInstalled |
bool |
Windows MIDI Services available. |
MidiServicesStatusText |
string |
Computed: "Installed" / "Not installed". |
MidiServicesVersion |
string |
MIDI Services version. |
IsMidiOsSupported |
bool |
Static: true if OS build >= 26100 (Win11 24H2). |
| Command | CanExecute | Description |
|---|---|---|
InstallMidiServicesCommand |
!IsMidiServicesInstalled && IsMidiOsSupported |
Raises InstallMidiServicesRequested. |
UninstallMidiServicesCommand |
IsMidiServicesInstalled && !HasAnyMidiSlots() |
Raises UninstallMidiServicesRequested. |
| Member | Type | Description |
|---|---|---|
HasAnyMidiSlots |
Func<bool> |
Set by MainWindow. True if any slot uses MIDI. Blocks UninstallMidiServicesCommand. |
HasAnyHidHideDevices |
Func<bool> |
Set by MainWindow. True if any device has HidHide enabled. Blocks UninstallHidHideCommand. |
RefreshDriverGuards() |
method | Re-evaluates uninstall CanExecute for HidHide and MIDI Services. Call after slot creation/deletion/type changes. |
| Property | Type | Default | Description |
|---|---|---|---|
AutoStartEngine |
bool |
true |
Auto-start engine on launch. |
MinimizeToTray |
bool |
false |
Minimize to system tray instead of taskbar. |
StartMinimized |
bool |
false |
Start minimized. |
StartAtLogin |
bool |
false |
Auto-start at login. |
EnablePollingOnFocusLoss |
bool |
true |
Continue polling on focus loss. |
PollingRateMs |
int |
1 |
Polling interval in ms. Clamped to 1–16. |
HmInactivityDestroyTimeoutSeconds |
int |
60 |
Seconds the engine waits for any mapped device to return online before tearing down the live HM virtual controller and freeing its kernel slot. Clamped to 0–3600. 0 disables the timeout. The slot's configuration (mappings, profile, position, enabled state) is preserved end-to-end. Only the live VC is destroyed. Once mapped devices come back online, the VC recreates automatically at the same visual position. Surviving Xbox HM VCs at higher visual positions bubble down to keep xinputhid indices contiguous after the teardown. |
EnableInputHiding |
bool |
true |
Master switch for device hiding (HidHide + input hooks). |
KeepHidHideCloaksBetweenLaunches |
bool |
false |
When true, HidHide cloaks stay asserted after PadForge exits so other apps still see the physical devices hidden. When false (default), cloaks clear on shutdown. |
| Property | Type | Description |
|---|---|---|
SettingsFilePath |
string |
Path to the loaded settings file. |
HasUnsavedChanges |
bool |
Unsaved changes exist. |
| Command | Description |
|---|---|
SaveCommand |
Raises SaveRequested. |
ReloadCommand |
Raises ReloadRequested. |
ResetCommand |
Raises ResetRequested. |
OpenSettingsFolderCommand |
Raises OpenSettingsFolderRequested. |
| Event | Description |
|---|---|
SaveRequested |
Save settings. |
ReloadRequested |
Reload from disk. |
ResetRequested |
Reset settings. |
OpenSettingsFolderRequested |
Open settings folder. |
| Property | Type | Description |
|---|---|---|
SdlVersion |
string |
SDL3 version. |
ApplicationVersion |
string |
Application version. |
RuntimeVersion |
string |
.NET runtime version. |
| Property | Type | Default | Description |
|---|---|---|---|
Use2DControllerView |
bool |
false |
Show 2D controller view instead of 3D. |
| Property | Type | Default | Description |
|---|---|---|---|
EnableAutoProfileSwitching |
bool |
false |
Auto-profile switching enabled. |
ProfileItems |
ObservableCollection<ProfileListItem> |
empty | Profile entries for UI list. |
SelectedProfile |
ProfileListItem |
null |
Selected profile. Refreshes delete/edit/load commands. |
ActiveProfileInfo |
string |
"Default" |
Active profile display text. |
| Command | CanExecute | Description |
|---|---|---|
NewProfileCommand |
always | Raises NewProfileRequested. |
SaveAsProfileCommand |
always | Raises SaveAsProfileRequested. |
DeleteProfileCommand |
SelectedProfile != null && !IsDefault |
Raises DeleteProfileRequested. |
EditProfileCommand |
SelectedProfile != null && !IsDefault |
Raises EditProfileRequested. |
LoadProfileCommand |
SelectedProfile != null |
Raises LoadProfileRequested or RevertToDefaultRequested if default. |
| Event | Description |
|---|---|
RevertToDefaultRequested |
Revert to default profile. |
NewProfileRequested |
Create new empty profile. |
SaveAsProfileRequested |
Save current settings as profile. |
DeleteProfileRequested |
Delete selected profile. |
EditProfileRequested |
Edit selected profile metadata. |
LoadProfileRequested |
Load selected profile. |
| Method | Description |
|---|---|
RefreshProfileCommands() |
Refreshes CanExecute for delete/edit/load commands. |
File: SettingsViewModel.cs (nested class)
Display item for a profile in the Settings list.
| Property | Type | Description |
|---|---|---|
Id |
string |
Profile identifier. |
Name |
string |
Display name. |
Executables |
string |
Comma-separated exe names for auto-switch. |
TopologyLabel |
string |
Slot topology summary. |
HasNoSlots |
bool |
Computed: all type counts are zero. |
XboxCount |
int |
Number of Xbox slots in this profile. |
PlayStationCount |
int |
Number of PlayStation slots. |
ExtendedCount |
int |
Number of Extended slots. |
MidiCount |
int |
Number of MIDI slots. |
KbmCount |
int |
Number of Keyboard+Mouse slots. |
IsDefault |
bool |
Computed: true if Id == "__default__". |
| Constant | Value | Description |
|---|---|---|
DefaultProfileId |
"__default__" |
Sentinel ID for the Default profile. |
File: DevicesViewModel.cs
DataContext for: Devices page
All detected input devices (online and offline) with raw input state for the selected device.
| Property | Type | Description |
|---|---|---|
Devices |
ObservableCollection<DeviceRowViewModel> |
All known devices. Updated by InputService on change. |
SelectedDevice |
DeviceRowViewModel |
Selected device. Notifies HasSelectedDevice, refreshes slot buttons and command state. |
HasSelectedDevice |
bool |
Computed: SelectedDevice != null. |
| Property | Type | Description |
|---|---|---|
TotalCount |
int |
Total detected devices. |
OnlineCount |
int |
Connected devices. |
| Property | Type | Description |
|---|---|---|
RawAxes |
ObservableCollection<AxisDisplayItem> |
Axis values (progress bars). |
RawButtons |
ObservableCollection<ButtonDisplayItem> |
Button states (circles). |
RawPovs |
ObservableCollection<PovDisplayItem> |
POV hat values (compass). |
KeyboardKeys |
ObservableCollection<KeyboardKeyItem> |
Keyboard layout items. |
IsKeyboardDevice |
bool |
Selected device is a keyboard. |
IsMouseDevice |
bool |
Selected device is a mouse. |
IsTouchpadDevice |
bool |
Selected device exposes a touchpad surface (DS4 / DualSense / Steam Controller / Steam Deck / overlay touchpad). |
HasTouchpadData |
bool |
At least one finger is currently in contact. |
TouchpadX0 / TouchpadY0
|
double |
First finger normalized position (0.0–1.0). |
TouchpadX1 / TouchpadY1
|
double |
Second finger normalized position. |
TouchpadDown0 / TouchpadDown1
|
bool |
Per-finger contact state. |
MouseMotionX |
double |
Mouse X motion. |
MouseMotionY |
double |
Mouse Y motion. |
MouseScrollIntensity |
double |
Normalized scroll intensity (−1 to 1). |
SelectedButtonTotal |
int |
Button count on selected device. |
HasRawData |
bool |
Raw state data available. |
| Property | Type | Description |
|---|---|---|
HasGyroData |
bool |
Gyroscope data available. |
HasAccelData |
bool |
Accelerometer data available. |
GyroX |
double |
Gyroscope X value. |
GyroY |
double |
Gyroscope Y value. |
GyroZ |
double |
Gyroscope Z value. |
AccelX |
double |
Accelerometer X value. |
AccelY |
double |
Accelerometer Y value. |
AccelZ |
double |
Accelerometer Z value. |
| Property | Type | Description |
|---|---|---|
ActiveSlotItems |
ObservableCollection<SlotButtonItem> |
Slot toggle buttons. Only includes created/active slots. |
| Command | CanExecute | Description |
|---|---|---|
RefreshCommand |
always | Raises RefreshRequested. Force-refreshes device list. |
AssignToSlotCommand |
HasSelectedDevice |
RelayCommand<int>. Raises AssignToSlotRequested with slot index (0–15). |
ToggleSlotCommand |
HasSelectedDevice |
RelayCommand<int>. Toggles slot assignment. Raises ToggleSlotRequested. |
HideDeviceCommand |
HasSelectedDevice |
Sets IsHidden = true, raises HideDeviceRequested. |
RemoveDeviceCommand |
HasSelectedDevice |
Removes device, raises RemoveDeviceRequested. |
| Event | Args | Description |
|---|---|---|
RefreshRequested |
EventArgs |
Refresh requested. |
AssignToSlotRequested |
int |
Slot index. |
ToggleSlotRequested |
int |
Slot index. |
HideDeviceRequested |
Guid |
Instance GUID. |
RemoveDeviceRequested |
Guid |
Instance GUID. |
DeviceHidingChanged |
Guid |
HidHide or ConsumeInput toggle changed. |
| Method | Description |
|---|---|
RebuildRawStateCollections(int, int, int, bool, bool) |
Rebuilds axis/button/POV collections for a new device. Handles keyboard and mouse cases. |
ClearRawState() |
Clears all raw state display data. |
RefreshSlotButtons() |
Rebuilds ActiveSlotItems from created slots and selected device assignments. |
FindByGuid(Guid) |
Finds a DeviceRowViewModel by instance GUID. |
RefreshCounts() |
Updates TotalCount and OnlineCount. |
NotifyDeviceHidingChanged(Guid) |
Raises DeviceHidingChanged. |
| Member | Type | Description |
|---|---|---|
LastRawStateDeviceGuid |
Guid |
Tracks which device's collections are populated. Prevents unnecessary rebuilds. |
File: DevicesViewModel.cs
Single slot toggle button on the Devices page.
| Property | Type | Description |
|---|---|---|
PadIndex |
int |
Zero-based slot index (0–15). |
SlotNumber |
int |
1-based number among active slots. |
IsAssigned |
bool |
Selected device is assigned to this slot. |
File: DevicesViewModel.cs
Display item for a single axis value.
| Property | Type | Description |
|---|---|---|
Index |
int |
Axis index. |
Name |
string |
Display name (e.g., "Axis 0"). |
NormalizedValue |
double |
Value normalized to 0.0–1.0. Bound to ProgressBar. |
RawValue |
int |
Raw value (0–65535). |
File: DevicesViewModel.cs
Display item for a single button state.
| Property | Type | Description |
|---|---|---|
Index |
int |
Button index. |
IsPressed |
bool |
Currently pressed. Bound to circle fill color. |
File: DevicesViewModel.cs
Display item for a keyboard key with position data. Rendered in a Canvas inside a Viewbox for auto-scaling.
| Property | Type | Description |
|---|---|---|
VKeyIndex |
int |
Windows Virtual Key code. |
Label |
string |
Key label. |
X |
double |
Canvas X position (px). |
Y |
double |
Canvas Y position (px). |
KeyWidth |
double |
Key width (px). |
KeyHeight |
double |
Key height (px). |
IsPressed |
bool |
Currently pressed. |
| Constant | Value | Description |
|---|---|---|
LayoutWidth |
556 |
Canvas width for the keyboard layout. |
LayoutHeight |
136 |
Canvas height for the keyboard layout. |
| Static Method | Description |
|---|---|
BuildLayout() |
Builds full ANSI QWERTY layout with numpad. Each key mapped to its VK code. |
IsVKeyPressed(bool[], int) |
Checks if a VKey is pressed in a button array. |
File: DevicesViewModel.cs
Display item for a single POV hat switch.
| Property | Type | Default | Description |
|---|---|---|---|
Index |
int |
- | POV hat index. |
Centidegrees |
int |
-1 |
Value in centidegrees (0–35900), or −1 for centered. Notifies IsCentered and AngleDegrees. |
IsCentered |
bool |
- | Computed: Centidegrees < 0. |
AngleDegrees |
double |
- | Computed: direction in degrees (0–359) for RotateTransform. |
File: DeviceRowViewModel.cs
Single device row on the Devices page. Shows identification, status, capabilities, and input hiding controls.
| Property | Type | Description |
|---|---|---|
InstanceGuid |
Guid |
Unique instance GUID. |
SdlGuid |
string |
SDL device GUID string used by gamecontrollerdb mappings. |
DeviceName |
string |
Display name. |
ProductName |
string |
Product name. |
ProductGuid |
Guid |
Product GUID in PIDVID format. |
| Property | Type | Description |
|---|---|---|
VendorId |
ushort |
USB Vendor ID. Notifies VendorIdHex. |
ProductId |
ushort |
USB Product ID. Notifies ProductIdHex. |
VendorIdHex |
string |
Computed: hex (e.g., "045E"). |
ProductIdHex |
string |
Computed: hex (e.g., "028E"). |
| Property | Type | Default | Description |
|---|---|---|---|
IsOnline |
bool |
false |
Device connected. Notifies StatusText. |
IsEnabled |
bool |
true |
Device enabled for mapping. Notifies StatusText. |
IsHidden |
bool |
false |
Hidden from the UI. |
StatusText |
string |
- | Computed: "Disabled", "Online", or "Offline". |
| Property | Type | Description |
|---|---|---|
AxisCount |
int |
Number of axes. |
ButtonCount |
int |
Number of buttons. |
PovCount |
int |
Number of POV hat switches. |
DeviceTypeKey |
string |
English type key ("Gamepad", "Joystick", "Wheel", "FlightStick", "FirstPerson", "Supplemental", "Mouse", "Keyboard"). Notifies DeviceType. |
DeviceType |
string |
Computed: localized type from DeviceTypeKey. |
HasRumble |
bool |
Supports rumble. |
HasGyro |
bool |
Has gyroscope. |
HasAccel |
bool |
Has accelerometer. |
HasTouchpad |
bool |
Exposes a touchpad surface. |
CapabilitiesSummary |
string |
Computed: e.g., "6 axes, 11 buttons, 1 POV, Rumble, Gyro". |
| Property | Type | Description |
|---|---|---|
AssignedSlots |
List<int> |
Assigned pad slot indices (0–15). Set via SetAssignedSlots(). |
SlotBadges |
ObservableCollection<SlotBadge> |
Slot badges for XAML (icon + number). Rebuilt by SetAssignedSlots(). |
IsUnassigned |
bool |
Computed: true if AssignedSlots is empty. |
| Method | Description |
|---|---|
SetAssignedSlots(List<int>) |
Replaces assigned slots, rebuilds SlotBadges with sequential numbering, notifies UI. |
| Property | Type | Default | Description |
|---|---|---|---|
HidHideEnabled |
bool |
false |
Hidden via HidHide (driver-level). |
ConsumeInputEnabled |
bool |
false |
Mapped inputs consumed via low-level hooks. |
ForceRawJoystickMode |
bool |
false |
Bypass SDL gamepad remapping. Read raw joystick indices. |
IsHidHideAvailable |
bool |
false |
HidHide installed (controls toggle IsEnabled). |
ShowConsumeToggle |
bool |
- | Computed: true for keyboards and mice only. |
IsInternalVirtual |
bool |
- | Computed: true for PadForge-internal virtual sources (web controllers, web touchpads, the on-screen touchpad overlay), identified by URI-scheme DevicePath (web://, overlay://). HidHide can't blacklist non-HID paths, so the "Hide from games" toggle hides itself for these. |
ShowInputHidingSection |
bool |
- | Computed: !IsInternalVirtual. Drives the Input Hiding section visibility. |
ShowInputModeSection |
bool |
- | Computed: IsGamepad && !IsInternalVirtual. Drives the Input Mode (Force Raw Joystick) section visibility. |
ShowInputModeOrHidingSection |
bool |
- | Computed: union of the two above. Gates the separator between Slot Assignment and the hiding/mode sections so a virtual device doesn't leave a dangling divider. |
| Property | Type | Description |
|---|---|---|
DevicePath |
string |
Device path (diagnostics). |
HidHideInstancePath |
string |
HID instance path for HidHide blacklisting. |
| Property | Type | Description |
|---|---|---|
IsGamepad |
bool |
Computed: true if DeviceTypeKey == "Gamepad". |
ShowSubmitMapping |
bool |
Computed: true for joysticks only. |
| Method | Description |
|---|---|
NotifyDisplayChanged() |
Refreshes computed properties (StatusText, IsUnassigned, CapabilitiesSummary, hex IDs). |
File: DeviceRowViewModel.cs
Slot assignment badge (icon + number).
| Property | Type | Description |
|---|---|---|
SlotIndex |
int |
Zero-based pad slot index. |
SlotNumber |
int |
Sequential global number (1-based among created slots). |
Files: PadViewModel.cs, PadViewModel.Touchpad.cs (partial class added in v3.3 for Touchpad-tab properties)
DataContext for: Pad page (one per virtual controller slot)
The largest ViewModel. One per virtual controller slot (16 total). Handles output type, multi-device selection, mapping grid, deadzone/sensitivity, macros, force feedback, Touchpad-tab settings, and live state display.
| Property | Type | Default | Description |
|---|---|---|---|
PadIndex |
int |
- | Zero-based slot index (0–15). Read-only. |
SlotNumber |
int |
PadIndex + 1 |
1-based number among active slots. |
SlotLabel |
string |
- | Display label (e.g., "Virtual Controller 1"). |
OutputType |
VirtualControllerType |
Xbox |
Output type. Resets deadzones, rebuilds mappings/stick/trigger configs, syncs macro button style. |
TypeInstanceLabel |
string |
"1" |
Per-type instance label. Set by RefreshNavControllerItems. |
OutputTypeIndex |
int |
- | ComboBox SelectedIndex (0=Xbox, 1=PlayStation, 2=Extended, 3=Midi, 4=KeyboardMouse). Maps directly to VirtualControllerType enum values. |
ConfigItemDirtyCallback |
Action |
null |
Called on config item change. Wired to SettingsService.MarkDirty(). |
| Property | Type | Description |
|---|---|---|
ExtendedConfig |
ExtendedSlotConfig |
Per-slot Extended config (preset, axis/button/POV counts). Drives the HID descriptor handed to HIDMaestro for Extended slots. Only meaningful when OutputType == Extended. Subscribes to PropertyChanged for dynamic rebuilds. |
| Property | Type | Description |
|---|---|---|
MidiConfig |
MidiSlotConfig |
Per-slot MIDI config (channel, CC/note mappings). Only meaningful when OutputType == Midi. |
| Property | Type | Description |
|---|---|---|
MappedDevices |
ObservableCollection<MappedDeviceInfo> |
Physical devices mapped to this slot. |
SelectedMappedDevice |
MappedDeviceInfo |
Selected device for configuration. Raises SelectedDeviceChanged, notifies HasSelectedDevice. |
HasSelectedDevice |
bool |
Computed: SelectedMappedDevice != null. |
MappedDeviceName |
string |
Mapped device name. Default: "No device mapped". |
MappedDeviceGuid |
Guid |
Mapped device GUID. |
IsDeviceOnline |
bool |
Mapped device is online. |
| Event | Args | Description |
|---|---|---|
SelectedDeviceChanged |
MappedDeviceInfo |
Different device selected. InputService reloads PadSetting. |
| Property | Type | Description |
|---|---|---|
Name |
string |
Device display name. |
InstanceGuid |
Guid |
Device instance GUID. |
IsOnline |
bool |
Device connected. |
Combined slot output values, updated at 30 Hz by UpdateFromEngineState(). Bound to the 2D/3D controller visualizer.
Buttons (all bool):
ButtonA, ButtonB, ButtonX, ButtonY, LeftShoulder, RightShoulder, ButtonBack, ButtonStart, LeftThumbButton, RightThumbButton, ButtonGuide, DPadUp, DPadDown, DPadLeft, DPadRight
Axes (combined slot values):
| Property | Type | Description |
|---|---|---|
LeftTrigger |
double |
Left trigger (0.0–1.0). |
RightTrigger |
double |
Right trigger (0.0–1.0). |
ThumbLX |
double |
Left stick X (0.0–1.0, 0.5 = center). |
ThumbLY |
double |
Left stick Y (0.0–1.0, 0.5 = center, Y inverted). |
ThumbRX |
double |
Right stick X (0.0–1.0, 0.5 = center). |
ThumbRY |
double |
Right stick Y (0.0–1.0, 0.5 = center, Y inverted). |
Raw values:
| Property | Type | Description |
|---|---|---|
RawThumbLX |
short |
Raw left stick X (−32768 to 32767). |
RawThumbLY |
short |
Raw left stick Y. |
RawThumbRX |
short |
Raw right stick X. |
RawThumbRY |
short |
Raw right stick Y. |
RawLeftTrigger |
ushort |
Raw left trigger (0–65535). |
RawRightTrigger |
ushort |
Raw right trigger (0–65535). |
Per-device values (selected device only, for stick/trigger tab previews):
| Property | Type | Description |
|---|---|---|
DeviceThumbLX |
double |
Selected device left stick X (0.0–1.0). |
DeviceThumbLY |
double |
Selected device left stick Y. |
DeviceThumbRX |
double |
Selected device right stick X. |
DeviceThumbRY |
double |
Selected device right stick Y. |
DeviceRawThumbLX |
short |
Selected device raw left stick X. |
DeviceRawThumbLY |
short |
Selected device raw left stick Y. |
DeviceRawThumbRX |
short |
Selected device raw right stick X. |
DeviceRawThumbRY |
short |
Selected device raw right stick Y. |
DeviceLeftTrigger |
double |
Selected device left trigger (0.0–1.0). |
DeviceRightTrigger |
double |
Selected device right trigger. |
DeviceRawLeftTrigger |
ushort |
Selected device raw left trigger. |
DeviceRawRightTrigger |
ushort |
Selected device raw right trigger. |
| Property | Type | Description |
|---|---|---|
Mappings |
ObservableCollection<MappingItem> |
Rows linking physical inputs to output targets. Rebuilt by RebuildMappings(). |
MappingSet |
MappingSet |
Per-virtual-controller mapping store (multi-source rows, shift layers, activators). Drives Mappings on layer / activator change. New in 3.2. See Button and Axis Mappings and Shift Layers. |
ActiveLayerMask |
string |
Active shift layer mask. Base when no layer is engaged. UI rebinds the mapping grid on change. |
LayerTabs |
ObservableCollection<ShiftLayerInfo> |
Tab strip entries above the mapping grid, one per layer (Base + each shift layer). Populated by RebuildLayerTabs from the slot's ShiftActivators. |
HasShiftLayers |
bool |
True when at least one shift activator is authored (i.e. at least one tab beyond Base). |
| Event | Description |
|---|---|
MappingsRebuilt |
Raised after RebuildMappings() completes so InputService can reload descriptors. |
LayerActivated |
Raised when ActiveLayerMask changes. Subscribers reload per-row source data so the DataGrid reflects the active layer's rows. |
| Property | Type | Description |
|---|---|---|
TestRumbleTargetGuid |
Guid |
InstanceGuid of the device currently visible in per-device tabs (Impulse Triggers, Force Feedback, Adaptive Triggers, Lighting). Test/Probe actions on those tabs gate on target == Empty || ud.InstanceGuid == target so only the selected physical pad fires. The same gate covers the dispatcher / routing branches that emit physical effects from those tabs (e.g. auto-routed impulse-to-AT vibration). |
| Property | Type | Description |
|---|---|---|
TouchpadClickPressed |
bool |
Derived from state.Buttons[16] (= SDL_GAMEPAD_BUTTON_TOUCHPAD). Drives the 2D/3D model click highlight and the per-press lightbar overlay synth. |
TouchpadX0 / TouchpadY0 / TouchpadDown0
|
float / float / bool
|
First finger position and contact state on the source touchpad. |
TouchpadX1 / TouchpadY1 / TouchpadDown1
|
float / float / bool
|
Second finger position and contact state. |
| Method | Description |
|---|---|
RebuildMappings() |
Rebuilds Mappings from OutputType and Extended config. Dispatches to type-specific initializers. |
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
ForceOverallGain |
int |
100 |
0–100 | Overall FFB gain %. |
LeftMotorStrength |
int |
100 |
0–100 | Left motor strength %. |
RightMotorStrength |
int |
100 |
0–100 | Right motor strength %. |
SwapMotors |
bool |
false |
- | Swap left/right motor assignment. |
LeftMotorDisplay |
double |
0 |
0–1 | Live left motor level (post-scaling). |
RightMotorDisplay |
double |
0 |
0–1 | Live right motor level. |
Audio Bass Rumble (per-device):
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
AudioRumbleEnabled |
bool |
false |
- | Audio-driven rumble from system bass frequencies. |
AudioRumbleSensitivity |
double |
4.0 |
1–20 | Bass detection sensitivity multiplier. |
AudioRumbleCutoffHz |
double |
80.0 |
20–200 | Low-pass cutoff (Hz) for bass extraction. |
AudioRumbleLeftMotor |
int |
100 |
0–100 | Left motor strength for audio rumble. |
AudioRumbleRightMotor |
int |
100 |
0–100 | Right motor strength for audio rumble. |
AudioRumbleLevelMeter |
double |
0 |
- | Live audio bass level meter. |
Reset commands: ResetForceAllCommand, ResetOverallGainCommand, ResetLeftMotorCommand, ResetRightMotorCommand, ResetAudioRumbleAllCommand, ResetAudioSensitivityCommand, ResetAudioCutoffCommand, ResetAudioLeftMotorCommand, ResetAudioRightMotorCommand.
Constant Force (per-device, FFB-capable + scalar-rumble pads):
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
ConstantForceEnabled |
bool |
false |
- | Apply a continuous force vector until toggled off. Resumes after game/macro forces stop. |
ConstantForceX |
double |
0 |
−1.0–1.0 | X component of the force vector. |
ConstantForceY |
double |
0 |
−1.0–1.0 | Y component (+ = up in the UI grid). |
Per-pad-per-slot per-trigger-motor effects. Tab visible only when an assigned device exposes SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN (Xbox One+, DualSense).
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
ImpulseOverallGain |
int |
100 |
0–100 | Master scale for the trigger-motor pipeline. |
ImpulseLeftStrength |
int |
100 |
0–100 | Left trigger motor scale. |
ImpulseRightStrength |
int |
100 |
0–100 | Right trigger motor scale. |
ImpulseSwapTriggers |
bool |
false |
- | Swap left/right trigger motor assignment. |
Constant Trigger Force:
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
ConstantTriggerForceEnabled |
bool |
false |
- | Override-with-resume continuous force on the trigger motors. |
ConstantTriggerForceLeft |
double |
0 |
0.0–1.0 | Left trigger steady force. |
ConstantTriggerForceRight |
double |
0 |
0.0–1.0 | Right trigger steady force. |
Audio Bass Trigger Rumble:
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
AudioRumbleTriggersEnabled |
bool |
false |
- | Drive trigger motors from system audio bass. Runs alongside the body-motor audio rumble. |
AudioRumbleTriggersSensitivity |
double |
4.0 |
1.0–20.0 | Bass intensity multiplier (trigger channel). |
AudioRumbleTriggersCutoffHz |
double |
80.0 |
20–200 | Low-pass cutoff (trigger channel). |
AudioRumbleLeftTrigger |
int |
100 |
0–100 | Audio-driven left-trigger motor scale. |
AudioRumbleRightTrigger |
int |
100 |
0–100 | Audio-driven right-trigger motor scale. |
AudioRumbleTriggersLevelMeter |
double |
0 |
- | Live trigger-channel level. |
| Event | Args | Description |
|---|---|---|
TestLeftImpulseTriggerRequested |
EventArgs |
Per-device test pulse on the left trigger motor. |
TestRightImpulseTriggerRequested |
EventArgs |
Per-device test pulse on the right trigger motor. |
Left Stick:
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
LeftDeadZoneShape |
int |
2 (ScaledRadial) |
0–5 | Deadzone shape index. |
LeftDeadZoneX |
double |
0 |
0–100 | X deadzone %. |
LeftDeadZoneY |
double |
0 |
0–100 | Y deadzone %. |
LeftAntiDeadZoneX |
double |
0 |
0–100 | X anti-deadzone %. |
LeftAntiDeadZoneY |
double |
0 |
0–100 | Y anti-deadzone %. |
LeftLinear |
double |
0 |
0–100 | Linear interpolation factor. |
LeftMaxRangeX |
double |
100 |
1–100 | X max range (positive). |
LeftMaxRangeY |
double |
100 |
1–100 | Y max range (positive). |
LeftMaxRangeXNeg |
double |
100 |
1–100 | X max range (negative). |
LeftMaxRangeYNeg |
double |
100 |
1–100 | Y max range (negative). |
LeftCenterOffsetX |
double |
0 |
−100 to 100 | X center offset %. |
LeftCenterOffsetY |
double |
0 |
−100 to 100 | Y center offset %. |
Right Stick: Same pattern with Right prefix: RightDeadZoneShape, RightDeadZoneX, RightDeadZoneY, RightAntiDeadZoneX, RightAntiDeadZoneY, RightLinear, RightMaxRangeX, RightMaxRangeY, RightMaxRangeXNeg, RightMaxRangeYNeg, RightCenterOffsetX, RightCenterOffsetY.
Backward compat shims: LeftDeadZone (get=LeftDeadZoneX, set=both X+Y), RightDeadZone (same pattern).
Sensitivity Curves (serialized control point strings, "x,y;x,y;..." format):
| Property | Default | Description |
|---|---|---|
LeftSensitivityCurveX |
"0,0;1,1" |
Left stick X sensitivity curve. |
LeftSensitivityCurveY |
"0,0;1,1" |
Left stick Y sensitivity curve. |
RightSensitivityCurveX |
"0,0;1,1" |
Right stick X sensitivity curve. |
RightSensitivityCurveY |
"0,0;1,1" |
Right stick Y sensitivity curve. |
LeftTriggerSensitivityCurve |
"0,0;1,1" |
Left trigger sensitivity curve. |
RightTriggerSensitivityCurve |
"0,0;1,1" |
Right trigger sensitivity curve. |
Triggers:
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
LeftTriggerDeadZone |
double |
0 |
0–100 | Left trigger deadzone %. |
RightTriggerDeadZone |
double |
0 |
0–100 | Right trigger deadzone %. |
LeftTriggerAntiDeadZone |
double |
0 |
0–100 | Left trigger anti-deadzone %. |
RightTriggerAntiDeadZone |
double |
0 |
0–100 | Right trigger anti-deadzone %. |
LeftTriggerMaxRange |
double |
100 |
1–100 | Left trigger max range %. |
RightTriggerMaxRange |
double |
100 |
1–100 | Right trigger max range %. |
Drive the ItemsControl-based Sticks and Triggers tabs. Gamepad presets: 2 sticks, 2 triggers. Custom Extended: N sticks, M triggers. KBM: 2 items (Mouse Movement, Scroll Wheel).
| Property | Type | Description |
|---|---|---|
StickConfigs |
ObservableCollection<StickConfigItem> |
Stick config items. Rebuilt by RebuildStickConfigs(). |
TriggerConfigs |
ObservableCollection<TriggerConfigItem> |
Trigger config items. Rebuilt by RebuildTriggerConfigs(). |
| Method | Description |
|---|---|
RebuildStickConfigs() |
Rebuilds stick configs for current output type. |
RebuildTriggerConfigs() |
Rebuilds trigger configs. KBM has none. |
SyncStickItemFromVm(StickConfigItem) |
Pushes VM deadzone properties into a stick item. |
SyncTriggerItemFromVm(TriggerConfigItem) |
Pushes VM trigger properties into a trigger item. |
SyncAllConfigItemsFromVm() |
Syncs all items from VM. Called after settings load/paste. |
ResetAllSettings() |
Resets per-slot settings to defaults. Called on slot deletion. |
| Property | Type | Description |
|---|---|---|
Macros |
ObservableCollection<MacroItem> |
Macros for this slot. |
SelectedMacro |
MacroItem |
Selected macro. Notifies HasSelectedMacro, refreshes remove command. |
HasSelectedMacro |
bool |
Computed: SelectedMacro != null. |
| Command | CanExecute | Description |
|---|---|---|
AddMacroCommand |
always | Adds a new macro with auto-numbered name. |
RemoveMacroCommand |
HasSelectedMacro |
Removes the selected macro. |
| Property | Type | Default | Description |
|---|---|---|---|
SelectedConfigTab |
int |
0 |
Always-visible: 0=Controller, 1=Macros, 2=Mappings, 3=Sticks, 4=Triggers, 5=Force Feedback. Visibility-gated on the active source device's capability flags: 6=Adaptive Triggers (HasAdaptiveTriggers), 7=Lighting (HasLightbar), 8=Gyro (HasGyro), 9=Impulse Triggers (HasRumbleTriggers), 10=Touchpad (HasTouchpad). Tag values match the RadioButton.Tag strings on the PadPage tab strip. |
| Command | CanExecute | Description |
|---|---|---|
TestRumbleCommand |
IsDeviceOnline |
Raises TestRumbleRequested. |
ClearMappingsCommand |
always | Clears all mapping source descriptors. |
CopySettingsCommand |
HasSelectedDevice |
Raises CopySettingsRequested. |
PasteSettingsCommand |
HasSelectedDevice |
Raises PasteSettingsRequested. |
CopyFromCommand |
HasSelectedDevice |
Raises CopyFromRequested. |
MapAllCommand |
HasSelectedDevice && !IsMapAllActive && SelectedMappedDevice.IsOnline |
Starts sequential "Map All" recording. |
| Property | Type | Description |
|---|---|---|
IsMapAllActive |
bool |
Map All recording in progress. |
MapAllCurrentIndex |
int |
Current mapping row index during Map All. |
MapAllCurrentTarget |
string |
Target setting name being recorded. |
MapAllPromptText |
string |
Descriptive text shown on Controller tab during Map All (e.g., "Press: A (1/21)"). |
CurrentRecordingTarget |
string |
TargetSettingName being recorded. Drives controller-tab flashing. |
MapAllRecordingNeg |
bool |
Recording negative direction of a bidirectional axis. |
| Event | Args | Description |
|---|---|---|
TestRumbleRequested |
EventArgs |
Test rumble requested. |
TestLeftMotorRequested |
EventArgs |
Test left motor only. Fired via FireTestLeftMotor(). |
TestRightMotorRequested |
EventArgs |
Test right motor only. Fired via FireTestRightMotor(). |
CopySettingsRequested |
EventArgs |
Copy settings to clipboard. |
PasteSettingsRequested |
EventArgs |
Paste settings from clipboard. |
CopyFromRequested |
EventArgs |
Copy from another device. |
MapAllRecordRequested |
MappingItem |
Request recording for the current Map All item. |
MapAllCancelRequested |
EventArgs |
Cancel an in-progress Map All recording. |
| Method | Description |
|---|---|
UpdateFromEngineState(Gamepad, Vibration) |
Updates combined slot output at 30 Hz. |
UpdateDeviceState(Gamepad) |
Updates per-device stick/trigger values for tab previews. |
UpdateFromExtendedRawState(ExtendedRawState) |
Updates combined output from Extended raw state. |
UpdateFromMidiRawState(MidiRawState) |
Updates MIDI preview snapshot. |
OnMapAllItemCompleted() |
Advances Map All to next item after 500 ms delay. |
StopMapAll() |
Stops Map All, clears state, raises MapAllCancelRequested. |
RefreshCommands() |
Refreshes CanExecute for all commands. |
| Property | Type | Description |
|---|---|---|
ExtendedOutputSnapshot |
ExtendedRawState |
Latest Extended raw state for custom display. Updated at 30 Hz. |
KbmOutputSnapshot |
KbmRawState |
Latest KBM raw state. Updated at 30 Hz. |
MidiOutputSnapshot |
MidiRawState |
Latest MIDI raw state snapshot. |
File: MappingItem.cs
Single mapping row linking a physical input to an output target in the Pad page mapping grid.
| Property | Type | Description |
|---|---|---|
TargetLabel |
string |
Display label (e.g., "A", "Left Stick X", "CC 1"). Read-only. |
TargetSettingName |
string |
PadSetting property name (e.g., "ButtonA", "LeftThumbAxisX"). Read-only. |
Category |
MappingCategory |
Grouping: Buttons, DPad, Triggers, LeftStick, RightStick. |
NegSettingName |
string |
Negative-direction PadSetting property. Null for non-axis targets. |
HasNegDirection |
bool |
Computed: NegSettingName != null. |
| Property | Type | Default | Description |
|---|---|---|---|
SourceDescriptor |
string |
"" |
Physical input descriptor. Format: "{MapType} {Index}", "IH{MapType} {Index}", or "POV {Index} {Direction}". Empty = unmapped. Notifies SourceDisplayText and IsMapped. |
NegSourceDescriptor |
string |
"" |
Negative-direction descriptor for stick axes. |
SourceDisplayText |
string |
- | Computed: readable text. Bidirectional axes show "neg / pos". Falls back to "Not mapped". |
IsMapped |
bool |
- | Computed: true if either SourceDescriptor or NegSourceDescriptor is non-empty. |
| Method | Description |
|---|---|
SetResolvedSourceText(string) |
Sets display text (e.g., "A" instead of "Button 65"). Called by InputService. |
SetResolvedNegText(string) |
Sets resolved text for negative direction. |
LoadDescriptor(string) |
Sets source descriptor, syncs IsInverted/IsHalfAxis from prefix flags. |
LoadNegDescriptor(string) |
Loads negative-direction descriptor. |
SyncSelectedInputFromDescriptor() |
Syncs SelectedInput to current SourceDescriptor without re-triggering update. |
| Property | Type | Description |
|---|---|---|
AvailableInputs |
ObservableCollection<InputChoice> |
Source dropdown choices. Populated by InputService on device change. |
SelectedInput |
InputChoice |
Selected dropdown input. Updates SourceDescriptor. Empty sentinel triggers ClearCommand. Suppression flag prevents re-entrancy. |
| Event | Description |
|---|---|
InputSelectedFromDropdown |
Input selected from dropdown (for display text resolution). |
| Property | Type | Default | Description |
|---|---|---|---|
IsRecording |
bool |
false |
Recording mode active. Notifies RecordButtonText. |
RecordButtonText |
string |
- | Computed: "Record" or "Recording...". |
| Property | Type | Description |
|---|---|---|
CurrentValueText |
string |
Source input raw value. Updated at 30 Hz when visible. |
| Property | Type | Default | Description |
|---|---|---|---|
MappingDeadZone |
int |
50 |
Axis activation threshold (0–100%). Input below this percentage is ignored for this mapping row. |
IsDeadZoneApplicable |
bool |
- | Computed: true for axis-based mappings where a per-mapping deadzone is meaningful. |
| Command | Description |
|---|---|
ResetDeadZoneCommand |
Resets MappingDeadZone to 50. |
PadViewModel.ClearAllMappings resets all mapping deadzones to 50.
| Property | Type | Default | Description |
|---|---|---|---|
IsInverted |
bool |
false |
Axis inverted. Calls RebuildDescriptor() to toggle "I" prefix. |
IsHalfAxis |
bool |
false |
Upper half of axis range only. Calls RebuildDescriptor() to toggle "H" prefix. |
| Command | Description |
|---|---|
ToggleRecordCommand |
Toggles recording. Raises StartRecordingRequested or StopRecordingRequested. |
ClearCommand |
Clears source, neg descriptor, resets IsInverted/IsHalfAxis. |
| Event | Description |
|---|---|
StartRecordingRequested |
Start recording. |
StopRecordingRequested |
Recording should stop. |
File: MappingItem.cs
Input choice in the source dropdown.
| Property | Type | Description |
|---|---|---|
Descriptor |
string |
Mapping descriptor (e.g., "Button 0", "Axis 1", "POV 0 Up"). Empty string = "clear" sentinel. |
DisplayName |
string |
Human-readable display name (e.g., "A", "Left Stick X"). |
Values: Buttons, DPad, Triggers, LeftStick, RightStick.
File: MacroItem.cs
A trigger combination of inputs that produces a sequence of output actions. Evaluated between Step 3 (mapping) and Step 4 (combining).
| Property | Type | Default | Description |
|---|---|---|---|
Name |
string |
"New Macro" |
User-facing name. |
IsEnabled |
bool |
true |
Macro active. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerButtons |
ushort |
0 |
Gamepad button bitmask (e.g., Gamepad.A | Gamepad.B). All must be pressed. |
TriggerCustomButtonWords |
uint[] |
new uint[4] |
Wide bitmask for custom Extended slots (128 buttons, 4x32-bit). Not serialized. |
TriggerCustomButtons |
string |
null |
Serializable hex form (e.g., "00000003,00000000,00000000,00000000"). |
UsesCustomTrigger |
bool |
- | Computed: any custom trigger button set. |
TriggerSource |
MacroTriggerSource |
InputDevice |
Record from physical device or virtual controller output. |
TriggerDisplayText |
string |
- | Computed: readable trigger combo with device name. |
ButtonStyle |
MacroButtonStyle |
Xbox360 |
Display name style. Not serialized. |
CustomButtonCount |
int |
11 |
Custom Extended button count. Not serialized. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerDeviceGuid |
Guid |
Guid.Empty |
Trigger source device. Empty = legacy Xbox bitmask. |
TriggerRawButtons |
int[] |
[] |
Raw button indices. All must be pressed. |
UsesRawTrigger |
bool |
- | Computed: TriggerDeviceGuid != Empty && TriggerRawButtons.Length > 0. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerPovs |
string[] |
[] |
POV hat triggers as "povIndex:centidegrees" (e.g., "0:0" for POV 0 Up). |
UsesPovTrigger |
bool |
- | Computed: TriggerPovs.Length > 0. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerAxisTargets |
MacroAxisTarget[] |
[] |
Axes that must all exceed threshold. Not serialized. |
TriggerAxisTargetList |
string |
null |
Serializable comma-separated form. |
TriggerAxisThreshold |
int |
50 |
Threshold % (1–100). |
UsesAxisTrigger |
bool |
- | Computed: TriggerAxisTargets.Length > 0. |
TriggerAxisDirections |
MacroAxisDirection[] |
[] |
Direction filter per axis. Parallel array. Not serialized. |
TriggerAxisDirectionList |
string |
null |
Serializable comma-separated form. |
TriggerAxisDirectionIndex |
int |
- | UI index for direction (0=Any, 1=Positive, 2=Negative). Sets all uniformly. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerMode |
MacroTriggerMode |
OnPress |
OnPress, OnRelease, WhileHeld, Always, or CustomExpression (v3.2). |
IsNotAlwaysMode |
bool |
- | Computed: TriggerMode != Always. Controls trigger UI visibility. |
ConsumeTriggerButtons |
bool |
true |
Remove trigger buttons from Gamepad state on fire. |
| Property | Type | Default | Description |
|---|---|---|---|
IsRecordingTrigger |
bool |
false |
Recording trigger combo. Notifies RecordTriggerButtonText. |
RecordTriggerButtonText |
string |
- | Computed: "Stop" or "Record Trigger". |
RecordingLiveText |
string |
"" |
Live display of buttons pressed during recording. Not serialized. |
| Property | Type | Description |
|---|---|---|
Actions |
ObservableCollection<MacroAction> |
Ordered sequence of actions to execute. |
SelectedAction |
MacroAction |
Selected action. Refreshes remove command. |
| Property | Type | Default | Description |
|---|---|---|---|
RepeatMode |
MacroRepeatMode |
Once |
How actions repeat: Once, FixedCount, UntilRelease. |
RepeatCount |
int |
1 |
Repeat count for FixedCount mode. Min 1. |
RepeatDelayMs |
int |
100 |
Delay between repeats (ms). Min 0. |
| Property | Type | Description |
|---|---|---|
IsExecuting |
bool |
Executing action sequence. |
CurrentActionIndex |
int |
Position in action sequence. |
RemainingRepeats |
int |
Remaining repeat count. |
ActionStartTime |
DateTime |
When current action/delay started. |
WasTriggerActive |
bool |
Trigger active on previous frame. |
| Command | Description |
|---|---|
RecordTriggerCommand |
Toggles IsRecordingTrigger and raises RecordTriggerRequested. |
AddActionCommand |
Adds a new MacroAction with default type ButtonPress. |
RemoveActionCommand |
Removes selected action (CanExecute: SelectedAction != null). |
| Event | Description |
|---|---|
RecordTriggerRequested |
Trigger recording toggled. |
File: MacroItem.cs (nested class)
Single action in a macro's sequence.
| Property | Type | Default | Description |
|---|---|---|---|
Type |
MacroActionType |
ButtonPress |
Action type. Notifies all Is*Type properties. |
DurationMs |
int |
50 |
Hold/delay duration (ms). Min 0. |
DisplayText |
string |
- | Computed: readable action summary. |
IsButtonType, IsKeyType, IsDurationType, IsAxisType, IsSystemVolumeType, IsAppVolumeType, IsMouseMoveType, IsMouseButtonType, IsContinuousAxisType, IsDeviceAxisSource, IsOutputAxisSource
| Property | Type | Default | Description |
|---|---|---|---|
ButtonFlags |
ushort |
0 |
Xbox bitmask for gamepad presets. |
ButtonStyle |
MacroButtonStyle |
Xbox360 |
Display name style. Not serialized. |
CustomButtonCount |
int |
11 |
Numbered style button count. Not serialized. |
CustomButtonWords |
uint[] |
new uint[4] |
Wide bitmask for Extended slots (128 buttons). Not serialized. |
CustomButtons |
string |
null |
Serializable hex form. |
ButtonOptions |
IReadOnlyList<GamepadButtonOption> |
- | Computed: checkbox-bindable list. Lazy-built from style and count. |
| Method | Description |
|---|---|
SetCustomButton(int, bool) |
Sets/clears a custom Extended button by 0-based index. |
IsCustomButtonPressed(int) |
Returns whether a custom button is pressed. |
HasCustomButtons |
Computed: any custom button is set. |
| Property | Type | Default | Description |
|---|---|---|---|
KeyCode |
int |
0 |
Win32 VK_ code. Notifies SelectedVirtualKey. |
SelectedVirtualKey |
VirtualKey |
None |
Enum wrapper for ComboBox. Not serialized. |
KeyString |
string |
"" |
Multi-key combo in x360ce format ("{Control}{Alt}{Delete}"). |
ParsedKeyCodes |
int[] |
- | Computed: VK codes from KeyString; falls back to KeyCode. |
SelectedKeyToAdd |
VirtualKey |
None |
Key picker binding. Auto-appends to KeyString and resets. |
| Command | Description |
|---|---|
ClearKeyStringCommand |
Clears the KeyString. |
| Static | Description |
|---|---|
VirtualKeyValues |
List<KeyDisplayItem> with localized display names. Rebuilt on culture change. |
ParseKeyString(string) |
Parses "{Key1}{Key2}..." into int[] of VK codes. |
FormatKeyString(int[]) |
Formats VK codes into "{Key1}{Key2}..." string. |
| Property | Type | Default | Description |
|---|---|---|---|
AxisValue |
short |
0 |
AxisSet: signed value (−32768 to 32767). |
AxisTarget |
MacroAxisTarget |
None |
Which axis to set/read. |
InvertAxis |
bool |
false |
Invert axis value. |
| Property | Type | Default | Description |
|---|---|---|---|
ShowVolumeOsd |
bool |
true |
Trigger Windows volume OSD. |
ProcessName |
string |
"" |
AppVolume: target process name. |
AudioProcessNames |
ObservableCollection<string> |
empty | Processes with active audio sessions (suggestions). |
VolumeLimit |
int |
100 |
Max volume % (1–100). |
| Command | Description |
|---|---|
RefreshAudioProcessesCommand |
Refreshes active audio session process list. |
| Property | Type | Default | Description |
|---|---|---|---|
MouseSensitivity |
float |
10f |
Pixels/scroll units per frame at full deflection (1–100). |
MouseButton |
MacroMouseButton |
Left |
Mouse button for press/release. |
MouseAccumulator |
float |
0 |
Fractional pixel accumulator for sub-pixel precision. |
| Property | Type | Default | Description |
|---|---|---|---|
AxisSource |
MacroAxisSource |
OutputController |
Axis value source. |
SourceDeviceGuid |
Guid |
Guid.Empty |
InputDevice source: physical device GUID. |
SourceDeviceAxisIndex |
int |
-1 |
InputDevice source: axis index in InputState.Axis[]. |
MacroTriggerMode: OnPress, OnRelease, WhileHeld, Always, CustomExpression (v3.2)
MacroTriggerSource: InputDevice, OutputController
MacroRepeatMode: Once, FixedCount, UntilRelease
MacroActionType: ButtonPress, ButtonRelease, KeyPress, KeyRelease, Delay, AxisSet, SystemVolume, AppVolume, MouseMove, MouseButtonPress, MouseButtonRelease, MouseScroll, ToggleTouchpadOverlay (v3.2), LightbarColor / LightbarColorClear / LightbarModeSet / LightbarModeCycle (v3.1+), Rumble / RumbleStop (v3.1+)
MacroLightbarHoldMode: Reactive, Sticky (v3.1)
MacroLightbarColorSource: Fixed, RandomHue, PaletteStep (v3.1)
MacroRumbleHoldMode: Reactive, Sticky (v3.1)
MacroMouseButton: Left, Right, Middle, X1, X2
MacroAxisTarget: None, LeftStickX, LeftStickY, RightStickX, RightStickY, LeftTrigger, RightTrigger
MacroAxisDirection: Any, Positive, Negative
MacroAxisSource: OutputController, InputDevice
MacroButtonStyle: Xbox360, DualShock4, Numbered
File: MacroItem.cs
Checkbox for a single gamepad button. Reads/writes bits from the parent MacroAction's ButtonFlags (or CustomButtonWords for Extended slots).
| Property | Type | Description |
|---|---|---|
Label |
string |
Button display name. |
Flag |
ushort |
Xbox/PlayStation bitmask flag (0 for custom). |
CustomIndex |
int |
Extended button index (0-based). −1 = use Flag. |
IsChecked |
bool |
Button selected. Reads/writes parent's flags. |
| Method | Description |
|---|---|
Refresh() |
Re-evaluates IsChecked after external state change. |
File: MacroItem.cs
Wraps a VirtualKey with a localized display name for ComboBox binding.
| Property | Type | Description |
|---|---|---|
Key |
VirtualKey |
The virtual key value. |
DisplayName |
string |
Localized display name. |
File: ProfileShortcutViewModel.cs
Wraps a GlobalMacroData instance for data binding in the ProfilesPage shortcuts card. One ViewModel per shortcut row.
public ProfileShortcutViewModel(
GlobalMacroData data,
Action<ProfileShortcutViewModel> deleteCallback,
Action<ProfileShortcutViewModel> saveCallback)deleteCallback removes the row; saveCallback triggers a settings save via SettingsService.MarkDirty().
| Property | Type | Description |
|---|---|---|
SwitchMode |
SwitchProfileMode |
Two-way bound to mode ComboBox. Setter writes through to Data.SwitchMode and raises IsSpecificMode. |
IsSpecificMode |
bool (computed) |
true when SwitchMode == Specific. Controls visibility of the target profile dropdown. |
SwitchModes |
ObservableCollection<SwitchProfileModeItem> |
Dropdown items: Next, Previous, Specific, ToggleWindow, ToggleVCsDisabled (v3.2). |
SwitchProfileModeItem is a class extending ObservableObject with a read-only Mode and a mutable DisplayName that updates in place on culture change. ToString() returns DisplayName so ComboBox display refreshes on language switch without rebuilding the list.
| Property | Type | Description |
|---|---|---|
TargetProfileName |
string |
Display name of the target profile. Getter resolves Data.TargetProfileId via SettingsManager.Profiles. Setter looks up by name and writes the ID. null ID maps to "Default". |
ProfileNames |
ObservableCollection<string> (computed) |
"Default" + all profile names from SettingsManager.Profiles. |
| Property | Type | Description |
|---|---|---|
SelectedDeviceName |
string |
Resolved device name or "Any". Guid.Empty = any device. |
DeviceOptions |
ObservableCollection<string> (computed) |
"Any" + online device names from SettingsManager.UserDevices. |
| Property | Type | Description |
|---|---|---|
ButtonComboDisplay |
string (computed) |
Human-readable trigger combo. Joins entries with " + ", resolving each to a friendly name (e.g., "A (Xbox Controller) + LT+ (Xbox Controller)"). During recording, appends countdown. |
Name resolution helpers:
-
ResolveButtonName(int index, Guid deviceGuid). Gamepad-type devices use standard names (A, B, X, Y, LB, RB, Back, Start, LS, RS, Guide) for indices 0–10. Keyboard devices resolve viaVirtualKeyenum. Others fall back to "Button N". -
ResolveAxisName(int index, Guid deviceGuid, AxisTriggerDirection direction). Gamepad axes use LX/LY/LT/RX/RY/RT names with +/– suffix. Others use "Axis N+/–". -
ResolveDeviceName(Guid deviceGuid). ReturnsResolvedNamefromUserDevices, ornullforGuid.Empty.
| Property | Type | Description |
|---|---|---|
IsRecording |
bool |
true during Learn mode. Raises LearnButtonText and LearnButtonIcon. |
RecordingCountdown |
int |
Seconds remaining. Raises ButtonComboDisplay on change. |
LearnButtonText |
string (computed) |
"Learning..." or "Learn" |
LearnButtonIcon |
string (computed) |
\uE71A (Stop) or \uE7C8 (Record) |
| Method | Description |
|---|---|
SetLearnedButtons(TriggerButtonEntry[] entries) |
Saves captured entries to Data.TriggerEntries, clears recording state, invokes save callback. |
CancelRecording() |
Clears IsRecording without saving. |
NotifyComboChanged() |
Raises ButtonComboDisplay for live display during recording. |
| Command | Action |
|---|---|
DeleteCommand |
Invokes _deleteCallback. Removes this shortcut from the list. |
ClearCommand |
Sets Data.TriggerEntries = null, updates display, saves. |
File: StickConfigItem.cs
One thumbstick section in the Sticks tab. Gamepad presets: 0 = Left, 1 = Right. Custom Extended: 0..N per ThumbstickCount.
| Property | Type | Description |
|---|---|---|
Title |
string |
Display title (e.g., "Left Thumbstick", "Stick 1"). Read-only. |
Index |
int |
Stick index (0-based). Read-only. |
AxisXIndex |
int |
Raw axis index for X in ExtendedRawState.Axes (-1 for gamepad). Read-only. |
AxisYIndex |
int |
Raw axis index for Y in ExtendedRawState.Axes (-1 for gamepad). Read-only. |
All percentage properties clamped to 0–100. Each has a *Digit companion for digit-based binding (signed 16-bit: +/−32768).
| Property (%) | Digit Property | Default | Description |
|---|---|---|---|
DeadZoneX |
DeadZoneXDigit |
0 |
X deadzone percentage. |
DeadZoneY |
DeadZoneYDigit |
0 |
Y deadzone percentage. |
AntiDeadZoneX |
AntiDeadZoneXDigit |
0 |
X anti-deadzone percentage. |
AntiDeadZoneY |
AntiDeadZoneYDigit |
0 |
Y anti-deadzone percentage. |
MaxRangeX |
MaxRangeXDigit |
100 |
X max range (positive), 1–100. |
MaxRangeY |
MaxRangeYDigit |
100 |
Y max range (positive), 1–100. |
MaxRangeXNeg |
MaxRangeXNegDigit |
100 |
X max range (negative), 1–100. |
MaxRangeYNeg |
MaxRangeYNegDigit |
100 |
Y max range (negative), 1–100. |
CenterOffsetX |
CenterOffsetXDigit |
0 |
X center offset, −100 to 100. |
CenterOffsetY |
CenterOffsetYDigit |
0 |
Y center offset, −100 to 100. |
Linear |
- | 0 |
Linear interpolation factor (0–100). |
| Property | Type | Default | Description |
|---|---|---|---|
DeadZoneShape |
DeadZoneShape |
ScaledRadial |
Shape enum. Notifies DeadZoneShapeIndex and Is*Shape properties. |
DeadZoneShapeIndex |
int |
0 |
ComboBox SelectedIndex. Maps display order to enum. |
IsAxialShape |
bool |
- | Computed. |
IsRadialShape |
bool |
- | Computed: Radial or ScaledRadial. |
IsSlopedShape |
bool |
- | Computed: SlopedAxial or SlopedScaledAxial. |
IsHybridShape |
bool |
- | Computed. |
HasSlopedWedges |
bool |
- | Computed: SlopedAxial, SlopedScaledAxial, or Hybrid. |
Display order: ScaledRadial(0), Radial(1), Axial(2), Hybrid(3), SlopedScaledAxial(4), SlopedAxial(5).
| Property | Type | Default | Description |
|---|---|---|---|
SensitivityCurveX |
string |
"0,0;1,1" |
X-axis sensitivity curve (control point string). |
SensitivityCurveY |
string |
"0,0;1,1" |
Y-axis sensitivity curve. |
PresetNameX |
string |
- | Computed: matched preset name for X curve. |
PresetNameY |
string |
- | Computed: matched preset name for Y curve. |
| Static | Description |
|---|---|
CurvePresetNames |
string[] of available curve preset display names. Rebuilt on culture change. |
| Property | Type | Default | Description |
|---|---|---|---|
IsCalibrating |
bool |
false |
Center calibration in progress. |
HardwareRawX |
short |
- | Unprocessed hardware X value (not affected by offset/deadzone). |
HardwareRawY |
short |
- | Unprocessed hardware Y value. |
| Method | Description |
|---|---|
StartCalibration() |
Samples RawX/RawY over ~0.5 s (15 frames at 33 ms). Sets CenterOffsetX/Y to negate drift. |
| Property | Type | Default | Description |
|---|---|---|---|
LiveX |
double |
0.5 |
Live X (0.0–1.0 for Canvas). |
LiveY |
double |
0.5 |
Live Y. |
RawX |
short |
0 |
Processed raw X. Notifies RawDisplay. |
RawY |
short |
0 |
Processed raw Y. |
RawDisplay |
string |
- | Computed: "X: -1234 (50.0%) Y: 5678 (58.7%)". |
LiveInputX |
double |
0 |
CurveEditor X input (0–1). |
LiveInputY |
double |
0 |
CurveEditor Y input. |
ResetAllCommand, ResetDeadZoneShapeCommand, ResetCenterOffsetXCommand, ResetCenterOffsetYCommand, ResetDeadZoneXCommand, ResetDeadZoneYCommand, ResetAntiDeadZoneXCommand, ResetAntiDeadZoneYCommand, ResetLinearCommand, ResetSensitivityXCommand, ResetSensitivityYCommand, ResetMaxRangeXCommand, ResetMaxRangeYCommand, ResetMaxRangeXNegCommand, ResetMaxRangeYNegCommand
| Method | Description |
|---|---|
ApplyCurve(double, string) |
Applies spline LUT curve to a magnitude. Used by preview and Extended raw output. |
BuildTriggerCurvePoints(string, double, double, int, int) |
Builds 0–1 curve points for trigger charts with deadzone flattened. Returns PointCollection. |
File: TriggerConfigItem.cs
One trigger section in the Triggers tab. Gamepad presets: 0 = Left, 1 = Right. Custom Extended: 0..N per TriggerCount.
| Property | Type | Description |
|---|---|---|
Title |
string |
Display title (e.g., "Left Trigger", "Trigger 1"). Read-only. |
Index |
int |
Trigger index (0-based). Read-only. |
AxisIndex |
int |
Raw axis index in ExtendedRawState.Axes (-1 for gamepad). Read-only. |
All percentage properties clamped to 0–100 (except MaxRange: 1–100). Each has a *Digit companion for digit-based binding (unsigned 16-bit: 0–65535).
| Property (%) | Digit Property | Default | Description |
|---|---|---|---|
DeadZone |
DeadZoneDigit |
0 |
Deadzone %. |
MaxRange |
MaxRangeDigit |
100 |
Max range % (1–100). |
AntiDeadZone |
AntiDeadZoneDigit |
0 |
Anti-deadzone %. |
| Property | Type | Default | Description |
|---|---|---|---|
SensitivityCurve |
string |
"0,0;1,1" |
Sensitivity curve (control point string). |
PresetName |
string |
- | Computed: matched preset name for the curve. |
| Static | Description |
|---|---|
CurvePresetNames |
string[] of available curve preset display names. Rebuilt on culture change. |
| Property | Type | Default | Description |
|---|---|---|---|
LiveValue |
double |
0 |
Processed trigger value (0.0–1.0). |
RawValue |
ushort |
0 |
Processed raw value. Notifies RawDisplay. |
RawDisplay |
string |
- | Computed: formatted display "32768 (50.0%)". |
LiveInputForCurve |
double |
0 |
Live input for CurveEditor binding. |
ResetAllCommand, ResetRangeCommand (resets DeadZone+MaxRange), ResetAntiDeadZoneCommand, ResetSensitivityCommand
File: ExtendedSlotConfig.cs
Per-slot Extended-controller configuration. Drives stick/trigger/POV/button counts, the HID descriptor handed to HIDMaestro for Extended slots, and mapping generation.
| Constant | Value | Description |
|---|---|---|
MaxAxes |
8 |
DirectInput max axis count (shared between sticks and triggers). |
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
Customize |
bool |
false |
- | Master toggle for the override fields. When false, the VC is built from the catalog HM profile with no customizations (Product String, layout counts, OEM-name override are ignored even if they hold values). When true, each sub-field is applied on top of the catalog profile via HMProfileBuilder. |
ThumbstickCount |
int |
2 |
0–(MaxAxes - TriggerCount) / 2
|
Thumbsticks (2 axes each). Applied only when Customize is true. |
TriggerCount |
int |
2 |
0–MaxAxes - ThumbstickCount * 2
|
Triggers (1 axis each). Applied only when Customize is true. |
PovCount |
int |
1 |
0–4 | POV hat switches. Applied only when Customize is true. |
ButtonCount |
int |
11 |
0–128 | Buttons. Applied only when Customize is true. |
TotalAxes |
int |
- | - | Computed: ThumbstickCount * 2 + TriggerCount (max 8). |
MaxThumbsticks |
int |
- | - | Computed: max sticks given current triggers. |
MaxTriggers |
int |
- | - | Computed: max triggers given current sticks. |
OemNameOverride |
bool |
false |
- | Whether this slot claims the Windows DirectInput OEM-name table entry for its profile's VID:PID at create time, using ProductString as the label. Customize-gated. |
ProductString |
string |
"" |
- | Custom product string applied to the HID descriptor when Customize is true. |
| Method | Description |
|---|---|
ComputeAxisLayout(out int[], out int[], out int[]) |
Computes interleaved axis indices per group. |
The v2 ExtendedPreset enum (Xbox360 / DualShock4 / Custom) and the ApplyPresetDefaults() method that paired with it were dropped in v3 (commit d57a725). v3 picks layouts from the 225+ HIDMaestro profile catalog instead, with Customize as the single boolean that gates user overrides on top of the catalog profile.
Serializable DTO for persisting in PadForge.xml. All properties have [XmlAttribute].
| Property | Type | Default |
|---|---|---|
SlotIndex |
int |
0 |
Customize |
bool |
false |
ThumbstickCount |
int |
2 |
TriggerCount |
int |
2 |
PovCount |
int |
1 |
ButtonCount |
int |
11 |
OemNameOverride |
bool |
false |
ProductString |
string |
"" |
ForceFeedbackEnabled |
bool |
true |
ForceFeedbackEnabled defaults to true so v3.0.0/v3.0.1/v3.0.2 PadForge.xml files (which never wrote this attribute) deserialize with FFB enabled. Customize-gated like the layout overrides: only honored when Customize == true.
Older PadForge.xml files written by v2 contained a Preset attribute (Xbox360 / DualShock4 / Custom). v3 ignores it on read since the ExtendedPreset enum was removed in commit d57a725. Equivalent layouts in v3 come from the active HIDMaestro profile.
File: MidiSlotConfig.cs
Per-slot MIDI output configuration: CC/note counts, starting numbers, channel, and velocity.
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
Channel |
int |
1 |
1–16 | MIDI channel (1-based). |
CcCount |
int |
6 |
0–128 - StartCc
|
CC output count. |
StartCc |
int |
1 |
0–127 | Starting CC number. Re-clamps CcCount. |
NoteCount |
int |
11 |
0–128 - StartNote
|
Note output count. |
StartNote |
int |
60 |
0–127 | Starting note number. Re-clamps NoteCount. |
Velocity |
byte |
127 |
0–127 | Note velocity for button presses. |
| Method | Description |
|---|---|
GetCcNumbers() |
Returns int[] of sequential CC numbers from StartCc. |
GetNoteNumbers() |
Returns int[] of sequential note numbers from StartNote. |
Serializable DTO. All properties have [XmlAttribute].
| Property | Type | Default |
|---|---|---|
SlotIndex |
int |
0 |
Channel |
int |
1 |
CcCount |
int |
6 |
StartCc |
int |
1 |
NoteCount |
int |
11 |
StartNote |
int |
60 |
Velocity |
byte |
127 |
-
Architecture Overview: MVVM design philosophy,
CommunityToolkit.Mvvmusage -
XAML Views: View counterparts:
DashboardPage,PadPage,DevicesPage,SettingsPage -
Services Layer:
InputService,SettingsService,DeviceServiceconsumed by ViewModels -
Engine Library:
Gamepad,ExtendedRawState,KbmRawState,MidiRawState,PadSetting -
Settings and Serialization:
SettingsManagerdata synced to/from ViewModels bySettingsService -
Input Pipeline:
InputManagerstate reflected inPadViewModeloutput snapshots -
2D Overlay System:
ControllerModel2DView,ControllerSchematicViewbound toPadViewModel -
3D Model System:
ControllerModelViewbound toPadViewModel