Skip to content

Commit 4b09ca3

Browse files
authored
Merge pull request #9 from brummbrum/TrackListChange
Changes to tracklist update the Mixer View
2 parents e814a3c + d232fa7 commit 4b09ca3

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

src/niMidi.cpp

+31-13
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,31 @@ class NiMidiSurface: public BaseSurface {
220220
return "Komplete Kontrol S-series Mk2/A-series/M-series";
221221
}
222222

223-
// ToDo: If the tracklist changes, we always need to call _allMixerUpdate because the change may (or may not) affect the currently visible bank
224-
225-
// ToDo: Consider using OnTrackSelection() rather than SetSurfaceSelected.
226-
// Reason: SetSurfaceSelected() is less economical because it will be called multiple times (also for unselecting tracks)
227-
// It seems, however, that SetSurfaceSelected() may be the more robust choice because according to other people's
228-
// findings OnTrackSelection() does not work in many situations, e.g. when track is selected via an action! The latter
229-
// is quite common, however, and thus we may have to stick to SetSurfaceSelected().
230-
// See: https://github.com/reaper-oss/sws/blob/6963f7563851c8dd919db426bae825843939077f/sws_extension.cpp#L528
231-
// Remark: The naming of OnTrackSelection() is confusing because typically this would indicate a call from the plugin to
232-
// Reaper to update the project (just like other calls like OnVolumeChange(), OnPlay(), .. etc) .
233-
// When something changes in the project Reaper typically calls functions starting with Set, hence SetTrackSelected()
234-
// seems more logical.
223+
// If tracklist changes update Mixer View and ensure sanity of track and bank focus
224+
virtual void SetTrackListChange() override {
225+
int numTracks = CSurf_NumTracks(false);
226+
// Protect against loosing track focus that could impede track navigation. Set focus on last track in this case.
227+
if (g_trackInFocus > numTracks) {
228+
g_trackInFocus = numTracks;
229+
// Unfortunately we cannot afford to explicitly select the last track automatically because this could screw up
230+
// running actions or macros. The plugin may not manipulate track selection without the user deliberately triggering
231+
// track selection/navigation on the keyboard (or from within Reaper).
232+
}
233+
// Protect against loosing bank focus. Set focus on last bank in this case.
234+
if (this->_bankStart > numTracks) {
235+
int lastInBank = numTracks % BANK_NUM_TRACKS;
236+
this->_bankStart = numTracks - lastInBank;
237+
}
238+
// If no track is selected at all (e.g. if previously selected track got removed), then this will now also show up in the
239+
// Mixer View. However, KK instance focus may still be present! This can be a little bit confusing for the user as typically
240+
// the track holding the focused KK instance will also be selected. This situation gets resolved as soon as any form of
241+
// track navigation/selection happens (from keyboard or from within Reaper).
242+
this->_allMixerUpdate();
243+
}
244+
245+
// Using SetSurfaceSelected() rather than OnTrackSelection():
246+
// SetSurfaceSelected() is less economical because it will be called multiple times (also for unselecting tracks).
247+
// However, SetSurfaceSelected() is the more robust choice because of: https://forum.cockos.com/showpost.php?p=2138446&postcount=15
235248
virtual void SetSurfaceSelected(MediaTrack* track, bool selected) override {
236249
if (selected) {
237250
int id = CSurf_TrackToID(track, false);
@@ -496,8 +509,13 @@ class NiMidiSurface: public BaseSurface {
496509

497510
void _onTrackNav(signed char value) {
498511
// Move to next/previous track relative to currently focused track = last selected track
512+
int numTracks = CSurf_NumTracks(false);
513+
// Backstop measure to protect against unreported track removal that was not captured in SetTrackListChange callback due to race condition
514+
if (g_trackInFocus > numTracks) {
515+
g_trackInFocus = numTracks;
516+
}
499517
if (((g_trackInFocus <= 1) && (value < 0)) ||
500-
((g_trackInFocus >= CSurf_NumTracks(false))) && (value >0 )) {
518+
((g_trackInFocus >= numTracks) && (value >0 ))) {
501519
return;
502520
}
503521
int id = g_trackInFocus + value;

src/reaKontrol.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define REAPERAPI_WANT_Main_OnCommand
3636
#define REAPERAPI_WANT_CSurf_ScrubAmt
3737
#define REAPERAPI_WANT_GetSetMediaTrackInfo
38+
#define REAPERAPI_WANT_CSurf_SetTrackListChange
3839
#define REAPERAPI_WANT_CSurf_SetSurfaceVolume
3940
#define REAPERAPI_WANT_CSurf_SetSurfacePan
4041
#define REAPERAPI_WANT_CSurf_OnVolumeChange

0 commit comments

Comments
 (0)