mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 20:56:43 +01:00
wip: refactor arranger to device
This commit is contained in:
parent
fa73821a0b
commit
89288f2920
40 changed files with 2015 additions and 1919 deletions
217
crates/device/src/arranger/arranger_view.rs
Normal file
217
crates/device/src/arranger/arranger_view.rs
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
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,
|
||||
|
||||
pub is_editing: bool,
|
||||
|
||||
pub width: u16,
|
||||
pub width_mid: u16,
|
||||
pub width_side: u16,
|
||||
|
||||
pub inputs_count: usize,
|
||||
pub inputs_height: u16,
|
||||
|
||||
pub outputs_count: usize,
|
||||
pub outputs_height: u16,
|
||||
|
||||
pub scene_last: usize,
|
||||
pub scene_count: usize,
|
||||
pub scene_scroll: Fill<Fixed<u16, ScrollbarV>>,
|
||||
pub scene_selected: Option<usize>,
|
||||
pub scenes_height: u16,
|
||||
|
||||
pub track_scroll: Fill<Fixed<u16, ScrollbarH>>,
|
||||
pub track_count: usize,
|
||||
pub track_selected: Option<usize>,
|
||||
pub tracks_height: u16,
|
||||
|
||||
pub show_debug_info: bool,
|
||||
}
|
||||
|
||||
impl<'a> ArrangerView<'a> {
|
||||
pub fn new (
|
||||
arrangement: &'a Arrangement,
|
||||
editor: Option<&'a MidiEditor>
|
||||
) -> Self {
|
||||
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();
|
||||
Self {
|
||||
arrangement,
|
||||
is_editing: editor.is_some(),
|
||||
|
||||
width: arrangement.w(),
|
||||
width_mid: arrangement.w_tracks_area(),
|
||||
width_side: arrangement.w_sidebar(),
|
||||
|
||||
inputs_height: arrangement.h_inputs(),
|
||||
inputs_count: arrangement.midi_ins.len(),
|
||||
|
||||
outputs_height: arrangement.h_outputs(),
|
||||
outputs_count: arrangement.midi_outs.len(),
|
||||
|
||||
scenes_height: h_scenes_area,
|
||||
scene_selected: selected.map(|s|s.scene()).flatten(),
|
||||
scene_count: arrangement.scenes.len(),
|
||||
scene_last: arrangement.scenes.len().saturating_sub(1),
|
||||
scene_scroll: Fill::y(Fixed::x(1, ScrollbarV {
|
||||
offset: arrangement.scene_scroll,
|
||||
length: h_scenes_area as usize,
|
||||
total: h_scenes as usize,
|
||||
})),
|
||||
|
||||
tracks_height: h_tracks_area,
|
||||
track_count: arrangement.tracks.len(),
|
||||
track_selected: selected.map(|s|s.track()).flatten(),
|
||||
track_scroll: Fill::x(Fixed::y(1, ScrollbarH {
|
||||
offset: arrangement.track_scroll,
|
||||
length: h_tracks_area as usize,
|
||||
total: h_scenes as usize,
|
||||
})),
|
||||
|
||||
show_debug_info: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Content<TuiOut> for ArrangerView<'a> {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
let ins = |x|Bsp::n(self.inputs(), x);
|
||||
let tracks = |x|Bsp::s(self.tracks(), x);
|
||||
let devices = |x|Bsp::s(self.devices(), x);
|
||||
let outs = |x|Bsp::s(self.outputs(), x);
|
||||
let bg = |x|Tui::bg(Reset, x);
|
||||
//let track_scroll = |x|Bsp::s(&self.track_scroll, x);
|
||||
//let scene_scroll = |x|Bsp::e(&self.scene_scroll, x);
|
||||
outs(tracks(devices(ins(bg(self.scenes(None))))))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArrangerView<'a> {
|
||||
/// Render input matrix.
|
||||
pub(crate) fn inputs (&'a self) -> impl Content<TuiOut> + 'a {
|
||||
Tui::bg(Reset, Bsp::s(
|
||||
self.input_intos(),
|
||||
Bsp::s(self.input_routes(), self.input_ports()),
|
||||
))
|
||||
}
|
||||
|
||||
/// Render output matrix.
|
||||
pub(crate) fn outputs (&'a self) -> impl Content<TuiOut> + 'a {
|
||||
Tui::bg(Reset, Align::n(Bsp::s(
|
||||
Bsp::s(self.output_ports(), self.output_conns()),
|
||||
Bsp::s(self.output_nexts(), self.output_froms()),
|
||||
)))
|
||||
}
|
||||
|
||||
/// Render track headers
|
||||
pub(crate) fn tracks (&'a self) -> impl Content<TuiOut> + 'a {
|
||||
let Self { width_side, width_mid, track_count, track_selected, is_editing, .. } = self;
|
||||
Tryptich::center(3)
|
||||
.left(*width_side, button_3("t", "track", format!("{}", *track_count), *is_editing))
|
||||
.right(*width_side, button_2("T", "add track", *is_editing))
|
||||
.middle(*width_mid, per_track(*width_mid, ||self.tracks_with_sizes_scrolled(),
|
||||
|index, track|wrap(
|
||||
if *track_selected == Some(index) {
|
||||
track.color.light
|
||||
} else {
|
||||
track.color.base
|
||||
}.rgb,
|
||||
track.color.lightest.rgb,
|
||||
Tui::bold(true, Fill::xy(Align::nw(&track.name)))
|
||||
)))
|
||||
}
|
||||
|
||||
/// Render device switches.
|
||||
pub(crate) fn devices (&'a self) -> impl Content<TuiOut> + 'a {
|
||||
let Self { width_side, width_mid, track_count, track_selected, is_editing, .. } = self;
|
||||
Tryptich::top(1)
|
||||
.left(*width_side, button_3("d", "devices", format!("{}", 0), *is_editing))
|
||||
.right(*width_side, button_2("D", "add device", *is_editing))
|
||||
.middle(*width_mid, per_track_top(*width_mid, ||self.tracks_with_sizes_scrolled(),
|
||||
move|index, track|{
|
||||
let bg = if *track_selected == Some(index) {
|
||||
track.color.light
|
||||
} else {
|
||||
track.color.base
|
||||
};
|
||||
let fg = Tui::g(224);
|
||||
track.devices.get(0).map(|device|wrap(bg.rgb, fg, device.name()))
|
||||
}))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue