mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-04-10 11:30:13 +02:00
376 lines
16 KiB
Rust
376 lines
16 KiB
Rust
//impl Bar for ArrangerStatus {
|
|
//type State = (ArrangerFocus, ArrangerSelection, bool);
|
|
//fn hotkey_fg () -> Color where Self: Sized {
|
|
//TuiTheme::HOTKEY_FG
|
|
//}
|
|
//fn update (&mut self, (focused, selected, entered): &Self::State) {
|
|
//*self = match focused {
|
|
////ArrangerFocus::Menu => { todo!() },
|
|
//ArrangerFocus::Transport(_) => ArrangerStatus::Transport,
|
|
//ArrangerFocus::Arranger => match selected {
|
|
//ArrangerSelection::Mix => ArrangerStatus::ArrangerMix,
|
|
//ArrangerSelection::Track(_) => ArrangerStatus::ArrangerTrack,
|
|
//ArrangerSelection::Scene(_) => ArrangerStatus::ArrangerScene,
|
|
//ArrangerSelection::Clip(_, _) => ArrangerStatus::ArrangerClip,
|
|
//},
|
|
//ArrangerFocus::Phrases => ArrangerStatus::PhrasePool,
|
|
//ArrangerFocus::PhraseEditor => match entered {
|
|
//true => ArrangerStatus::PhraseEdit,
|
|
//false => ArrangerStatus::PhraseView,
|
|
//},
|
|
//}
|
|
//}
|
|
//}
|
|
|
|
//render!(<Tui>|self: ArrangerStatus|{
|
|
|
|
//let label = match self {
|
|
//Self::Transport => "TRANSPORT",
|
|
//Self::ArrangerMix => "PROJECT",
|
|
//Self::ArrangerTrack => "TRACK",
|
|
//Self::ArrangerScene => "SCENE",
|
|
//Self::ArrangerClip => "CLIP",
|
|
//Self::PhrasePool => "SEQ LIST",
|
|
//Self::PhraseView => "VIEW SEQ",
|
|
//Self::PhraseEdit => "EDIT SEQ",
|
|
//};
|
|
|
|
//let status_bar_bg = TuiTheme::status_bar_bg();
|
|
|
|
//let mode_bg = TuiTheme::mode_bg();
|
|
//let mode_fg = TuiTheme::mode_fg();
|
|
//let mode = Tui::fg(mode_fg, Tui::bg(mode_bg, Tui::bold(true, format!(" {label} "))));
|
|
|
|
//let commands = match self {
|
|
//Self::ArrangerMix => Self::command(&[
|
|
//["", "c", "olor"],
|
|
//["", "<>", "resize"],
|
|
//["", "+-", "zoom"],
|
|
//["", "n", "ame/number"],
|
|
//["", "Enter", " stop all"],
|
|
//]),
|
|
//Self::ArrangerClip => Self::command(&[
|
|
//["", "g", "et"],
|
|
//["", "s", "et"],
|
|
//["", "a", "dd"],
|
|
//["", "i", "ns"],
|
|
//["", "d", "up"],
|
|
//["", "e", "dit"],
|
|
//["", "c", "olor"],
|
|
//["re", "n", "ame"],
|
|
//["", ",.", "select"],
|
|
//["", "Enter", " launch"],
|
|
//]),
|
|
//Self::ArrangerTrack => Self::command(&[
|
|
//["re", "n", "ame"],
|
|
//["", ",.", "resize"],
|
|
//["", "<>", "move"],
|
|
//["", "i", "nput"],
|
|
//["", "o", "utput"],
|
|
//["", "m", "ute"],
|
|
//["", "s", "olo"],
|
|
//["", "Del", "ete"],
|
|
//["", "Enter", " stop"],
|
|
//]),
|
|
//Self::ArrangerScene => Self::command(&[
|
|
//["re", "n", "ame"],
|
|
//["", "Del", "ete"],
|
|
//["", "Enter", " launch"],
|
|
//]),
|
|
//Self::PhrasePool => Self::command(&[
|
|
//["", "a", "ppend"],
|
|
//["", "i", "nsert"],
|
|
//["", "d", "uplicate"],
|
|
//["", "Del", "ete"],
|
|
//["", "c", "olor"],
|
|
//["re", "n", "ame"],
|
|
//["leng", "t", "h"],
|
|
//["", ",.", "move"],
|
|
//["", "+-", "resize view"],
|
|
//]),
|
|
//Self::PhraseView => Self::command(&[
|
|
//["", "enter", " edit"],
|
|
//["", "arrows/pgup/pgdn", " scroll"],
|
|
//["", "+=", "zoom"],
|
|
//]),
|
|
//Self::PhraseEdit => Self::command(&[
|
|
//["", "esc", " exit"],
|
|
//["", "a", "ppend"],
|
|
//["", "s", "et"],
|
|
//["", "][", "length"],
|
|
//["", "+-", "zoom"],
|
|
//]),
|
|
//_ => Self::command(&[])
|
|
//};
|
|
|
|
////let commands = commands.iter().reduce(String::new(), |s, (a, b, c)| format!("{s} {a}{b}{c}"));
|
|
//Tui::bg(status_bar_bg, Fill::w(row!([mode, commands])))
|
|
|
|
//});
|
|
|
|
///// Status bar for arranger app
|
|
//#[derive(Copy, Clone, Debug)]
|
|
//pub enum ArrangerStatus {
|
|
//Transport,
|
|
//ArrangerMix,
|
|
//ArrangerTrack,
|
|
//ArrangerScene,
|
|
//ArrangerClip,
|
|
//PhrasePool,
|
|
//PhraseView,
|
|
//PhraseEdit,
|
|
//}
|
|
|
|
//let focused = true;
|
|
//let _tracks = view.tracks();
|
|
//lay!(
|
|
//focused.then_some(Background(TuiTheme::border_bg())),
|
|
//row!(
|
|
//// name
|
|
//Widget::new(|_|{todo!()}, |_: &mut TuiOutput|{
|
|
//todo!()
|
|
////let Self(tracks, selected) = self;
|
|
////let yellow = Some(Style::default().yellow().bold().not_dim());
|
|
////let white = Some(Style::default().white().bold().not_dim());
|
|
////let area = to.area();
|
|
////let area = [area.x(), area.y(), 3 + 5.max(track_name_max_len(tracks)) as u16, area.h()];
|
|
////let offset = 0; // track scroll offset
|
|
////for y in 0..area.h() {
|
|
////if y == 0 {
|
|
////to.blit(&"Mixer", area.x() + 1, area.y() + y, Some(DIM))?;
|
|
////} else if y % 2 == 0 {
|
|
////let index = (y as usize - 2) / 2 + offset;
|
|
////if let Some(track) = tracks.get(index) {
|
|
////let selected = selected.track() == Some(index);
|
|
////let style = if selected { yellow } else { white };
|
|
////to.blit(&format!(" {index:>02} "), area.x(), area.y() + y, style)?;
|
|
////to.blit(&*track.name.read().unwrap(), area.x() + 4, area.y() + y, style)?;
|
|
////}
|
|
////}
|
|
////}
|
|
////Ok(Some(area))
|
|
//}),
|
|
//// monitor
|
|
//Widget::new(|_|{todo!()}, |_: &mut TuiOutput|{
|
|
//todo!()
|
|
////let Self(tracks) = self;
|
|
////let mut area = to.area();
|
|
////let on = Some(Style::default().not_dim().green().bold());
|
|
////let off = Some(DIM);
|
|
////area.x += 1;
|
|
////for y in 0..area.h() {
|
|
////if y == 0 {
|
|
//////" MON ".blit(to.buffer, area.x, area.y + y, style2)?;
|
|
////} else if y % 2 == 0 {
|
|
////let index = (y as usize - 2) / 2;
|
|
////if let Some(track) = tracks.get(index) {
|
|
////let style = if track.monitoring { on } else { off };
|
|
////to.blit(&" MON ", area.x(), area.y() + y, style)?;
|
|
////} else {
|
|
////area.height = y;
|
|
////break
|
|
////}
|
|
////}
|
|
////}
|
|
////area.width = 4;
|
|
////Ok(Some(area))
|
|
//}),
|
|
//// record
|
|
//Widget::new(|_|{todo!()}, |_: &mut TuiOutput|{
|
|
//todo!()
|
|
////let Self(tracks) = self;
|
|
////let mut area = to.area();
|
|
////let on = Some(Style::default().not_dim().red().bold());
|
|
////let off = Some(Style::default().dim());
|
|
////area.x += 1;
|
|
////for y in 0..area.h() {
|
|
////if y == 0 {
|
|
//////" REC ".blit(to.buffer, area.x, area.y + y, style2)?;
|
|
////} else if y % 2 == 0 {
|
|
////let index = (y as usize - 2) / 2;
|
|
////if let Some(track) = tracks.get(index) {
|
|
////let style = if track.recording { on } else { off };
|
|
////to.blit(&" REC ", area.x(), area.y() + y, style)?;
|
|
////} else {
|
|
////area.height = y;
|
|
////break
|
|
////}
|
|
////}
|
|
////}
|
|
////area.width = 4;
|
|
////Ok(Some(area))
|
|
//}),
|
|
//// overdub
|
|
//Widget::new(|_|{todo!()}, |_: &mut TuiOutput|{
|
|
//todo!()
|
|
////let Self(tracks) = self;
|
|
////let mut area = to.area();
|
|
////let on = Some(Style::default().not_dim().yellow().bold());
|
|
////let off = Some(Style::default().dim());
|
|
////area.x = area.x + 1;
|
|
////for y in 0..area.h() {
|
|
////if y == 0 {
|
|
//////" OVR ".blit(to.buffer, area.x, area.y + y, style2)?;
|
|
////} else if y % 2 == 0 {
|
|
////let index = (y as usize - 2) / 2;
|
|
////if let Some(track) = tracks.get(index) {
|
|
////to.blit(&" OVR ", area.x(), area.y() + y, if track.overdub {
|
|
////on
|
|
////} else {
|
|
////off
|
|
////})?;
|
|
////} else {
|
|
////area.height = y;
|
|
////break
|
|
////}
|
|
////}
|
|
////}
|
|
////area.width = 4;
|
|
////Ok(Some(area))
|
|
//}),
|
|
//// erase
|
|
//Widget::new(|_|{todo!()}, |_: &mut TuiOutput|{
|
|
//todo!()
|
|
////let Self(tracks) = self;
|
|
////let mut area = to.area();
|
|
////let off = Some(Style::default().dim());
|
|
////area.x = area.x + 1;
|
|
////for y in 0..area.h() {
|
|
////if y == 0 {
|
|
//////" DEL ".blit(to.buffer, area.x, area.y + y, style2)?;
|
|
////} else if y % 2 == 0 {
|
|
////let index = (y as usize - 2) / 2;
|
|
////if let Some(_) = tracks.get(index) {
|
|
////to.blit(&" DEL ", area.x(), area.y() + y, off)?;
|
|
////} else {
|
|
////area.height = y;
|
|
////break
|
|
////}
|
|
////}
|
|
////}
|
|
////area.width = 4;
|
|
////Ok(Some(area))
|
|
//}),
|
|
//// gain
|
|
//Widget::new(|_|{todo!()}, |_: &mut TuiOutput|{
|
|
//todo!()
|
|
////let Self(tracks) = self;
|
|
////let mut area = to.area();
|
|
////let off = Some(Style::default().dim());
|
|
////area.x = area.x() + 1;
|
|
////for y in 0..area.h() {
|
|
////if y == 0 {
|
|
//////" GAIN ".blit(to.buffer, area.x, area.y + y, style2)?;
|
|
////} else if y % 2 == 0 {
|
|
////let index = (y as usize - 2) / 2;
|
|
////if let Some(_) = tracks.get(index) {
|
|
////to.blit(&" +0.0 ", area.x(), area.y() + y, off)?;
|
|
////} else {
|
|
////area.height = y;
|
|
////break
|
|
////}
|
|
////}
|
|
////}
|
|
////area.width = 7;
|
|
////Ok(Some(area))
|
|
//}),
|
|
//// scenes
|
|
//Widget::new(|_|{todo!()}, |to: &mut TuiOutput|{
|
|
//let [x, y, _, height] = to.area();
|
|
//let mut x2 = 0;
|
|
//Ok(for (scene_index, scene) in view.scenes().iter().enumerate() {
|
|
//let active_scene = view.selected.scene() == Some(scene_index);
|
|
//let sep = Some(if active_scene {
|
|
//Style::default().yellow().not_dim()
|
|
//} else {
|
|
//Style::default().dim()
|
|
//});
|
|
//for y in y+1..y+height {
|
|
//to.blit(&"│", x + x2, y, sep);
|
|
//}
|
|
//let name = scene.name.read().unwrap();
|
|
//let mut x3 = name.len() as u16;
|
|
//to.blit(&*name, x + x2, y, sep);
|
|
//for (i, clip) in scene.clips.iter().enumerate() {
|
|
//let active_track = view.selected.track() == Some(i);
|
|
//if let Some(clip) = clip {
|
|
//let y2 = y + 2 + i as u16 * 2;
|
|
//let label = format!("{}", clip.read().unwrap().name);
|
|
//to.blit(&label, x + x2, y2, Some(if active_track && active_scene {
|
|
//Style::default().not_dim().yellow().bold()
|
|
//} else {
|
|
//Style::default().not_dim()
|
|
//}));
|
|
//x3 = x3.max(label.len() as u16)
|
|
//}
|
|
//}
|
|
//x2 = x2 + x3 + 1;
|
|
//})
|
|
//}),
|
|
//)
|
|
//)
|
|
//}
|
|
|
|
//impl Command<ArrangerModel> for ArrangerSceneCommand {
|
|
//}
|
|
//Edit(phrase) => { state.state.phrase = phrase.clone() },
|
|
//ToggleViewMode => { state.state.mode.to_next(); },
|
|
//Delete => { state.state.delete(); },
|
|
//Activate => { state.state.activate(); },
|
|
//ZoomIn => { state.state.zoom_in(); },
|
|
//ZoomOut => { state.state.zoom_out(); },
|
|
//MoveBack => { state.state.move_back(); },
|
|
//MoveForward => { state.state.move_forward(); },
|
|
//RandomColor => { state.state.randomize_color(); },
|
|
//Put => { state.state.phrase_put(); },
|
|
//Get => { state.state.phrase_get(); },
|
|
//AddScene => { state.state.scene_add(None, None)?; },
|
|
//AddTrack => { state.state.track_add(None, None)?; },
|
|
//ToggleLoop => { state.state.toggle_loop() },
|
|
//pub fn zoom_in (&mut self) {
|
|
//if let ArrangerEditorMode::V(factor) = self.mode {
|
|
//self.mode = ArrangerEditorMode::V(factor + 1)
|
|
//}
|
|
//}
|
|
//pub fn zoom_out (&mut self) {
|
|
//if let ArrangerEditorMode::V(factor) = self.mode {
|
|
//self.mode = ArrangerEditorMode::V(factor.saturating_sub(1))
|
|
//}
|
|
//}
|
|
//pub fn move_back (&mut self) {
|
|
//match self.selected {
|
|
//ArrangerEditorFocus::Scene(s) => {
|
|
//if s > 0 {
|
|
//self.scenes.swap(s, s - 1);
|
|
//self.selected = ArrangerEditorFocus::Scene(s - 1);
|
|
//}
|
|
//},
|
|
//ArrangerEditorFocus::Track(t) => {
|
|
//if t > 0 {
|
|
//self.tracks.swap(t, t - 1);
|
|
//self.selected = ArrangerEditorFocus::Track(t - 1);
|
|
//// FIXME: also swap clip order in scenes
|
|
//}
|
|
//},
|
|
//_ => todo!("arrangement: move forward")
|
|
//}
|
|
//}
|
|
//pub fn move_forward (&mut self) {
|
|
//match self.selected {
|
|
//ArrangerEditorFocus::Scene(s) => {
|
|
//if s < self.scenes.len().saturating_sub(1) {
|
|
//self.scenes.swap(s, s + 1);
|
|
//self.selected = ArrangerEditorFocus::Scene(s + 1);
|
|
//}
|
|
//},
|
|
//ArrangerEditorFocus::Track(t) => {
|
|
//if t < self.tracks.len().saturating_sub(1) {
|
|
//self.tracks.swap(t, t + 1);
|
|
//self.selected = ArrangerEditorFocus::Track(t + 1);
|
|
//// FIXME: also swap clip order in scenes
|
|
//}
|
|
//},
|
|
//_ => todo!("arrangement: move forward")
|
|
//}
|
|
//}
|