wip: down to 25 errors woo

This commit is contained in:
🪞👃🪞 2025-05-14 02:13:13 +03:00
parent 89288f2920
commit 6ce83fb27a
25 changed files with 688 additions and 620 deletions

View file

@ -1,78 +1,5 @@
use crate::*;
impl Arrangement {
/// Width of display
pub(crate) fn w (&self) -> u16 {
self.size.w() as u16
}
/// Width allocated for sidebar.
pub(crate) fn w_sidebar (&self) -> u16 {
self.w() / if self.is_editing() { 16 } else { 8 } as u16
}
/// Width taken by all tracks.
pub(crate) fn w_tracks (&self) -> u16 {
self.tracks_with_sizes().last().map(|(_, _, _, x)|x as u16).unwrap_or(0)
}
/// Width available to display tracks.
pub(crate) fn w_tracks_area (&self) -> u16 {
self.w().saturating_sub(2 * self.w_sidebar())
}
/// Height of display
pub(crate) fn h (&self) -> u16 {
self.size.h() as u16
}
/// Height available to display track headers.
pub(crate) fn h_tracks_area (&self) -> u16 {
5 // FIXME
//self.h().saturating_sub(self.h_inputs() + self.h_outputs())
}
/// Height available to display tracks.
pub(crate) fn h_scenes_area (&self) -> u16 {
//15
self.h().saturating_sub(
self.h_inputs() +
self.h_outputs() +
self.h_devices() +
13 // FIXME
)
}
/// Height taken by all scenes.
pub(crate) fn h_scenes (&self) -> u16 {
let (selected_track, selected_scene) = match Has::<Option<Selection>>::get(self) {
Some(Selection::Track(t)) => (Some(*t), None),
Some(Selection::Scene(s)) => (None, Some(*s)),
Some(Selection::TrackClip { track, scene }) => (Some(*track), Some(*scene)),
_ => (None, None)
};
self.scenes_with_sizes(
self.is_editing,
ArrangerView::H_SCENE,
ArrangerView::H_EDITOR,
selected_track,
selected_scene
)
.last()
.map(|(_, _, _, y)|y as u16).unwrap_or(0)
}
/// Height taken by all inputs.
pub(crate) fn h_inputs (&self) -> u16 {
self.inputs_with_sizes()
.last()
.map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
/// Height taken by all outputs.
pub(crate) fn h_outputs (&self) -> u16 {
self.outputs_with_sizes()
.last()
.map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
/// Height taken by visible device slots.
pub(crate) fn h_devices (&self) -> u16 {
2
//1 + self.devices_with_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
}
}
pub(crate) struct ArrangerView<'a> {
pub arrangement: &'a Arrangement,
@ -107,17 +34,18 @@ impl<'a> ArrangerView<'a> {
arrangement: &'a Arrangement,
editor: Option<&'a MidiEditor>
) -> Self {
let is_editing = editor.is_some();
let selected = arrangement.selected;
let h_tracks_area = arrangement.h_tracks_area();
let h_scenes_area = arrangement.h_scenes_area();
let h_scenes = arrangement.h_scenes();
let h_scenes = arrangement.h_scenes(is_editing);
Self {
arrangement,
is_editing: editor.is_some(),
is_editing,
width: arrangement.w(),
width_mid: arrangement.w_tracks_area(),
width_side: arrangement.w_sidebar(),
width_mid: arrangement.w_tracks_area(is_editing),
width_side: arrangement.w_sidebar(is_editing),
inputs_height: arrangement.h_inputs(),
inputs_count: arrangement.midi_ins.len(),
@ -214,4 +142,144 @@ impl<'a> ArrangerView<'a> {
track.devices.get(0).map(|device|wrap(bg.rgb, fg, device.name()))
}))
}
/// Default scene height.
pub(crate) const H_SCENE: usize = 2;
/// Default editor height.
pub(crate) const H_EDITOR: usize = 15;
/// Render scenes with clips
pub(crate) fn scenes (&'a self, editor: Option<MidiEditor>) -> impl Content<TuiOut> + 'a {
/// A scene with size and color.
type SceneWithColor<'a> = (usize, &'a Scene, usize, usize, Option<ItemTheme>);
let Self {
arrangement,
width, width_side, width_mid,
scenes_height, scene_last, scene_selected,
track_selected, is_editing, ..
} = self;
let selection = Has::<Option<Selection>>::get(self.arrangement);
let selected_track = selection.map(|s|s.track()).flatten();
let selected_scene = selection.map(|s|s.scene()).flatten();
let scenes_with_scene_colors = ||HasScenes::scenes_with_sizes(self.arrangement,
*is_editing,
Self::H_SCENE,
Self::H_EDITOR,
selected_track,
selected_scene,
).map_while(|(s, scene, y1, y2)|if y2 as u16 > *scenes_height {
None
} else {
Some((s, scene, y1, y2, if s == 0 {
None
} else {
Some(arrangement.scenes()[s-1].color)
}))
});
let scene_header = |(s, scene, y1, y2, previous): SceneWithColor, _|{
let height = (1 + y2 - y1) as u16;
let name = Some(scene.name.clone());
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e("", name))));
let same_track = true;
let selected = same_track && *scene_selected == Some(s);
let neighbor = same_track && s > 0 && *scene_selected == Some(s - 1);
let is_last = *scene_last == s;
let theme = scene.color;
let fg = theme.lightest.rgb;
let bg = if selected { theme.light } else { theme.base }.rgb;
let hi = if let Some(previous) = previous {
if neighbor {
previous.light.rgb
} else {
previous.base.rgb
}
} else {
Reset
};
let lo = if is_last {
Reset
} else if selected {
theme.light.rgb
} else {
theme.base.rgb
};
Fill::x(map_south(y1 as u16, height, Fixed::y(height, Phat {
width: 0, height: 0, content, colors: [fg, bg, hi, lo]
})))
};
let scenes_with_track_colors = |track: usize| arrangement.scenes_with_sizes(
self.is_editing,
Self::H_SCENE,
Self::H_EDITOR,
selected_track,
selected_scene,
).map_while(|(s, scene, y1, y2)|if y2 as u16 > self.scenes_height {
None
} else {
Some((s, scene, y1, y2, if s == 0 {
None
} else {
Some(self.arrangement.scenes[s-1].clips[track].as_ref()
.map(|c|c.read().unwrap().color)
.unwrap_or(ItemTheme::G[32]))
}))
});
Tryptich::center(*scenes_height)
.left(*width_side, Map::new(
||scenes_with_scene_colors(),
scene_header))
.middle(*width_mid, per_track(
*width_mid,
||self.tracks_with_sizes_scrolled(),
|track_index, track|Map::new(
||scenes_with_track_colors(track_index),
|(s, scene, y1, y2, previous): SceneWithColor<'a>, _|{
let (name, theme) = if let Some(clip) = &scene.clips[track_index] {
let clip = clip.read().unwrap();
(Some(clip.name.clone()), clip.color)
} else {
(None, ItemTheme::G[32])
};
let height = (1 + y2 - y1) as u16;
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e("", name))));
let same_track = *track_selected == Some(track_index);
let selected = same_track && *scene_selected == Some(s);
let neighbor = same_track && s > 0 && *scene_selected == Some(s - 1);
let is_last = *scene_last == s;
let fg = theme.lightest.rgb;
let bg = if selected { theme.light } else { theme.base }.rgb;
let hi = if let Some(previous) = previous {
if neighbor {
previous.light.rgb
} else {
previous.base.rgb
}
} else {
Reset
};
let lo = if is_last {
Reset
} else if selected {
theme.light.rgb
} else {
theme.base.rgb
};
map_south(y1 as u16, height, Bsp::b(Fixed::y(height, Phat {
width: 0, height: 0, content, colors: [fg, bg, hi, lo]
}), When(
*is_editing && same_track && *scene_selected == Some(s),
editor
)))
})))
}
}