-
Notifications
You must be signed in to change notification settings - Fork 2
ViewModels
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", "VJoyControllerIcon", "MidiControllerIcon", "KeyboardMouseControllerIcon"). |
IsEnabled |
bool |
Virtual controller enabled. |
ConnectedDeviceCount |
int |
Mapped physical devices connected. |
IsInitializing |
bool |
Virtual controller initializing. |
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: Green (#4CAF50) = Running, Amber (#FFB300) = Idle, Gray (#9E9E9E) = Stopped. Frozen (thread-safe). |
PollingFrequency |
double |
0 |
Current polling frequency in Hz. |
ConnectedDeviceCount |
int |
0 |
Connected input device count. |
IsViGEmInstalled |
bool |
false |
ViGEmBus installed. |
| 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. |
| Property | Type | Description |
|---|---|---|
IsViGEmInstalled |
bool |
ViGEmBus installed. Notifies ViGEmStatusText. |
ViGEmStatusText |
string |
Computed: "Installed" / "Not installed". |
ViGEmVersion |
string |
ViGEmBus version. |
IsHidHideInstalled |
bool |
HidHide installed. |
HidHideStatusText |
string |
Computed: "Installed" / "Not installed". |
IsVJoyInstalled |
bool |
vJoy installed. |
VJoyStatusText |
string |
Computed: "Installed" / "Not installed". |
IsMidiServicesInstalled |
bool |
Windows MIDI Services installed. |
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. |
| 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 |
Xbox360 |
Virtual controller output type. |
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. |
| Property | Type | Description |
|---|---|---|
IsViGEmInstalled |
bool |
ViGEmBus installed. Notifies ViGEmStatusText and refreshes commands. |
ViGEmStatusText |
string |
Computed: "Installed" / "Not installed". |
ViGEmVersion |
string |
ViGEmBus version. |
| Command | CanExecute | Description |
|---|---|---|
InstallViGEmCommand |
!IsViGEmInstalled |
Raises InstallViGEmRequested. |
UninstallViGEmCommand |
IsViGEmInstalled && !HasAnyViGEmSlots() |
Raises UninstallViGEmRequested. |
| Event | Description |
|---|---|
InstallViGEmRequested |
Install ViGEmBus. |
UninstallViGEmRequested |
Uninstall ViGEmBus. |
| 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 |
|---|---|---|
IsVJoyInstalled |
bool |
vJoy installed and DLL accessible. |
VJoyStatusText |
string |
Computed: "Installed" / "Not installed". |
VJoyVersion |
string |
vJoy version. |
| Command | CanExecute | Description |
|---|---|---|
InstallVJoyCommand |
!IsVJoyInstalled |
Raises InstallVJoyRequested. |
UninstallVJoyCommand |
IsVJoyInstalled && !HasAnyVJoySlots() |
Raises UninstallVJoyRequested. |
| Event | Description |
|---|---|
InstallVJoyRequested |
Install vJoy. |
UninstallVJoyRequested |
Uninstall vJoy. |
| 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 |
|---|---|---|
HasAnyViGEmSlots |
Func<bool> |
Set by MainWindow. True if any slot uses ViGEm. |
HasAnyVJoySlots |
Func<bool> |
Set by MainWindow. True if any slot uses vJoy. |
HasAnyMidiSlots |
Func<bool> |
Set by MainWindow. True if any slot uses MIDI. |
HasAnyHidHideDevices |
Func<bool> |
Set by MainWindow. True if any device has HidHide enabled. |
RefreshDriverGuards() |
method | Re-evaluates uninstall CanExecute. 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. |
EnableInputHiding |
bool |
true |
Master switch for device hiding (HidHide + input hooks). |
| 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 360 slots in this profile. |
DS4Count |
int |
Number of DualShock 4 slots. |
VJoyCount |
int |
Number of vJoy 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. |
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. |
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. |
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. |
| 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). |
File: PadViewModel.cs
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, dead zone/sensitivity, macros, force feedback, 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 |
Xbox360 |
Output type. Resets dead zones, 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 360, 1=DS4, 2=VJoy, 3=Midi, 4=KBM). Maps directly to VirtualControllerType enum values. |
ConfigItemDirtyCallback |
Action |
null |
Called on config item change. Wired to SettingsService.MarkDirty(). |
| Property | Type | Description |
|---|---|---|
VJoyConfig |
VJoySlotConfig |
Per-slot vJoy config (preset, axis/button counts). Only meaningful when OutputType == VJoy. 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(). |
| Event | Description |
|---|---|
MappingsRebuilt |
Raised after RebuildMappings() completes so InputService can reload descriptors. |
| Method | Description |
|---|---|
RebuildMappings() |
Rebuilds Mappings from OutputType and vJoy 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.
Left Stick:
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
LeftDeadZoneShape |
int |
2 (ScaledRadial) |
0–5 | Dead zone shape index. |
LeftDeadZoneX |
double |
0 |
0–100 | X dead zone %. |
LeftDeadZoneY |
double |
0 |
0–100 | Y dead zone %. |
LeftAntiDeadZoneX |
double |
0 |
0–100 | X anti-dead zone %. |
LeftAntiDeadZoneY |
double |
0 |
0–100 | Y anti-dead zone %. |
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 dead zone %. |
RightTriggerDeadZone |
double |
0 |
0–100 | Right trigger dead zone %. |
LeftTriggerAntiDeadZone |
double |
0 |
0–100 | Left trigger anti-dead zone %. |
RightTriggerAntiDeadZone |
double |
0 |
0–100 | Right trigger anti-dead zone %. |
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 vJoy: 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 dead zone 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 |
0=Controller, 1=Macros, 2=Mappings, 3=Sticks, 4=Triggers, 5=Force Feedback. |
| 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. |
UpdateFromVJoyRawState(VJoyRawState) |
Updates combined output from vJoy 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 |
|---|---|---|
VJoyOutputSnapshot |
VJoyRawState |
Latest vJoy 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 |
|---|---|---|---|
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 vJoy (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 vJoy 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, or Always. |
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 vJoy (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 vJoy 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
MacroTriggerSource: InputDevice, OutputController
MacroRepeatMode: Once, FixedCount, UntilRelease
MacroActionType: ButtonPress, ButtonRelease, KeyPress, KeyRelease, Delay, AxisSet, SystemVolume, AppVolume, MouseMove, MouseButtonPress, MouseButtonRelease, MouseScroll
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 vJoy).
| Property | Type | Description |
|---|---|---|
Label |
string |
Button display name. |
Flag |
ushort |
Xbox/DS4 bitmask flag (0 for custom). |
CustomIndex |
int |
vJoy 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: StickConfigItem.cs
One thumbstick section in the Sticks tab. Gamepad presets: 0 = Left, 1 = Right. Custom vJoy: 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 VJoyRawState.Axes (-1 for gamepad). Read-only. |
AxisYIndex |
int |
Raw axis index for Y in VJoyRawState.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 dead zone percentage. |
DeadZoneY |
DeadZoneYDigit |
0 |
Y dead zone percentage. |
AntiDeadZoneX |
AntiDeadZoneXDigit |
0 |
X anti-dead zone percentage. |
AntiDeadZoneY |
AntiDeadZoneYDigit |
0 |
Y anti-dead zone 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/dead zone). |
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 vJoy. |
BuildTriggerCurvePoints(string, double, double, int, int) |
Builds 0–1 curve points for trigger charts with dead zone flattened. Returns PointCollection. |
File: TriggerConfigItem.cs
One trigger section in the Triggers tab. Gamepad presets: 0 = Left, 1 = Right. Custom vJoy: 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 VJoyRawState.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 |
Dead zone %. |
MaxRange |
MaxRangeDigit |
100 |
Max range % (1–100). |
AntiDeadZone |
AntiDeadZoneDigit |
0 |
Anti-dead zone %. |
| 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: VJoySlotConfig.cs
Per-slot vJoy configuration. Drives stick/trigger/POV/button counts, HID descriptor generation, and mapping generation.
| Constant | Value | Description |
|---|---|---|
MaxAxes |
8 |
DirectInput max axis count (shared between sticks and triggers). |
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
Preset |
VJoyPreset |
Xbox360 |
- | Preset. Calls ApplyPresetDefaults(). |
ThumbstickCount |
int |
2 |
0–(MaxAxes - TriggerCount) / 2
|
Thumbsticks (2 axes each). |
TriggerCount |
int |
2 |
0–MaxAxes - ThumbstickCount * 2
|
Triggers (1 axis each). |
PovCount |
int |
1 |
0–4 | POV hat switches. |
ButtonCount |
int |
11 |
0–128 | Buttons. |
TotalAxes |
int |
- | - | Computed: ThumbstickCount * 2 + TriggerCount (max 8). |
MaxThumbsticks |
int |
- | - | Computed: max sticks given current triggers. |
MaxTriggers |
int |
- | - | Computed: max triggers given current sticks. |
IsGamepadPreset |
bool |
- | - | Computed: Preset != Custom. |
| Method | Description |
|---|---|
ComputeAxisLayout(out int[], out int[], out int[]) |
Computes interleaved axis indices per group. |
ApplyPresetDefaults() |
Sets counts: Xbox360 (2/2/1/11), DS4 (2/2/1/14). Custom keeps current. |
VJoyPreset enum: Xbox360, DualShock4, Custom
Serializable DTO for persisting in PadForge.xml. All properties have [XmlAttribute].
| Property | Type | Default |
|---|---|---|
SlotIndex |
int |
0 |
Preset |
VJoyPreset |
- |
ThumbstickCount |
int |
2 |
TriggerCount |
int |
2 |
PovCount |
int |
1 |
ButtonCount |
int |
11 |
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,VJoyRawState,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