mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
generalize Fixed and bring back some more of the arranger
This commit is contained in:
parent
d577449b72
commit
2352b72377
4 changed files with 51 additions and 52 deletions
|
|
@ -298,12 +298,32 @@ pub enum Fixed<U: Number, T> {
|
|||
/// Enforce fixed width and height
|
||||
XY(U, U, T),
|
||||
}
|
||||
|
||||
impl<N: Number, T> Fixed<N, T> {
|
||||
pub fn inner (&self) -> &T {
|
||||
match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, }
|
||||
}
|
||||
}
|
||||
impl<E: Engine, T: Widget<Engine = E>> Widget for Fixed<E::Unit, T> {
|
||||
type Engine = E;
|
||||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
Ok(match self {
|
||||
Self::X(w, _) =>
|
||||
if to.w() >= *w { Some([*w, to.h()].into()) } else { None },
|
||||
Self::Y(h, _) =>
|
||||
if to.h() >= *h { Some([to.w(), *h].into()) } else { None },
|
||||
Self::XY(w, h, _)
|
||||
=> if to.w() >= *w && to.h() >= *h { Some([*w, *h].into()) } else { None },
|
||||
})
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
// 🡘 🡙 ←🡙→
|
||||
if let Some(size) = self.layout(to.area().wh().into())? {
|
||||
to.render_in(to.area().clip(size).into(), self.inner())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Enforce minimum size of drawing area
|
||||
pub enum Min<U: Number, T> {
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ impl Widget for &str {
|
|||
type Engine = Tui;
|
||||
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
// TODO: line breaks
|
||||
Ok(Some([self.len() as u16, 1]))
|
||||
Ok(Some([self.chars().count() as u16, 1]))
|
||||
}
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
let [x, y, ..] = to.area();
|
||||
|
|
@ -296,7 +296,7 @@ pub struct Styled<T: Widget<Engine = Tui>>(pub Option<Style>, pub T);
|
|||
impl Widget for Styled<&str> {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
Ok(Some([self.1.len() as u16, 1]))
|
||||
Ok(Some([self.1.chars().count() as u16, 1]))
|
||||
}
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
// FIXME
|
||||
|
|
@ -318,25 +318,6 @@ impl Widget for Background {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Widget<Engine = Tui>> Widget for Fixed<u16, T> {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
Ok(match self {
|
||||
Self::X(w, _) => (to.w() < *w).then(||[to.w() - *w, to.h()]),
|
||||
Self::Y(h, _) => (to.h() < *h).then(||[to.w(), to.h() - *h]),
|
||||
Self::XY(w, h, _) => (to.w() < *w && to.h() < *h).then(||[to.w() - *w, to.h() - *h])
|
||||
}.map(|offset_area|self.inner().layout(offset_area.into())).transpose()?.flatten())
|
||||
}
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
// 🡘 🡙 ←🡙→
|
||||
if let Some(size) = self.layout(to.area().wh())? {
|
||||
to.render_in(to.area().clip(size), self.inner())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//impl<F> Widget for Layers<Tui, F>
|
||||
//where
|
||||
//F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
|
||||
|
|
|
|||
|
|
@ -359,12 +359,12 @@ impl<'a, 'b> Content for ArrangerViewVertical<'a, 'b, Tui> {
|
|||
let Self(state, cols, rows) = self;
|
||||
let tracks = state.tracks.as_ref();
|
||||
let scenes = state.scenes.as_ref();
|
||||
let offset = 3 + scene_name_max_len(scenes) as u16;
|
||||
let offset = 4 + scene_name_max_len(scenes) as u16;
|
||||
Layers::new(move |add|{
|
||||
//.add_ref(&Background(Color::Rgb(30, 33, 36)))//COLOR_BG1))//bg_lo(state.focused, state.entered)))
|
||||
add(&ColumnSeparators(offset, cols))?;
|
||||
add(&RowSeparators(rows))?;
|
||||
add(&CursorFocus(state.selected, offset, cols, rows))?;
|
||||
add(&CursorFocus(state.focused, state.selected, offset, cols, rows))?;
|
||||
add(&Split::down(|add|{
|
||||
add(&TracksHeader(offset, cols, tracks))?;
|
||||
add(&SceneRows(offset, cols, rows, tracks, scenes))
|
||||
|
|
@ -416,14 +416,14 @@ impl<'a> Widget for RowSeparators<'a> {
|
|||
}
|
||||
|
||||
struct CursorFocus<'a>(
|
||||
ArrangerFocus, u16, &'a [(usize, usize)], &'a [(usize, usize)]
|
||||
bool, ArrangerFocus, u16, &'a [(usize, usize)], &'a [(usize, usize)]
|
||||
);
|
||||
|
||||
impl<'a> Widget for CursorFocus<'a> {
|
||||
type Engine = Tui;
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
let area = to.area();
|
||||
let Self(selected, offset, cols, rows) = *self;
|
||||
let Self(focused, selected, offset, cols, rows) = *self;
|
||||
let get_track_area = |t: usize| [
|
||||
offset + area.x() + cols[t].1 as u16 - 1,
|
||||
area.y(),
|
||||
|
|
@ -447,7 +447,9 @@ impl<'a> Widget for CursorFocus<'a> {
|
|||
let mut clip_area: Option<[u16;4]> = None;
|
||||
let area = match selected {
|
||||
ArrangerFocus::Mix => {
|
||||
to.fill_bg(area, COLOR_BG0);
|
||||
if focused {
|
||||
to.fill_bg(area, COLOR_BG0);
|
||||
}
|
||||
area
|
||||
},
|
||||
ArrangerFocus::Track(t) => {
|
||||
|
|
@ -473,12 +475,14 @@ impl<'a> Widget for CursorFocus<'a> {
|
|||
to.fill_ul([area.x(), y - 1, area.w(), 1], COLOR_BG5);
|
||||
to.fill_ul([area.x(), y + height - 1, area.w(), 1], COLOR_BG5);
|
||||
}
|
||||
if let Some(clip_area) = clip_area {
|
||||
to.fill_bg(clip_area, COLOR_BG0);
|
||||
} else if let Some(track_area) = track_area {
|
||||
to.fill_bg(track_area, COLOR_BG0);
|
||||
} else if let Some(scene_area) = scene_area {
|
||||
to.fill_bg(scene_area, COLOR_BG0);
|
||||
if focused {
|
||||
if let Some(clip_area) = clip_area {
|
||||
to.fill_bg(clip_area, COLOR_BG0);
|
||||
} else if let Some(track_area) = track_area {
|
||||
to.fill_bg(track_area, COLOR_BG0);
|
||||
} else if let Some(scene_area) = scene_area {
|
||||
to.fill_bg(scene_area, COLOR_BG0);
|
||||
}
|
||||
}
|
||||
//Ok(Some(area))
|
||||
Ok(())
|
||||
|
|
@ -515,9 +519,7 @@ impl<'a> Content for SceneRows<'a> {
|
|||
let Self(offset, columns, rows, tracks, scenes) = *self;
|
||||
Split::down(move |add| {
|
||||
for (scene, (pulses, _)) in scenes.iter().zip(rows) {
|
||||
add(&Fixed::X(1.max((pulses / 96) as u16), SceneRow(
|
||||
tracks, scene, columns, offset
|
||||
)))?;
|
||||
add(&SceneRow(tracks, scene, columns, offset, 1.max((pulses / 96) as u16)))?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
|
@ -525,28 +527,24 @@ impl<'a> Content for SceneRows<'a> {
|
|||
}
|
||||
|
||||
struct SceneRow<'a>(
|
||||
&'a[Sequencer<Tui>], &'a Scene, &'a[(usize, usize)], u16
|
||||
&'a[Sequencer<Tui>], &'a Scene, &'a[(usize, usize)], u16, u16
|
||||
);
|
||||
|
||||
impl<'a> Content for SceneRow<'a> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
let Self(tracks, scene, columns, _offset) = self;
|
||||
let Self(tracks, scene, columns, offset, height) = self;
|
||||
let playing = scene.is_playing(tracks);
|
||||
Split::right(move |add| {
|
||||
add(&Layers::new(|add|{
|
||||
//add(&Split::right(|add|{
|
||||
//add(&if playing { "▶" } else { " " })?;
|
||||
add(&scene.name.read().unwrap().as_str())?;
|
||||
//}))?;
|
||||
//add(&Background(COLOR_BG1))
|
||||
Ok(())
|
||||
}))?;
|
||||
//for (track, (_w, _x)) in columns.iter().enumerate() {
|
||||
//add(&SceneClip(tracks.get(track), scene.clips.get(track)))?;
|
||||
//}
|
||||
Fixed::Y(*height, Split::right(move |add| {
|
||||
add(&Fixed::XY(offset.saturating_sub(1), *height, Split::right(|add|{
|
||||
add(&if playing { "▶ " } else { " " })?;
|
||||
add(&scene.name.read().unwrap().as_str())
|
||||
})))?;
|
||||
for (track, (_w, _x)) in columns.iter().enumerate() {
|
||||
add(&SceneClip(tracks.get(track), scene.clips.get(track)))?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ impl Content for TransportPlayPauseButton<Tui> {
|
|||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
Layers::new(|add|{
|
||||
add(&Plus::X(1, Min::Y(2, Styled(match self.value {
|
||||
add(&Plus::X(1, Min::XY(11, 2, Styled(match self.value {
|
||||
Some(TransportState::Stopped) => Some(GRAY_DIM.bold()),
|
||||
Some(TransportState::Starting) => Some(GRAY_NOT_DIM_BOLD),
|
||||
Some(TransportState::Rolling) => Some(WHITE_NOT_DIM_BOLD),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue