Skip to content

Commit

Permalink
#252 Add menu actions to make targets non-sticky in different ways
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Aug 14, 2024
1 parent e508c6b commit 56c6544
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 95 deletions.
100 changes: 43 additions & 57 deletions main/src/application/mapping_model.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::application::{
merge_affected, ActivationConditionCommand, ActivationConditionModel, ActivationConditionProp,
Affected, Change, ChangeResult, GetProcessingRelevance, MappingExtensionModel, ModeCommand,
ModeModel, ModeProp, ProcessingRelevance, SourceCommand, SourceModel, SourceProp,
TargetCategory, TargetCommand, TargetModel, TargetModelFormatVeryShort, TargetModelWithContext,
TargetProp,
Affected, Change, ChangeResult, GetProcessingRelevance, MakeFxNonStickyMode,
MakeTrackNonStickyMode, MappingExtensionModel, ModeCommand, ModeModel, ModeProp,
ProcessingRelevance, SourceCommand, SourceModel, SourceProp, TargetCategory, TargetCommand,
TargetModel, TargetModelFormatVeryShort, TargetModelWithContext, TargetProp,
};
use crate::domain::{
ActivationCondition, CompartmentKind, CompoundMappingSource, CompoundMappingTarget,
Expand All @@ -17,7 +17,7 @@ use helgoboss_learn::{
ModeApplicabilityCheckInput, ModeParameter, SourceCharacter, Target, UnitValue,
};

use helgobox_api::persistence::TrackScope;
use reaper_high::{Fx, Track};
use std::cell::RefCell;
use std::error::Error;
use std::rc::Rc;
Expand Down Expand Up @@ -292,50 +292,56 @@ impl MappingModel {
}
}

pub fn make_target_non_sticky(
&mut self,
context: ExtendedProcessorContext,
track_mode: MakeTrackNonStickyMode,
fx_mode: MakeFxNonStickyMode,
) -> Option<Affected<MappingProp>> {
self.make_target_non_sticky_internal(
context,
|t| track_mode.build_virtual_track(t.as_ref()),
|fx| fx_mode.build_virtual_fx(fx.as_ref()),
)
}

