mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
remove PhraseViewState
This commit is contained in:
parent
9319315595
commit
3569019b86
16 changed files with 432 additions and 473 deletions
|
|
@ -1,29 +1,41 @@
|
|||
use crate::*;
|
||||
|
||||
impl Widget for PhraseEditorModel {
|
||||
type Engine = Tui;
|
||||
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
PhraseView(self).layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
PhraseView(self).render(to)
|
||||
pub struct PhraseView2<'a> {
|
||||
pub(crate) focused: bool,
|
||||
pub(crate) entered: bool,
|
||||
pub(crate) phrase: &'a Option<Arc<RwLock<Phrase>>>,
|
||||
pub(crate) size: &'a Measure<Tui>,
|
||||
pub(crate) keys: &'a Buffer,
|
||||
pub(crate) buffer: &'a BigBuffer,
|
||||
pub(crate) note_len: usize,
|
||||
pub(crate) note_axis: &'a RwLock<FixedAxis<usize>>,
|
||||
pub(crate) time_axis: &'a RwLock<ScaledAxis<usize>>,
|
||||
pub(crate) now: &'a Arc<Pulse>,
|
||||
}
|
||||
|
||||
impl<'a, T: HasEditor> From<&'a T> for PhraseView2<'a> {
|
||||
fn from (state: &'a T) -> Self {
|
||||
Self {
|
||||
focused: state.editor_focused(),
|
||||
entered: state.editor_entered(),
|
||||
note_len: state.editor().note_len,
|
||||
phrase: &state.editor().phrase,
|
||||
size: &state.editor().size,
|
||||
keys: &state.editor().keys,
|
||||
buffer: &state.editor().buffer,
|
||||
note_axis: &state.editor().note_axis,
|
||||
time_axis: &state.editor().time_axis,
|
||||
now: &state.editor().now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PhraseView<'a, T: PhraseViewState>(pub &'a T);
|
||||
|
||||
impl<'a, T: PhraseViewState> Content for PhraseView<'a, T> {
|
||||
impl<'a> Content for PhraseView2<'a> {
|
||||
type Engine = Tui;
|
||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||
let phrase = self.0.phrase_editing();
|
||||
let size = self.0.size();
|
||||
let focused = self.0.phrase_editor_focused();
|
||||
let entered = self.0.phrase_editor_entered();
|
||||
let keys = self.0.keys();
|
||||
let buffer = self.0.buffer();
|
||||
let note_len = self.0.note_len();
|
||||
let note_axis = self.0.note_axis();
|
||||
let time_axis = self.0.time_axis();
|
||||
let Self {
|
||||
focused, entered, phrase, size, keys, buffer, note_len, note_axis, time_axis, now
|
||||
} = self;
|
||||
let FixedAxis { start: note_start, point: note_point, clamp: note_clamp }
|
||||
= *note_axis.read().unwrap();
|
||||
let ScaledAxis { start: time_start, point: time_point, clamp: time_clamp, scale: time_scale }
|
||||
|
|
@ -68,7 +80,7 @@ impl<'a, T: PhraseViewState> Content for PhraseView<'a, T> {
|
|||
})
|
||||
}).fill_x();
|
||||
let cursor = CustomWidget::new(|to|Ok(Some(to)), move|to: &mut TuiOutput|{
|
||||
Ok(if focused && entered {
|
||||
Ok(if *focused && *entered {
|
||||
let area = to.area();
|
||||
if let (Some(time), Some(note)) = (time_point, note_point) {
|
||||
let x1 = area.x() + (time / time_scale) as u16;
|
||||
|
|
@ -87,7 +99,7 @@ impl<'a, T: PhraseViewState> Content for PhraseView<'a, T> {
|
|||
|to:[u16;2]|Ok(Some(to.clip_h(1))),
|
||||
move|to: &mut TuiOutput|{
|
||||
if let Some(_) = phrase {
|
||||
let now = self.0.now().get() as usize; // TODO FIXME: self.now % phrase.read().unwrap().length;
|
||||
let now = now.get() as usize; // TODO FIXME: self.now % phrase.read().unwrap().length;
|
||||
let time_clamp = time_clamp
|
||||
.expect("time_axis of sequencer expected to be clamped");
|
||||
for x in 0..(time_clamp/time_scale).saturating_sub(time_start) {
|
||||
|
|
@ -103,14 +115,14 @@ impl<'a, T: PhraseViewState> Content for PhraseView<'a, T> {
|
|||
Ok(())
|
||||
}
|
||||
).push_x(6).align_sw();
|
||||
let border_color = if focused{Color::Rgb(100, 110, 40)}else{Color::Rgb(70, 80, 50)};
|
||||
let title_color = if focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)};
|
||||
let border_color = if *focused{Color::Rgb(100, 110, 40)}else{Color::Rgb(70, 80, 50)};
|
||||
let title_color = if *focused{Color::Rgb(150, 160, 90)}else{Color::Rgb(120, 130, 100)};
|
||||
let border = Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(border_color));
|
||||
let note_area = lay!(notes, cursor).fill_x();
|
||||
let piano_roll = row!(keys, note_area).fill_x();
|
||||
let content = piano_roll.bg(Color::Rgb(40, 50, 30)).border(border);
|
||||
let content = lay!(content, playhead);
|
||||
let mut upper_left = format!("[{}] Sequencer", if entered {"■"} else {" "});
|
||||
let mut upper_left = format!("[{}] Sequencer", if *entered {"■"} else {" "});
|
||||
if let Some(phrase) = phrase {
|
||||
upper_left = format!("{upper_left}: {}", phrase.read().unwrap().name);
|
||||
}
|
||||
|
|
@ -121,10 +133,10 @@ impl<'a, T: PhraseViewState> Content for PhraseView<'a, T> {
|
|||
//time_start, time_point.unwrap_or(0),
|
||||
//time_scale, time_clamp.unwrap_or(0),
|
||||
//);
|
||||
if focused && entered {
|
||||
if *focused && *entered {
|
||||
lower_right = format!("┤Note: {} {}├─{lower_right}",
|
||||
note_axis.read().unwrap().point.unwrap(),
|
||||
pulses_to_name(note_len));
|
||||
pulses_to_name(*note_len));
|
||||
//lower_right = format!("Note: {} (+{}:{}|{}) {upper_right}",
|
||||
//pulses_to_name(*note_len),
|
||||
//note_start,
|
||||
|
|
@ -146,74 +158,6 @@ impl<'a, T: PhraseViewState> Content for PhraseView<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait PhraseViewState: Send + Sync {
|
||||
fn phrase_editing (&self) -> &Option<Arc<RwLock<Phrase>>>;
|
||||
fn phrase_editor_focused (&self) -> bool;
|
||||
fn phrase_editor_size (&self) -> &Measure<Tui>;
|
||||
fn phrase_editor_entered (&self) -> bool;
|
||||
fn keys (&self) -> &Buffer;
|
||||
fn buffer (&self) -> &BigBuffer;
|
||||
fn note_len (&self) -> usize;
|
||||
fn note_axis (&self) -> &RwLock<FixedAxis<usize>>;
|
||||
fn time_axis (&self) -> &RwLock<ScaledAxis<usize>>;
|
||||
fn now (&self) -> &Arc<Pulse>;
|
||||
fn size (&self) -> &Measure<Tui>;
|
||||
}
|
||||
|
||||
macro_rules! impl_phrase_view_state {
|
||||
($Struct:ident $(:: $field:ident)* [$self1:ident : $focused:expr] [$self2:ident : $entered:expr]) => {
|
||||
impl PhraseViewState for $Struct {
|
||||
fn phrase_editing (&self) -> &Option<Arc<RwLock<Phrase>>> {
|
||||
&self$(.$field)*.phrase
|
||||
}
|
||||
fn phrase_editor_focused (&$self1) -> bool {
|
||||
$focused
|
||||
//self$(.$field)*.focus.is_focused()
|
||||
}
|
||||
fn phrase_editor_entered (&$self2) -> bool {
|
||||
$entered
|
||||
//self$(.$field)*.focus.is_entered()
|
||||
}
|
||||
fn phrase_editor_size (&self) -> &Measure<Tui> {
|
||||
todo!()
|
||||
}
|
||||
fn keys (&self) -> &Buffer {
|
||||
&self$(.$field)*.keys
|
||||
}
|
||||
fn buffer (&self) -> &BigBuffer {
|
||||
&self$(.$field)*.buffer
|
||||
}
|
||||
fn note_len (&self) -> usize {
|
||||
self$(.$field)*.note_len
|
||||
}
|
||||
fn note_axis (&self) -> &RwLock<FixedAxis<usize>> {
|
||||
&self$(.$field)*.note_axis
|
||||
}
|
||||
fn time_axis (&self) -> &RwLock<ScaledAxis<usize>> {
|
||||
&self$(.$field)*.time_axis
|
||||
}
|
||||
fn now (&self) -> &Arc<Pulse> {
|
||||
&self$(.$field)*.now
|
||||
}
|
||||
fn size (&self) -> &Measure<Tui> {
|
||||
&self$(.$field)*.size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_phrase_view_state!(PhraseEditorModel
|
||||
[self: true]
|
||||
[self: true]
|
||||
);
|
||||
impl_phrase_view_state!(SequencerTui::editor
|
||||
[self: self.focused() == AppFocus::Content(SequencerFocus::PhraseEditor)]
|
||||
[self: self.entered() && self.focused() == AppFocus::Content(SequencerFocus::PhraseEditor)]
|
||||
);
|
||||
impl_phrase_view_state!(ArrangerTui::editor
|
||||
[self: self.focused() == AppFocus::Content(ArrangerFocus::PhraseEditor)]
|
||||
[self: self.entered() && self.focused() == AppFocus::Content(ArrangerFocus::PhraseEditor)])
|
||||
;
|
||||
|
||||
/// Colors of piano keys
|
||||
const KEY_COLORS: [(Color, Color);6] = [
|
||||
(Color::Rgb(255, 255, 255), Color::Rgb(255, 255, 255)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue