Skip to content

Fixed with assistance Claude and tested on x64 : modifiers were not being discriminated in the FX mapping process. Enhancement: added Paged vs Standard output. #56

Open
greg15apr-alt wants to merge 5 commits into
FunkybotsEvilTwin:mainfrom
greg15apr-alt:fix/fx-automapping-modifier-discrimination-add-paging
Open

Fixed with assistance Claude and tested on x64 : modifiers were not being discriminated in the FX mapping process. Enhancement: added Paged vs Standard output. #56
greg15apr-alt wants to merge 5 commits into
FunkybotsEvilTwin:mainfrom
greg15apr-alt:fix/fx-automapping-modifier-discrimination-add-paging

Conversation

@greg15apr-alt
Copy link
Copy Markdown

@greg15apr-alt greg15apr-alt commented May 10, 2026

Fix modifier-combo mapping and add Paged output mode in FX AutoMap
Background
The LearnFX dialog lets users map VST/AU plugin parameters to control surface widgets. This PR fixes a bug that prevented modifier combinations (e.g. Shift+Fader) from being mapped after Fader has been mapped already, and adds a new Paged output format that makes modifier groups navigable as separate zone pages rather than stacked in a single file.

Bug fix: modifier combination widgets could not be mapped
Problem

When a zone file already existed for an FX plugin, reopening it in the Learn dialog would leave all modifier-variant widgets (e.g. Shift+Fader1, Option+Fader1) without any ActionContext in memory. Because the dialog only creates contexts when a widget is first encountered, attempting to assign a modifier combo would silently fail — the Assign/Link button would not appear, and the mapping would be lost on save.

Root cause

Zone loading only populated contexts for modifier rows that were explicitly present in the .zon file. Missing modifier rows meant GetLearnFocusedFXActionContexts() returned empty, which the dialog interpreted as "widget not in this zone" rather than "widget has no assignment yet."

Fix

Added FillMissingFXZoneContexts() in control_surface_integrator_ui.cpp, called immediately after LoadZoneFile() in control_surface_integrator.h. It walks all modifier rows defined in the surface template and inserts NoAction contexts for any widget/modifier pair that the zone file didn't cover.
Fixed WidgetMoved's else branch to correctly show/hide the Assign and Link buttons based on whether a cell exists for the current modifier, rather than always clearing the UI.
Fixed WM_COMMAND handler (in both dlgProcLearnFX and dlgProcLearnFXDeepEdit) to use the captured s_currentModifier (set at widget-move time) instead of re-reading the live surface modifier state at button-click time — these can differ when the user releases the modifier key before clicking.
Enhancement: Paged output mode
Overview

The Save dialog now has a Save as: Standard / Paged radio button pair. Standard output is unchanged. Paged output splits the mapping into one .zon file per modifier group, making each set of assignments a navigable page on the control surface.

Paged file format

Page 1 writes to PluginName.zon (the existing filename, loaded by default).
Additional pages write to PluginName-1.zon, PluginName-2.zon, etc.
Each page file is stamped with // CSI:paged-modifier=N so the format can be identified and round-tripped.
The last page has BankRight/Right mapped to NoAction to prevent wraparound past the end.
Each page includes Cancel GoZone SelectedTrackFXMenu for consistent navigation.
Standard ↔ Paged round-trip

If a plugin was previously saved in Paged format and the user switches back to Standard, SaveZone() reads the paged page files (-1.zon, -2.zon, …), extracts the modifier stamp and widget lines from each, and reconstructs the full modifier-row content in the standard single-file output. This prevents modifier mappings from being lost during format conversion — only page 1 is loaded into the dialog's in-memory zone, but all pages are preserved through the round-trip.

Stale page files from a prior save with more pages are removed automatically. When switching back to Standard, the old paged files are renamed to .zon_inact and the standard backup (.zon_inact) is removed.

UI changes

Added IDC_OutputStandard (1310) and IDC_OutputPaged (1311) radio buttons to IDD_DIALOG_LearnFX in res.rc and resource.h.
The s_outputPaged flag persists within the session so the choice is remembered between successive saves.
Files changed
File Change
control_surface_integrator_ui.cpp Bug fix + SaveZonePaged, CleanupPagedFiles, FillMissingFXZoneContexts, UI wiring
control_surface_integrator.h Declare FillMissingFXZoneContexts; call it after LoadZoneFile
res.rc Add Standard/Paged radio buttons to LearnFX dialog
resource.h Add IDC_OutputStandard and IDC_OutputPaged IDs

…eing discriminated in the FX mapping process. For instance, Shift+Fader1 could not be mapped after Fader1 had been already mapped. Enhancement: added Paged vs Standard output. In Paged output, navigation between FX paged can be made using Left/Right or BankLeft/BankRight. One can switch Standard -> Paged or vice versa using the dialog new radio buttons.
@greg15apr-alt greg15apr-alt changed the title Fixed with assistance Claude and tested on x64 : modifiers were not being discriminated in the FX mapping process. For instance, Shift+Fader1 could not be mapped after Fader1 had been already mapped. Enhancement: added Paged vs Standard output. In Paged output, navigation between FX paged can be made using Left/Right or BankLeft/BankRight. One can switch Standard -> Paged or vice versa using the dialog new radio buttons. Fixed with assistance Claude and tested on x64 : modifiers were not being discriminated in the FX mapping process. Enhancement: added Paged vs Standard output. May 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant