177 lines
9.0 KiB
Rust
177 lines
9.0 KiB
Rust
use iced::Task;
|
|
|
|
use super::{Editor, Message, ModalState};
|
|
use crate::engine::{EngineCommand, TransportState};
|
|
use crate::gui::editor::{new_track_wizard, track_header};
|
|
use crate::history::EditCommand;
|
|
use crate::track::Track;
|
|
|
|
impl Editor {
|
|
pub(crate) fn handle_tracks(&mut self, message: Message) -> Task<Message> {
|
|
match message {
|
|
Message::ShowNewTrackWizard => {
|
|
self.modal_state =
|
|
Some(ModalState::NewTrackWizard(new_track_wizard::State::default()));
|
|
}
|
|
Message::NewTrackWizard(wizard_message) => {
|
|
if let Some(ModalState::NewTrackWizard(state)) = &mut self.modal_state {
|
|
match wizard_message {
|
|
new_track_wizard::Message::Cancel => self.modal_state = None,
|
|
new_track_wizard::Message::Create => {
|
|
let config = state.config.clone();
|
|
let track = Track::new(config, self.track_count);
|
|
self.track_count += 1;
|
|
if let Some(ref engine) = self.engine {
|
|
engine.send(EngineCommand::CreateBus {
|
|
name: track.bus_name.clone(),
|
|
is_midi: track.track_type == crate::track::TrackType::Midi,
|
|
});
|
|
engine.send(EngineCommand::SetBusVolume {
|
|
bus_name: track.bus_name.clone(),
|
|
volume: track.volume,
|
|
});
|
|
}
|
|
let idx = self.tracks.len();
|
|
self.tracks.push(track);
|
|
self.history.push(EditCommand::CreateTrack { index: idx });
|
|
self.modal_state = None;
|
|
}
|
|
new_track_wizard::Message::NameChanged(name) => state.config.name = name,
|
|
new_track_wizard::Message::TrackTypeSelected(track_type) => {
|
|
state.config.track_type = track_type
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Message::TrackHeader(i, msg) => {
|
|
if let Some(track) = self.tracks.get_mut(i) {
|
|
match msg {
|
|
track_header::Message::MuteToggled => {
|
|
track.muted = !track.muted;
|
|
if let Some(ref engine) = self.engine {
|
|
engine.send(EngineCommand::SetBusMute {
|
|
bus_name: track.bus_name.clone(),
|
|
muted: track.muted,
|
|
});
|
|
}
|
|
self.mark_dirty();
|
|
}
|
|
track_header::Message::SoloToggled => {
|
|
track.soloed = !track.soloed;
|
|
if let Some(ref engine) = self.engine {
|
|
engine.send(EngineCommand::SetBusSolo {
|
|
bus_name: track.bus_name.clone(),
|
|
soloed: track.soloed,
|
|
});
|
|
}
|
|
self.mark_dirty();
|
|
}
|
|
track_header::Message::RecordArmToggled => {
|
|
track.record_armed = !track.record_armed;
|
|
if let Some(ref engine) = self.engine {
|
|
if track.record_armed {
|
|
engine.send(EngineCommand::ArmTrack {
|
|
bus_name: track.bus_name.clone(),
|
|
});
|
|
} else {
|
|
engine.send(EngineCommand::DisarmTrack {
|
|
bus_name: track.bus_name.clone(),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
track_header::Message::VolumeChanged(vol) => {
|
|
track.volume = if (vol - 0.75).abs() < 0.02 { 0.75 } else { vol };
|
|
let group_vol = track.group_id
|
|
.and_then(|gid| self.groups.iter().find(|g| g.id == gid))
|
|
.map(|g| g.volume)
|
|
.unwrap_or(1.0);
|
|
if let Some(ref engine) = self.engine {
|
|
engine.send(EngineCommand::SetBusVolume {
|
|
bus_name: track.bus_name.clone(),
|
|
volume: track.volume * group_vol,
|
|
});
|
|
}
|
|
let should_record = self.transport == TransportState::Playing && track.automation_mode.writes();
|
|
let vol_val = track.volume;
|
|
self.mark_dirty();
|
|
if should_record {
|
|
let sample_pos = self.current_position.to_samples_mapped(
|
|
&self.tempo_map, self.project_config.sample_rate,
|
|
self.time_signature_numerator as u32,
|
|
);
|
|
self.record_automation_point(i, crate::automation::AutomationTarget::Volume, sample_pos, vol_val);
|
|
}
|
|
}
|
|
track_header::Message::PanChanged(pan) => {
|
|
track.pan = if pan.abs() < 0.02 { 0.0 } else { pan };
|
|
if let Some(ref engine) = self.engine {
|
|
engine.send(EngineCommand::SetBusPan {
|
|
bus_name: track.bus_name.clone(),
|
|
pan: track.pan,
|
|
});
|
|
}
|
|
let should_record = self.transport == TransportState::Playing && track.automation_mode.writes();
|
|
let pan_val = track.pan;
|
|
self.mark_dirty();
|
|
if should_record {
|
|
let sample_pos = self.current_position.to_samples_mapped(
|
|
&self.tempo_map, self.project_config.sample_rate,
|
|
self.time_signature_numerator as u32,
|
|
);
|
|
self.record_automation_point(i, crate::automation::AutomationTarget::Pan, sample_pos, pan_val);
|
|
}
|
|
}
|
|
track_header::Message::Delete => {
|
|
let removed = self.tracks.remove(i);
|
|
for region in &removed.regions {
|
|
self.waveform_cache.remove(®ion.id);
|
|
}
|
|
if let Some(ref engine) = self.engine {
|
|
engine.send(EngineCommand::RemoveBus {
|
|
name: removed.bus_name.clone(),
|
|
});
|
|
}
|
|
self.history.push(EditCommand::DeleteTrack {
|
|
index: i,
|
|
track: removed,
|
|
});
|
|
self.mark_dirty();
|
|
if self.selected_track == Some(i) {
|
|
self.selected_track = None;
|
|
} else if let Some(sel) = self.selected_track {
|
|
if sel > i {
|
|
self.selected_track = Some(sel - 1);
|
|
}
|
|
}
|
|
}
|
|
track_header::Message::Select => {
|
|
self.selected_track = Some(i);
|
|
for (idx, t) in self.tracks.iter_mut().enumerate() {
|
|
t.selected = idx == i;
|
|
}
|
|
}
|
|
track_header::Message::FreezeToggled => {
|
|
return self.update(Message::FreezeTrack(i));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Message::SetTrackColor(i, color) => {
|
|
if let Some(track) = self.tracks.get_mut(i) {
|
|
track.color = color;
|
|
self.mark_dirty();
|
|
}
|
|
}
|
|
Message::SetMonitorMode(i, mode) => {
|
|
if let Some(track) = self.tracks.get_mut(i) {
|
|
track.monitor_mode = mode;
|
|
self.mark_dirty();
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
Task::none()
|
|
}
|
|
}
|