Investigate "SelectProjectInstance()" for TODO's missing ability to specify ReaProject
Uncertain what this does (never seen it used in code), but if it switches the internal pointer to the current ReaProject for functions that don't take a ReaProject as a param, maybe it could work to quickly swap to another project + back to the original hackily?
https://www.reaper.fm/sdk/reascript/reascripthelp.html#SelectProjectInstance
So maybe we can fix this -> :(
// TODO-low reaper::InsertTrackAtIndex unfortunately doesn't allow to specify ReaProject :(
Current impl:
// TODO-low Introduce variant that doesn't notify ControlSurface
pub fn insert_track_at(self, index: u32) -> Track {
self.complain_if_not_available();
// TODO-low reaper::InsertTrackAtIndex unfortunately doesn't allow to specify ReaProject :(
let reaper = Reaper::get().medium_reaper();
reaper.insert_track_at_index(index, TrackDefaultsBehavior::OmitDefaultEnvAndFx);
reaper.track_list_update_all_external_surfaces();
let media_track = reaper.get_track(Proj(self.rea_project), index).unwrap();
Track::new(media_track, Some(self.rea_project))
}
Naive theoretical impl (if SelectProjectInstance does what I hope):
// TODO-low Introduce variant that doesn't notify ControlSurface
pub fn insert_track_at(self, index: u32, project: Project) -> Track {
self.complain_if_not_available();
let reaper = Reaper::get().medium_reaper();
let current_project = Reaper::get().current_project();
unsafe {
reaper.low().SelectProjectInstance(project.rea_project);
}
reaper.insert_track_at_index(index, TrackDefaultsBehavior::OmitDefaultEnvAndFx);
reaper.track_list_update_all_external_surfaces();
let media_track = reaper.get_track(Proj(self.rea_project), index).unwrap();
unsafe {
reaper.low().SelectProjectInstance(current_project.rea_project);
}
Track::new(media_track, Some(self.rea_project))
}
🙂
Thanks Gavin! That could be a solution. Just would need to make sure that the function doesn't do anything with the GUI, otherwise this could lead to flickering.
Thanks Gavin! That could be a solution. Just would need to make sure that the function doesn't do anything with the GUI, otherwise this could lead to flickering.
I just tested, it actually does visually swap the project tabs =/

Spoke with @cfillion about this, he said calling reaper.PreventUIRefresh() at the beginning and end of the function will prevent the flicker! 😃
proj1, _ = reaper.EnumProjects(0)
proj2, _ = reaper.EnumProjects(1)
reaper.PreventUIRefresh(1)
reaper.SelectProjectInstance(proj2)
t = reaper.GetTrack(0, 0) -- 0 = "current project"
_, name = reaper.GetTrackName(t)
reaper.ShowConsoleMsg("Proj2 track 1 name = " .. name)
reaper.SelectProjectInstance(proj1)
reaper.PreventUIRefresh(-1)
Can probably make this a generic/higher-order function or trait, something roughly like this (excuse poor Rust): https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=67923d3fc92d3776473a9af26e6d3072
fn prevent_ui_refresh<FnType, FnReturn>(F: FnType) -> FnReturn
where
F: Fn() -> FnReturn
{
reaper.PreventUIRefresh(1);
let result = f();
reaper.PreventUIRefresh(-1);
return result;
}
fn main() {
let myfunc = |x: i32| -> i32 { x * x };
let result = prevent_ui_refresh(|| {
myfunc(5)
});
println!("Result is {}", result);
}
