mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
lozenges
This commit is contained in:
parent
3886e34519
commit
de2e2a2124
7 changed files with 119 additions and 65 deletions
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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 style = Style::default().gray();
|
||||
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> {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ impl Sampler {
|
|||
samples: samples.unwrap_or(BTreeMap::new()),
|
||||
voices: vec![],
|
||||
midi_in: client.register_port("midi", ::jack::MidiIn::default())?,
|
||||
audio_ins: vec![
|
||||
audio_ins: vec![
|
||||
client.register_port("recL", ::jack::AudioIn::default())?,
|
||||
client.register_port("recR", ::jack::AudioIn::default())?,
|
||||
],
|
||||
|
|
@ -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()
|
||||
|
|
@ -198,9 +198,9 @@ pub fn handle (state: &mut Sampler, event: &AppEvent) -> Usually<bool> {
|
|||
Ok(handle_keymap(state, event, KEYMAP)?)
|
||||
}
|
||||
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],
|
||||
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
||||
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
||||
[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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
if self.focused {
|
||||
Style::default().green().dim()
|
||||
} else {
|
||||
Style::default().dim()
|
||||
}
|
||||
));
|
||||
let style = Some(Style::default().green().dim());
|
||||
if self.focused {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -52,15 +52,16 @@ impl Launcher {
|
|||
let transport = client.transport();
|
||||
let ppq = timebase.ppq() as u32;
|
||||
DynamicDevice::new(render, handle, process, Self {
|
||||
name: name.into(),
|
||||
view: LauncherView::Tracks,
|
||||
playing: transport.query_state()?,
|
||||
monitoring: true,
|
||||
recording: false,
|
||||
overdub: true,
|
||||
name: name.into(),
|
||||
view: LauncherView::Tracks,
|
||||
playing: transport.query_state()?,
|
||||
transport,
|
||||
cursor: (0, 0),
|
||||
position: 0,
|
||||
timebase: timebase.clone(),
|
||||
monitoring: true,
|
||||
recording: false,
|
||||
overdub: true,
|
||||
cursor: (0, 0),
|
||||
position: 0,
|
||||
scenes: scenes.unwrap_or_else(||vec![Scene::new(&"Scene 1", &[None])]),
|
||||
tracks: if let Some(tracks) = tracks { tracks } else { vec![
|
||||
Track::new("Track 1", &timebase, None, Some(vec![
|
||||
|
|
@ -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
35
src/layout/lozenge.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ mod scroll;
|
|||
pub use scroll::*;
|
||||
mod table;
|
||||
pub use table::*;
|
||||
mod lozenge;
|
||||
pub use lozenge::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue