-
Notifications
You must be signed in to change notification settings - Fork 6
ViewModels
All ViewModels live in PadForge.App/ViewModels/ under the PadForge.ViewModels namespace. They use CommunityToolkit.Mvvm (ObservableObject, RelayCommand).
File: ViewModelBase.cs
Abstract base class for all PadForge ViewModels. Extends ObservableObject (which provides INotifyPropertyChanged and SetProperty helpers).
public abstract class ViewModelBase : ObservableObject
{
public string Title { get; set; }
}| Property | Type | Description |
|---|---|---|
Title |
string |
Display title for the view. Used by navigation and page headers. |
ViewModelBase subscribes to Strings.CultureChanged in its constructor to support live language switching. When the user changes the UI language at runtime, Strings.ChangeCulture() raises CultureChanged, and every living ViewModel's OnCultureChanged() method is called. Derived ViewModels override OnCultureChanged() to refresh culture-dependent computed properties (status text, display titles, etc.).
Strings.CultureChanged uses a weak event pattern: instance-method subscribers are stored as (WeakReference<Target>, MethodInfo) pairs rather than strong delegates. This means short-lived ViewModels are eligible for garbage collection without needing to explicitly unsubscribe. Dead entries are pruned automatically 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)
ViewModel for a single virtual controller entry in the sidebar navigation. Displays the controller type icon, sequential slot number, and per-type instance label.
| Property | Type | Description |
|---|---|---|
PadIndex |
int |
Zero-based pad slot index (0-15). Read-only, set in constructor. |
Tag |
string |
Navigation tag for this item ("Pad1"-"Pad16"). Computed as $"Pad{PadIndex + 1}". |
SlotNumber |
int |
Overall controller number among active slots (1-based). |
InstanceLabel |
string |
Per-type instance number label (e.g., "1", "2"). |
IconKey |
string |
Resource key for the controller type icon (e.g., "XboxControllerIcon", "DS4ControllerIcon", "VJoyControllerIcon", "MidiControllerIcon", "KeyboardMouseControllerIcon"). |
IsEnabled |
bool |
Whether this virtual controller is enabled (ViGEm active). |
ConnectedDeviceCount |
int |
Number of mapped physical devices that are currently connected. |
IsInitializing |
bool |
Whether the virtual controller for this slot is currently initializing. |
XAML binding: Sidebar ListBox items bind to NavControllerItems collection on MainViewModel. Each item's template binds SlotNumber, InstanceLabel, IconKey (as DynamicResource), and IsEnabled for status indicators.
File: MainViewModel.cs
DataContext for: MainWindow
Root ViewModel for the application. Manages navigation state, the collection of 16 pad ViewModels, sidebar controller entries, and app-wide status information.
| Property | Type | Description |
|---|---|---|
Pads |
ObservableCollection<PadViewModel> |
The 16 virtual controller pad ViewModels (one per slot). Created in constructor. |
NavControllerItems |
ObservableCollection<NavControllerItemViewModel> |
Sidebar navigation items for created virtual controller slots. Dynamically rebuilt by RefreshNavControllerItems(). |
Dashboard |
DashboardViewModel |
Dashboard overview ViewModel. |
Devices |
DevicesViewModel |
Devices list ViewModel. |
Settings |
SettingsViewModel |
Application settings ViewModel. |
| Property | Type | Description |
|---|---|---|
SelectedNavTag |
string |
Tag of the currently selected navigation item. Values: "Dashboard", "Pad1"-"Pad16", "Devices", "Settings", "About". Setting this also raises PropertyChanged for IsPadPageSelected and SelectedPadIndex. |
IsPadPageSelected |
bool |
True if a Pad page (Pad1-Pad16) is currently selected. Computed. |
SelectedPadIndex |
int |
Zero-based pad index for the currently selected Pad page, or -1. Computed from SelectedNavTag. |
SelectedPad |
PadViewModel |
The PadViewModel for the currently selected Pad page, or null. Computed. |
| Property | Type | Default | Description |
|---|---|---|---|
StatusText |
string |
"Ready" |
Status bar text displayed at the bottom of the main window. |
IsEngineRunning |
bool |
false |
Whether the input engine polling loop is currently active. Setting this calls RefreshEngineStatus(). |
HasActiveSlots |
bool |
false |
Whether any virtual controller slots are currently created. Setting this calls RefreshEngineStatus(). |
EngineStatusText |
string |
- | Computed: "Running" / "Idle" / "Stopped" depending on IsEngineRunning and HasActiveSlots. |
EngineStatusBrush |
Brush |
- | Computed: Green (#4CAF50) = Running, Amber (#FFB300) = Idle, Gray (#9E9E9E) = Stopped. Frozen brushes (thread-safe). |
PollingFrequency |
double |
0 |
Current input polling frequency in Hz. |
ConnectedDeviceCount |
int |
0 |
Number of currently connected input devices. |
IsViGEmInstalled |
bool |
false |
Whether the ViGEmBus driver is installed and available. |
| Command | CanExecute | Description |
|---|---|---|
StartEngineCommand |
!IsEngineRunning |
Raises StartEngineRequested event. Wired by MainWindow code-behind. |
StopEngineCommand |
IsEngineRunning |
Raises StopEngineRequested event. |
| Event | Args | Description |
|---|---|---|
StartEngineRequested |
EventArgs |
User requested starting the engine. |
StopEngineRequested |
EventArgs |
User requested stopping the engine. |
NavControllerItemsRefreshed |
EventArgs |
Raised after RefreshNavControllerItems() completes collection changes. MainWindow subscribes to this instead of CollectionChanged to avoid multiple rapid sidebar rebuilds. |
| Method | Description |
|---|---|
RefreshNavControllerItems() |
Rebuilds sidebar entries based on which slots are created (SettingsManager.SlotCreated[]). Computes per-type instance numbers (Xbox #1, DS4 #2, etc.) and updates each pad's Title, SlotLabel, and TypeInstanceLabel. Only triggers NavControllerItemsRefreshed when slots are added/removed. |
ForceNavControllerItemsRefreshed() |
Forces a NavControllerItemsRefreshed event even when slot count hasn't changed. Used after slot reorder/swap. |
RefreshEngineStatus() |
Raises PropertyChanged for EngineStatusText and EngineStatusBrush. |
RefreshCommands() |
Notifies CanExecuteChanged on start/stop commands. Call after IsEngineRunning changes. |
File: DashboardViewModel.cs
DataContext for: Dashboard page
Shows an at-a-glance overview of all controller slots, engine status, connected devices, and driver status.
| Property | Type | Description |
|---|---|---|
SlotSummaries |
ObservableCollection<SlotSummary> |
Summary cards for created virtual controller slots. Rebuilt by RefreshActiveSlots(). |
ShowAddController |
bool |
Whether the "Add Controller" card should be visible (any controller type has capacity). |
| Property | Type | Default | Description |
|---|---|---|---|
EngineStatus |
string |
"Stopped" |
Current engine status text (localized). |
EngineStateKey |
string |
"Stopped" |
Non-localized engine state key ("Running", "Stopped", "Idle") for XAML DataTriggers. |
PollingFrequency |
double |
0 |
Current polling frequency in Hz. Setting this also notifies PollingFrequencyText. |
PollingFrequencyText |
string |
- | Computed: formatted polling frequency (e.g., "987.3 Hz") or dash when zero. |
| Property | Type | Description |
|---|---|---|
TotalDevices |
int |
Total number of detected input devices (online + offline). |
OnlineDevices |
int |
Number of currently connected (online) input devices. |
MappedDevices |
int |
Number of devices that have an active mapping to a pad slot. |
| Property | Type | Description |
|---|---|---|
IsViGEmInstalled |
bool |
Whether ViGEmBus is installed. Setting this notifies ViGEmStatusText. |
ViGEmStatusText |
string |
Computed: "Installed" / "Not installed". |
ViGEmVersion |
string |
ViGEmBus driver version string. |
IsHidHideInstalled |
bool |
Whether HidHide is installed. |
HidHideStatusText |
string |
Computed: "Installed" / "Not installed". |
IsVJoyInstalled |
bool |
Whether the vJoy driver is installed. |
VJoyStatusText |
string |
Computed: "Installed" / "Not installed". |
IsMidiServicesInstalled |
bool |
Whether Windows MIDI Services is installed. |
MidiServicesStatusText |
string |
Computed: "Installed" / "Not installed". |
| Property | Type | Default | Description |
|---|---|---|---|
EnableDsuMotionServer |
bool |
false |
Whether the DSU (cemuhook) motion server is enabled. |
DsuMotionServerPort |
int |
26760 |
UDP port for the DSU motion server. Clamped to 1024-65535. |
DsuServerStatus |
string |
"Stopped" |
Current status of the DSU server. |
| Property | Type | Default | Description |
|---|---|---|---|
EnableWebController |
bool |
false |
Whether the web controller server is enabled. |
WebControllerPort |
int |
8080 |
HTTP/WebSocket port. Clamped to 1024-65535. |
WebControllerStatus |
string |
"Stopped" |
Current status of the web controller server. |
WebControllerClientCount |
int |
0 |
Number of currently connected web controller clients. |
| Method | Description |
|---|---|
RefreshActiveSlots(IList<int>, bool) |
Rebuilds SlotSummaries to only include active slots. Updates sequential display labels. Sets ShowAddController. Called from InputService. |
File: DashboardViewModel.cs (nested class)
Summary information for a single virtual controller slot, displayed as a card on the Dashboard page.
| Property | Type | Default | Description |
|---|---|---|---|
PadIndex |
int |
- | Zero-based pad slot index. Read-only. |
SlotLabel |
string |
- | Display label (e.g., "Virtual Controller 1"). |
DeviceName |
string |
"No device" |
Name of the primary device mapped to this slot. |
IsActive |
bool |
false |
Whether this slot has at least one online mapped device. |
IsVirtualControllerConnected |
bool |
false |
Whether the ViGEm virtual controller is connected. |
IsInitializing |
bool |
false |
Whether the virtual controller is currently initializing. |
MappedDeviceCount |
int |
0 |
Number of devices mapped to this slot. |
ConnectedDeviceCount |
int |
0 |
Number of mapped devices that are currently connected. |
StatusText |
string |
"Idle" |
Status text (e.g., "Active", "Idle", "No mapping", "Disabled"). |
IsEnabled |
bool |
true |
Whether this slot is enabled for ViGEm output. |
SlotNumber |
int |
1 |
Overall controller number among active slots (1-based). |
TypeInstanceLabel |
string |
"1" |
Per-type instance number label. |
OutputType |
VirtualControllerType |
Xbox360 |
The virtual controller output type. |
File: SettingsViewModel.cs
DataContext for: Settings page
Manages application-level settings including theme, language, driver management, profiles, and engine configuration.
| Property | Type | Default | Description |
|---|---|---|---|
SelectedThemeIndex |
int |
0 |
0 = System, 1 = Light, 2 = Dark. Setting this raises ThemeChanged event. |
| Event | Args | Description |
|---|---|---|
ThemeChanged |
int |
Raised when theme selection changes. Arg = theme index. |
| Property | Type | Description |
|---|---|---|
AvailableLanguages |
ObservableCollection<CultureInfo> |
Available UI languages: en, de, fr, ja, ko, zh-Hans, pt-BR, es, it, nl. |
SelectedLanguage |
CultureInfo |
Currently selected UI language. Setting this applies the new language immediately via Strings.ChangeCulture(). Defaults to current UI culture or English. |
| Member | Type | Description |
|---|---|---|
LanguageCode |
string |
Internal: persisted language code for serialization. |
SetLanguageFromCode(string) |
method | Internal: sets language from a persisted code on startup without raising CultureChanged. |
| Property | Type | Description |
|---|---|---|
IsViGEmInstalled |
bool |
Whether ViGEmBus is installed. Setting this notifies ViGEmStatusText and refreshes install/uninstall commands. |
ViGEmStatusText |
string |
Computed: "Installed" / "Not installed". |
ViGEmVersion |
string |
ViGEmBus driver version string. |
| Command | CanExecute | Description |
|---|---|---|
InstallViGEmCommand |
!IsViGEmInstalled |
Raises InstallViGEmRequested. |
UninstallViGEmCommand |
IsViGEmInstalled && !HasAnyViGEmSlots() |
Raises UninstallViGEmRequested. |
| Event | Description |
|---|---|
InstallViGEmRequested |
User requested ViGEmBus installation. |
UninstallViGEmRequested |
User requested ViGEmBus uninstallation. |
| Property | Type | Description |
|---|---|---|
IsHidHideInstalled |
bool |
Whether HidHide is installed. |
HidHideStatusText |
string |
Computed: "Installed" / "Not installed". |
HidHideVersion |
string |
HidHide driver version string. |
HidHideWhitelistPaths |
ObservableCollection<string> |
Application paths whitelisted in HidHide. |
SelectedWhitelistPath |
string |
Currently selected whitelist path. Setting this refreshes RemoveWhitelistPathCommand. |
| Command | CanExecute | Description |
|---|---|---|
InstallHidHideCommand |
!IsHidHideInstalled |
Raises InstallHidHideRequested. |
UninstallHidHideCommand |
IsHidHideInstalled && !HasAnyHidHideDevices() |
Raises UninstallHidHideRequested. |
AddWhitelistPathCommand |
IsHidHideInstalled |
Raises AddWhitelistPathRequested. |
RemoveWhitelistPathCommand |
SelectedWhitelistPath != null |
Removes selected path and raises WhitelistChanged. |
| Event | Description |
|---|---|
InstallHidHideRequested |
User requested HidHide installation. |
UninstallHidHideRequested |
User requested HidHide uninstallation. |
AddWhitelistPathRequested |
User requested adding a whitelist path (opens file dialog). |
WhitelistChanged |
Whitelist was modified (add or remove). |
| Property | Type | Description |
|---|---|---|
IsVJoyInstalled |
bool |
Whether vJoy driver is installed and DLL is accessible. |
VJoyStatusText |
string |
Computed: "Installed" / "Not installed". |
VJoyVersion |
string |
vJoy driver version string. |
| Command | CanExecute | Description |
|---|---|---|
InstallVJoyCommand |
!IsVJoyInstalled |
Raises InstallVJoyRequested. |
UninstallVJoyCommand |
IsVJoyInstalled && !HasAnyVJoySlots() |
Raises UninstallVJoyRequested. |
| Event | Description |
|---|---|
InstallVJoyRequested |
User requested vJoy installation. |
UninstallVJoyRequested |
User requested vJoy uninstallation. |
| Property | Type | Description |
|---|---|---|
IsMidiServicesInstalled |
bool |
Whether Windows MIDI Services is available. |
MidiServicesStatusText |
string |
Computed: "Installed" / "Not installed". |
MidiServicesVersion |
string |
MIDI Services version string. |
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> |
Internal. Set by MainWindow. Returns true if any slot uses ViGEm. |
HasAnyVJoySlots |
Func<bool> |
Internal. Set by MainWindow. Returns true if any slot uses vJoy. |
HasAnyMidiSlots |
Func<bool> |
Internal. Set by MainWindow. Returns true if any slot uses MIDI. |
HasAnyHidHideDevices |
Func<bool> |
Internal. Set by MainWindow. Returns true if any device has HidHide enabled. |
RefreshDriverGuards() |
method | Re-evaluates uninstall button CanExecute state. Call after slot creation/deletion/type changes. |
| Property | Type | Default | Description |
|---|---|---|---|
AutoStartEngine |
bool |
true |
Whether to auto-start the input engine on launch. |
MinimizeToTray |
bool |
false |
Whether to minimize to system tray instead of taskbar. |
StartMinimized |
bool |
false |
Whether to start the application minimized. |
StartAtLogin |
bool |
false |
Whether to auto-start PadForge at login. |
EnablePollingOnFocusLoss |
bool |
true |
Whether to continue polling when the application loses focus. |
PollingRateMs |
int |
1 |
Target polling interval in milliseconds. Clamped to 1-16. |
EnableInputHiding |
bool |
true |
Global master switch for device hiding (HidHide + input hooks). |
| Property | Type | Description |
|---|---|---|
SettingsFilePath |
string |
Full path to the currently loaded settings file. |
HasUnsavedChanges |
bool |
Whether there are unsaved changes. |
| Command | Description |
|---|---|
SaveCommand |
Raises SaveRequested. |
ReloadCommand |
Raises ReloadRequested. |
ResetCommand |
Raises ResetRequested. |
OpenSettingsFolderCommand |
Raises OpenSettingsFolderRequested. |
| Event | Description |
|---|---|
SaveRequested |
User requested saving. |
ReloadRequested |
User requested reloading from disk. |
ResetRequested |
User requested settings reset. |
OpenSettingsFolderRequested |
User wants to open the settings folder. |
| Property | Type | Description |
|---|---|---|
SdlVersion |
string |
SDL3 library version string. |
ApplicationVersion |
string |
Application version string. |
RuntimeVersion |
string |
.NET runtime version string. |
| Property | Type | Default | Description |
|---|---|---|---|
Use2DControllerView |
bool |
false |
Whether to show the 2D controller view instead of 3D. |
| Property | Type | Default | Description |
|---|---|---|---|
EnableAutoProfileSwitching |
bool |
false |
Whether auto-profile switching is enabled. |
ProfileItems |
ObservableCollection<ProfileListItem> |
empty | List of profile entries for the UI. |
SelectedProfile |
ProfileListItem |
null |
Currently selected profile. Setting this refreshes delete/edit/load commands. |
ActiveProfileInfo |
string |
"Default" |
Display text for the currently active profile. |
| 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 |
User requested reverting to default profile. |
NewProfileRequested |
User requested creating a new empty profile. |
SaveAsProfileRequested |
User requested saving current settings as a new profile. |
DeleteProfileRequested |
User requested deleting the selected profile. |
EditProfileRequested |
User requested editing the selected profile metadata. |
LoadProfileRequested |
User requested loading the selected profile. |
| Method | Description |
|---|---|
RefreshProfileCommands() |
Refreshes CanExecute state of delete/edit/load profile commands. |
File: SettingsViewModel.cs (nested class)
Display item for a profile in the Settings page list.
| Property | Type | Description |
|---|---|---|
Id |
string |
Profile identifier. |
Name |
string |
Display name. |
Executables |
string |
Comma-separated exe names for auto-switching. |
TopologyLabel |
string |
Summary of slot topology. |
HasNoSlots |
bool |
Computed: true if 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 built-in Default profile entry. |
File: DevicesViewModel.cs
DataContext for: Devices page
Shows all detected input devices (online and offline) and raw input state for the selected device.
| Property | Type | Description |
|---|---|---|
Devices |
ObservableCollection<DeviceRowViewModel> |
All known devices. Updated by InputService when the device list changes. |
SelectedDevice |
DeviceRowViewModel |
Currently selected device. Setting this notifies HasSelectedDevice, refreshes slot buttons, and refreshes assign/remove command state. |
HasSelectedDevice |
bool |
Computed: SelectedDevice != null. |
| Property | Type | Description |
|---|---|---|
TotalCount |
int |
Total number of detected devices. |
OnlineCount |
int |
Number of currently connected devices. |
| Property | Type | Description |
|---|---|---|
RawAxes |
ObservableCollection<AxisDisplayItem> |
Structured axis values for visual display (progress bars). |
RawButtons |
ObservableCollection<ButtonDisplayItem> |
Structured button states for visual display (circles). |
RawPovs |
ObservableCollection<PovDisplayItem> |
Structured POV hat values for visual display (compass). |
KeyboardKeys |
ObservableCollection<KeyboardKeyItem> |
Keyboard key layout items for visual keyboard display. |
IsKeyboardDevice |
bool |
Whether the selected device is a keyboard. |
IsMouseDevice |
bool |
Whether the selected device is a mouse. |
MouseMotionX |
double |
Mouse X motion value. |
MouseMotionY |
double |
Mouse Y motion value. |
MouseScrollIntensity |
double |
Normalized scroll intensity (-1 to 1). |
SelectedButtonTotal |
int |
Total number of buttons on the selected device. |
HasRawData |
bool |
Whether raw state data is available. |
| Property | Type | Description |
|---|---|---|
HasGyroData |
bool |
Whether gyroscope data is available. |
HasAccelData |
bool |
Whether accelerometer data is 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> |
Dynamic list of virtual controller slot toggle buttons. Only includes created/active slots. |
| Command | CanExecute | Description |
|---|---|---|
RefreshCommand |
always | Raises RefreshRequested. Force-refreshes the device list. |
AssignToSlotCommand |
HasSelectedDevice |
RelayCommand<int>. Raises AssignToSlotRequested with slot index (0-15). |
ToggleSlotCommand |
HasSelectedDevice |
RelayCommand<int>. Toggles selected device's assignment to a slot. Raises ToggleSlotRequested. |
HideDeviceCommand |
HasSelectedDevice |
Sets SelectedDevice.IsHidden = true, raises HideDeviceRequested. |
RemoveDeviceCommand |
HasSelectedDevice |
Removes device from list, raises RemoveDeviceRequested. |
| Event | Args | Description |
|---|---|---|
RefreshRequested |
EventArgs |
Refresh requested. |
AssignToSlotRequested |
int |
Device assigned to slot. Arg = slot index. |
ToggleSlotRequested |
int |
Slot toggle requested. Arg = slot index. |
HideDeviceRequested |
Guid |
Device hidden. Arg = instance GUID. |
RemoveDeviceRequested |
Guid |
Device removed. Arg = instance GUID. |
DeviceHidingChanged |
Guid |
Device's HidHide or ConsumeInput toggle changed. |
| Method | Description |
|---|---|
RebuildRawStateCollections(int, int, int, bool, bool) |
Internal. Rebuilds axis/button/POV collections for a new device. Handles keyboard layout and mouse special cases. |
ClearRawState() |
Internal. Clears all raw state display data. |
RefreshSlotButtons() |
Rebuilds ActiveSlotItems based on created slots and selected device's assignments. |
FindByGuid(Guid) |
Finds a DeviceRowViewModel by instance GUID. |
RefreshCounts() |
Updates TotalCount and OnlineCount from the Devices collection. |
NotifyDeviceHidingChanged(Guid) |
Raises DeviceHidingChanged event. |
| Member | Type | Description |
|---|---|---|
LastRawStateDeviceGuid |
Guid |
Internal. Tracks which device's collections are currently populated. Prevents unnecessary rebuilds. |
File: DevicesViewModel.cs
Represents a single virtual controller slot button on the Devices page.
| Property | Type | Description |
|---|---|---|
PadIndex |
int |
Zero-based pad slot index (0-15). |
SlotNumber |
int |
1-based slot number among active slots. |
IsAssigned |
bool |
Whether the currently selected device is assigned to this slot. |
File: DevicesViewModel.cs
Visual display item for a single axis value.
| Property | Type | Description |
|---|---|---|
Index |
int |
Axis index. |
Name |
string |
Display name (e.g., "Axis 0"). |
NormalizedValue |
double |
Axis value normalized to 0.0-1.0 range. Bound to ProgressBar. |
RawValue |
int |
Raw axis value (0-65535). |
File: DevicesViewModel.cs
Visual display item for a single button state.
| Property | Type | Description |
|---|---|---|
Index |
int |
Button index. |
IsPressed |
bool |
Whether the button is currently pressed. Bound to circle fill color. |
File: DevicesViewModel.cs
Visual display item for a single keyboard key with position data. Used in a Canvas inside a Viewbox for auto-scaling.
| Property | Type | Description |
|---|---|---|
VKeyIndex |
int |
Windows Virtual Key code. |
Label |
string |
Key label text. |
X |
double |
Canvas X position (pixels). |
Y |
double |
Canvas Y position (pixels). |
KeyWidth |
double |
Key width (pixels). |
KeyHeight |
double |
Key height (pixels). |
IsPressed |
bool |
Whether the key is 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 a full ANSI QWERTY keyboard layout with numpad as positioned key items. Each key mapped to its Windows VK code. |
IsVKeyPressed(bool[], int) |
Checks if a VKey is pressed in a button array. |
File: DevicesViewModel.cs
Visual display item for a single POV hat switch.
| Property | Type | Default | Description |
|---|---|---|---|
Index |
int |
- | POV hat index. |
Centidegrees |
int |
-1 |
POV value in centidegrees (0-35900), or -1 for centered. Setting this notifies IsCentered and AngleDegrees. |
IsCentered |
bool |
- | Computed: true if Centidegrees < 0. |
AngleDegrees |
double |
- | Computed: direction in degrees (0-359) for RotateTransform. |
File: DeviceRowViewModel.cs
ViewModel for a single device row in the Devices page list. Displays device 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. Setting this notifies VendorIdHex. |
ProductId |
ushort |
USB Product ID. Setting this notifies ProductIdHex. |
VendorIdHex |
string |
Computed: Vendor ID as hex (e.g., "045E"). |
ProductIdHex |
string |
Computed: Product ID as hex (e.g., "028E"). |
| Property | Type | Default | Description |
|---|---|---|---|
IsOnline |
bool |
false |
Whether the device is connected. Setting this notifies StatusText. |
IsEnabled |
bool |
true |
Whether the device is enabled for mapping. Setting this notifies StatusText. |
IsHidden |
bool |
false |
Whether the device is 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 |
Internal English type key ("Gamepad", "Joystick", "Wheel", "FlightStick", "FirstPerson", "Supplemental", "Mouse", "Keyboard"). Setting this notifies DeviceType. |
DeviceType |
string |
Computed: localized device type description, derived from DeviceTypeKey. |
HasRumble |
bool |
Whether the device supports rumble vibration. |
HasGyro |
bool |
Whether the device has a gyroscope. |
HasAccel |
bool |
Whether the device has an accelerometer. |
CapabilitiesSummary |
string |
Computed: formatted summary (e.g., "6 axes, 11 buttons, 1 POV, Rumble, Gyro"). |
| Property | Type | Description |
|---|---|---|
AssignedSlots |
List<int> |
Pad slot indices this device is assigned to (0-15). Writable via SetAssignedSlots(). |
SlotBadges |
ObservableCollection<SlotBadge> |
Observable slot badges for XAML binding (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 global numbering, and notifies UI. |
| Property | Type | Default | Description |
|---|---|---|---|
HidHideEnabled |
bool |
false |
Whether this device is hidden via HidHide (driver-level). |
ConsumeInputEnabled |
bool |
false |
Whether mapped inputs are consumed via low-level hooks. |
ForceRawJoystickMode |
bool |
false |
Whether to bypass SDL's gamepad remapping and read raw joystick indices. |
IsHidHideAvailable |
bool |
false |
Whether HidHide is installed (controls toggle IsEnabled). |
ShowConsumeToggle |
bool |
- | Computed: true for keyboards and mice only. |
| Property | Type | Description |
|---|---|---|
DevicePath |
string |
File system device path (diagnostics). |
HidHideInstancePath |
string |
Resolved HID instance path for HidHide blacklisting. |
| Property | Type | Description |
|---|---|---|
IsGamepad |
bool |
Computed: true if DeviceTypeKey == "Gamepad". |
ShowSubmitMapping |
bool |
Computed: true for joysticks only (not gamepads/mice/keyboards). |
| Method | Description |
|---|---|
NotifyDisplayChanged() |
Refreshes all computed display properties (StatusText, IsUnassigned, CapabilitiesSummary, hex IDs). |
File: DeviceRowViewModel.cs
Display item for a 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)
ViewModel for a single virtual controller slot (one of 16 pads). The largest ViewModel, handling output type configuration, multi-device selection, mapping grid, dead zone/sensitivity settings, macros, force feedback, and live state display.
| Property | Type | Default | Description |
|---|---|---|---|
PadIndex |
int |
- | Zero-based pad slot index (0-15). Read-only. |
SlotNumber |
int |
PadIndex + 1 |
One-based sequential number among active slots. |
SlotLabel |
string |
- | Display label (e.g., "Virtual Controller 1"). |
OutputType |
VirtualControllerType |
Xbox360 |
Virtual controller output type. Setting this resets dead zones, rebuilds mappings, stick configs, trigger configs, and syncs macro button style. |
TypeInstanceLabel |
string |
"1" |
Per-type instance number label. Set by RefreshNavControllerItems. |
OutputTypeIndex |
int |
- | Int binding for ComboBox SelectedIndex (0=Xbox 360, 1=DS4, etc.). |
ConfigItemDirtyCallback |
Action |
null |
Callback invoked when a config item property changes. Wired by MainWindow to call SettingsService.MarkDirty(). |
| Property | Type | Description |
|---|---|---|
VJoyConfig |
VJoySlotConfig |
Per-slot vJoy configuration (preset, axis/button counts). Always present but only meaningful when OutputType == VJoy. Setting this subscribes to PropertyChanged for dynamic rebuilds. |
| Property | Type | Description |
|---|---|---|
MidiConfig |
MidiSlotConfig |
Per-slot MIDI configuration (port, channel, CC/note mappings). Always present but only meaningful when OutputType == Midi. |
| Property | Type | Description |
|---|---|---|
MappedDevices |
ObservableCollection<MappedDeviceInfo> |
All physical devices currently mapped to this slot. |
SelectedMappedDevice |
MappedDeviceInfo |
Currently selected device for configuration. Setting this raises SelectedDeviceChanged and notifies HasSelectedDevice. |
HasSelectedDevice |
bool |
Computed: SelectedMappedDevice != null. |
MappedDeviceName |
string |
Name of the currently mapped device. Default: "No device mapped". |
MappedDeviceGuid |
Guid |
GUID of the currently mapped device. |
IsDeviceOnline |
bool |
Whether the currently mapped device is online. |
| Event | Args | Description |
|---|---|---|
SelectedDeviceChanged |
MappedDeviceInfo |
User selected a different device within this slot. InputService reloads the PadSetting. |
| Property | Type | Description |
|---|---|---|
Name |
string |
Device display name. |
InstanceGuid |
Guid |
Device instance GUID. |
IsOnline |
bool |
Whether the device is connected. |
Combined slot output values, updated at 30Hz 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 normalized). |
RightTrigger |
double |
Right trigger (0.0-1.0 normalized). |
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 for display). |
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 for display). |
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> |
Mapping 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 the Mappings collection based on OutputType and vJoy config. Dispatches to InitializeGamepadMappings(), InitializeMidiMappings(), InitializeKeyboardMouseMappings(), or InitializeVJoyCustomMappings(). |
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
ForceOverallGain |
int |
100 |
0-100 | Overall FFB gain percentage. |
LeftMotorStrength |
int |
100 |
0-100 | Left motor strength percentage. |
RightMotorStrength |
int |
100 |
0-100 | Right motor strength percentage. |
SwapMotors |
bool |
false |
- | Swap left/right motor assignment. |
LeftMotorDisplay |
double |
0 |
0-1 | Live left motor vibration level (post-scaling). |
RightMotorDisplay |
double |
0 |
0-1 | Live right motor vibration level. |
Audio Bass Rumble (per-device):
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
AudioRumbleEnabled |
bool |
false |
- | Enable audio-driven rumble from system audio bass frequencies. |
AudioRumbleSensitivity |
double |
4.0 |
1-20 | Sensitivity multiplier for audio bass detection. |
AudioRumbleCutoffHz |
double |
80.0 |
20-200 | Low-pass cutoff frequency in 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 for display. |
Reset commands: ResetForceAllCommand, ResetOverallGainCommand, ResetLeftMotorCommand, ResetRightMotorCommand, ResetAudioRumbleAllCommand, ResetAudioSensitivityCommand, ResetAudioCutoffCommand, ResetAudioLeftMotorCommand, ResetAudioRightMotorCommand.
Left Stick:
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
LeftDeadZoneShape |
int |
0 (ScaledRadial) |
0-5 | Dead zone shape enum index. |
LeftDeadZoneX |
double |
0 |
0-100 | Left stick X dead zone %. |
LeftDeadZoneY |
double |
0 |
0-100 | Left stick Y dead zone %. |
LeftAntiDeadZoneX |
double |
0 |
0-100 | Left stick X anti-dead zone %. |
LeftAntiDeadZoneY |
double |
0 |
0-100 | Left stick Y anti-dead zone %. |
LeftLinear |
double |
0 |
0-100 | Left stick linear interpolation factor. |
LeftMaxRangeX |
double |
100 |
1-100 | Left stick X max range (positive direction). |
LeftMaxRangeY |
double |
100 |
1-100 | Left stick Y max range (positive direction). |
LeftMaxRangeXNeg |
double |
100 |
1-100 | Left stick X max range (negative direction). |
LeftMaxRangeYNeg |
double |
100 |
1-100 | Left stick Y max range (negative direction). |
LeftCenterOffsetX |
double |
0 |
-100 to 100 | Left stick X center offset %. |
LeftCenterOffsetY |
double |
0 |
-100 to 100 | Left stick 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 %. |
These collections drive the ItemsControl-based dynamic UI for the Sticks and Triggers tabs. For gamepad presets: 2 sticks, 2 triggers. For custom vJoy: N sticks, M triggers. For KBM: 2 items (Mouse Movement, Scroll Wheel).
| Property | Type | Description |
|---|---|---|
StickConfigs |
ObservableCollection<StickConfigItem> |
Dynamic stick configuration items. Rebuilt by RebuildStickConfigs(). |
TriggerConfigs |
ObservableCollection<TriggerConfigItem> |
Dynamic trigger configuration items. Rebuilt by RebuildTriggerConfigs(). |
| Method | Description |
|---|---|
RebuildStickConfigs() |
Rebuilds stick configs for current output type. |
RebuildTriggerConfigs() |
Rebuilds trigger configs for current output type. KBM has no triggers. |
SyncStickItemFromVm(StickConfigItem) |
Pushes VM dead zone properties into a stick config item. |
SyncTriggerItemFromVm(TriggerConfigItem) |
Pushes VM trigger properties into a trigger config item. |
SyncAllConfigItemsFromVm() |
Syncs all config items from current VM properties. Called after settings load/paste. |
ResetAllSettings() |
Resets all per-slot settings to defaults. Called when a slot is deleted. |
| Property | Type | Description |
|---|---|---|
Macros |
ObservableCollection<MacroItem> |
Macros configured for this pad slot. |
SelectedMacro |
MacroItem |
Currently selected macro. Setting this notifies HasSelectedMacro and refreshes remove command. |
HasSelectedMacro |
bool |
Computed: SelectedMacro != null. |
| Command | CanExecute | Description |
|---|---|---|
AddMacroCommand |
always | Creates and adds a new macro with auto-numbered name. |
RemoveMacroCommand |
HasSelectedMacro |
Removes the selected macro. |
| Property | Type | Default | Description |
|---|---|---|---|
SelectedConfigTab |
int |
0 |
0=Mappings, 1=Left Stick, 2=Right Stick, 3=Triggers, 4=Force Feedback, 5=Macros. |
| 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 |
Whether Map All sequential recording is 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 |
The TargetSettingName of the mapping currently being recorded. Drives controller-tab element flashing. |
MapAllRecordingNeg |
bool |
Internal. When true, currently recording the 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 (buttons, axes, triggers, motor display) at 30Hz from InputService. |
UpdateDeviceState(Gamepad) |
Updates per-device stick/trigger values for tab previews. Syncs live values to StickConfigs/TriggerConfigs. |
UpdateFromVJoyRawState(VJoyRawState) |
Updates combined output from vJoy raw state (custom vJoy slots). Syncs live values to config items. |
UpdateFromMidiRawState(MidiRawState) |
Updates MIDI preview snapshot. |
OnMapAllItemCompleted() |
Called when a Map All recording completes. Advances to next after 500ms delay. |
StopMapAll() |
Stops Map All, clears state, and raises MapAllCancelRequested. |
RefreshCommands() |
Refreshes CanExecute state of all commands. |
| Property | Type | Description |
|---|---|---|
VJoyOutputSnapshot |
VJoyRawState |
Latest vJoy raw state snapshot for custom vJoy display. Updated at 30Hz. |
KbmOutputSnapshot |
KbmRawState |
Latest KBM raw state snapshot. Updated at 30Hz. |
MidiOutputSnapshot |
MidiRawState |
Latest MIDI raw state snapshot. |
File: MappingItem.cs
Represents a single mapping row linking a physical input source to an output target. Displayed in the mapping grid on the Pad page.
| Property | Type | Description |
|---|---|---|
TargetLabel |
string |
Human-readable label (e.g., "A", "Left Stick X", "CC 1"). Read-only. |
TargetSettingName |
string |
PadSetting property name (e.g., "ButtonA", "LeftThumbAxisX", "KbmKey41"). Read-only. |
Category |
MappingCategory |
Category for grouping in tabs: Buttons, DPad, Triggers, LeftStick, RightStick. |
NegSettingName |
string |
PadSetting property for negative direction (e.g., "LeftThumbAxisXNeg"). Null for non-axis targets. |
HasNegDirection |
bool |
Computed: NegSettingName != null. |
| Property | Type | Default | Description |
|---|---|---|---|
SourceDescriptor |
string |
"" |
Mapping descriptor identifying the physical input. Format: "{MapType} {Index}" or "IH{MapType} {Index}" or "POV {Index} {Direction}". Empty = unmapped. Setting this clears resolved text and notifies SourceDisplayText and IsMapped. |
NegSourceDescriptor |
string |
"" |
Negative-direction descriptor for stick axes. |
SourceDisplayText |
string |
- | Computed: human-readable display text. For bidirectional axes with both pos and neg set, shows "neg / pos" format. Falls back to "Not mapped" when empty. |
IsMapped |
bool |
- | Computed: true if either SourceDescriptor or NegSourceDescriptor is non-empty. |
| Method | Description |
|---|---|
SetResolvedSourceText(string) |
Sets human-readable display text (e.g., "A" instead of "Button 65"). Called by InputService. Also caches the base name for RebuildDescriptor. |
SetResolvedNegText(string) |
Sets resolved text for the negative direction. |
LoadDescriptor(string) |
Sets source descriptor and syncs IsInverted/IsHalfAxis from "I"/"H" prefixes. |
LoadNegDescriptor(string) |
Loads a negative-direction descriptor. |
SyncSelectedInputFromDescriptor() |
Synchronizes SelectedInput to match current SourceDescriptor without triggering a descriptor update. |
| Property | Type | Description |
|---|---|---|
AvailableInputs |
ObservableCollection<InputChoice> |
Available input choices for the source dropdown. Populated by InputService when the selected device changes. |
SelectedInput |
InputChoice |
Currently selected input from the dropdown. Setting this updates SourceDescriptor accordingly. Selecting the empty-descriptor sentinel triggers ClearCommand. Suppression flag prevents re-entrant sync loops. |
| Event | Description |
|---|---|
InputSelectedFromDropdown |
Raised when the user selects an input from the dropdown (for display text resolution). |
| Property | Type | Default | Description |
|---|---|---|---|
IsRecording |
bool |
false |
Whether this row is in recording mode. Setting this notifies RecordButtonText. |
RecordButtonText |
string |
- | Computed: "Record" or "Recording...". |
| Property | Type | Description |
|---|---|---|
CurrentValueText |
string |
Current raw value of the source input. Updated at 30Hz when the Pad page is visible. |
| Property | Type | Default | Description |
|---|---|---|---|
IsInverted |
bool |
false |
Whether the axis value is inverted. Setting this calls RebuildDescriptor() to add/remove "I" prefix. |
IsHalfAxis |
bool |
false |
Whether to use only the upper half of the axis range. Setting this calls RebuildDescriptor() to add/remove "H" prefix. |
| Command | Description |
|---|---|
ToggleRecordCommand |
Toggles recording mode. Raises StartRecordingRequested or StopRecordingRequested. |
ClearCommand |
Clears source assignment, neg descriptor, and resets IsInverted/IsHalfAxis. |
| Event | Description |
|---|---|
StartRecordingRequested |
User clicked Record. |
StopRecordingRequested |
Recording should stop. |
File: MappingItem.cs
Available 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
Represents a single macro: a trigger combination of controller inputs that produces a sequence of output actions. Macros are evaluated between Step 3 (mapping) and Step 4 (combining) in the input pipeline.
| Property | Type | Default | Description |
|---|---|---|---|
Name |
string |
"New Macro" |
User-facing name. |
IsEnabled |
bool |
true |
Whether this macro is active. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerButtons |
ushort |
0 |
Gamepad button flag bitmask (e.g., Gamepad.A | Gamepad.B). All must be pressed simultaneously. |
TriggerCustomButtonWords |
uint[] |
new uint[4] |
Wide button bitmask for custom vJoy (128 buttons, 4x32-bit). Not serialized directly. |
TriggerCustomButtons |
string |
null |
Serializable hex form (e.g., "00000003,00000000,00000000,00000000"). |
UsesCustomTrigger |
bool |
- | Computed: true if any custom trigger button is set. |
TriggerSource |
MacroTriggerSource |
InputDevice |
Whether to record from physical device or virtual controller output. |
TriggerDisplayText |
string |
- | Computed: human-readable display of the trigger combo including device name. |
ButtonStyle |
MacroButtonStyle |
Xbox360 |
Button display names style. Not serialized. Set by PadViewModel on type changes. |
CustomButtonCount |
int |
11 |
Number of custom vJoy buttons. Not serialized. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerDeviceGuid |
Guid |
Guid.Empty |
Device whose raw buttons are the trigger. Empty = use legacy Xbox bitmask. |
TriggerRawButtons |
int[] |
[] |
Raw button indices that must all be pressed simultaneously. |
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 the threshold. Not serialized directly. |
TriggerAxisTargetList |
string |
null |
Serializable comma-separated form. |
TriggerAxisThreshold |
int |
50 |
Threshold percentage (1-100). |
UsesAxisTrigger |
bool |
- | Computed: TriggerAxisTargets.Length > 0. |
TriggerAxisDirections |
MacroAxisDirection[] |
[] |
Direction filter per trigger axis. Parallel array. Not serialized directly. |
TriggerAxisDirectionList |
string |
null |
Serializable comma-separated form. |
TriggerAxisDirectionIndex |
int |
- | UI-facing index for first direction (0=Any, 1=Positive, 2=Negative). Sets all uniformly. |
| Property | Type | Default | Description |
|---|---|---|---|
TriggerMode |
MacroTriggerMode |
OnPress |
When to fire: OnPress, OnRelease, WhileHeld, Always. |
IsNotAlwaysMode |
bool |
- | Computed: TriggerMode != Always. Controls trigger recording UI visibility. |
ConsumeTriggerButtons |
bool |
true |
Remove trigger buttons from Gamepad state when macro fires. |
| Property | Type | Default | Description |
|---|---|---|---|
IsRecordingTrigger |
bool |
false |
Whether recording trigger combo. Setting this notifies RecordTriggerButtonText. |
RecordTriggerButtonText |
string |
- | Computed: "Stop" or "Record Trigger". |
RecordingLiveText |
string |
"" |
Live display of buttons being pressed during recording. Not serialized. |
| Property | Type | Description |
|---|---|---|
Actions |
ObservableCollection<MacroAction> |
Ordered sequence of actions to execute. |
SelectedAction |
MacroAction |
Currently selected action. Setting this 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 in ms. Min 0. |
| Property | Type | Description |
|---|---|---|
IsExecuting |
bool |
Whether currently executing action sequence. |
CurrentActionIndex |
int |
Current position in action sequence. |
RemainingRepeats |
int |
Remaining repeat count. |
ActionStartTime |
DateTime |
When the current action/delay started. |
WasTriggerActive |
bool |
Whether trigger was 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)
A single action within a macro's action sequence.
| Property | Type | Default | Description |
|---|---|---|---|
Type |
MacroActionType |
ButtonPress |
Action type. Setting this notifies all Is*Type computed properties. |
DurationMs |
int |
50 |
Hold/delay duration in ms (for ButtonPress, KeyPress, Delay, MouseButtonPress). Min 0. |
DisplayText |
string |
- | Computed: human-readable action summary for the list. |
IsButtonType, IsKeyType, IsDurationType, IsAxisType, IsSystemVolumeType, IsAppVolumeType, IsMouseMoveType, IsMouseButtonType, IsContinuousAxisType, IsDeviceAxisSource, IsOutputAxisSource
| Property | Type | Default | Description |
|---|---|---|---|
ButtonFlags |
ushort |
0 |
Xbox bitmask flags for gamepad presets. |
ButtonStyle |
MacroButtonStyle |
Xbox360 |
Button display name style. Not serialized. |
CustomButtonCount |
int |
11 |
Button count for Numbered style. Not serialized. |
CustomButtonWords |
uint[] |
new uint[4] |
Wide bitmask for custom vJoy (128 buttons). Not serialized directly. |
CustomButtons |
string |
null |
Serializable hex form. |
ButtonOptions |
IReadOnlyList<GamepadButtonOption> |
- | Computed: checkbox-bindable options. 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 |
Virtual key code (Win32 VK_ constant). Setting this notifies SelectedVirtualKey. |
SelectedVirtualKey |
VirtualKey |
None |
Typed enum wrapper for ComboBox binding. Not serialized. |
KeyString |
string |
"" |
Multi-key combo in x360ce format ("{Control}{Alt}{Delete}"). |
ParsedKeyCodes |
int[] |
- | Computed: parsed VK codes from KeyString, falls back to KeyCode. |
SelectedKeyToAdd |
VirtualKey |
None |
Key picker ComboBox binding. Auto-appends to KeyString and resets. |
| Command | Description |
|---|---|
ClearKeyStringCommand |
Clears the KeyString. |
| Static | Description |
|---|---|
VirtualKeyValues |
List<KeyDisplayItem> of all VK values 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 |
For AxisSet: signed axis 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 flyout OSD. |
ProcessName |
string |
"" |
For AppVolume: target process name. |
AudioProcessNames |
ObservableCollection<string> |
empty | Process names with active audio sessions (suggestion items). |
VolumeLimit |
int |
100 |
Maximum volume percentage (1-100). |
| Command | Description |
|---|---|
RefreshAudioProcessesCommand |
Refreshes list of processes with active audio sessions. |
| Property | Type | Default | Description |
|---|---|---|---|
MouseSensitivity |
float |
10f |
Pixels/scroll units per frame at full deflection (1-100). |
MouseButton |
MacroMouseButton |
Left |
Which mouse button for press/release. |
MouseAccumulator |
float |
0 |
Internal. Fractional pixel accumulator for sub-pixel precision. |
| Property | Type | Default | Description |
|---|---|---|---|
AxisSource |
MacroAxisSource |
OutputController |
Where to read axis values from. |
SourceDeviceGuid |
Guid |
Guid.Empty |
For InputDevice source: physical device GUID. |
SourceDeviceAxisIndex |
int |
-1 |
For 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
Toggleable checkbox option for a single gamepad button. Reads/writes individual bits from the parent MacroAction's ButtonFlags (or CustomButtonWords for vJoy custom).
| Property | Type | Description |
|---|---|---|
Label |
string |
Button display name. |
Flag |
ushort |
Xbox/DS4 bitmask flag (0 for custom mode). |
CustomIndex |
int |
Custom vJoy button index (0-based). -1 = use Flag. |
IsChecked |
bool |
Whether this button is selected. Reads/writes parent's button flags. |
| Method | Description |
|---|---|
Refresh() |
Re-evaluates IsChecked when button state is changed externally. |
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
Represents one thumbstick section in the dynamic Sticks tab. For gamepad presets: index 0 = Left, index 1 = Right. For custom vJoy: index 0..N based on 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 are clamped to 0-100. Each has a *Digit companion for direct 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), clamped 1-100. |
MaxRangeY |
MaxRangeYDigit |
100 |
Y max range (positive), clamped 1-100. |
MaxRangeXNeg |
MaxRangeXNegDigit |
100 |
X max range (negative), clamped 1-100. |
MaxRangeYNeg |
MaxRangeYNegDigit |
100 |
Y max range (negative), clamped 1-100. |
CenterOffsetX |
CenterOffsetXDigit |
0 |
X center offset, clamped -100 to 100. |
CenterOffsetY |
CenterOffsetYDigit |
0 |
Y center offset, clamped -100 to 100. |
Linear |
- | 0 |
Linear interpolation factor (0-100). |
| Property | Type | Default | Description |
|---|---|---|---|
DeadZoneShape |
DeadZoneShape |
ScaledRadial |
Dead zone shape enum. Setting this notifies DeadZoneShapeIndex and all Is*Shape properties. |
DeadZoneShapeIndex |
int |
0 |
ComboBox SelectedIndex binding. 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 |
Whether center calibration is in progress. |
HardwareRawX |
short |
- | Unprocessed hardware X value (not affected by offset/dead zone). |
HardwareRawY |
short |
- | Unprocessed hardware Y value. |
| Method | Description |
|---|---|
StartCalibration() |
Starts center calibration by sampling RawX/RawY over ~0.5s (15 frames at 33ms). Sets CenterOffsetX/Y to negate average drift. |
| Property | Type | Default | Description |
|---|---|---|---|
LiveX |
double |
0.5 |
Live X position (0.0-1.0 normalized for Canvas). |
LiveY |
double |
0.5 |
Live Y position. |
RawX |
short |
0 |
Processed raw X value. Setting this notifies RawDisplay. |
RawY |
short |
0 |
Processed raw Y value. |
RawDisplay |
string |
- | Computed: formatted display "X: -1234 (50.0%) Y: 5678 (58.7%)". |
LiveInputX |
double |
0 |
Live input for CurveEditor X binding (normalized 0-1 unsigned). |
LiveInputY |
double |
0 |
Live input for CurveEditor Y binding. |
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 processing. |
BuildTriggerCurvePoints(string, double, double, int, int) |
Builds 0-1 curve points for trigger charts with dead zone flattened. Returns PointCollection. |
File: TriggerConfigItem.cs
Represents one trigger section in the dynamic Triggers tab. For gamepad presets: index 0 = Left, index 1 = Right. For custom vJoy: index 0..N based on 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 clamped 1-100). Each has a *Digit companion for direct digit-based binding (unsigned 16-bit: 0-65535).
| Property (%) | Digit Property | Default | Description |
|---|---|---|---|
DeadZone |
DeadZoneDigit |
0 |
Dead zone percentage. |
MaxRange |
MaxRangeDigit |
100 |
Max range percentage (1-100). |
AntiDeadZone |
AntiDeadZoneDigit |
0 |
Anti-dead zone percentage. |
| 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. Setting this 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 item generation.
| Constant | Value | Description |
|---|---|---|
MaxAxes |
8 |
DirectInput maximum axis count (shared between sticks and triggers). |
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
Preset |
VJoyPreset |
Xbox360 |
- | vJoy preset. Setting this calls ApplyPresetDefaults(). |
ThumbstickCount |
int |
2 |
0 to (MaxAxes - TriggerCount) / 2
|
Number of thumbsticks. Each uses 2 axes. |
TriggerCount |
int |
2 |
0 to MaxAxes - ThumbstickCount * 2
|
Number of triggers. Each uses 1 axis. |
PovCount |
int |
1 |
0-4 | Number of POV hat switches. |
ButtonCount |
int |
11 |
0-128 | Number of 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: [StickX, StickY, Trigger] per group. |
ApplyPresetDefaults() |
Sets counts for Xbox360 (2/2/1/11) or DS4 (2/2/1/14). Custom keeps current values. |
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 with dynamic CC and note counts, configurable starting numbers, channel, and velocity.
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
Channel |
int |
1 |
1-16 | MIDI channel (1-based). |
CcCount |
int |
6 |
0 to 128 - StartCc
|
Number of CC outputs. |
StartCc |
int |
1 |
0-127 | Starting CC number. Changing this re-clamps CcCount. |
NoteCount |
int |
11 |
0 to 128 - StartNote
|
Number of note outputs. |
StartNote |
int |
60 |
0-127 | Starting note number. Changing this 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 |