This commit is contained in:
🪞👃🪞 2024-06-29 22:06:53 +03:00
parent 3886e34519
commit de2e2a2124
7 changed files with 119 additions and 65 deletions

View file

@ -70,8 +70,9 @@ pub fn render (state: &Chain, buf: &mut Buffer, area: Rect)
draw_box_styled(buf, area, selected)
},
ChainView::Row => {
draw_box_styled(buf, area, selected);
let (area, areas) = Row::draw(buf, area, &state.items, 0)?;
draw_box_styled(buf, area, selected)
area
},
ChainView::Column => {
draw_as_column(state, buf, area, selected)?
@ -124,7 +125,7 @@ pub fn draw_as_row (
x = x + 1;
let mut h = 0u16;
let mut frames = vec![];
for device in state.items.iter() {
for (i, device) in state.items.iter().enumerate() {
let mut x2 = 1u16;
let mut y2 = 1u16;
for port in device.midi_ins()?.iter() {
@ -138,7 +139,18 @@ pub fn draw_as_row (
y2 = y2 + 1;
}
let width = width.saturating_sub(x).saturating_sub(x2);
let style = Some(if i == state.focus {
if state.focused {
Style::default().green().not_dim()
} else {
Style::default().green().dim()
}
} else {
Style::default().dim()
});
lozenge_left(buf, x + x2, y, height, style);
let frame = device.render(buf, Rect { x: x + x2, y, width, height })?;
lozenge_right(buf, x + x2 + frame.width - 1, y, height, style);
let mut y2 = 1u16;
for port in device.midi_outs()?.iter() {
port.blit(buf, x + x2 + frame.width, y + y2, Some(Style::default()));

View file

@ -168,43 +168,34 @@ impl PortList for Plugin {
pub fn render (state: &Plugin, buf: &mut Buffer, area: Rect)
-> Usually<Rect>
{
let Rect { x, y, width, height } = area;
let height = height.saturating_sub(3);
let style = Style::default().gray();
let Rect { x, y, height, .. } = area;
let mut width = 40u16;
match &state.plugin {
Some(PluginKind::LV2 { portList, instance, .. }) => {
for i in 0..height - 4 {
Some(PluginKind::LV2 { portList, .. }) => {
//draw_box(buf, Rect { x, y, width, height });
for i in 0..height-3 {
if let Some(port) = portList.get(i as usize) {
let label = &format!("C·· M·· {:25} = {:03}", port.name, port.default_value);
width = width.max(label.len() as u16);
label.blit(buf, x + 2, y + 3 + i as u16, None);
label.blit(buf, x + 2, y + 2 + i as u16, None);
} else {
break
}
}
draw_box(buf, Rect { x, y, width, height });
},
_ => {
buf.set_string(x + 1, y + 3, &format!(" Parameter 1 0.0"), style);
buf.set_string(x + 1, y + 4, &format!(" Parameter 2 0.0"), style);
buf.set_string(x + 1, y + 5, &format!(" Parameter 3 0.0"), style);
buf.set_string(x + 1, y + 6, &format!(" Parameter 4 0.0"), style);
}
_ => {}
};
draw_header(state, buf, area.x, area.y, width);
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();
buf.set_string(x + 1, y + 1,
&format!(" {}", state.name), style.white().bold());
buf.set_string(x + 13, y + 1,
&format!("{}...", &HELM[..(w as usize - 20).min(HELM.len())]), style.not_dim());
buf.set_string(x + 0, y + 2,
&format!("{}", "-".repeat(w as usize - 2)), style.dim());
Ok(Rect { x, y, width: w, height: 3 })
let label1 = format!(" {}", state.name);
label1.blit(buf, x + 1, y, Some(style.white().bold()));
let label2 = format!("{}", &HELM[..(w as usize - 10).min(HELM.len())]);
label2.blit(buf, x + 2 + label1.len() as u16, y, Some(style.not_dim()));
Ok(Rect { x, y, width: w, height: 1 })
}
pub fn handle (s: &mut Plugin, event: &AppEvent) -> Usually<bool> {

View file

@ -127,7 +127,7 @@ pub fn render (state: &Sampler, buf: &mut Buffer, Rect { x, y, height, .. }: Rec
{
let width = 40;
let style = Style::default().gray();
format!(" {}", state.name).blit(buf, x+1, y, Some(style.white().bold()));
format!(" {} ", state.name).blit(buf, x+1, y, Some(style.white().bold().not_dim()));
for (i, (note, sample)) in state.samples.iter().enumerate() {
let style = if i == state.cursor.0 {
Style::default().green()
@ -200,7 +200,7 @@ pub fn handle (state: &mut Sampler, event: &AppEvent) -> Usually<bool> {
pub const KEYMAP: &'static [KeyBinding<Sampler>] = keymap!(Sampler {
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
[Enter, NONE, "enter", "activate", enter],
[Enter, NONE, "select", "select item under cursor", select],
});
fn cursor_up (state: &mut Sampler) -> Usually<bool> {
state.cursor.0 = if state.cursor.0 == 0 {
@ -214,6 +214,9 @@ fn cursor_down (state: &mut Sampler) -> Usually<bool> {
state.cursor.0 = (state.cursor.0 + 1) % state.samples.len();
Ok(true)
}
fn enter (state: &mut Sampler) -> Usually<bool> {
fn select (state: &mut Sampler) -> Usually<bool> {
if let Some(sample) = state.samples.get(&u7::from_int_lossy(state.cursor.0 as u8)) {
state.voices.push(sample.play())
}
Ok(true)
}

View file

@ -17,13 +17,13 @@ impl<'a> LauncherGridView<'a> {
//self.separator_h(2, false);
//self.separator_h((self.state.cursor.1 * 2) as u16, true);
//self.separator_h(((self.state.cursor.1 + 1) * 2) as u16, true);
draw_box_styled(self.buf, self.area, Some(
let style = Some(Style::default().green().dim());
if self.focused {
Style::default().green().dim()
} else {
Style::default().dim()
let Rect { x, y, width, height } = self.area;
lozenge_left(self.buf, x, y, height, style);
lozenge_right(self.buf, x + width - 1, y, height, style);
}
));
let columns = self.column_names();
let mut x = self.area.x;

View file

@ -55,10 +55,11 @@ impl Launcher {
name: name.into(),
view: LauncherView::Tracks,
playing: transport.query_state()?,
transport,
timebase: timebase.clone(),
monitoring: true,
recording: false,
overdub: true,
transport,
cursor: (0, 0),
position: 0,
scenes: scenes.unwrap_or_else(||vec![Scene::new(&"Scene 1", &[None])]),
@ -72,8 +73,7 @@ impl Launcher {
])))
]))?,
] },
timebase: timebase.clone(),
show_help: true
show_help: true,
}).activate(client)
}
fn cols (&self) -> usize {
@ -181,15 +181,13 @@ pub fn render (state: &Launcher, buf: &mut Buffer, mut area: Rect) -> Usually<Re
crate::device::sequencer::draw_dub(buf, x + 26, y, state.overdub);
draw_bpm(buf, x + 33, y, state.timebase.tempo());
draw_timer(buf, x + width - 1, y, &state.timebase, state.position);
//let separator = format!("├{}┤", "-".repeat((width - 2).into()));
//separator.blit(buf, x, y + 22, Some(Style::default().dim()));
//separator.blit(buf, x, y + 41, Some(Style::default().dim()));
let mut y = y + 1;
y = y + LauncherGridView::new(
state, buf, Rect { x, y, width, height: 8 }, state.view.is_tracks()
).draw()?.height;
y = y + draw_section_sequencer(state, buf, Rect { x, y, width, height: 8 })?.height;
y = y + draw_section_chains(state, buf, Rect { x, y, width, height: 8 })?.height;
area.height = y;
if state.show_help {
let style = Some(Style::default().bold().white().not_dim().on_black().italic());
let hide = "[Left Right] Track [Up Down] Scene [, .] Value [F1] Toggle help ";
@ -225,7 +223,8 @@ fn draw_section_sequencer (state: &Launcher, buf: &mut Buffer, area: Rect) -> Us
let view = &state.view;
match view {
LauncherView::Sequencer => {
draw_box_styled(buf, area, style);
lozenge_left(buf, x, y, height, style);
lozenge_right(buf, x + width - 1, y, height, style);
},
_ => {},
};
@ -236,9 +235,13 @@ fn draw_section_sequencer (state: &Launcher, buf: &mut Buffer, area: Rect) -> Us
let state = track.sequencer.state();
let zoom = state.resolution;
let step = state.phrase().map(|_|tick / zoom);
let steps = if let Some(_phrase) = state.phrase() {
0
} else {
0
} / 4;
crate::device::sequencer::horizontal::timer(buf, x+5, y,
step.unwrap_or(0) / 4,
steps,
state.steps * zoom,
state.time_axis.0,
state.time_axis.1
@ -279,6 +282,14 @@ fn draw_highlight (buf: &mut Buffer, highlight: &Option<Rect>, style: Style) {
}
fn draw_section_chains (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
let style = Some(Style::default().green().dim());
match state.view {
LauncherView::Chains => {
let Rect { x, y, width, height} = area;
lozenge_left(buf, x, y, height, style);
lozenge_right(buf, x + width - 1, y, height, style);
},
_ => {},
};
let chain = state.active_chain();
let plugins = if let Some(chain) = &chain {
let (_, plugins) = crate::device::chain::draw_as_row(
@ -294,17 +305,17 @@ fn draw_section_chains (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usual
//},
//_ => {},
//};
draw_highlight(buf, &Some(area), match state.view {
LauncherView::Chains => Style::default().green().dim(),
_ => Style::default().dim()
});
if let Some(chain) = &chain {
if let Some(plugin) = plugins.get(chain.focus) {
draw_highlight(buf, &Some(*plugin), match state.view {
LauncherView::Chains => Style::default().green().not_dim(),
_ => Style::default().green().dim()
});
}
}
//draw_highlight(buf, &Some(area), match state.view {
//LauncherView::Chains => Style::default().green().dim(),
//_ => Style::default().dim()
//});
//if let Some(chain) = &chain {
//if let Some(plugin) = plugins.get(chain.focus) {
//draw_highlight(buf, &Some(*plugin), match state.view {
//LauncherView::Chains => Style::default().green().not_dim(),
//_ => Style::default().green().dim()
//});
//}
//}
Ok(area)
}

35
src/layout/lozenge.rs Normal file
View file

@ -0,0 +1,35 @@
use crate::prelude::*;
const LOZENGE: [[&'static str;3];3] = [
["", "", ""],
["", " ", ""],
["", "", ""],
];
pub fn lozenge_left (buf: &mut Buffer, x: u16, y1: u16, h: u16, style: Option<Style>) {
let y2 = y1 + h;
let y3 = y2.saturating_sub(1);
for y in y1..y2 {
if y == y1 {
LOZENGE[0][0]
} else if y == y3 {
LOZENGE[2][0]
} else {
LOZENGE[1][0]
}.blit(buf, x, y, style)
}
}
pub fn lozenge_right (buf: &mut Buffer, x: u16, y1: u16, h: u16, style: Option<Style>) {
let y2 = y1 + h;
let y3 = y2.saturating_sub(1);
for y in y1..y2 {
if y == y1 {
LOZENGE[0][2]
} else if y == y3 {
LOZENGE[2][2]
} else {
LOZENGE[1][2]
}.blit(buf, x, y, style)
}
}

View file

@ -6,6 +6,8 @@ mod scroll;
pub use scroll::*;
mod table;
pub use table::*;
mod lozenge;
pub use lozenge::*;
use crate::prelude::*;