mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +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
|
|
@ -2,8 +2,8 @@
|
|||
(@q launch)
|
||||
(@t select :select-track-header)
|
||||
(@s select :select-scene-header)
|
||||
(@tab edit :clip-selected)
|
||||
(@enter edit :clip-selected)
|
||||
(@tab edit :clip-selected)
|
||||
(@enter edit :clip-selected)
|
||||
(@shift-I project input-add)
|
||||
(@shift-O project output-add)
|
||||
(@shift-S project scene-add)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ impl HasSceneScroll for App {
|
|||
fn scene_scroll (&self) -> usize { self.project.scene_scroll() }
|
||||
}
|
||||
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|{
|
||||
//editor = self.editor;
|
||||
//editor_w = {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ pub struct Arrangement {
|
|||
pub arranger: Arc<RwLock<Buffer>>,
|
||||
/// Display size
|
||||
pub size: Measure<TuiOut>,
|
||||
/// Display size of clips area
|
||||
pub inner_size: Measure<TuiOut>,
|
||||
}
|
||||
|
||||
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> {
|
||||
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
|
||||
fn scene_default_name (&self) -> Arc<str> {
|
||||
format!("s{:3>}", self.scenes().len() + 1).into()
|
||||
|
|
|
|||
|
|
@ -1,12 +1,25 @@
|
|||
use crate::*;
|
||||
|
||||
impl<T> TracksView for T
|
||||
where T: ScenesView + HasMidiIns + HasMidiOuts + HasSize<TuiOut> + HasTrackScroll + HasSelection + HasMidiIns + HasEditor {}
|
||||
pub trait HasClipsSize {
|
||||
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 {}
|
||||
|
||||
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 {
|
||||
(self.width() as u16).saturating_sub(40)
|
||||
|
|
@ -16,11 +29,15 @@ pub trait TracksView:
|
|||
let editor_width = self.editor().map(|e|e.width());
|
||||
let active_track = self.selection().track();
|
||||
let mut x = 0;
|
||||
self.tracks().iter().enumerate().map(move |(index, track)|{
|
||||
let width = active_track.and_then(|_|editor_width).unwrap_or(track.width.max(8));
|
||||
let data = (index, track, x, x + width);
|
||||
x += width + Self::TRACK_SPACING;
|
||||
data
|
||||
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 data = (index, track, x, x + width);
|
||||
x += width + Self::TRACK_SPACING;
|
||||
Some(data)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
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,
|
||||
Align::nw(Bsp::s(
|
||||
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(),
|
||||
|port, index|Tui::fg_bg(Rgb(255, 255, 255), track.color.dark.rgb,
|
||||
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.
|
||||
const H_SCENE: usize = 2;
|
||||
/// Default editor height.
|
||||
|
|
@ -155,9 +183,28 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
|||
fn h_scenes (&self) -> u16;
|
||||
fn w_side (&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> {
|
||||
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));
|
||||
}
|
||||
})
|
||||
|
|
@ -166,7 +213,7 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + Send + Sync {
|
|||
let h = if self.selection().scene() == Some(index) && let Some(editor) = self.editor() {
|
||||
(editor.height() as u16).max(12)
|
||||
} else {
|
||||
Self::H_SCENE as u16
|
||||
Self::H_SCENE as u16
|
||||
};
|
||||
let bg = if self.selection().scene() == Some(index) {
|
||||
scene.color.light.rgb
|
||||
|
|
@ -185,30 +232,38 @@ 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)
|
||||
-> impl Content<TuiOut> + 'a
|
||||
{
|
||||
Fill::xy(Stack::<TuiOut, _>::east(move|column: &mut dyn FnMut(&dyn Render<TuiOut>)|{
|
||||
for (track_index, track, _, _) in self.tracks_with_sizes() {
|
||||
//column(&Fixed::x(5, Fill::xy(Tui::bg(Green, "kyp"))));
|
||||
column(&Fixed::x(
|
||||
if self.selection().track() == Some(track_index)
|
||||
&& let Some(editor) = self.editor()
|
||||
{
|
||||
editor.width().max(24).max(track.width)
|
||||
} else {
|
||||
track.width
|
||||
} as u16,
|
||||
Fill::y(self.view_track_clips(track_index, track))
|
||||
))
|
||||
}
|
||||
}))
|
||||
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() {
|
||||
//column(&Fixed::x(5, Fill::xy(Tui::bg(Green, "kyp"))));
|
||||
column(&Fixed::x(
|
||||
if self.selection().track() == Some(track_index)
|
||||
&& let Some(editor) = self.editor()
|
||||
{
|
||||
editor.width().max(24).max(track.width)
|
||||
} else {
|
||||
track.width
|
||||
} as u16,
|
||||
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 {
|
||||
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 clip = clip.read().unwrap();
|
||||
(clip.name.clone(), clip.color)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ impl Default for Sequencer {
|
|||
play_clip: None,
|
||||
next_clip: None,
|
||||
recording: false,
|
||||
monitoring: false,
|
||||
monitoring: true,
|
||||
overdub: false,
|
||||
|
||||
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