mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: p.48, e=14, somewhat less todo.
This commit is contained in:
parent
28d0020261
commit
550fd4cbcd
4 changed files with 118 additions and 23 deletions
|
|
@ -121,7 +121,7 @@ pub fn arranger_content_vertical (
|
||||||
// track titles
|
// track titles
|
||||||
let header = row!((track, w) in tracks.iter().zip(cols.iter().map(|col|col.0))=>{
|
let header = row!((track, w) in tracks.iter().zip(cols.iter().map(|col|col.0))=>{
|
||||||
// name and width of track
|
// name and width of track
|
||||||
let name = track.name.read().unwrap();
|
let name = track.name().read().unwrap();
|
||||||
let max_w = w.saturating_sub(1).min(name.len()).max(2);
|
let max_w = w.saturating_sub(1).min(name.len()).max(2);
|
||||||
let name = format!("▎{}", &name[0..max_w]);
|
let name = format!("▎{}", &name[0..max_w]);
|
||||||
let name = TuiStyle::bold(name, true);
|
let name = TuiStyle::bold(name, true);
|
||||||
|
|
@ -159,7 +159,7 @@ pub fn arranger_content_vertical (
|
||||||
.unwrap_or("(none)".into()));
|
.unwrap_or("(none)".into()));
|
||||||
col!(name, /*input, output,*/ until_next, elapsed)
|
col!(name, /*input, output,*/ until_next, elapsed)
|
||||||
.min_xy(w as u16, header_h)
|
.min_xy(w as u16, header_h)
|
||||||
.bg(track.color.rgb)
|
.bg(track.color().rgb)
|
||||||
.push_x(scenes_w)
|
.push_x(scenes_w)
|
||||||
});
|
});
|
||||||
// tracks and scenes
|
// tracks and scenes
|
||||||
|
|
@ -205,7 +205,7 @@ pub fn arranger_content_vertical (
|
||||||
// cursor
|
// cursor
|
||||||
add(&CustomWidget::new(any_size, move|to: &mut TuiOutput|{
|
add(&CustomWidget::new(any_size, move|to: &mut TuiOutput|{
|
||||||
let area = to.area();
|
let area = to.area();
|
||||||
let focused = view.focused;
|
let focused = view.is_focused();
|
||||||
let selected = view.selected;
|
let selected = view.selected;
|
||||||
let get_track_area = |t: usize| [
|
let get_track_area = |t: usize| [
|
||||||
scenes_w + area.x() + cols[t].1 as u16, area.y(),
|
scenes_w + area.x() + cols[t].1 as u16, area.y(),
|
||||||
|
|
@ -258,7 +258,7 @@ pub fn arranger_content_vertical (
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
}).bg(bg.rgb);
|
}).bg(bg.rgb);
|
||||||
let color = TuiTheme::title_fg(view.focused);
|
let color = TuiTheme::title_fg(view.is_focused());
|
||||||
let size = format!("{}x{}", view.size.w(), view.size.h());
|
let size = format!("{}x{}", view.size.w(), view.size.h());
|
||||||
let lower_right = TuiStyle::fg(size, color).pull_x(1).align_se().fill_xy();
|
let lower_right = TuiStyle::fg(size, color).pull_x(1).align_se().fill_xy();
|
||||||
lay!(arrangement, lower_right)
|
lay!(arrangement, lower_right)
|
||||||
|
|
@ -267,7 +267,7 @@ pub fn arranger_content_vertical (
|
||||||
pub fn arranger_content_horizontal (
|
pub fn arranger_content_horizontal (
|
||||||
view: &ArrangerTui,
|
view: &ArrangerTui,
|
||||||
) -> impl Widget<Engine = Tui> + use<'_> {
|
) -> impl Widget<Engine = Tui> + use<'_> {
|
||||||
let focused = view.focused;
|
let focused = view.is_focused();
|
||||||
let _tracks = view.tracks();
|
let _tracks = view.tracks();
|
||||||
lay!(
|
lay!(
|
||||||
focused.then_some(Background(TuiTheme::border_bg())),
|
focused.then_some(Background(TuiTheme::border_bg())),
|
||||||
|
|
@ -461,7 +461,7 @@ impl TransportViewState for ArrangerTui {
|
||||||
fn focus (&self) -> TransportFocus {
|
fn focus (&self) -> TransportFocus {
|
||||||
self.focus
|
self.focus
|
||||||
}
|
}
|
||||||
fn focused (&self) -> bool {
|
fn is_focused (&self) -> bool {
|
||||||
self.focused
|
self.focused
|
||||||
}
|
}
|
||||||
fn transport_state (&self) -> Option<TransportState> {
|
fn transport_state (&self) -> Option<TransportState> {
|
||||||
|
|
@ -482,7 +482,52 @@ impl TransportViewState for ArrangerTui {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhrasesViewState for ArrangerTui {
|
impl PhrasesViewState for ArrangerTui {
|
||||||
|
fn focused (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn entered (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn phrases (&self) -> Vec<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn phrase (&self) -> usize {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn mode (&self) -> Option<&PhrasesMode> {
|
||||||
|
&self.mode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhraseViewState for ArrangerTui {
|
impl PhraseViewState for ArrangerTui {
|
||||||
|
fn focused (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn entered (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn keys (&self) -> &Buffer {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn phrase (&self) -> &Option<Arc<RwLock<Phrase>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn buffer (&self) -> &BigBuffer {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn note_len (&self) -> usize {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn note_axis (&self) -> &RwLock<FixedAxis<usize>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn time_axis (&self) -> &RwLock<ScaledAxis<usize>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn size (&self) -> &Measure<Tui> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn now (&self) -> &Arc<Pulse> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ pub trait PhrasesViewState {
|
||||||
fn focused (&self) -> bool;
|
fn focused (&self) -> bool;
|
||||||
fn entered (&self) -> bool;
|
fn entered (&self) -> bool;
|
||||||
fn phrases (&self) -> Vec<()>;
|
fn phrases (&self) -> Vec<()>;
|
||||||
fn phrase (&self) -> ();
|
fn phrase (&self) -> usize;
|
||||||
fn mode (&self) -> PhrasesMode;
|
fn mode (&self) -> Option<&PhrasesMode>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhrasesViewState for PhrasesTui {
|
impl PhrasesViewState for PhrasesTui {
|
||||||
|
|
@ -28,11 +28,11 @@ impl PhrasesViewState for PhrasesTui {
|
||||||
fn phrases (&self) -> Vec<()> {
|
fn phrases (&self) -> Vec<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
fn phrase (&self) -> () {
|
fn phrase (&self) -> usize {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
fn mode (&self) -> PhrasesMode {
|
fn mode (&self) -> Option<&PhrasesMode> {
|
||||||
todo!()
|
&self.mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ impl<'a, T: PhrasesViewState> Content for PhrasesView<'a, T> {
|
||||||
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
|
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
|
||||||
let mut length = PhraseLength::new(length, None);
|
let mut length = PhraseLength::new(length, None);
|
||||||
if let Some(PhrasesMode::Length(phrase, new_length, focus)) = mode {
|
if let Some(PhrasesMode::Length(phrase, new_length, focus)) = mode {
|
||||||
if focused && i == phrase {
|
if focused && i == *phrase {
|
||||||
length.pulses = new_length;
|
length.pulses = new_length;
|
||||||
length.focus = Some(focus);
|
length.focus = Some(focus);
|
||||||
}
|
}
|
||||||
|
|
@ -61,11 +61,16 @@ impl<'a, T: PhrasesViewState> Content for PhrasesView<'a, T> {
|
||||||
let row1 = lay!(format!(" {i}").align_w().fill_x(), length).fill_x();
|
let row1 = lay!(format!(" {i}").align_w().fill_x(), length).fill_x();
|
||||||
let mut row2 = format!(" {name}");
|
let mut row2 = format!(" {name}");
|
||||||
if let Some(PhrasesMode::Rename(phrase, _)) = mode {
|
if let Some(PhrasesMode::Rename(phrase, _)) = mode {
|
||||||
if focused && i == phrase { row2 = format!("{row2}▄"); }
|
if focused && i == *phrase {
|
||||||
|
row2 = format!("{row2}▄");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let row2 = TuiStyle::bold(row2, true);
|
let row2 = TuiStyle::bold(row2, true);
|
||||||
add(&col!(row1, row2).fill_x().bg(color.base.rgb))?;
|
add(&col!(row1, row2).fill_x().bg(color.base.rgb))?;
|
||||||
Ok(if focused && i == phrase { add(&CORNERS)?; })
|
if focused && i == *phrase {
|
||||||
|
add(&CORNERS)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
let border_color = if focused {Color::Rgb(100, 110, 40)} else {Color::Rgb(70, 80, 50)};
|
let border_color = if focused {Color::Rgb(100, 110, 40)} else {Color::Rgb(70, 80, 50)};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ impl TransportViewState for SequencerTui {
|
||||||
fn focus (&self) -> TransportFocus {
|
fn focus (&self) -> TransportFocus {
|
||||||
self.focus
|
self.focus
|
||||||
}
|
}
|
||||||
fn focused (&self) -> bool {
|
fn is_focused (&self) -> bool {
|
||||||
self.focused
|
self.focused
|
||||||
}
|
}
|
||||||
fn transport_state (&self) -> Option<TransportState> {
|
fn transport_state (&self) -> Option<TransportState> {
|
||||||
|
|
@ -37,8 +37,53 @@ impl TransportViewState for SequencerTui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhrasesViewState for ArrangerTui {
|
impl PhrasesViewState for SequencerTui {
|
||||||
|
fn focused (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn entered (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn phrases (&self) -> Vec<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn phrase (&self) -> usize {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn mode (&self) -> Option<&PhrasesMode> {
|
||||||
|
&self.mode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhraseViewState for ArrangerTui {
|
impl PhraseViewState for SequencerTui {
|
||||||
|
fn focused (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn entered (&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn keys (&self) -> &Buffer {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn phrase (&self) -> &Option<Arc<RwLock<Phrase>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn buffer (&self) -> &BigBuffer {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn note_len (&self) -> usize {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn note_axis (&self) -> &RwLock<FixedAxis<usize>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn time_axis (&self) -> &RwLock<ScaledAxis<usize>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn size (&self) -> &Measure<Tui> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn now (&self) -> &Arc<Pulse> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub struct TransportView<'a, T: TransportViewState>(pub &'a T);
|
||||||
|
|
||||||
pub trait TransportViewState: Send + Sync {
|
pub trait TransportViewState: Send + Sync {
|
||||||
fn focus (&self) -> TransportFocus;
|
fn focus (&self) -> TransportFocus;
|
||||||
fn focused (&self) -> bool;
|
fn is_focused (&self) -> bool;
|
||||||
fn transport_state (&self) -> Option<TransportState>;
|
fn transport_state (&self) -> Option<TransportState>;
|
||||||
fn bpm_value (&self) -> f64;
|
fn bpm_value (&self) -> f64;
|
||||||
fn sync_value (&self) -> f64;
|
fn sync_value (&self) -> f64;
|
||||||
|
|
@ -26,7 +26,7 @@ impl TransportViewState for TransportTui {
|
||||||
fn focus (&self) -> TransportFocus {
|
fn focus (&self) -> TransportFocus {
|
||||||
self.focus
|
self.focus
|
||||||
}
|
}
|
||||||
fn focused (&self) -> bool {
|
fn is_focused (&self) -> bool {
|
||||||
self.focused
|
self.focused
|
||||||
}
|
}
|
||||||
fn transport_state (&self) -> Option<TransportState> {
|
fn transport_state (&self) -> Option<TransportState> {
|
||||||
|
|
@ -51,7 +51,7 @@ impl<'a, T: TransportViewState> Content for TransportView<'a, T> {
|
||||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||||
let state = self.0;
|
let state = self.0;
|
||||||
lay!(
|
lay!(
|
||||||
state.focus().wrap(state.focused(), TransportFocus::PlayPause, &Styled(
|
state.focus().wrap(state.is_focused(), TransportFocus::PlayPause, &Styled(
|
||||||
None,
|
None,
|
||||||
match state.transport_state() {
|
match state.transport_state() {
|
||||||
Some(TransportState::Rolling) => "▶ PLAYING",
|
Some(TransportState::Rolling) => "▶ PLAYING",
|
||||||
|
|
@ -62,19 +62,19 @@ impl<'a, T: TransportViewState> Content for TransportView<'a, T> {
|
||||||
).min_xy(11, 2).push_x(1)).align_x().fill_x(),
|
).min_xy(11, 2).push_x(1)).align_x().fill_x(),
|
||||||
|
|
||||||
row!(
|
row!(
|
||||||
state.focus().wrap(state.focused(), TransportFocus::Bpm, &Outset::X(1u16, {
|
state.focus().wrap(state.is_focused(), TransportFocus::Bpm, &Outset::X(1u16, {
|
||||||
let bpm = state.bpm_value();
|
let bpm = state.bpm_value();
|
||||||
row! { "BPM ", format!("{}.{:03}", bpm as usize, (bpm * 1000.0) % 1000.0) }
|
row! { "BPM ", format!("{}.{:03}", bpm as usize, (bpm * 1000.0) % 1000.0) }
|
||||||
})),
|
})),
|
||||||
//let quant = state.focus().wrap(state.focused(), TransportFocus::Quant, &Outset::X(1u16, row! {
|
//let quant = state.focus().wrap(state.focused(), TransportFocus::Quant, &Outset::X(1u16, row! {
|
||||||
//"QUANT ", ppq_to_name(state.0.quant as usize)
|
//"QUANT ", ppq_to_name(state.0.quant as usize)
|
||||||
//})),
|
//})),
|
||||||
state.focus().wrap(state.focused(), TransportFocus::Sync, &Outset::X(1u16, row! {
|
state.focus().wrap(state.is_focused(), TransportFocus::Sync, &Outset::X(1u16, row! {
|
||||||
"SYNC ", pulses_to_name(state.sync_value() as usize)
|
"SYNC ", pulses_to_name(state.sync_value() as usize)
|
||||||
}))
|
}))
|
||||||
).align_w().fill_x(),
|
).align_w().fill_x(),
|
||||||
|
|
||||||
state.focus().wrap(state.focused(), TransportFocus::Clock, &{
|
state.focus().wrap(state.is_focused(), TransportFocus::Clock, &{
|
||||||
let time1 = state.format_beat();
|
let time1 = state.format_beat();
|
||||||
let time2 = state.format_msu();
|
let time2 = state.format_msu();
|
||||||
row!("B" ,time1.as_str(), " T", time2.as_str()).outset_x(1)
|
row!("B" ,time1.as_str(), " T", time2.as_str()).outset_x(1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue