mod plugin; pub use self::plugin::*; mod sampler; pub use self::sampler::*; use crate::prelude::*; pub struct Chain { pub name: String, pub focused: bool, pub focus: usize, pub items: Vec>, pub view: ChainView } pub enum ChainView { Hidden, Compact, Row, Column, } impl Chain { pub fn new (name: &str, items: Option>>) -> Result, Box> { Ok(DynamicDevice::new(render, handle, process, Self { name: name.into(), focused: false, focus: 0, items: items.unwrap_or_else(||vec![]), view: ChainView::Column })) } } impl PortList for Chain { fn midi_ins (&self) -> Usually> { if let Some(device) = self.items.get(0) { device.midi_ins() } else { Ok(vec![]) } } fn audio_outs (&self) -> Usually> { if let Some(device) = self.items.get(self.items.len().saturating_sub(1)) { device.audio_outs() } else { Ok(vec![]) } } } pub fn process (_: &mut Chain, _: &Client, _: &ProcessScope) -> Control { Control::Continue } pub fn render (state: &Chain, buf: &mut Buffer, area: Rect) -> Usually { let Rect { x, y, .. } = area; let selected = Some(if state.focused { Style::default().green().not_dim() } else { Style::default().green().dim() }); Ok(match state.view { ChainView::Hidden => Rect { x, y, width: 0, height: 0 }, ChainView::Compact => { let area = Rect { x, y, width: (state.name.len() + 4) as u16, height: 3 }; buf.set_string(area.x + 2, area.y + 1, &state.name, Style::default()); draw_box_styled(buf, area, selected) }, ChainView::Row => { draw_box_styled(buf, area, selected); let (area, _) = Row::draw(buf, area, &state.items, 0)?; area }, ChainView::Column => { draw_as_column(state, buf, area, selected)? }, }) //let area = Rect { x, y, width: 40, height: 30 }; //let mut y = area.y; //buf.set_string(area.x, y, "│", Style::default().black()); //buf.set_string(area.x + area.width - 1, y, "│", Style::default().black()); //buf.set_string(area.x + 2, y, "Input...", Style::default().dim()); //let mut x = 0u16; //for (i, device) in state.items.iter().enumerate() { //let result = device.render(buf, Rect { //x: area.x, //y, //width: area.width, //height: 21//area.height.saturating_sub(y) //})?; //if i == state.focus { //if state.focused { //draw_box_styled(buf, result, Some(Style::default().green().not_dim())) //} else { //draw_box_styled_dotted(buf, result, Some(Style::default().green().dim())) //}; //}; ////let result = Rect { x: 0, y: 0, width: result.width, height: 21 }; //x = x.max(result.width); //y = y + result.height; ////y = y + 1; //buf.set_string(area.x, y, "│", Style::default().black()); //buf.set_string(area.x + area.width - 1, y, "│", Style::default().black()); //buf.set_string(area.x + 2, y, " Patch in ┐ │ └ Patch out", Style::default().dim()); //y = y + 1; ////buf.set_string(area.x, y, format!("{y}---BOT---"), Style::default().red()); ////buf.set_string(area.x + area.width - 1, area.y + 1, "│", Style::default().black()); ////buf.set_string(area.x + 2, y, "Patch...", Style::default().dim()); //} //Ok(draw_box(buf, Rect { //x: area.x, //y: area.y, //width: area.width, //height: y - area.y, //})) } pub fn draw_as_row ( state: &Chain, buf: &mut Buffer, area: Rect, _: Option