mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 04:36:45 +01:00
wip: <200 errors yay
This commit is contained in:
parent
14d619a10a
commit
694970bf0d
20 changed files with 384 additions and 305 deletions
|
|
@ -5,6 +5,7 @@ version = "0.1.0"
|
|||
|
||||
[dependencies]
|
||||
tek_core = { path = "../tek_core" }
|
||||
tek_proc = { path = "../tek_proc" }
|
||||
|
||||
livi = "0.7.4"
|
||||
suil-rs = { path = "../suil" }
|
||||
|
|
@ -31,4 +32,4 @@ path = "src/sampler_main.rs"
|
|||
|
||||
[[bin]]
|
||||
name = "tek_plugin"
|
||||
path = "src/plugin_main.rs"
|
||||
path = "src/sampler_main.rs"
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@ submod! {
|
|||
sample_add
|
||||
sampler
|
||||
sampler_edn
|
||||
sampler_view
|
||||
voice
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Mixer<E> {
|
||||
pub struct Mixer<E: Engine> {
|
||||
pub name: String,
|
||||
pub tracks: Vec<Track<E>>,
|
||||
pub selected_track: usize,
|
||||
pub selected_column: usize,
|
||||
}
|
||||
impl<E> Mixer<E> {
|
||||
impl<E: Engine> Mixer<E> {
|
||||
pub fn new (name: &str) -> Usually<Self> {
|
||||
let (client, _status) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
||||
Ok(Self {
|
||||
|
|
@ -25,7 +25,7 @@ impl<E> Mixer<E> {
|
|||
self.tracks.get(self.selected_track)
|
||||
}
|
||||
}
|
||||
impl<E> Process for Mixer<E> {
|
||||
impl<E: Engine> Process for Mixer<E> {
|
||||
fn process (&mut self, _: &Client, _: &ProcessScope) -> Control {
|
||||
Control::Continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,21 +22,20 @@ pub struct AddSampleModal {
|
|||
|
||||
exit!(AddSampleModal);
|
||||
|
||||
impl<'a> Render<TuiOutput<'a>, Rect> for AddSampleModal {
|
||||
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
make_dim(to.buffer);
|
||||
impl Render<Tui> for AddSampleModal {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
let area = to.area();
|
||||
to.make_dim();
|
||||
let area = center_box(
|
||||
to.area,
|
||||
64.max(to.area.width.saturating_sub(8)),
|
||||
20.max(to.area.width.saturating_sub(8)),
|
||||
area,
|
||||
64.max(area.width.saturating_sub(8)),
|
||||
20.max(area.width.saturating_sub(8)),
|
||||
);
|
||||
fill_fg(to.buffer, area, Color::Reset);
|
||||
fill_bg(to.buffer, area, Nord::bg_lo(true, true));
|
||||
fill_char(to.buffer, area, ' ');
|
||||
format!("{}", &self.dir.to_string_lossy())
|
||||
.blit(to.buffer, area.x+2, area.y+1, Some(Style::default().bold()))?;
|
||||
"Select sample:"
|
||||
.blit(to.buffer, area.x+2, area.y+2, Some(Style::default().bold()))?;
|
||||
to.fill_fg(area, Color::Reset);
|
||||
to.fill_bg(area, Nord::bg_lo(true, true));
|
||||
to.fill_char(area, ' ');
|
||||
to.blit(&format!("{}", &self.dir.to_string_lossy()), area.x+2, area.y+1, Some(Style::default().bold()))?;
|
||||
to.blit(&"Select sample:", 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)))
|
||||
|
|
@ -49,7 +48,7 @@ impl<'a> Render<TuiOutput<'a>, Rect> for AddSampleModal {
|
|||
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(to.buffer, area.x + 2, area.y + 3 + i as u16, Some(if i == self.cursor {
|
||||
to.blit(&line, area.x + 2, area.y + 3 + i as u16, Some(if i == self.cursor {
|
||||
Style::default().green()
|
||||
} else {
|
||||
Style::default().white()
|
||||
|
|
@ -58,13 +57,14 @@ impl<'a> Render<TuiOutput<'a>, Rect> for AddSampleModal {
|
|||
Lozenge(Style::default()).draw(to)
|
||||
}
|
||||
}
|
||||
|
||||
handle!(AddSampleModal |self,e|{
|
||||
if handle_keymap(self, e, KEYMAP_ADD_SAMPLE)? {
|
||||
return Ok(true)
|
||||
impl Handle<Tui> for AddSampleModal {
|
||||
fn handle (&mut self, e: &Tui) -> Usually<bool> {
|
||||
if handle_keymap(self, e, KEYMAP_ADD_SAMPLE)? {
|
||||
return Ok(true)
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
Ok(true)
|
||||
});
|
||||
}
|
||||
|
||||
impl AddSampleModal {
|
||||
pub fn new (
|
||||
|
|
|
|||
|
|
@ -13,56 +13,20 @@ pub struct Sampler {
|
|||
pub modal: Arc<Mutex<Option<Box<dyn Exit + Send>>>>,
|
||||
pub output_gain: f32
|
||||
}
|
||||
impl<E: Engine> Handle<E> for Sampler {
|
||||
fn handle (&mut self, e: &E) -> Usually<E::Handled> {
|
||||
handle_keymap(self, event, KEYMAP_SAMPLER)
|
||||
}
|
||||
}
|
||||
impl Render<Tui> for Sampler {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
tui_render_sampler(self, to)
|
||||
}
|
||||
}
|
||||
|
||||
process!(Sampler = Sampler::process);
|
||||
|
||||
handle!(Sampler |self, event| handle_keymap(self, event, KEYMAP_SAMPLER));
|
||||
|
||||
impl Render<Tui> for Sampler {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
let Rect { x, y, height, .. } = to.area();
|
||||
let style = Style::default().gray();
|
||||
let title = format!(" {} ({})", self.name, self.voices.read().unwrap().len());
|
||||
title.blit(to.buffer(), 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(to.buffer(), x, y + y1, note, &*sample.read().unwrap(), active)?
|
||||
);
|
||||
y1 = y1 + 1;
|
||||
j = j + 1;
|
||||
}
|
||||
let height = ((2 + y1) as u16).min(height);
|
||||
Ok(Some(Rect { x, y, width: (width as u16).min(to.area().width), height }))
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_sample (
|
||||
buf: &mut Buffer, x: u16, y: u16, note: Option<&u7>, sample: &Sample, focus: bool
|
||||
) -> Usually<usize> {
|
||||
let style = if focus { Style::default().green() } else { Style::default() };
|
||||
if focus {
|
||||
"🬴".blit(buf, x+1, y, Some(style.bold()))?;
|
||||
}
|
||||
let label1 = format!("{:3} {:12}",
|
||||
note.map(|n|n.to_string()).unwrap_or(String::default()),
|
||||
sample.name);
|
||||
let label2 = format!("{:>6} {:>6} +0.0",
|
||||
sample.start,
|
||||
sample.end);
|
||||
label1.blit(buf, x+2, y, Some(style.bold()))?;
|
||||
label2.blit(buf, x+3+label1.len()as u16, y, Some(style))?;
|
||||
Ok(label1.len() + label2.len() + 4)
|
||||
}
|
||||
|
||||
/// Key bindings for sampler device.
|
||||
pub const KEYMAP_SAMPLER: &'static [KeyBinding<Sampler>] = keymap!(Sampler {
|
||||
|
|
@ -105,7 +69,7 @@ pub const KEYMAP_SAMPLER: &'static [KeyBinding<Sampler>] = keymap!(Sampler {
|
|||
});
|
||||
|
||||
impl Sampler {
|
||||
pub fn from_edn <'e, E> (args: &[Edn<'e>]) -> Usually<JackDevice<E>> {
|
||||
pub fn from_edn <'e, E: Engine> (args: &[Edn<'e>]) -> Usually<JackDevice<E>> {
|
||||
let mut name = String::new();
|
||||
let mut dir = String::new();
|
||||
let mut samples = BTreeMap::new();
|
||||
|
|
@ -134,7 +98,7 @@ impl Sampler {
|
|||
Self::new(&name, Some(samples))
|
||||
}
|
||||
|
||||
pub fn new <E> (
|
||||
pub fn new <E: Engine> (
|
||||
name: &str, mapped: Option<BTreeMap<u7, Arc<RwLock<Sample>>>>
|
||||
) -> Usually<JackDevice<E>> {
|
||||
Jack::new(name)?
|
||||
|
|
|
|||
45
crates/tek_mixer/src/sampler_view.rs
Normal file
45
crates/tek_mixer/src/sampler_view.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
use crate::*;
|
||||
|
||||
pub fn tui_render_sampler (sampler: &Sampler, to: &mut Tui) -> Perhaps<Rect> {
|
||||
let Rect { x, y, height, .. } = to.area();
|
||||
let style = Style::default().gray();
|
||||
let title = format!(" {} ({})", sampler.name, sampler.voices.read().unwrap().len());
|
||||
to.blit(&title, 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 sampler.mapped.iter()
|
||||
.map(|(note, sample)|(Some(note), sample))
|
||||
.chain(sampler.unmapped.iter().map(|sample|(None, sample)))
|
||||
{
|
||||
if y1 >= height {
|
||||
break
|
||||
}
|
||||
let active = j == sampler.cursor.0;
|
||||
width = width.max(
|
||||
draw_sample(to, x, y + y1, note, &*sample.read().unwrap(), active)?
|
||||
);
|
||||
y1 = y1 + 1;
|
||||
j = j + 1;
|
||||
}
|
||||
let height = ((2 + y1) as u16).min(height);
|
||||
Ok(Some(Rect { x, y, width: (width as u16).min(to.area().width), height }))
|
||||
}
|
||||
|
||||
fn draw_sample (
|
||||
to: &mut Tui, x: u16, y: u16, note: Option<&u7>, sample: &Sample, focus: bool
|
||||
) -> Usually<usize> {
|
||||
let style = if focus { Style::default().green() } else { Style::default() };
|
||||
if focus {
|
||||
to.blit(&"🬴", x+1, y, Some(style.bold()))?;
|
||||
}
|
||||
let label1 = format!("{:3} {:12}",
|
||||
note.map(|n|n.to_string()).unwrap_or(String::default()),
|
||||
sample.name);
|
||||
let label2 = format!("{:>6} {:>6} +0.0",
|
||||
sample.start,
|
||||
sample.end);
|
||||
to.blit(&label1, x+2, y, Some(style.bold()))?;
|
||||
to.blit(&label2, x+3+label1.len()as u16, y, Some(style))?;
|
||||
Ok(label1.len() + label2.len() + 4)
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::*;
|
||||
use tek_core::Direction;
|
||||
|
||||
impl<'a> Render<Tui> for Track<Tui> {
|
||||
fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
|
||||
impl Render<Tui> for Track<Tui> {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
TrackView {
|
||||
chain: Some(&self),
|
||||
direction: tek_core::Direction::Right,
|
||||
|
|
@ -24,8 +24,8 @@ impl<'a> Render<Tui> for Track<Tui> {
|
|||
}.render(to)
|
||||
}
|
||||
}
|
||||
pub struct TrackView<'a, T, U> {
|
||||
pub chain: Option<&'a Track<T, U>>,
|
||||
pub struct TrackView<'a, E: Engine> {
|
||||
pub chain: Option<&'a Track<E>>,
|
||||
pub direction: Direction,
|
||||
pub focused: bool,
|
||||
pub entered: bool,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue