From 3b49a83821d72432e07d89a703a1cd595cd341d9 Mon Sep 17 00:00:00 2001 From: henrikvilhelmberglund Date: Sun, 12 Jul 2026 15:11:39 +0200 Subject: [PATCH] Add , and . keyboard shortcuts to switch models Exposes prev/next file navigation on NAMFileBrowserControl as public methods and installs a plugin-level key handler that maps , and . to the model browser's prev/next actions. Detection is done via the utf8 field of IKeyPress so the mapping works with any keyboard layout that produces those characters unshifted. Requires the plugin window to have keyboard focus. Text entries and other controls that consume the key still take precedence. Arrow keys were considered but on Windows they are intercepted by the dialog manager (WM_KEYDOWN gets translated to WM_NEXTDLGCTL) in some hosts, making the shortcut unreliable. Co-Authored-By: Claude Opus 4.7 (1M context) --- NeuralAmpModeler/NeuralAmpModeler.cpp | 20 ++++++++++ NeuralAmpModeler/NeuralAmpModelerControls.h | 43 ++++++++++++--------- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/NeuralAmpModeler/NeuralAmpModeler.cpp b/NeuralAmpModeler/NeuralAmpModeler.cpp index 4a08266ac..a3cae33af 100644 --- a/NeuralAmpModeler/NeuralAmpModeler.cpp +++ b/NeuralAmpModeler/NeuralAmpModeler.cpp @@ -309,6 +309,26 @@ NeuralAmpModeler::NeuralAmpModeler(const InstanceInfo& info) pControl->SetMouseOverWhenDisabled(true); }); + pGraphics->SetKeyHandlerFunc([pGraphics](const IKeyPress& key, bool isUp) { + if (isUp) + return false; + auto* pBrowser = pGraphics->GetControlWithTag(kCtrlTagModelFileBrowser); + if (pBrowser == nullptr) + return false; + auto* pModelBrowser = static_cast(pBrowser); + if (key.utf8[0] == ',') + { + pModelBrowser->SelectPreviousFile(); + return true; + } + if (key.utf8[0] == '.') + { + pModelBrowser->SelectNextFile(); + return true; + } + return false; + }); + // pGraphics->GetControlWithTag(kCtrlTagOutNorm)->SetMouseEventsWhenDisabled(false); // pGraphics->GetControlWithTag(kCtrlTagCalibrateInput)->SetMouseEventsWhenDisabled(false); }; diff --git a/NeuralAmpModeler/NeuralAmpModelerControls.h b/NeuralAmpModeler/NeuralAmpModelerControls.h index cd6e5b07b..99e0c9db9 100644 --- a/NeuralAmpModeler/NeuralAmpModelerControls.h +++ b/NeuralAmpModeler/NeuralAmpModelerControls.h @@ -302,31 +302,36 @@ class NAMFileBrowserControl : public IDirBrowseControlBase } } - void OnAttached() override + void SelectPreviousFile() { - auto prevFileFunc = [&](IControl* pCaller) { - const auto nItems = NItems(); - if (nItems == 0) - return; - mSelectedItemIndex--; + const auto nItems = NItems(); + if (nItems == 0) + return; + mSelectedItemIndex--; - if (mSelectedItemIndex < 0) - mSelectedItemIndex = nItems - 1; + if (mSelectedItemIndex < 0) + mSelectedItemIndex = nItems - 1; - LoadFileAtCurrentIndex(); - }; + LoadFileAtCurrentIndex(); + } - auto nextFileFunc = [&](IControl* pCaller) { - const auto nItems = NItems(); - if (nItems == 0) - return; - mSelectedItemIndex++; + void SelectNextFile() + { + const auto nItems = NItems(); + if (nItems == 0) + return; + mSelectedItemIndex++; - if (mSelectedItemIndex >= nItems) - mSelectedItemIndex = 0; + if (mSelectedItemIndex >= nItems) + mSelectedItemIndex = 0; - LoadFileAtCurrentIndex(); - }; + LoadFileAtCurrentIndex(); + } + + void OnAttached() override + { + auto prevFileFunc = [&](IControl* pCaller) { SelectPreviousFile(); }; + auto nextFileFunc = [&](IControl* pCaller) { SelectNextFile(); }; auto loadFileFunc = [&](IControl* pCaller) { WDL_String fileName;