wip: fixing the modal

This commit is contained in:
🪞👃🪞 2024-09-26 03:29:18 +03:00
parent 29f11b5977
commit 2adf0028c3
5 changed files with 57 additions and 69 deletions

View file

@ -178,6 +178,11 @@ impl<H, E: Engine> Handle<E> for Arc<RwLock<H>> where H: Handle<E> {
pub trait Component<E: Engine>: Widget<Engine = E> + Handle<E> {} pub trait Component<E: Engine>: Widget<Engine = E> + Handle<E> {}
/// Everything that implements [Render] and [Handle] is a [Component]. /// Everything that implements [Render] and [Handle] is a [Component].
impl<E: Engine, C: Widget<Engine = E> + Handle<E>> Component<E> for C {} impl<E: Engine, C: Widget<Engine = E> + Handle<E>> Component<E> for C {}
/// A UI component that can render itself and handle input
pub trait ContentComponent<E: Engine>: Widget<Engine = E> + Handle<E> {}
/// Everything that implements [Render] and [Handle] is a [Component].
impl<E: Engine, C: Content<Engine = E> + Handle<E>> ContentComponent<E> for C {}
pub trait Exit: Send { pub trait Exit: Send {
fn exited (&self) -> bool; fn exited (&self) -> bool;
fn exit (&mut self); fn exit (&mut self);
@ -185,6 +190,7 @@ pub trait Exit: Send {
Box::new(self) Box::new(self)
} }
} }
/// Marker trait for [Component]s that can [Exit] /// Marker trait for [Component]s that can [Exit]
pub trait ExitableComponent<E>: Exit + Component<E> where E: Engine { pub trait ExitableComponent<E>: Exit + Component<E> where E: Engine {
/// Perform type erasure for collecting heterogeneous components. /// Perform type erasure for collecting heterogeneous components.

View file

@ -217,15 +217,7 @@ impl<E: Engine, W: Widget<Engine = E>> Layout<E> for W {}
pub struct DebugOverlay<E: Engine, W: Widget<Engine = E>>(pub W); pub struct DebugOverlay<E: Engine, W: Widget<Engine = E>>(pub W);
pub struct ModalHost<E: Engine, M: Widget<Engine = E>, W: Widget<Engine = E>>( pub enum Fill<E: Engine, W: Widget<Engine = E>> { X(W), Y(W), XY(W) }
pub bool, pub M, pub W
);
pub enum Fill<E: Engine, W: Widget<Engine = E>> {
X(W),
Y(W),
XY(W)
}
impl<E: Engine, W: Widget<Engine = E>> Fill<E, W> { impl<E: Engine, W: Widget<Engine = E>> Fill<E, W> {
fn inner (&self) -> &W { fn inner (&self) -> &W {

View file

@ -410,21 +410,6 @@ pub trait TuiStyle: Widget<Engine = Tui> + Sized {
} }
} }
impl<W: Widget<Engine = Tui>> TuiStyle for W {} impl<W: Widget<Engine = Tui>> TuiStyle for W {}
impl<M: Widget<Engine = Tui>, W: Widget<Engine = Tui>> Widget for ModalHost<Tui, M, W> {
type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
Ok(Some(to))
}
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
self.2.render(to)?;
if self.0 {
to.fill_bg(to.area(), COLOR_BG1);
to.fill_fg(to.area(), COLOR_BG2);
self.1.render(to)?;
}
Ok(())
}
}
pub struct Foreground(pub Color); pub struct Foreground(pub Color);
impl Widget for Foreground { impl Widget for Foreground {

View file

@ -72,27 +72,33 @@ struct ArrangerStandalone<E: Engine> {
impl Content for ArrangerStandalone<Tui> { impl Content for ArrangerStandalone<Tui> {
type Engine = Tui; type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> { fn content (&self) -> impl Widget<Engine = Tui> {
let show = self.arranger.modal.is_some(); Layers::new(|add|{
let modal = self.arranger.modal.as_ref().map(|x|x as &dyn Content<Engine = Tui>); add(&Split::down(move|add|{
ModalHost(show, modal, Split::down(move|add|{ add(&(&self.transport as &dyn Widget<Engine = Tui>).debug())?;
add(&(&self.transport as &dyn Widget<Engine = Tui>).debug())?; if let (Some(direction), Some(sequencer)) = (
if let (Some(direction), Some(sequencer)) = ( self.show_sequencer,
self.show_sequencer, self.arranger.sequencer(),
self.arranger.sequencer(), ) {
) { add(&Split::new(direction, move|add|{
add(&Split::new(direction, move|add|{ add(&(&self.arranger as &dyn Widget<Engine = Tui>)
add(&(&self.arranger as &dyn Widget<Engine = Tui>) .shrink_y(30)
.shrink_y(30) .debug())?;
.debug())?; add(&(sequencer as &dyn Widget<Engine = Tui>)
add(&(sequencer as &dyn Widget<Engine = Tui>) .min_y(20)
.min_y(20) .debug())?;
.debug())?; Ok(())
Ok(()) }))
})) } else {
} else { add(&self.arranger)
add(&self.arranger) }
}));
if let Some(ref modal) = self.arranger.modal {
add(&Background(COLOR_BG1))?;
add(&Foreground(COLOR_BG2))?;
add(&modal as &dyn Widget<Engine = Tui>)?;
} }
})) Ok(())
})
} }
} }

View file

@ -34,7 +34,7 @@ pub struct Arranger<E: Engine> {
/// Display mode of arranger /// Display mode of arranger
pub mode: ArrangerViewMode, pub mode: ArrangerViewMode,
/// Slot for modal dialog displayed on top of app. /// Slot for modal dialog displayed on top of app.
pub modal: Option<Box<dyn ExitableComponent<E>>>, pub modal: Option<Box<dyn ContentComponent<E>>>,
/// Whether the arranger is currently focused /// Whether the arranger is currently focused
pub focused: bool pub focused: bool
} }
@ -223,7 +223,7 @@ impl Handle<Tui> for Arranger<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> { fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
if let Some(modal) = self.modal.as_mut() { if let Some(modal) = self.modal.as_mut() {
let result = modal.handle(from)?; let result = modal.handle(from)?;
if modal.exited() { if from.is_done() {
self.modal = None; self.modal = None;
} }
return Ok(result) return Ok(result)
@ -974,31 +974,30 @@ impl<E: Engine> ArrangerRenameModal<E> {
} }
} }
impl Widget for ArrangerRenameModal<Tui> { impl Content for ArrangerRenameModal<Tui> {
type Engine = Tui; type Engine = Tui;
fn layout (&self, _to: [u16;2]) -> Perhaps<[u16;2]> { fn content (&self) -> impl Widget<Engine = Tui> {
todo!() todo!();
} Layers::new(|add|{Ok(())})
fn render (&self, to: &mut TuiOutput) -> Usually<()> { //let area = to.area();
let area = to.area(); //let y = area.y() + area.h() / 2;
let y = area.y() + area.h() / 2; //let bg_area = [1, y - 1, area.w() - 2, 3];
let bg_area = [1, y - 1, area.w() - 2, 3]; //to.fill_bg(bg_area, COLOR_BG1);
to.fill_bg(bg_area, COLOR_BG1); //Lozenge(Style::default().bold().white().dim()).draw(to.with_rect(bg_area));
Lozenge(Style::default().bold().white().dim()).draw(to.with_rect(bg_area)); //let label = match self.target {
let label = match self.target { //ArrangerFocus::Mix => "Rename project:",
ArrangerFocus::Mix => "Rename project:", //ArrangerFocus::Track(_) => "Rename track:",
ArrangerFocus::Track(_) => "Rename track:", //ArrangerFocus::Scene(_) => "Rename scene:",
ArrangerFocus::Scene(_) => "Rename scene:", //ArrangerFocus::Clip(_, _) => "Rename clip:",
ArrangerFocus::Clip(_, _) => "Rename clip:", //};
}; //let style = Some(Style::default().not_bold().white().not_dim());
let style = Some(Style::default().not_bold().white().not_dim()); //to.blit(&label, area.x() + 3, y, style);
to.blit(&label, area.x() + 3, y, style); //let style = Some(Style::default().bold().white().not_dim());
let style = Some(Style::default().bold().white().not_dim()); //to.blit(&self.value, area.x() + 3 + label.len() as u16 + 1, y, style);
to.blit(&self.value, area.x() + 3 + label.len() as u16 + 1, y, style); //let style = Some(Style::default().bold().white().not_dim().reversed());
let style = Some(Style::default().bold().white().not_dim().reversed()); //to.blit(&"▂", area.x() + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style);
to.blit(&"", area.x() + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style);
//Ok(Some(area)) //Ok(Some(area))
Ok(()) //Ok(())
} }
} }