From 3f4cc63ee629d74cf8369100e0c86ee0c8bf429f Mon Sep 17 00:00:00 2001 From: bjoluc Date: Tue, 23 Apr 2024 21:53:27 +0200 Subject: [PATCH] feat: Allow switching encoder assignment pages via Shift + Channel Left/Right --- readme.md | 2 +- src/index.ts | 1 + src/mapping/encoders/EncoderPageGroup.ts | 51 +++++++++++++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index c082dba..3fdd71d 100644 --- a/readme.md +++ b/readme.md @@ -140,7 +140,7 @@ The table below summarizes all available encoder assignments: **Buttons** - Like in the MCU default mapping, the 8 channel type buttons apply MixConsole channel visibility presets 1-8. In the likely case that you don't want to waste 8 prominent buttons for loading visibility presets, feel free to re-assign some buttons in the MIDI Remote Mapping Assistant. -- The Channel Left/Right buttons below the Fader Bank buttons do not navigate between encoder parameter pages, but move the fader bank left/right by one channel. Navigating parameter banks can be achieved by pressing the respective Encoder Assign button multiple times to cycle through the available parameter pages in a round-robin fashion. +- The Channel Left/Right buttons move the fader bank left/right by one channel instead of navigating between encoder assignment pages. The latter can be achieved by pressing the respective Encoder Assign button multiple times to cycle through the available assignment pages in a round-robin fashion, or by using the Channel Left/Right buttons while holding the Shift button. - Pressing "Shift + Bank Left" navigates to the first (=leftmost) mixer bank. - Pressing "Shift + Edit" closes all **plugin** windows instead of only the currently active window (I couldn't find a command to "close the currently active window"). - The "Instrument" and "Master" buttons are assigned to the handy MixConsole History Undo and Redo commands, respectively. In the default MCU mapping, they would activate instrument and main insert effects encoder assignments. However, these can already be reached via the "Inst" and "Plug-In" encoder assign buttons, so I decided to use the buttons differently. diff --git a/src/index.ts b/src/index.ts index 0734119..5b6f486 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ // Polyfills // organize-imports-ignore import "core-js/actual/array/iterator"; +import "core-js/actual/array/at"; import "core-js/actual/array/from"; import "core-js/actual/array/includes"; import "core-js/actual/array/reverse"; diff --git a/src/mapping/encoders/EncoderPageGroup.ts b/src/mapping/encoders/EncoderPageGroup.ts index f96a9d2..306cbc9 100644 --- a/src/mapping/encoders/EncoderPageGroup.ts +++ b/src/mapping/encoders/EncoderPageGroup.ts @@ -19,6 +19,7 @@ export class EncoderPageGroup { this.activatorButtons, ); this.bindEncoderPagesToActivatorButtons(encoderPages); + this.bindEncoderPagesToChannelButtons(encoderPages); if (config.enhanceMapping) { config.enhanceMapping(encoderPages, this.activatorButtons); @@ -66,8 +67,10 @@ export class EncoderPageGroup { }); } + /** + * Maps the activator buttons to cycle through encoder pages in a round-robin fashion + */ private bindEncoderPagesToActivatorButtons(encoderPages: EncoderPage[]) { - // Bind encoder assign buttons to cycle through sub pages in a round-robin fashion for (const activatorButton of this.activatorButtons) { const activatorButtonValue = activatorButton.mSurfaceValue; this.dependencies.page.makeActionBinding( @@ -89,6 +92,52 @@ export class EncoderPageGroup { } } + /** + * Maps the main devices' channel navigation buttons to navigate through encoder pages (if the + * group has multiple pages) when Shift is held. + */ + private bindEncoderPagesToChannelButtons(encoderPages: EncoderPage[]) { + if (encoderPages.length > 1) { + for (const [index, encoderPage] of encoderPages.entries()) { + const nextEncoderPage = encoderPages.at(index + 1) ?? encoderPages[0]; + const previousEncoderPage = encoderPages.at(index - 1)!; + + for (const device of this.dependencies.mainDevices) { + const buttons = device.controlSectionElements.buttons.navigation.channel; + + for (const subpage of [ + encoderPage.subPages.defaultShift, + encoderPage.subPages.flipShift, + ]) { + this.dependencies.page + .makeActionBinding( + buttons.left.mSurfaceValue, + previousEncoderPage.subPages.defaultShift.mAction.mActivate, + ) + .setSubPage(subpage); + + this.dependencies.page + .makeActionBinding( + buttons.right.mSurfaceValue, + nextEncoderPage.subPages.defaultShift.mAction.mActivate, + ) + .setSubPage(subpage); + } + + // Light up channel navigation buttons in shift mode + this.dependencies.globalState.isShiftModeActive.addOnChangeCallback( + (context, isShiftModeActive) => { + if (EncoderPageGroup.activeInstance.get(context) === this) { + buttons.left.setLedValue(context, +isShiftModeActive); + buttons.right.setLedValue(context, +isShiftModeActive); + } + }, + ); + } + } + } + } + private setActivatorButtonLeds(context: MR_ActiveDevice, value: number) { for (const button of this.activatorButtons) { button.setLedValue(context, value);