wip: render: remove render! macro

This commit is contained in:
🪞👃🪞 2024-09-04 03:20:58 +03:00
parent bf165c6be1
commit 1d4db3c629
13 changed files with 337 additions and 304 deletions

View file

@ -1,17 +1,19 @@
use crate::*;
render!(Mixer |self, buf, area| {
let mut x = 0;
for channel in self.tracks.iter() {
x = x + channel.render(buf, Rect {
x: area.x + x,
y: area.y,
width: area.width,
height: area.height
})?.width;
if x >= area.width {
break
impl<'a> Render<TuiOutput<'a>, Rect> for Mixer {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
let mut x = 0;
for channel in self.tracks.iter() {
x = x + channel.render(buf, Rect {
x: area.x + x,
y: area.y,
width: area.width,
height: area.height
})?.width;
if x >= area.width {
break
}
}
Ok(area)
}
Ok(area)
});
}

View file

@ -9,9 +9,43 @@ pub struct Plugin {
pub mapping: bool,
pub ports: JackPorts,
}
render!(Plugin = render_plugin);
handle!(Plugin |self, e| handle_keymap(self, e, KEYMAP_PLUGIN));
process!(Plugin = Plugin::process);
impl<'a> Render<TuiOutput<'a>, Rect> for Plugin {
fn render (&self, to: &mut TuiOutput<'a>) -> Usually<Rect> {
let Rect { x, y, height, .. } = area;
let mut width = 20u16;
match &state.plugin {
Some(PluginKind::LV2(LV2Plugin { port_list, instance, .. })) => {
let start = state.selected.saturating_sub((height as usize / 2).saturating_sub(1));
let end = start + height as usize - 2;
//draw_box(buf, Rect { x, y, width, height });
for i in start..end {
if let Some(port) = port_list.get(i) {
let value = if let Some(value) = instance.control_input(port.index) {
value
} else {
port.default_value
};
//let label = &format!("C·· M·· {:25} = {value:.03}", port.name);
let label = &format!("{:25} = {value:.03}", port.name);
width = width.max(label.len() as u16 + 4);
label.blit(buf, x + 2, y + 1 + i as u16 - start as u16, if i == state.selected {
Some(Style::default().green())
} else {
None
})?;
} else {
break
}
}
},
_ => {}
};
draw_header(state, buf, area.x, area.y, width)?;
Ok(Some(Rect { width, ..area }))
}
}
/// Supported plugin formats.
pub enum PluginKind {
@ -21,7 +55,6 @@ pub enum PluginKind {
},
VST3,
}
impl Plugin {
pub fn new_lv2 (name: &str, path: &str) -> Usually<JackDevice> {
let plugin = LV2Plugin::new(path)?;
@ -102,43 +135,6 @@ impl Plugin {
Control::Continue
}
}
pub fn render_plugin (state: &Plugin, buf: &mut Buffer, area: Rect)
-> Usually<Rect>
{
let Rect { x, y, height, .. } = area;
let mut width = 20u16;
match &state.plugin {
Some(PluginKind::LV2(LV2Plugin { port_list, instance, .. })) => {
let start = state.selected.saturating_sub((height as usize / 2).saturating_sub(1));
let end = start + height as usize - 2;
//draw_box(buf, Rect { x, y, width, height });
for i in start..end {
if let Some(port) = port_list.get(i) {
let value = if let Some(value) = instance.control_input(port.index) {
value
} else {
port.default_value
};
//let label = &format!("C·· M·· {:25} = {value:.03}", port.name);
let label = &format!("{:25} = {value:.03}", port.name);
width = width.max(label.len() as u16 + 4);
label.blit(buf, x + 2, y + 1 + i as u16 - start as u16, if i == state.selected {
Some(Style::default().green())
} else {
None
})?;
} else {
break
}
}
},
_ => {}
};
draw_header(state, buf, area.x, area.y, width)?;
Ok(Rect { width, ..area })
}
fn draw_header (state: &Plugin, buf: &mut Buffer, x: u16, y: u16, w: u16) -> Usually<Rect> {
let style = Style::default().gray();
let label1 = format!(" {}", state.name);

View file

@ -22,40 +22,42 @@ pub struct AddSampleModal {
exit!(AddSampleModal);
render!(AddSampleModal |self,buf,area|{
make_dim(buf);
let area = center_box(
area,
64.max(area.width.saturating_sub(8)),
20.max(area.width.saturating_sub(8)),
);
fill_fg(buf, area, Color::Reset);
fill_bg(buf, area, Nord::bg_lo(true, true));
fill_char(buf, area, ' ');
format!("{}", &self.dir.to_string_lossy())
.blit(buf, area.x+2, area.y+1, Some(Style::default().bold()))?;
"Select sample:"
.blit(buf, area.x+2, area.y+2, Some(Style::default().bold()))?;
for (i, (is_dir, name)) in self.subdirs.iter()
.map(|path|(true, path))
.chain(self.files.iter().map(|path|(false, path)))
.enumerate()
.skip(self.offset)
{
if i >= area.height as usize - 4 {
break
impl<'a> Render<TuiOutput<'a>, Rect> for AddSampleModal {
fn render (&self, to: &mut TuiOutput<'a>) -> Usually<Rect> {
make_dim(to.buffer);
let area = center_box(
to.area,
64.max(to.area.width.saturating_sub(8)),
20.max(to.area.width.saturating_sub(8)),
);
fill_fg(buf, area, Color::Reset);
fill_bg(buf, area, Nord::bg_lo(true, true));
fill_char(buf, area, ' ');
format!("{}", &self.dir.to_string_lossy())
.blit(buf, area.x+2, area.y+1, Some(Style::default().bold()))?;
"Select sample:"
.blit(buf, area.x+2, area.y+2, Some(Style::default().bold()))?;
for (i, (is_dir, name)) in self.subdirs.iter()
.map(|path|(true, path))
.chain(self.files.iter().map(|path|(false, path)))
.enumerate()
.skip(self.offset)
{
if i >= area.height as usize - 4 {
break
}
let t = if is_dir { "" } else { "" };
let line = format!("{t} {}", name.to_string_lossy());
let line = &line[..line.len().min(area.width as usize - 4)];
line.blit(buf, area.x + 2, area.y + 3 + i as u16, Some(if i == self.cursor {
Style::default().green()
} else {
Style::default().white()
}))?;
}
let t = if is_dir { "" } else { "" };
let line = format!("{t} {}", name.to_string_lossy());
let line = &line[..line.len().min(area.width as usize - 4)];
line.blit(buf, area.x + 2, area.y + 3 + i as u16, Some(if i == self.cursor {
Style::default().green()
} else {
Style::default().white()
}))?;
Lozenge(Style::default()).draw(buf, area)
}
Lozenge(Style::default()).draw(buf, area)
});
}
handle!(AddSampleModal |self,e|{
if handle_keymap(self, e, KEYMAP_ADD_SAMPLE)? {

View file

@ -15,30 +15,34 @@ pub struct Sampler {
}
process!(Sampler = Sampler::process);
handle!(Sampler |self, event| handle_keymap(self, event, KEYMAP_SAMPLER));
render!(Sampler |self, buf, area| {
let Rect { x, y, height, .. } = area;
let style = Style::default().gray();
let title = format!(" {} ({})", self.name, self.voices.read().unwrap().len());
title.blit(buf, x+1, y, Some(style.white().bold().not_dim()))?;
let mut width = title.len() + 2;
let mut y1 = 1;
let mut j = 0;
for (note, sample) in self.mapped.iter()
.map(|(note, sample)|(Some(note), sample))
.chain(self.unmapped.iter().map(|sample|(None, sample)))
{
if y1 >= height {
break
impl<'a> Render<TuiOutput<'a>, Rect> for Sampler {
fn render (&self, to: &mut TuiOutput<'a>) -> Usually<Rect> {
let Rect { x, y, height, .. } = area;
let style = Style::default().gray();
let title = format!(" {} ({})", self.name, self.voices.read().unwrap().len());
title.blit(buf, x+1, y, Some(style.white().bold().not_dim()))?;
let mut width = title.len() + 2;
let mut y1 = 1;
let mut j = 0;
for (note, sample) in self.mapped.iter()
.map(|(note, sample)|(Some(note), sample))
.chain(self.unmapped.iter().map(|sample|(None, sample)))
{
if y1 >= height {
break
}
let active = j == self.cursor.0;
width = width.max(draw_sample(buf, x, y + y1, note, &*sample.read().unwrap(), active)?);
y1 = y1 + 1;
j = j + 1;
}
let active = j == self.cursor.0;
width = width.max(draw_sample(buf, x, y + y1, note, &*sample.read().unwrap(), active)?);
y1 = y1 + 1;
j = j + 1;
let height = ((2 + y1) as u16).min(height);
Ok(Rect { x, y, width: (width as u16).min(area.width), height })
}
let height = ((2 + y1) as u16).min(height);
Ok(Rect { x, y, width: (width as u16).min(area.width), height })
});
}
fn draw_sample (
buf: &mut Buffer, x: u16, y: u16, note: Option<&u7>, sample: &Sample, focus: bool

View file

@ -1,35 +1,37 @@
use crate::*;
use tek_core::Direction;
render!(Track |self, buf, area| TrackView {
chain: Some(&self),
direction: tek_core::Direction::Right,
focused: true,
entered: true,
//pub channels: u8,
//pub input_ports: Vec<Port<AudioIn>>,
//pub pre_gain_meter: f64,
//pub gain: f64,
//pub insert_ports: Vec<Port<AudioOut>>,
//pub return_ports: Vec<Port<AudioIn>>,
//pub post_gain_meter: f64,
//pub post_insert_meter: f64,
//pub level: f64,
//pub pan: f64,
//pub output_ports: Vec<Port<AudioOut>>,
//pub post_fader_meter: f64,
//pub route: String,
}.render(buf, area));
impl<'a> Render<TuiOutput<'a>, Rect> for Track {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
TrackView {
chain: Some(&self),
direction: tek_core::Direction::Right,
focused: true,
entered: true,
//pub channels: u8,
//pub input_ports: Vec<Port<AudioIn>>,
//pub pre_gain_meter: f64,
//pub gain: f64,
//pub insert_ports: Vec<Port<AudioOut>>,
//pub return_ports: Vec<Port<AudioIn>>,
//pub post_gain_meter: f64,
//pub post_insert_meter: f64,
//pub level: f64,
//pub pan: f64,
//pub output_ports: Vec<Port<AudioOut>>,
//pub post_fader_meter: f64,
//pub route: String,
}.render(to)
}
}
pub struct TrackView<'a> {
pub chain: Option<&'a Track>,
pub direction: Direction,
pub focused: bool,
pub entered: bool,
}
impl<'a> Render for TrackView<'a> {
fn render (&self, buf: &mut Buffer, mut area: Rect) -> Usually<Rect> {
impl<'a> Render<TuiOutput<'a>, Rect> for TrackView<'a> {
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
if let Some(chain) = self.chain {
match self.direction {
Direction::Down => area.width = area.width.min(40),