mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: unified app: still curiously empty
This commit is contained in:
parent
2cd56e7391
commit
f1bd9e7e88
1 changed files with 118 additions and 2 deletions
120
tek/src/app.rs
120
tek/src/app.rs
|
|
@ -103,7 +103,7 @@ impl EdnViewData<TuiOut> for &App {
|
||||||
Sym(":pool") => self.pool().boxed(),
|
Sym(":pool") => self.pool().boxed(),
|
||||||
Sym(":sample") => self.sample().boxed(),
|
Sym(":sample") => self.sample().boxed(),
|
||||||
Sym(":sampler") => self.sampler().boxed(),
|
Sym(":sampler") => self.sampler().boxed(),
|
||||||
Sym(":scenes") => self.scene_row(w).boxed(),
|
Sym(":scenes") => self.scene_row(w, self.size.h().saturating_sub(9) as u16).boxed(),
|
||||||
Sym(":status") => self.status(0).boxed(),
|
Sym(":status") => self.status(0).boxed(),
|
||||||
Sym(":toolbar") => self.toolbar().boxed(),
|
Sym(":toolbar") => self.toolbar().boxed(),
|
||||||
Sym(":tracks") => self.track_row(w, 3).boxed(),
|
Sym(":tracks") => self.track_row(w, 3).boxed(),
|
||||||
|
|
@ -180,7 +180,9 @@ impl App {
|
||||||
fn output_row (&self, w: u16, h: u16) -> impl Content<TuiOut> + '_ {
|
fn output_row (&self, w: u16, h: u16) -> impl Content<TuiOut> + '_ {
|
||||||
self.row(w, h, output_header(&self), output_cells(&self))
|
self.row(w, h, output_header(&self), output_cells(&self))
|
||||||
}
|
}
|
||||||
fn scene_row (&self, w: u16) -> impl Content<TuiOut> + '_ { "" }
|
fn scene_row (&self, w: u16, h: u16) -> impl Content<TuiOut> + '_ {
|
||||||
|
self.row(w, h, output_header(&self), output_cells(&self))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tracks_with_sizes (&self)
|
pub fn tracks_with_sizes (&self)
|
||||||
-> impl Iterator<Item = (usize, &ArrangerTrack, usize, usize)>
|
-> impl Iterator<Item = (usize, &ArrangerTrack, usize, usize)>
|
||||||
|
|
@ -191,6 +193,11 @@ impl App {
|
||||||
_ => None
|
_ => None
|
||||||
}, self.editor_w())
|
}, self.editor_w())
|
||||||
}
|
}
|
||||||
|
pub fn scenes_with_sizes (&self, h: usize)
|
||||||
|
-> impl Iterator<Item = (usize, &ArrangerScene, usize, usize)>
|
||||||
|
{
|
||||||
|
scenes_with_sizes(self.scenes.iter(), &self.selected, self.is_editing(), 2, 15)
|
||||||
|
}
|
||||||
fn is_editing (&self) -> bool {
|
fn is_editing (&self) -> bool {
|
||||||
self.editing.load(Relaxed)
|
self.editing.load(Relaxed)
|
||||||
}
|
}
|
||||||
|
|
@ -207,6 +214,26 @@ impl App {
|
||||||
w
|
w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn scenes_with_sizes <'a>(
|
||||||
|
scenes: impl Iterator<Item=&'a ArrangerScene> + 'a,
|
||||||
|
selected: &'a ArrangerSelection,
|
||||||
|
editing: bool,
|
||||||
|
scene_height: usize,
|
||||||
|
scene_larger: usize,
|
||||||
|
) -> impl Iterator<Item = (usize, &'a ArrangerScene, usize, usize)> + 'a {
|
||||||
|
let mut y = 0;
|
||||||
|
let (selected_track, selected_scene) = match selected {
|
||||||
|
ArrangerSelection::Clip(t, s) => (Some(t), Some(s)),
|
||||||
|
_ => (None, None)
|
||||||
|
};
|
||||||
|
scenes.enumerate().map(move|(s, scene)|{
|
||||||
|
let active = editing && selected_track.is_some() && selected_scene == Some(&s);
|
||||||
|
let height = if active { scene_larger } else { scene_height };
|
||||||
|
let data = (s, scene, y, y + height);
|
||||||
|
y += height;
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
pub fn tracks_with_sizes <'a> (
|
pub fn tracks_with_sizes <'a> (
|
||||||
tracks: impl Iterator<Item=&'a ArrangerTrack>,
|
tracks: impl Iterator<Item=&'a ArrangerTrack>,
|
||||||
active: Option<usize>,
|
active: Option<usize>,
|
||||||
|
|
@ -310,3 +337,92 @@ fn mute_solo (bg: Color, mute: bool, solo: bool) -> impl Content<TuiOut> {
|
||||||
fn cell <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
fn cell <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Fixed::y(1, field))
|
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Fixed::y(1, field))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn scene_headers <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
|
||||||
|
(||{
|
||||||
|
let last_color = Arc::new(RwLock::new(ItemPalette::from(Color::Rgb(0, 0, 0))));
|
||||||
|
let selected = state.selected.scene();
|
||||||
|
Fill::y(Align::c(Map::new(||state.scenes_with_sizes(2), move|(_, scene, y1, y2), i| {
|
||||||
|
let h = (y2 - y1) as u16;
|
||||||
|
let name = format!("🭬{}", &scene.name);
|
||||||
|
let color = scene.color();
|
||||||
|
let active = selected == Some(i);
|
||||||
|
let mid = if active { color.light } else { color.base };
|
||||||
|
let top = Some(last_color.read().unwrap().base.rgb);
|
||||||
|
let cell = phat_sel_3(
|
||||||
|
active,
|
||||||
|
Tui::bold(true, name.clone()),
|
||||||
|
Tui::bold(true, name),
|
||||||
|
top,
|
||||||
|
mid.rgb,
|
||||||
|
Color::Rgb(0, 0, 0)
|
||||||
|
);
|
||||||
|
*last_color.write().unwrap() = color;
|
||||||
|
map_south(y1 as u16, h + 1, Fixed::y(h + 1, cell))
|
||||||
|
}))).boxed()
|
||||||
|
}).into()
|
||||||
|
}
|
||||||
|
fn scene_cells <'a> (state: &'a App) -> BoxThunk<'a, TuiOut> {
|
||||||
|
let editing = state.is_editing();
|
||||||
|
let tracks = move||state.tracks_with_sizes();
|
||||||
|
let scenes = ||state.scenes_with_sizes(2);
|
||||||
|
let selected_track = state.selected.track();
|
||||||
|
let selected_scene = state.selected.scene();
|
||||||
|
(move||Fill::y(Align::c(Map::new(tracks, move|(_, track, x1, x2), t| {
|
||||||
|
let w = (x2 - x1) as u16;
|
||||||
|
let color: ItemPalette = track.color().dark.into();
|
||||||
|
let last_color = Arc::new(RwLock::new(ItemPalette::from(Color::Rgb(0, 0, 0))));
|
||||||
|
let cells = Map::new(scenes, move|(_, scene, y1, y2), s| {
|
||||||
|
let h = (y2 - y1) as u16;
|
||||||
|
let color = scene.color();
|
||||||
|
let (name, fg, bg) = if let Some(c) = &scene.clips[t] {
|
||||||
|
let c = c.read().unwrap();
|
||||||
|
(c.name.to_string(), c.color.lightest.rgb, c.color.base.rgb)
|
||||||
|
} else {
|
||||||
|
("⏹ ".to_string(), TuiTheme::g(64), TuiTheme::g(32))
|
||||||
|
};
|
||||||
|
let last = last_color.read().unwrap().clone();
|
||||||
|
let active = editing && selected_scene == Some(s) && selected_track == Some(t);
|
||||||
|
let editor = Thunk::new(||&state.editor);
|
||||||
|
let cell = Thunk::new(move||phat_sel_3(
|
||||||
|
selected_track == Some(t) && selected_scene == Some(s),
|
||||||
|
Tui::fg(fg, Push::x(1, Tui::bold(true, name.to_string()))),
|
||||||
|
Tui::fg(fg, Push::x(1, Tui::bold(true, name.to_string()))),
|
||||||
|
if selected_track == Some(t) && selected_scene.map(|s|s+1) == Some(s) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(bg.into())
|
||||||
|
},
|
||||||
|
bg.into(),
|
||||||
|
bg.into(),
|
||||||
|
));
|
||||||
|
let cell = Either(active, editor, cell);
|
||||||
|
*last_color.write().unwrap() = bg.into();
|
||||||
|
map_south(
|
||||||
|
y1 as u16,
|
||||||
|
h + 1,
|
||||||
|
Fill::x(Fixed::y(h + 1, cell))
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let column = Fixed::x(w, Tui::bg(Color::Reset, Align::y(cells)).boxed());
|
||||||
|
Fixed::x(w, map_east(x1 as u16, w, column))
|
||||||
|
}))).boxed()).into()
|
||||||
|
}
|
||||||
|
fn cell_clip <'a> (
|
||||||
|
scene: &'a ArrangerScene, index: usize, track: &'a ArrangerTrack, w: u16, h: u16
|
||||||
|
) -> impl Content<TuiOut> + use<'a> {
|
||||||
|
scene.clips.get(index).map(|clip|clip.as_ref().map(|clip|{
|
||||||
|
let clip = clip.read().unwrap();
|
||||||
|
let mut bg = TuiTheme::border_bg();
|
||||||
|
let name = clip.name.to_string();
|
||||||
|
let max_w = name.len().min((w as usize).saturating_sub(2));
|
||||||
|
let color = clip.color;
|
||||||
|
bg = color.dark.rgb;
|
||||||
|
if let Some((_, Some(ref playing))) = track.player.play_clip() {
|
||||||
|
if *playing.read().unwrap() == *clip {
|
||||||
|
bg = color.light.rgb
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Fixed::xy(w, h, &Tui::bg(bg, Push::x(1, Fixed::x(w, &name.as_str()[0..max_w]))));
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue