//pub struct ArrangerVCursor { //cols: Vec<(usize, usize)>, //rows: Vec<(usize, usize)>, //color: ItemPalette, //reticle: Reticle, //selected: ArrangerSelection, //scenes_w: u16, //} //pub(crate) const HEADER_H: u16 = 0; // 5 //pub(crate) const SCENES_W_OFFSET: u16 = 0; //from!(|args:(&Arranger, usize)|ArrangerVCursor = Self { //cols: Arranger::track_widths(&args.0.tracks), //rows: Arranger::scene_heights(&args.0.scenes, args.1), //selected: args.0.selected(), //scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&args.0.scenes) as u16, //color: args.0.color, //reticle: Reticle(Style { //fg: Some(args.0.color.lighter.rgb), //bg: None, //underline_color: None, //add_modifier: Modifier::empty(), //sub_modifier: Modifier::DIM //}), //}); //impl Content for ArrangerVCursor { //fn render (&self, to: &mut TuiOut) { //let area = to.area(); //let focused = true; //let selected = self.selected; //let get_track_area = |t: usize| [ //self.scenes_w + area.x() + self.cols[t].1 as u16, area.y(), //self.cols[t].0 as u16, area.h(), //]; //let get_scene_area = |s: usize| [ //area.x(), HEADER_H + area.y() + (self.rows[s].1 / PPQ) as u16, //area.w(), (self.rows[s].0 / PPQ) as u16 //]; //let get_clip_area = |t: usize, s: usize| [ //(self.scenes_w + area.x() + self.cols[t].1 as u16).saturating_sub(1), //HEADER_H + area.y() + (self.rows[s].1/PPQ) as u16, //self.cols[t].0 as u16 + 2, //(self.rows[s].0 / PPQ) as u16 //]; //let mut track_area: Option<[u16;4]> = None; //let mut scene_area: Option<[u16;4]> = None; //let mut clip_area: Option<[u16;4]> = None; //let area = match selected { //ArrangerSelection::Mix => area, //ArrangerSelection::Track(t) => { //track_area = Some(get_track_area(t)); //area //}, //ArrangerSelection::Scene(s) => { //scene_area = Some(get_scene_area(s)); //area //}, //ArrangerSelection::Clip(t, s) => { //track_area = Some(get_track_area(t)); //scene_area = Some(get_scene_area(s)); //clip_area = Some(get_clip_area(t, s)); //area //}, //}; //let bg = self.color.lighter.rgb;//Color::Rgb(0, 255, 0); //if let Some([x, y, width, height]) = track_area { //to.fill_fg([x, y, 1, height], bg); //to.fill_fg([x + width, y, 1, height], bg); //} //if let Some([_, y, _, height]) = scene_area { //to.fill_ul([area.x(), y - 1, area.w(), 1], bg); //to.fill_ul([area.x(), y + height - 1, area.w(), 1], bg); //} //if focused { //to.place(if let Some(clip_area) = clip_area { //clip_area //} else if let Some(track_area) = track_area { //track_area.clip_h(HEADER_H) //} else if let Some(scene_area) = scene_area { //scene_area.clip_w(self.scenes_w) //} else { //area.clip_w(self.scenes_w).clip_h(HEADER_H) //}, &self.reticle) //}; //} //} //impl Arranger { //fn render_mode (state: &Self) -> impl Content + use<'_> { //match state.mode { //ArrangerMode::H => todo!("horizontal arranger"), //ArrangerMode::V(factor) => Self::render_mode_v(state, factor), //} //} //} //render!(TuiOut: (self: Arranger) => { //let pool_w = if self.pool.visible { self.splits[1] } else { 0 }; //let color = self.color; //let layout = Bsp::a(Fill::xy(ArrangerStatus::from(self)), //Bsp::n(Fixed::x(pool_w, PoolView(self.pool.visible, &self.pool)), //Bsp::n(TransportView::new(true, &self.clock), //Bsp::s(Fixed::y(1, MidiEditStatus(&self.editor)), //Bsp::n(Fill::x(Fixed::y(20, //Bsp::a(Fill::xy(Tui::bg(color.darkest.rgb, "background")), //Bsp::a( //Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))), //Self::render_mode(self))))), Fill::y(&"fixme: self.editor")))))); //self.size.of(layout) //}); //Align::n(Fill::xy(lay!( //Align::n(Fill::xy(Tui::bg(self.color.darkest.rgb, " "))), //Align::n(Fill::xy(ArrangerVRowSep::from((self, 1)))), //Align::n(Fill::xy(ArrangerVColSep::from(self))), //Align::n(Fill::xy(ArrangerVClips::new(self, 1))), //Align::n(Fill::xy(ArrangerVCursor::from((self, 1)))))))))))))))); //Align::n(Fill::xy(":"))))))))))))); //"todo:")))))))); //Bsp::s( //Align::n(Fixed::y(1, Fill::x(ArrangerVIns::from(self)))), //Bsp::s( //Fixed::y(20, Align::n(ArrangerVClips::new(self, 1))), //Fill::x(Fixed::y(1, ArrangerVOuts::from(self))))))))))))); //Bsp::s( //Bsp::s( //Bsp::s( //Fill::xy(ArrangerVClips::new(self, 1)), //Fill::x(ArrangerVOuts::from(self))))) //let cell = phat_sel_3( //selected_track == Some(i) && selected_scene == Some(j), //Tui::fg(TuiTheme::g(64), Push::x(1, name)), //Tui::fg(TuiTheme::g(64), Push::x(1, name)), //if selected_track == Some(i) && selected_scene.map(|s|s+1) == Some(j) { //None //} else { //Some(TuiTheme::g(32).into()) //}, //TuiTheme::g(32).into(), //TuiTheme::g(32).into(), //); // TODO: port per track: //for connection in midi_from.iter() { //let mut split = connection.as_ref().split("="); //let number = split.next().unwrap().trim(); //if let Ok(track) = number.parse::() { //if track < 1 { //panic!("Tracks start from 1") //} //if track > count { //panic!("Tried to connect track {track} or {count}. Pass -t {track} to increase number of tracks.") //} //if let Some(port) = split.next() { //if let Some(port) = jack.read().unwrap().client().port_by_name(port).as_ref() { ////jack.read().unwrap().client().connect_ports(port, &self.tracks[track-1].player.midi_ins[0])?; //} else { //panic!("Missing MIDI output: {port}. Use jack_lsp to list all port names."); //} //} else { //panic!("No port specified for track {track}. Format is TRACK_NUMBER=PORT_NAME") //} //} else { //panic!("Failed to parse track number: {number}") //} //} //for connection in midi_to.iter() { //let mut split = connection.as_ref().split("="); //let number = split.next().unwrap().trim(); //if let Ok(track) = number.parse::() { //if track < 1 { //panic!("Tracks start from 1") //} //if track > count { //panic!("Tried to connect track {track} or {count}. Pass -t {track} to increase number of tracks.") //} //if let Some(port) = split.next() { //if let Some(port) = jack.read().unwrap().client().port_by_name(port).as_ref() { ////jack.read().unwrap().client().connect_ports(&self.tracks[track-1].player.midi_outs[0], port)?; //} else { //panic!("Missing MIDI input: {port}. Use jack_lsp to list all port names."); //} //} else { //panic!("No port specified for track {track}. Format is TRACK_NUMBER=PORT_NAME") //} //} else { //panic!("Failed to parse track number: {number}") //} //}