wip: refactor pt.9, 403 errors

This commit is contained in:
🪞👃🪞 2024-11-10 18:38:22 +01:00
parent a784f7a6f2
commit 8aa1ba8d0f
29 changed files with 1008 additions and 902 deletions

View file

@ -6,49 +6,39 @@ pub struct ArrangerView<E: Engine> {
pub sequencer: SequencerView<E>,
/// Contains all the sequencers.
pub arrangement: ArrangementEditor<E>,
/// Status bar
pub status: ArrangerStatusBar,
/// Height of arrangement
pub split: u16,
/// Width and height of app at last render
pub size: Measure<E>,
/// Menu bar
pub menu: MenuBar<E, Self, ArrangerViewCommand>,
/// Command history
pub history: Vec<ArrangerViewCommand>,
/// Which view is focused
pub cursor: (usize, usize),
/// Whether the focused view is entered
pub entered: bool,
}
impl<E: Engine> Audio for ArrangerView<E> {
fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control {
if let Some(ref transport) = self.transport {
transport.write().unwrap().process(client, scope);
#[inline] fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control {
if self.sequencer.transport.process(client, scope) == Control::Quit {
return Control::Quit
}
let Arrangement { scenes, ref mut tracks, selected, .. } = &mut self.arrangement;
for track in tracks.iter_mut() {
track.player.process(client, scope);
if self.arrangement.process(client, scope) == Control::Quit {
return Control::Quit
}
if let ArrangementEditorFocus::Clip(t, s) = selected {
if let Some(Some(Some(phrase))) = scenes.get(*s).map(|scene|scene.clips.get(*t)) {
if let Some(track) = tracks.get(*t) {
if let ArrangementEditorFocus::Clip(t, s) = self.arrangement.selected {
let phrase = self.arrangement.state.scenes.get(s).map(|scene|scene.clips.get(t));
if let Some(Some(Some(phrase))) = phrase {
if let Some(track) = self.arrangement.state.tracks.get(t) {
if let Some((ref started_at, Some(ref playing))) = track.player.phrase {
let phrase = phrase.read().unwrap();
if *playing.read().unwrap() == *phrase {
let pulse = self.clock.current.pulse.get();
let start = started_at.pulse.get();
let now = (pulse - start) % phrase.length as f64;
self.editor.now.set(now);
self.sequencer.editor.now.set(now);
return Control::Continue
}
}
}
}
}
self.editor.now.set(0.);
Control::Continue
self.sequencer.editor.now.set(0.);
self.state.process(client, scope)
}
}
@ -57,9 +47,9 @@ impl Content for ArrangerView<Tui> {
type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> {
let focused = self.arrangement.focused;
let border_bg = Arranger::<Tui>::border_bg();
let border_fg = Arranger::<Tui>::border_fg(focused);
let title_fg = Arranger::<Tui>::title_fg(focused);
let border_bg = TuiTheme::border_bg();
let border_fg = TuiTheme::border_fg(focused);
let title_fg = TuiTheme::title_fg(focused);
let border = Lozenge(Style::default().bg(border_bg).fg(border_fg));
let entered = if self.arrangement.entered { "" } else { " " };
Split::down(
@ -95,109 +85,14 @@ impl Content for ArrangerView<Tui> {
/// General methods for arranger
impl<E: Engine> ArrangerView<E> {
pub fn new (
jack: &Arc<RwLock<JackClient>>,
transport: Option<Arc<RwLock<TransportToolbar<E>>>>,
arrangement: Arrangement<E>,
phrases: Arc<RwLock<PhrasePool<E>>>,
sequencer: SequencerView<E>,
arrangement: ArrangementEditor<E>,
) -> Self {
let mut app = Self {
jack: jack.clone(),
focus_cursor: (0, 1),
entered: false,
phrases_split: 20,
arrangement_split: 15,
editor: PhraseEditor::new(),
status: ArrangerStatusBar::ArrangementClip,
transport: transport.clone(),
arrangement,
phrases,
history: vec![],
size: Measure::new(),
clock: if let Some(ref transport) = transport {
transport.read().unwrap().clock.clone()
} else {
Arc::new(Clock::default())
},
menu: {
use ArrangerViewCommand::*;
MenuBar::new()
.add({
use ArrangementCommand::*;
Menu::new("File")
.cmd("n", "New project", Arrangement(New))
.cmd("l", "Load project", Arrangement(Load))
.cmd("s", "Save project", Arrangement(Save))
})
.add({
use TransportViewCommand::*;
Menu::new("Transport")
.cmd("p", "Play", Transport(Play))
.cmd("s", "Play from start", Transport(PlayFromStart))
.cmd("a", "Pause", Transport(Pause))
})
.add({
use ArrangementCommand::*;
Menu::new("Track")
.cmd("a", "Append new", Arrangement(AddTrack))
.cmd("i", "Insert new", Arrangement(AddTrack))
.cmd("n", "Rename", Arrangement(AddTrack))
.cmd("d", "Delete", Arrangement(AddTrack))
.cmd(">", "Move up", Arrangement(AddTrack))
.cmd("<", "Move down", Arrangement(AddTrack))
})
.add({
use ArrangementCommand::*;
Menu::new("Scene")
.cmd("a", "Append new", Arrangement(AddScene))
.cmd("i", "Insert new", Arrangement(AddTrack))
.cmd("n", "Rename", Arrangement(AddTrack))
.cmd("d", "Delete", Arrangement(AddTrack))
.cmd(">", "Move up", Arrangement(AddTrack))
.cmd("<", "Move down", Arrangement(AddTrack))
})
.add({
use PhrasePoolCommand::*;
use PhraseRenameCommand as Rename;
use PhraseLengthCommand as Length;
Menu::new("Phrase")
.cmd("a", "Append new", Phrases(Append))
.cmd("i", "Insert new", Phrases(Insert))
.cmd("n", "Rename", Phrases(Rename(Rename::Begin)))
.cmd("t", "Set length", Phrases(Length(Length::Begin)))
.cmd("d", "Delete", Phrases(Delete))
.cmd("l", "Load from MIDI...", Phrases(Import))
.cmd("s", "Save to MIDI...", Phrases(Export))
.cmd(">", "Move up", Phrases(MoveUp))
.cmd("<", "Move down", Phrases(MoveDown))
})
}
};
let mut app = Self { sequencer, arrangement, split: 15, size: Default::default() };
app.update_focus();
app
}
//pub fn new (
//jack: &Arc<RwLock<JackClient>>,
//clock: &Arc<Clock>,
//name: &str,
//phrases: &Arc<RwLock<PhrasePool<E>>>
//) -> Self {
//Self {
//jack: jack.clone(),
//clock: clock.clone(),
//name: Arc::new(RwLock::new(name.into())),
//mode: ArrangementViewMode::Vertical(2),
//selected: ArrangementEditorFocus::Clip(0, 0),
//phrases: phrases.clone(),
//scenes: vec![],
//tracks: vec![],
//focused: false,
//color: Color::Rgb(28, 35, 25).into(),
//size: Measure::new(),
//entered: false,
//}
//}
/// Toggle global play/pause
pub fn toggle_play (&mut self) -> Perhaps<bool> {
match self.transport {
@ -216,10 +111,12 @@ impl<E: Engine> ArrangerView<E> {
}
}
/// Focus the editor with the current phrase
pub fn show_phrase (&mut self) { self.editor.show(self.arrangement.phrase().as_ref()); }
pub fn show_phrase (&mut self) {
self.editor.show(self.arrangement.state.phrase().as_ref());
}
/// Focus the editor with the current phrase
pub fn edit_phrase (&mut self) {
if self.arrangement.selected.is_clip() && self.arrangement.phrase().is_none() {
if self.arrangement.selected.is_clip() && self.arrangement.state.phrase().is_none() {
self.phrases.write().unwrap().append_new(None, Some(self.next_color().into()));
self.arrangement.phrase_put();
}
@ -284,7 +181,7 @@ impl<E: Engine> ArrangerView<E> {
}
}
pub fn delete (&mut self) {
match self.selected {
match self.arrangement.selected {
ArrangementEditorFocus::Track(_) => self.track_del(),
ArrangementEditorFocus::Scene(_) => self.scene_del(),
ArrangementEditorFocus::Clip(_, _) => self.phrase_del(),
@ -292,7 +189,7 @@ impl<E: Engine> ArrangerView<E> {
}
}
pub fn increment (&mut self) {
match self.selected {
match self.arrangement.selected {
ArrangementEditorFocus::Track(_) => self.track_width_inc(),
ArrangementEditorFocus::Scene(_) => self.scene_next(),
ArrangementEditorFocus::Clip(_, _) => self.phrase_next(),
@ -300,7 +197,7 @@ impl<E: Engine> ArrangerView<E> {
}
}
pub fn decrement (&mut self) {
match self.selected {
match self.arrangement.selected {
ArrangementEditorFocus::Track(_) => self.track_width_dec(),
ArrangementEditorFocus::Scene(_) => self.scene_prev(),
ArrangementEditorFocus::Clip(_, _) => self.phrase_prev(),
@ -308,13 +205,13 @@ impl<E: Engine> ArrangerView<E> {
}
}
pub fn zoom_in (&mut self) {
if let ArrangementViewMode::Vertical(factor) = self.mode {
self.mode = ArrangementViewMode::Vertical(factor + 1)
if let ArrangementEditorMode::Vertical(factor) = self.mode {
self.mode = ArrangementEditorMode::Vertical(factor + 1)
}
}
pub fn zoom_out (&mut self) {
if let ArrangementViewMode::Vertical(factor) = self.mode {
self.mode = ArrangementViewMode::Vertical(factor.saturating_sub(1))
if let ArrangementEditorMode::Vertical(factor) = self.mode {
self.mode = ArrangementEditorMode::Vertical(factor.saturating_sub(1))
}
}
pub fn is_first_row (&self) -> bool {
@ -336,25 +233,25 @@ impl<E: Engine> ArrangerView<E> {
}
pub fn go_up (&mut self) {
match self.mode {
ArrangementViewMode::Horizontal => self.track_prev(),
ArrangementEditorMode::Horizontal => self.track_prev(),
_ => self.scene_prev(),
};
}
pub fn go_down (&mut self) {
match self.mode {
ArrangementViewMode::Horizontal => self.track_next(),
ArrangementEditorMode::Horizontal => self.track_next(),
_ => self.scene_next(),
};
}
pub fn go_left (&mut self) {
match self.mode {
ArrangementViewMode::Horizontal => self.scene_prev(),
ArrangementEditorMode::Horizontal => self.scene_prev(),
_ => self.track_prev(),
};
}
pub fn go_right (&mut self) {
match self.mode {
ArrangementViewMode::Horizontal => self.scene_next(),
ArrangementEditorMode::Horizontal => self.scene_next(),
_ => self.track_next(),
};
}
@ -457,10 +354,10 @@ impl<E: Engine> Arrangement<E> {
}
/// Methods for scenes in arrangement
impl<E: Engine> Arrangement<E> {
pub fn scene (&self) -> Option<&Scene> {
pub fn scene (&self) -> Option<&ArrangementScene> {
self.selected.scene().map(|s|self.scenes.get(s)).flatten()
}
pub fn scene_mut (&mut self) -> Option<&mut Scene> {
pub fn scene_mut (&mut self) -> Option<&mut ArrangementScene> {
self.selected.scene().map(|s|self.scenes.get_mut(s)).flatten()
}
pub fn scene_next (&mut self) {
@ -573,7 +470,7 @@ impl ArrangementTrack {
}
/// Arranger display mode can be cycled
impl ArrangementViewMode {
impl ArrangementEditorMode {
/// Cycle arranger display mode
pub fn to_next (&mut self) {
*self = match self {