mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
starting to look very much like something
This commit is contained in:
parent
f1f5ac63e1
commit
29b2789be6
7 changed files with 94 additions and 51 deletions
|
|
@ -49,6 +49,9 @@ impl HasSceneScroll for App {
|
||||||
fn scene_scroll (&self) -> usize { self.project.scene_scroll() }
|
fn scene_scroll (&self) -> usize { self.project.scene_scroll() }
|
||||||
}
|
}
|
||||||
has_clips!(|self: App|self.pool.clips);
|
has_clips!(|self: App|self.pool.clips);
|
||||||
|
impl HasClipsSize for App {
|
||||||
|
fn clips_size (&self) -> &Measure<TuiOut> { &self.project.inner_size }
|
||||||
|
}
|
||||||
//has_editor!(|self: App|{
|
//has_editor!(|self: App|{
|
||||||
//editor = self.editor;
|
//editor = self.editor;
|
||||||
//editor_w = {
|
//editor_w = {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ pub struct Arrangement {
|
||||||
pub arranger: Arc<RwLock<Buffer>>,
|
pub arranger: Arc<RwLock<Buffer>>,
|
||||||
/// Display size
|
/// Display size
|
||||||
pub size: Measure<TuiOut>,
|
pub size: Measure<TuiOut>,
|
||||||
|
/// Display size of clips area
|
||||||
|
pub inner_size: Measure<TuiOut>,
|
||||||
}
|
}
|
||||||
|
|
||||||
has!(Jack: |self: Arrangement|self.jack);
|
has!(Jack: |self: Arrangement|self.jack);
|
||||||
|
|
|
||||||
|
|
@ -9,23 +9,6 @@ pub trait HasScenes: Has<Vec<Scene>> + Send + Sync {
|
||||||
fn scenes_mut (&mut self) -> &mut Vec<Scene> {
|
fn scenes_mut (&mut self) -> &mut Vec<Scene> {
|
||||||
Has::<Vec<Scene>>::get_mut(self)
|
Has::<Vec<Scene>>::get_mut(self)
|
||||||
}
|
}
|
||||||
fn scenes_with_sizes (
|
|
||||||
&self,
|
|
||||||
editing: bool,
|
|
||||||
height: usize,
|
|
||||||
larger: usize,
|
|
||||||
selected_track: Option<usize>,
|
|
||||||
selected_scene: Option<usize>,
|
|
||||||
) -> impl ScenesSizes<'_> {
|
|
||||||
let mut y = 0;
|
|
||||||
self.scenes().iter().enumerate().map(move|(s, scene)|{
|
|
||||||
let active = editing && selected_track.is_some() && selected_scene == Some(s);
|
|
||||||
let height = if active { larger } else { height };
|
|
||||||
let data = (s, scene, y, y + height);
|
|
||||||
y += height;
|
|
||||||
data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// Generate the default name for a new scene
|
/// Generate the default name for a new scene
|
||||||
fn scene_default_name (&self) -> Arc<str> {
|
fn scene_default_name (&self) -> Arc<str> {
|
||||||
format!("s{:3>}", self.scenes().len() + 1).into()
|
format!("s{:3>}", self.scenes().len() + 1).into()
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,25 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
impl<T> TracksView for T
|
pub trait HasClipsSize {
|
||||||
where T: ScenesView + HasMidiIns + HasMidiOuts + HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiIns + HasEditor {}
|
fn clips_size (&self) -> &Measure<TuiOut>;
|
||||||
|
}
|
||||||
|
impl HasClipsSize for Arrangement {
|
||||||
|
fn clips_size (&self) -> &Measure<TuiOut> { &self.inner_size }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TracksView for Arrangement {}
|
||||||
|
|
||||||
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
|
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
|
||||||
|
|
||||||
pub trait TracksView:
|
pub trait TracksView:
|
||||||
ScenesView + HasMidiIns + HasMidiOuts + HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiIns + HasEditor
|
ScenesView +
|
||||||
|
HasMidiIns +
|
||||||
|
HasMidiOuts +
|
||||||
|
HasSize<TuiOut> +
|
||||||
|
HasTrackScroll +
|
||||||
|
HasSelection +
|
||||||
|
HasEditor +
|
||||||
|
HasClipsSize
|
||||||
{
|
{
|
||||||
fn tracks_width_available (&self) -> u16 {
|
fn tracks_width_available (&self) -> u16 {
|
||||||
(self.width() as u16).saturating_sub(40)
|
(self.width() as u16).saturating_sub(40)
|
||||||
|
|
@ -16,11 +29,15 @@ pub trait TracksView:
|
||||||
let editor_width = self.editor().map(|e|e.width());
|
let editor_width = self.editor().map(|e|e.width());
|
||||||
let active_track = self.selection().track();
|
let active_track = self.selection().track();
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
self.tracks().iter().enumerate().map(move |(index, track)|{
|
self.tracks().iter().enumerate().map_while(move |(index, track)|{
|
||||||
|
if x < self.clips_size().w() {
|
||||||
let width = active_track.and_then(|_|editor_width).unwrap_or(track.width.max(8));
|
let width = active_track.and_then(|_|editor_width).unwrap_or(track.width.max(8));
|
||||||
let data = (index, track, x, x + width);
|
let data = (index, track, x, x + width);
|
||||||
x += width + Self::TRACK_SPACING;
|
x += width + Self::TRACK_SPACING;
|
||||||
data
|
Some(data)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn tracks_with_sizes_scrolled <'t> (&'t self) -> impl TracksSizes<'t> {
|
fn tracks_with_sizes_scrolled <'t> (&'t self) -> impl TracksSizes<'t> {
|
||||||
|
|
@ -130,7 +147,11 @@ pub trait TracksView:
|
||||||
add(&Fixed::xy(self.track_width(index, track), h + 1,
|
add(&Fixed::xy(self.track_width(index, track), h + 1,
|
||||||
Align::nw(Bsp::s(
|
Align::nw(Bsp::s(
|
||||||
Tui::bg(track.color.base.rgb,
|
Tui::bg(track.color.base.rgb,
|
||||||
Fill::x(Align::w(format!("·mon ·rec ·dub")))),
|
Fill::x(Align::w(row!(
|
||||||
|
Either(track.sequencer.monitoring, Tui::fg(Green, "●mon "), "·mon "),
|
||||||
|
Either(track.sequencer.recording, Tui::fg(Red, "●rec "), "·rec "),
|
||||||
|
Either(track.sequencer.overdub, Tui::fg(Yellow, "●dub "), "·dub "),
|
||||||
|
)))),
|
||||||
Map::south(1, ||track.sequencer.midi_ins.iter(),
|
Map::south(1, ||track.sequencer.midi_ins.iter(),
|
||||||
|port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb,
|
|port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb,
|
||||||
Fill::x(Align::w(format!("·i{index:02} {}", port.name())))))))));
|
Fill::x(Align::w(format!("·i{index:02} {}", port.name())))))))));
|
||||||
|
|
@ -147,7 +168,14 @@ pub trait TracksView:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
pub trait ScenesView:
|
||||||
|
HasEditor +
|
||||||
|
HasSelection +
|
||||||
|
HasSceneScroll +
|
||||||
|
HasClipsSize +
|
||||||
|
Send +
|
||||||
|
Sync
|
||||||
|
{
|
||||||
/// Default scene height.
|
/// Default scene height.
|
||||||
const H_SCENE: usize = 2;
|
const H_SCENE: usize = 2;
|
||||||
/// Default editor height.
|
/// Default editor height.
|
||||||
|
|
@ -155,9 +183,28 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
||||||
fn h_scenes (&self) -> u16;
|
fn h_scenes (&self) -> u16;
|
||||||
fn w_side (&self) -> u16;
|
fn w_side (&self) -> u16;
|
||||||
fn w_mid (&self) -> u16;
|
fn w_mid (&self) -> u16;
|
||||||
|
fn scenes_with_sizes (&self) -> impl ScenesSizes<'_> {
|
||||||
|
let editing = self.editor().is_some();
|
||||||
|
let height = Self::H_SCENE;
|
||||||
|
let larger = self.editor().map(|e|e.height()).unwrap_or(Self::H_SCENE);
|
||||||
|
let selected_track = self.selection().track();
|
||||||
|
let selected_scene = self.selection().scene();
|
||||||
|
let mut y = 0;
|
||||||
|
self.scenes().iter().enumerate().skip(self.scene_scroll()).map_while(move|(s, scene)|{
|
||||||
|
if y < self.clips_size().h() {
|
||||||
|
let active = editing && selected_track.is_some() && selected_scene == Some(s);
|
||||||
|
let height = if active { larger } else { height };
|
||||||
|
let data = (s, scene, y, y + height);
|
||||||
|
y += height;
|
||||||
|
Some(data)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
fn view_scenes_names (&self) -> impl Content<TuiOut> {
|
fn view_scenes_names (&self) -> impl Content<TuiOut> {
|
||||||
Stack::south(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
Stack::south(move|add: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||||
for (index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) {
|
for (index, scene, ..) in self.scenes_with_sizes() {
|
||||||
add(&self.view_scene_name(index, scene));
|
add(&self.view_scene_name(index, scene));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -185,11 +232,19 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ClipsView: TracksView + ScenesView + Send + Sync {
|
pub trait ClipsView:
|
||||||
|
TracksView +
|
||||||
|
ScenesView +
|
||||||
|
HasClipsSize +
|
||||||
|
Send +
|
||||||
|
Sync
|
||||||
|
{
|
||||||
fn view_scenes_clips <'a> (&'a self)
|
fn view_scenes_clips <'a> (&'a self)
|
||||||
-> impl Content<TuiOut> + 'a
|
-> impl Content<TuiOut> + 'a
|
||||||
{
|
{
|
||||||
Fill::xy(Stack::<TuiOut, _>::east(move|column: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
self.clips_size().of(Fill::xy(Bsp::a(
|
||||||
|
Fill::xy(Align::se(Tui::fg(Green, format!("{}x{}", self.clips_size().w(), self.clips_size().h())))),
|
||||||
|
Stack::<TuiOut, _>::east(move|column: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||||
for (track_index, track, _, _) in self.tracks_with_sizes() {
|
for (track_index, track, _, _) in self.tracks_with_sizes() {
|
||||||
//column(&Fixed::x(5, Fill::xy(Tui::bg(Green, "kyp"))));
|
//column(&Fixed::x(5, Fill::xy(Tui::bg(Green, "kyp"))));
|
||||||
column(&Fixed::x(
|
column(&Fixed::x(
|
||||||
|
|
@ -203,12 +258,12 @@ pub trait ClipsView: TracksView + ScenesView + Send + Sync {
|
||||||
Fill::y(self.view_track_clips(track_index, track))
|
Fill::y(self.view_track_clips(track_index, track))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}))
|
}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_track_clips <'a> (&'a self, track_index: usize, track: &'a Track) -> impl Content<TuiOut> + 'a {
|
fn view_track_clips <'a> (&'a self, track_index: usize, track: &'a Track) -> impl Content<TuiOut> + 'a {
|
||||||
Stack::south(move|cell: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
Stack::south(move|cell: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||||
for (scene_index, scene) in self.scenes().iter().enumerate().skip(self.scene_scroll()) {
|
for (scene_index, scene, ..) in self.scenes_with_sizes() {
|
||||||
let (name, theme): (Arc<str>, ItemTheme) = if let Some(Some(clip)) = &scene.clips.get(track_index) {
|
let (name, theme): (Arc<str>, ItemTheme) = if let Some(Some(clip)) = &scene.clips.get(track_index) {
|
||||||
let clip = clip.read().unwrap();
|
let clip = clip.read().unwrap();
|
||||||
(clip.name.clone(), clip.color)
|
(clip.name.clone(), clip.color)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ impl Default for Sequencer {
|
||||||
play_clip: None,
|
play_clip: None,
|
||||||
next_clip: None,
|
next_clip: None,
|
||||||
recording: false,
|
recording: false,
|
||||||
monitoring: false,
|
monitoring: true,
|
||||||
overdub: false,
|
overdub: false,
|
||||||
|
|
||||||
notes_in: RwLock::new([false;128]).into(),
|
notes_in: RwLock::new([false;128]).into(),
|
||||||
|
|
|
||||||
2
deps/tengri
vendored
2
deps/tengri
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit a55e84c29f51606e0996f7f88b7664ca0d37365b
|
Subproject commit c9f01648712a0c3c1a8290fc09c65746decbbbcb
|
||||||
Loading…
Add table
Add a link
Reference in a new issue