#[must_use]
pub fn make_project_independent(
fn make_target_non_sticky_internal(
&mut self,
context: ExtendedProcessorContext,
create_virtual_track: impl FnOnce(Option<Track>) -> Option<VirtualTrack>,
create_virtual_fx: impl FnOnce(Option<Fx>) -> Option<VirtualFx>,
) -> Option<Affected<MappingProp>> {
let compartment = self.compartment();
let target = &mut self.target_model;
match target.category() {
TargetCategory::Reaper => {
let changed_to_track_ignore_fx = if target.supports_fx() {
let refers_to_project = target.fx_type().refers_to_project();
if refers_to_project {
let target_with_context = target.with_context(context, compartment);
let virtual_fx = if target_with_context.first_fx().ok().as_ref()
== Some(context.context().containing_fx())
{
// This is ourselves!
VirtualFx::This
} else {
VirtualFx::Unit
};
let _ = target.set_virtual_fx(virtual_fx, context, compartment);
true
// Change FX
if target.supports_fx() {
let target_with_context = target.with_context(context, compartment);
let containing_fx = context.context().containing_fx();
let resolved_fx = target_with_context.first_fx().ok();
let new_virtual_fx = if resolved_fx.as_ref() == Some(containing_fx) {
// This is ourselves!
Some(VirtualFx::This)
} else {
false
create_virtual_fx(resolved_fx)
};
if let Some(fx) = new_virtual_fx {
let _ = target.set_virtual_fx(fx, context, compartment);
}
} else {
false
};
if target.target_type().supports_track() && target.track_type().refers_to_project()
{
let new_virtual_track = if changed_to_track_ignore_fx {
}
// Change track
if target.target_type().supports_track() {
let new_virtual_track = if target.fx_type().requires_fx_chain() {
let resolved_track = target
.with_context(context, compartment)
.first_effective_track()
.ok();
create_virtual_track(resolved_track)
} else {
// Track doesn't matter at all. We change it to <This>. Looks nice.
Some(VirtualTrack::This)
} else if let Ok(t) = target
.with_context(context, compartment)
.first_effective_track()
{
t.index().map(|index| VirtualTrack::ByIndex {
index,
scope: TrackScope::AllTracks,
})
} else {
None
};
if let Some(t) = new_virtual_track {
let _ = target.set_virtual_track(t, Some(context.context()));
Expand All @@ -347,26 +353,6 @@ impl MappingModel {
}
}

pub fn make_target_use_unit_track_and_fx(
&mut self,
context: ExtendedProcessorContext,
) -> Option<Affected<MappingProp>> {
let compartment = self.compartment();
let target = &mut self.target_model;
match target.category() {
TargetCategory::Reaper => {
if target.supports_track() {
let _ = target.set_virtual_track(VirtualTrack::Unit, Some(context.context()));
}
if target.supports_fx() {
let _ = target.set_virtual_fx(VirtualFx::Unit, context, compartment);
}
}
TargetCategory::Virtual => {}
}
Some(Affected::Multiple)
}

pub fn make_target_sticky(
&mut self,
context: ExtendedProcessorContext,
Expand Down
103 changes: 103 additions & 0 deletions main/src/application/target_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4673,3 +4673,106 @@ impl MappingModificationKind {
}
}
}

#[derive(Copy, Clone, Eq, PartialEq, derive_more::Display, EnumIter)]
pub enum MakeFxNonStickyMode {
#[display(fmt = "<Focused>")]
Focused,
#[display(fmt = "<Unit>")]
Unit,
#[display(fmt = "Named")]
Named,
#[display(fmt = "All named")]
AllNamed,
#[display(fmt = "At position")]
AtPosition,
}

#[derive(Copy, Clone, Eq, PartialEq, derive_more::Display, EnumIter)]
pub enum MakeTrackNonStickyMode {
#[display(fmt = "<Selected>")]
Selected,
#[display(fmt = "<All selected>")]
AllSelected,
#[display(fmt = "<Unit>")]
Unit,
#[display(fmt = "Named")]
Named,
#[display(fmt = "All named")]
AllNamed,
#[display(fmt = "At position")]
AtPosition,
#[display(fmt = "At TCP position")]
AtTcpPosition,
#[display(fmt = "At MCP position")]
AtMcpPosition,
}

impl MakeFxNonStickyMode {
pub fn build_virtual_fx(&self, fx: Option<&Fx>) -> Option<VirtualFx> {
let virtual_fx = match self {
MakeFxNonStickyMode::Focused => VirtualFx::Focused,
MakeFxNonStickyMode::Unit => VirtualFx::Unit,
MakeFxNonStickyMode::Named | MakeFxNonStickyMode::AllNamed => {
let fx = fx?;
VirtualFx::ChainFx {
is_input_fx: fx.is_input_fx(),
chain_fx: VirtualChainFx::ByName {
wild_match: WildMatch::new(fx.name().to_str()),
allow_multiple: *self == MakeFxNonStickyMode::AllNamed,
},
}
}
MakeFxNonStickyMode::AtPosition => {
let fx = fx?;
VirtualFx::ChainFx {
is_input_fx: fx.is_input_fx(),
chain_fx: VirtualChainFx::ByIndex(fx.index()),
}
}
};
Some(virtual_fx)
}
}

impl MakeTrackNonStickyMode {
pub fn build_virtual_track(&self, track: Option<&Track>) -> Option<VirtualTrack> {
let virtual_track = match self {
MakeTrackNonStickyMode::Selected => VirtualTrack::Selected {
allow_multiple: false,
},
MakeTrackNonStickyMode::AllSelected => VirtualTrack::Selected {
allow_multiple: true,
},
MakeTrackNonStickyMode::Unit => VirtualTrack::Unit,
MakeTrackNonStickyMode::Named | MakeTrackNonStickyMode::AllNamed => {
if let Some(name) = track?.name() {
VirtualTrack::ByName {
wild_match: WildMatch::new(name.to_str()),
allow_multiple: *self == MakeTrackNonStickyMode::AllNamed,
}
} else {
VirtualTrack::Master
}
}
MakeTrackNonStickyMode::AtPosition
| MakeTrackNonStickyMode::AtTcpPosition
| MakeTrackNonStickyMode::AtMcpPosition => {
if let Some(index) = track?.index() {
VirtualTrack::ByIndex {
index,
scope: match *self {
MakeTrackNonStickyMode::AtPosition => TrackScope::AllTracks,
MakeTrackNonStickyMode::AtTcpPosition => TrackScope::TracksVisibleInTcp,
MakeTrackNonStickyMode::AtMcpPosition => TrackScope::TracksVisibleInMcp,
_ => unreachable!(),
},
}
} else {
VirtualTrack::Master
}
}
};
Some(virtual_track)
}
}
8 changes: 0 additions & 8 deletions main/src/application/unit_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,14 +499,6 @@ impl UnitModel {
mappings_have_project_references(self.mappings[compartment].iter())
}

pub fn make_mappings_project_independent(&mut self, compartment: CompartmentKind) {
let context = self.extended_context();
for m in &self.mappings[compartment] {
let _ = m.borrow_mut().make_project_independent(context);
}
self.notify_everything_has_changed();
}

pub fn virtualize_main_mappings(&mut self) -> Result<(), String> {
let count = self.mappings[CompartmentKind::Main]
.iter()
Expand Down
Loading

0 comments on commit 56c6544

Please sign in to comment.