mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
why do the borders think they are enabled
This commit is contained in:
parent
1463460c4f
commit
3a6202464c
5 changed files with 135 additions and 167 deletions
|
|
@ -32,7 +32,7 @@ content!(TuiOut: |self: SamplerTui| {
|
||||||
let keys = move||"";//SamplerKeys(self);
|
let keys = move||"";//SamplerKeys(self);
|
||||||
let fg = self.color.base.rgb;
|
let fg = self.color.base.rgb;
|
||||||
let bg = self.color.darkest.rgb;
|
let bg = self.color.darkest.rgb;
|
||||||
let border = Fill::xy(Outer(Style::default().fg(fg).bg(bg)));
|
let border = Fill::xy(Outer(true, Style::default().fg(fg).bg(bg)));
|
||||||
let with_border = |x|lay!(border, Fill::xy(x));
|
let with_border = |x|lay!(border, Fill::xy(x));
|
||||||
let with_size = |x|lay!(self.size.clone(), x);
|
let with_size = |x|lay!(self.size.clone(), x);
|
||||||
Tui::bg(bg, Fill::xy(with_border(Bsp::s(
|
Tui::bg(bg, Fill::xy(with_border(Bsp::s(
|
||||||
|
|
@ -83,7 +83,7 @@ impl Sampler {
|
||||||
let note_lo = editor.note_lo().load(Relaxed);
|
let note_lo = editor.note_lo().load(Relaxed);
|
||||||
let note_pt = editor.note_pos();
|
let note_pt = editor.note_pos();
|
||||||
let note_hi = editor.note_hi();
|
let note_hi = editor.note_hi();
|
||||||
Outer(Style::default().fg(TuiTheme::g(96))).enclose(Map::new(move||(note_lo..=note_hi).rev(), move|note, i| {
|
Outer(true, Style::default().fg(TuiTheme::g(96))).enclose(Map::new(move||(note_lo..=note_hi).rev(), move|note, i| {
|
||||||
let offset = |a|Push::y(i as u16, Align::n(Fixed::y(1, Fill::x(a))));
|
let offset = |a|Push::y(i as u16, Align::n(Fixed::y(1, Fill::x(a))));
|
||||||
let mut bg = if note == note_pt { TuiTheme::g(64) } else { Color::Reset };
|
let mut bg = if note == note_pt { TuiTheme::g(64) } else { Color::Reset };
|
||||||
let mut fg = TuiTheme::g(160);
|
let mut fg = TuiTheme::g(160);
|
||||||
|
|
|
||||||
173
tek/src/lib.rs
173
tek/src/lib.rs
|
|
@ -200,23 +200,68 @@ edn_view!(TuiOut: |self: Tek| self.size.of(EdnView::from_source(self, self.edn.a
|
||||||
":tracks" => self.view_row(self.w(), 3, self.track_header(), self.track_cells()).boxed(),
|
":tracks" => self.view_row(self.w(), 3, self.track_header(), self.track_cells()).boxed(),
|
||||||
":inputs" => self.view_row(self.w(), 3, self.input_header(), self.input_cells()).boxed(),
|
":inputs" => self.view_row(self.w(), 3, self.input_header(), self.input_cells()).boxed(),
|
||||||
":outputs" => self.view_row(self.w(), 3, self.output_header(), self.output_cells()).boxed(),
|
":outputs" => self.view_row(self.w(), 3, self.output_header(), self.output_cells()).boxed(),
|
||||||
":scenes" => Outer(Style::default().fg(TuiTheme::g(0))).enclose_bg(self.view_row(
|
":scenes" => Outer(false, Style::default().fg(TuiTheme::g(0))).enclose_bg(self.view_row(
|
||||||
self.w(), self.size.h().saturating_sub(12) as u16,
|
self.w(), self.size.h().saturating_sub(12) as u16,
|
||||||
self.scene_header(), self.clip_columns()
|
self.scene_header(), self.clip_columns()
|
||||||
)).boxed() }});
|
)).boxed() }});
|
||||||
impl Tek {
|
impl Tek {
|
||||||
|
fn new_clock (
|
||||||
|
jack: &Arc<RwLock<JackConnection>>,
|
||||||
|
bpm: Option<f64>, sync_lead: bool, sync_follow: bool,
|
||||||
|
midi_froms: &[PortConnection], midi_tos: &[PortConnection],
|
||||||
|
) -> Usually<Self> {
|
||||||
|
let tek = Self {
|
||||||
|
edn: include_str!("./view_transport.edn").to_string(),
|
||||||
|
jack: jack.clone(),
|
||||||
|
color: ItemPalette::random(),
|
||||||
|
clock: Clock::new(jack, bpm),
|
||||||
|
midi_ins: vec![JackPort::<MidiIn>::new(jack, "GlobalI", midi_froms)?],
|
||||||
|
midi_outs: vec![JackPort::<MidiOut>::new(jack, "GlobalO", midi_tos)?],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
tek.sync_lead(sync_lead);
|
||||||
|
tek.sync_follow(sync_follow);
|
||||||
|
Ok(tek)
|
||||||
|
}
|
||||||
|
fn new_sequencer (
|
||||||
|
jack: &Arc<RwLock<JackConnection>>,
|
||||||
|
bpm: Option<f64>, sync_lead: bool, sync_follow: bool,
|
||||||
|
midi_froms: &[PortConnection], midi_tos: &[PortConnection],
|
||||||
|
) -> Usually<Self> {
|
||||||
|
let clip = MidiClip::new("Clip", true, 384usize, None, Some(ItemColor::random().into()));
|
||||||
|
let clip = Arc::new(RwLock::new(clip));
|
||||||
|
Ok(Self {
|
||||||
|
edn: include_str!("./view_sequencer.edn").to_string(),
|
||||||
|
pool: Some((&clip).into()),
|
||||||
|
editor: Some((&clip).into()),
|
||||||
|
editing: false.into(),
|
||||||
|
midi_buf: vec![vec![];65536],
|
||||||
|
player: Some(MidiPlayer::new(&jack, "sequencer", Some(&clip), &midi_froms, &midi_tos)?),
|
||||||
|
..Self::new_clock(jack, bpm, sync_lead, sync_follow, midi_froms, midi_tos)?
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn new_groovebox (
|
||||||
|
jack: &Arc<RwLock<JackConnection>>,
|
||||||
|
bpm: Option<f64>, sync_lead: bool, sync_follow: bool,
|
||||||
|
midi_froms: &[PortConnection], midi_tos: &[PortConnection],
|
||||||
|
audio_froms: &[&[PortConnection];2], audio_tos: &[&[PortConnection];2],
|
||||||
|
) -> Usually<Self> {
|
||||||
|
let app = Self {
|
||||||
|
edn: include_str!("./view_groovebox.edn").to_string(),
|
||||||
|
sampler: Some(Sampler::new(jack, &"sampler", midi_froms, audio_froms, audio_tos)?),
|
||||||
|
..Self::new_sequencer(jack, bpm, sync_lead, sync_follow, midi_froms, midi_tos)?
|
||||||
|
};
|
||||||
|
if let Some(sampler) = app.sampler.as_ref().unwrap().midi_in.as_ref() {
|
||||||
|
jack.connect_ports(&app.player.as_ref().unwrap().midi_outs[0].port, &sampler.port)?;
|
||||||
|
}
|
||||||
|
Ok(app)
|
||||||
|
}
|
||||||
fn new_arranger (
|
fn new_arranger (
|
||||||
jack: &Arc<RwLock<JackConnection>>,
|
jack: &Arc<RwLock<JackConnection>>,
|
||||||
bpm: Option<f64>,
|
bpm: Option<f64>, sync_lead: bool, sync_follow: bool,
|
||||||
sync_lead: bool,
|
midi_froms: &[PortConnection], midi_tos: &[PortConnection],
|
||||||
sync_follow: bool,
|
audio_froms: &[&[PortConnection];2], audio_tos: &[&[PortConnection];2],
|
||||||
midi_froms: &[PortConnection],
|
scenes: usize, tracks: usize, track_width: usize,
|
||||||
midi_tos: &[PortConnection],
|
|
||||||
audio_froms: &[&[PortConnection];2],
|
|
||||||
audio_tos: &[&[PortConnection];2],
|
|
||||||
scenes: usize,
|
|
||||||
tracks: usize,
|
|
||||||
track_width: usize,
|
|
||||||
) -> Usually<Self> {
|
) -> Usually<Self> {
|
||||||
let mut arranger = Self {
|
let mut arranger = Self {
|
||||||
edn: include_str!("./view_arranger.edn").to_string(),
|
edn: include_str!("./view_arranger.edn").to_string(),
|
||||||
|
|
@ -240,6 +285,21 @@ impl Tek {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn scene_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
||||||
|
-> Usually<(usize, &mut Scene)>
|
||||||
|
{
|
||||||
|
let scene = Scene {
|
||||||
|
name: name.map_or_else(||self.scene_default_name(), |x|x.to_string().into()),
|
||||||
|
clips: vec![None;self.tracks().len()],
|
||||||
|
color: color.unwrap_or_else(ItemPalette::random),
|
||||||
|
};
|
||||||
|
self.scenes_mut().push(scene);
|
||||||
|
let index = self.scenes().len() - 1;
|
||||||
|
Ok((index, &mut self.scenes_mut()[index]))
|
||||||
|
}
|
||||||
|
fn scene_default_name (&self) -> Arc<str> {
|
||||||
|
format!("Sc{:3>}", self.scenes().len() + 1).into()
|
||||||
|
}
|
||||||
fn tracks_add (
|
fn tracks_add (
|
||||||
&mut self, count: usize, width: usize,
|
&mut self, count: usize, width: usize,
|
||||||
midi_from: &[PortConnection], midi_to: &[PortConnection],
|
midi_from: &[PortConnection], midi_to: &[PortConnection],
|
||||||
|
|
@ -282,71 +342,6 @@ impl Tek {
|
||||||
}
|
}
|
||||||
Ok((index, &mut self.tracks_mut()[index]))
|
Ok((index, &mut self.tracks_mut()[index]))
|
||||||
}
|
}
|
||||||
fn new_groovebox (
|
|
||||||
jack: &Arc<RwLock<JackConnection>>,
|
|
||||||
bpm: Option<f64>,
|
|
||||||
sync_lead: bool,
|
|
||||||
sync_follow: bool,
|
|
||||||
midi_froms: &[PortConnection],
|
|
||||||
midi_tos: &[PortConnection],
|
|
||||||
audio_froms: &[&[PortConnection];2],
|
|
||||||
audio_tos: &[&[PortConnection];2],
|
|
||||||
) -> Usually<Self> {
|
|
||||||
let app = Self {
|
|
||||||
edn: include_str!("./view_groovebox.edn").to_string(),
|
|
||||||
sampler: Some(Sampler::new(jack, &"sampler", midi_froms, audio_froms, audio_tos)?),
|
|
||||||
..Self::new_sequencer(jack, bpm, sync_lead, sync_follow, midi_froms, midi_tos)?
|
|
||||||
};
|
|
||||||
if let Some(sampler) = app.sampler.as_ref().unwrap().midi_in.as_ref() {
|
|
||||||
jack.connect_ports(&app.player.as_ref().unwrap().midi_outs[0].port, &sampler.port)?;
|
|
||||||
}
|
|
||||||
Ok(app)
|
|
||||||
}
|
|
||||||
fn new_sequencer (
|
|
||||||
jack: &Arc<RwLock<JackConnection>>,
|
|
||||||
bpm: Option<f64>,
|
|
||||||
sync_lead: bool,
|
|
||||||
sync_follow: bool,
|
|
||||||
midi_froms: &[PortConnection],
|
|
||||||
midi_tos: &[PortConnection],
|
|
||||||
) -> Usually<Self> {
|
|
||||||
let clip = MidiClip::new("Clip", true, 384usize, None, Some(ItemColor::random().into()));
|
|
||||||
let clip = Arc::new(RwLock::new(clip));
|
|
||||||
Ok(Self {
|
|
||||||
edn: include_str!("./view_sequencer.edn").to_string(),
|
|
||||||
pool: Some((&clip).into()),
|
|
||||||
editor: Some((&clip).into()),
|
|
||||||
editing: false.into(),
|
|
||||||
midi_buf: vec![vec![];65536],
|
|
||||||
player: Some(MidiPlayer::new(&jack, "sequencer", Some(&clip), &midi_froms, &midi_tos)?),
|
|
||||||
..Self::new_clock(jack, bpm, sync_lead, sync_follow, midi_froms, midi_tos)?
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn new_clock (
|
|
||||||
jack: &Arc<RwLock<JackConnection>>,
|
|
||||||
bpm: Option<f64>,
|
|
||||||
sync_lead: bool,
|
|
||||||
sync_follow: bool,
|
|
||||||
midi_froms: &[PortConnection],
|
|
||||||
midi_tos: &[PortConnection],
|
|
||||||
) -> Usually<Self> {
|
|
||||||
let tek = Self {
|
|
||||||
edn: include_str!("./view_transport.edn").to_string(),
|
|
||||||
jack: jack.clone(),
|
|
||||||
color: ItemPalette::random(),
|
|
||||||
clock: Clock::new(jack, bpm),
|
|
||||||
midi_ins: vec![
|
|
||||||
JackPort::<MidiIn>::new(jack, "GlobalI", midi_froms)?
|
|
||||||
],
|
|
||||||
midi_outs: vec![
|
|
||||||
JackPort::<MidiOut>::new(jack, "GlobalO", midi_tos)?
|
|
||||||
],
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
tek.sync_lead(sync_lead);
|
|
||||||
tek.sync_follow(sync_follow);
|
|
||||||
Ok(tek)
|
|
||||||
}
|
|
||||||
fn sync_lead (&self, enable: bool) -> Usually<()> {
|
fn sync_lead (&self, enable: bool) -> Usually<()> {
|
||||||
if enable {
|
if enable {
|
||||||
self.jack.read().unwrap().client().register_timebase_callback(false, |mut state|{
|
self.jack.read().unwrap().client().register_timebase_callback(false, |mut state|{
|
||||||
|
|
@ -363,7 +358,7 @@ impl Tek {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn view_clock (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_clock (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
Outer(Style::default().fg(TuiTheme::g(0))).enclose(row!(
|
Outer(false, Style::default().fg(TuiTheme::g(0))).enclose(row!(
|
||||||
self.view_engine_stats(), " ",
|
self.view_engine_stats(), " ",
|
||||||
self.view_play_pause(), " ",
|
self.view_play_pause(), " ",
|
||||||
self.view_beat_stats(),
|
self.view_beat_stats(),
|
||||||
|
|
@ -485,25 +480,13 @@ impl Tek {
|
||||||
scene.clips.remove(index);
|
scene.clips.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn scene_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
|
||||||
-> Usually<(usize, &mut Scene)>
|
|
||||||
{
|
|
||||||
let scene = Scene {
|
|
||||||
name: name.map_or_else(||self.scene_default_name(), |x|x.to_string().into()),
|
|
||||||
clips: vec![None;self.tracks().len()],
|
|
||||||
color: color.unwrap_or_else(ItemPalette::random),
|
|
||||||
};
|
|
||||||
self.scenes_mut().push(scene);
|
|
||||||
let index = self.scenes().len() - 1;
|
|
||||||
Ok((index, &mut self.scenes_mut()[index]))
|
|
||||||
}
|
|
||||||
fn clip_columns <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
fn clip_columns <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||||
let editing = self.is_editing();
|
let editing = self.is_editing();
|
||||||
let tracks = move||self.tracks_sizes(editing, self.editor_w());
|
let tracks = move||self.tracks_sizes(editing, self.editor_w());
|
||||||
let scenes = move||self.scenes_sizes(editing, 2, 15);
|
let scenes = move||self.scenes_sizes(editing, 2, 15);
|
||||||
let selected_track = self.selected().track();
|
let selected_track = self.selected().track();
|
||||||
let selected_scene = self.selected().scene();
|
let selected_scene = self.selected().scene();
|
||||||
let border = |x|Outer(Style::default().fg(TuiTheme::g(0))).enclose(x);
|
let border = |x|Outer(false, Style::default().fg(TuiTheme::g(0))).enclose(x);
|
||||||
(move||Align::c(Map::new(tracks, move|(_, track, x1, x2), t| {
|
(move||Align::c(Map::new(tracks, move|(_, track, x1, x2), t| {
|
||||||
let w = (x2 - x1) as u16;
|
let w = (x2 - x1) as u16;
|
||||||
let color: ItemPalette = track.color.dark.into();
|
let color: ItemPalette = track.color.dark.into();
|
||||||
|
|
@ -955,7 +938,8 @@ trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
||||||
let bfg = if active { Color::Rgb(255,255,255) } else { Color::Rgb(0,0,0) };
|
let bfg = if active { Color::Rgb(255,255,255) } else { Color::Rgb(0,0,0) };
|
||||||
let border = Style::default().fg(bfg).bg(bg);
|
let border = Style::default().fg(bfg).bg(bg);
|
||||||
Tui::bg(bg, map_east(x1 as u16, (x2 - x1) as u16,
|
Tui::bg(bg, map_east(x1 as u16, (x2 - x1) as u16,
|
||||||
Outer(border).enclose(Tui::fg_bg(fg, bg, Tui::bold(true, Fill::x(Align::x(name)))))
|
Outer(false, border)
|
||||||
|
.enclose(Tui::fg_bg(fg, bg, Tui::bold(true, Fill::x(Align::x(name)))))
|
||||||
))
|
))
|
||||||
})).boxed()).into()
|
})).boxed()).into()
|
||||||
}
|
}
|
||||||
|
|
@ -1107,9 +1091,6 @@ trait HasScenes: HasSelection + HasEditor + Send + Sync {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn scene_default_name (&self) -> Arc<str> {
|
|
||||||
format!("Sc{:3>}", self.scenes().len() + 1).into()
|
|
||||||
}
|
|
||||||
fn scene (&self) -> Option<&Scene> {
|
fn scene (&self) -> Option<&Scene> {
|
||||||
self.selected().scene().and_then(|s|self.scenes().get(s))
|
self.selected().scene().and_then(|s|self.scenes().get(s))
|
||||||
}
|
}
|
||||||
|
|
@ -1142,7 +1123,7 @@ trait HasScenes: HasSelection + HasEditor + Send + Sync {
|
||||||
);
|
);
|
||||||
*last_color.write().unwrap() = color;
|
*last_color.write().unwrap() = color;
|
||||||
map_south(y1 as u16, h, Push::y(1, Fixed::y(h,
|
map_south(y1 as u16, h, Push::y(1, Fixed::y(h,
|
||||||
Outer(Style::default().fg(TuiTheme::g(0))).enclose(cell))))
|
Outer(false, Style::default().fg(TuiTheme::g(0))).enclose(cell))))
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}).into()
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,42 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub struct Bordered<S: BorderStyle, W: Content<TuiOut>>(pub S, pub W);
|
pub struct Bordered<S: BorderStyle, W: Content<TuiOut>>(pub bool, pub S, pub W);
|
||||||
content!(TuiOut: |self: Bordered<S: BorderStyle, W: Content<TuiOut>>|Fill::xy(
|
content!(TuiOut: |self: Bordered<S: BorderStyle, W: Content<TuiOut>>|Fill::xy(
|
||||||
lay!(Border(self.0), Padding::xy(1, 1, &self.1))
|
lay!(When::new(self.0, Border(self.0, self.1)), Padding::xy(1, 1, &self.2))
|
||||||
));
|
));
|
||||||
|
|
||||||
pub struct Border<S: BorderStyle>(pub S);
|
pub struct Border<S: BorderStyle>(pub bool, pub S);
|
||||||
render!(TuiOut: |self: Border<S: BorderStyle>, to| {
|
render!(TuiOut: |self: Border<S: BorderStyle>, to| {
|
||||||
let area = to.area();
|
if self.0 {
|
||||||
if area.w() > 0 && area.y() > 0 {
|
let area = to.area();
|
||||||
to.blit(&self.0.nw(), area.x(), area.y(), self.0.style());
|
if area.w() > 0 && area.y() > 0 {
|
||||||
to.blit(&self.0.ne(), area.x() + area.w() - 1, area.y(), self.0.style());
|
to.blit(&self.1.nw(), area.x(), area.y(), self.1.style());
|
||||||
to.blit(&self.0.sw(), area.x(), area.y() + area.h() - 1, self.0.style());
|
to.blit(&self.1.ne(), area.x() + area.w() - 1, area.y(), self.1.style());
|
||||||
to.blit(&self.0.se(), area.x() + area.w() - 1, area.y() + area.h() - 1, self.0.style());
|
to.blit(&self.1.sw(), area.x(), area.y() + area.h() - 1, self.1.style());
|
||||||
for x in area.x()+1..area.x()+area.w()-1 {
|
to.blit(&self.1.se(), area.x() + area.w() - 1, area.y() + area.h() - 1, self.1.style());
|
||||||
to.blit(&self.0.n(), x, area.y(), self.0.style());
|
for x in area.x()+1..area.x()+area.w()-1 {
|
||||||
to.blit(&self.0.s(), x, area.y() + area.h() - 1, self.0.style());
|
to.blit(&self.1.n(), x, area.y(), self.1.style());
|
||||||
}
|
to.blit(&self.1.s(), x, area.y() + area.h() - 1, self.1.style());
|
||||||
for y in area.y()+1..area.y()+area.h()-1 {
|
}
|
||||||
to.blit(&self.0.w(), area.x(), y, self.0.style());
|
for y in area.y()+1..area.y()+area.h()-1 {
|
||||||
to.blit(&self.0.e(), area.x() + area.w() - 1, y, self.0.style());
|
to.blit(&self.1.w(), area.x(), y, self.1.style());
|
||||||
|
to.blit(&self.1.e(), area.x() + area.w() - 1, y, self.1.style());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pub trait BorderStyle: Send + Sync + Copy {
|
pub trait BorderStyle: Send + Sync + Copy {
|
||||||
fn wrap <W: Content<TuiOut>> (self, w: W) -> Bordered<Self, W> {
|
fn enabled (&self) -> bool;
|
||||||
Bordered(self, w)
|
|
||||||
}
|
|
||||||
fn enclose <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
fn enclose <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
||||||
lay!(Fill::xy(Border(self)), w)
|
Bsp::b(Fill::xy(Border(self.enabled(), self)), w)
|
||||||
}
|
}
|
||||||
fn enclose2 <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
fn enclose2 <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
||||||
Bsp::b(Margin::xy(1, 1, Fill::xy(Border(self))), w)
|
Bsp::b(Margin::xy(1, 1, Fill::xy(Border(self.enabled(), self))), w)
|
||||||
}
|
}
|
||||||
fn enclose_bg <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
fn enclose_bg <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
|
||||||
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset), lay!(
|
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset),
|
||||||
Fill::xy(Border(self)),
|
Bsp::b(Fill::xy(Border(self.enabled(), self)), w))
|
||||||
w
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
const NW: &'static str = "";
|
const NW: &'static str = "";
|
||||||
const N: &'static str = "";
|
const N: &'static str = "";
|
||||||
|
|
@ -65,9 +63,11 @@ pub trait BorderStyle: Send + Sync + Copy {
|
||||||
#[inline] fn draw <'a> (
|
#[inline] fn draw <'a> (
|
||||||
&self, to: &mut TuiOut
|
&self, to: &mut TuiOut
|
||||||
) -> Usually<()> {
|
) -> Usually<()> {
|
||||||
self.draw_horizontal(to, None)?;
|
if self.enabled() {
|
||||||
self.draw_vertical(to, None)?;
|
self.draw_horizontal(to, None)?;
|
||||||
self.draw_corners(to, None)?;
|
self.draw_vertical(to, None)?;
|
||||||
|
self.draw_corners(to, None)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[inline] fn draw_horizontal (
|
#[inline] fn draw_horizontal (
|
||||||
|
|
@ -135,11 +135,13 @@ macro_rules! border {
|
||||||
const S: &'static str = $s;
|
const S: &'static str = $s;
|
||||||
const SE: &'static str = $se;
|
const SE: &'static str = $se;
|
||||||
$($x)*
|
$($x)*
|
||||||
|
fn enabled (&self) -> bool { self.0 }
|
||||||
}
|
}
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
|
||||||
pub struct $T(pub Style);
|
|
||||||
impl Content<TuiOut> for $T {
|
impl Content<TuiOut> for $T {
|
||||||
fn render (&self, to: &mut TuiOut) { let _ = self.draw(to); }
|
fn render (&self, to: &mut TuiOut) {
|
||||||
|
if self.enabled() { let _ = self.draw(to); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)+}
|
)+}
|
||||||
}
|
}
|
||||||
|
|
@ -148,57 +150,57 @@ border! {
|
||||||
Square {
|
Square {
|
||||||
"┌" "─" "┐"
|
"┌" "─" "┐"
|
||||||
"│" "│"
|
"│" "│"
|
||||||
"└" "─" "┘" fn style (&self) -> Option<Style> { Some(self.0) }
|
"└" "─" "┘" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
SquareBold {
|
SquareBold {
|
||||||
"┏" "━" "┓"
|
"┏" "━" "┓"
|
||||||
"┃" "┃"
|
"┃" "┃"
|
||||||
"┗" "━" "┛" fn style (&self) -> Option<Style> { Some(self.0) }
|
"┗" "━" "┛" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
TabLike {
|
TabLike {
|
||||||
"╭" "─" "╮"
|
"╭" "─" "╮"
|
||||||
"│" "│"
|
"│" "│"
|
||||||
"│" " " "│" fn style (&self) -> Option<Style> { Some(self.0) }
|
"│" " " "│" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Lozenge {
|
Lozenge {
|
||||||
"╭" "─" "╮"
|
"╭" "─" "╮"
|
||||||
"│" "│"
|
"│" "│"
|
||||||
"╰" "─" "╯" fn style (&self) -> Option<Style> { Some(self.0) }
|
"╰" "─" "╯" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Brace {
|
Brace {
|
||||||
"╭" "" "╮"
|
"╭" "" "╮"
|
||||||
"│" "│"
|
"│" "│"
|
||||||
"╰" "" "╯" fn style (&self) -> Option<Style> { Some(self.0) }
|
"╰" "" "╯" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
LozengeDotted {
|
LozengeDotted {
|
||||||
"╭" "┅" "╮"
|
"╭" "┅" "╮"
|
||||||
"┇" "┇"
|
"┇" "┇"
|
||||||
"╰" "┅" "╯" fn style (&self) -> Option<Style> { Some(self.0) }
|
"╰" "┅" "╯" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Quarter {
|
Quarter {
|
||||||
"▎" "▔" "🮇"
|
"▎" "▔" "🮇"
|
||||||
"▎" "🮇"
|
"▎" "🮇"
|
||||||
"▎" "▁" "🮇" fn style (&self) -> Option<Style> { Some(self.0) }
|
"▎" "▁" "🮇" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
QuarterV {
|
QuarterV {
|
||||||
"▎" "" "🮇"
|
"▎" "" "🮇"
|
||||||
"▎" "🮇"
|
"▎" "🮇"
|
||||||
"▎" "" "🮇" fn style (&self) -> Option<Style> { Some(self.0) }
|
"▎" "" "🮇" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Chamfer {
|
Chamfer {
|
||||||
"🭂" "▔" "🭍"
|
"🭂" "▔" "🭍"
|
||||||
"▎" "🮇"
|
"▎" "🮇"
|
||||||
"🭓" "▁" "🭞" fn style (&self) -> Option<Style> { Some(self.0) }
|
"🭓" "▁" "🭞" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Corners {
|
Corners {
|
||||||
"🬆" "" "🬊" // 🬴 🬸
|
"🬆" "" "🬊" // 🬴 🬸
|
||||||
"" ""
|
"" ""
|
||||||
"🬱" "" "🬵" fn style (&self) -> Option<Style> { Some(self.0) }
|
"🬱" "" "🬵" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
CornersTall {
|
CornersTall {
|
||||||
"🭽" "" "🭾"
|
"🭽" "" "🭾"
|
||||||
"" ""
|
"" ""
|
||||||
"🭼" "" "🭿" fn style (&self) -> Option<Style> { Some(self.0) }
|
"🭼" "" "🭿" fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Outer {
|
Outer {
|
||||||
"🭽" "▔" "🭾"
|
"🭽" "▔" "🭾"
|
||||||
|
|
@ -208,25 +210,25 @@ border! {
|
||||||
const E0: &'static str = "]";
|
const E0: &'static str = "]";
|
||||||
const N0: &'static str = "⎴";
|
const N0: &'static str = "⎴";
|
||||||
const S0: &'static str = "⎵";
|
const S0: &'static str = "⎵";
|
||||||
fn style (&self) -> Option<Style> { Some(self.0) }
|
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Phat {
|
Phat {
|
||||||
"▄" "▄" "▄"
|
"▄" "▄" "▄"
|
||||||
"█" "█"
|
"█" "█"
|
||||||
"▀" "▀" "▀"
|
"▀" "▀" "▀"
|
||||||
fn style (&self) -> Option<Style> { Some(self.0) }
|
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Rugged {
|
Rugged {
|
||||||
"▄" "▂" "▄"
|
"▄" "▂" "▄"
|
||||||
"▐" "▌"
|
"▐" "▌"
|
||||||
"▀" "🮂" "▀"
|
"▀" "🮂" "▀"
|
||||||
fn style (&self) -> Option<Style> { Some(self.0) }
|
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Skinny {
|
Skinny {
|
||||||
"▗" "▄" "▖"
|
"▗" "▄" "▖"
|
||||||
"▐" "▌"
|
"▐" "▌"
|
||||||
"▝" "▀" "▘"
|
"▝" "▀" "▘"
|
||||||
fn style (&self) -> Option<Style> { Some(self.0) }
|
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Brackets {
|
Brackets {
|
||||||
"⎡" "" "⎤"
|
"⎡" "" "⎤"
|
||||||
|
|
@ -236,7 +238,7 @@ border! {
|
||||||
const E0: &'static str = "]";
|
const E0: &'static str = "]";
|
||||||
const N0: &'static str = "⎴";
|
const N0: &'static str = "⎴";
|
||||||
const S0: &'static str = "⎵";
|
const S0: &'static str = "⎵";
|
||||||
fn style (&self) -> Option<Style> { Some(self.0) }
|
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
},
|
},
|
||||||
Reticle {
|
Reticle {
|
||||||
"⎡" "" "⎤"
|
"⎡" "" "⎤"
|
||||||
|
|
@ -246,22 +248,6 @@ border! {
|
||||||
const E0: &'static str = "╢";
|
const E0: &'static str = "╢";
|
||||||
const N0: &'static str = "┯";
|
const N0: &'static str = "┯";
|
||||||
const S0: &'static str = "┷";
|
const S0: &'static str = "┷";
|
||||||
fn style (&self) -> Option<Style> { Some(self.0) }
|
fn style (&self) -> Option<Style> { Some(self.1) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CORNERS: Brackets = Brackets(Style {
|
|
||||||
fg: Some(Color::Rgb(96, 255, 32)),
|
|
||||||
bg: None,
|
|
||||||
underline_color: None,
|
|
||||||
add_modifier: Modifier::empty(),
|
|
||||||
sub_modifier: Modifier::DIM
|
|
||||||
});
|
|
||||||
|
|
||||||
pub const RETICLE: Reticle = Reticle(Style {
|
|
||||||
fg: Some(Color::Rgb(96, 255, 32)),
|
|
||||||
bg: None,
|
|
||||||
underline_color: None,
|
|
||||||
add_modifier: Modifier::empty(),
|
|
||||||
sub_modifier: Modifier::DIM
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,8 @@ pub fn phat_sel_3 <T: Content<TuiOut>> (
|
||||||
) -> impl Content<TuiOut> {
|
) -> impl Content<TuiOut> {
|
||||||
let border = Style::default().fg(Color::Rgb(255,255,255)).bg(middle);
|
let border = Style::default().fg(Color::Rgb(255,255,255)).bg(middle);
|
||||||
Either::new(selected,
|
Either::new(selected,
|
||||||
Tui::bg(middle, Outer(border).enclose(Align::w(Bsp::s("", Bsp::n("", Fill::y(field_1)))))),
|
Tui::bg(middle, Outer(true, border)
|
||||||
|
.enclose(Align::w(Bsp::s("", Bsp::n("", Fill::y(field_1)))))),
|
||||||
Bsp::s(Fixed::y(1, top.map(|top|phat_lo(middle, top))),
|
Bsp::s(Fixed::y(1, top.map(|top|phat_lo(middle, top))),
|
||||||
Bsp::n(Fixed::y(1, phat_hi(middle, bottom)),
|
Bsp::n(Fixed::y(1, phat_hi(middle, bottom)),
|
||||||
Fill::xy(Tui::bg(middle, field_2)),
|
Fill::xy(Tui::bg(middle, field_2)),
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ pub trait TuiStyle {
|
||||||
fn fg_bg <R: Content<TuiOut>> (fg: Color, bg: Color, w: R) -> Background<Foreground<R>> {
|
fn fg_bg <R: Content<TuiOut>> (fg: Color, bg: Color, w: R) -> Background<Foreground<R>> {
|
||||||
Background(bg, Foreground(fg, w))
|
Background(bg, Foreground(fg, w))
|
||||||
}
|
}
|
||||||
fn bold <R: Content<TuiOut>> (on: bool, w: R) -> Bold<R> {
|
fn bold <R: Content<TuiOut>> (enable: bool, w: R) -> Bold<R> {
|
||||||
Bold(on, w)
|
Bold(enable, w)
|
||||||
}
|
}
|
||||||
fn border <R: Content<TuiOut>, S: BorderStyle> (style: S, w: R) -> Bordered<S, R> {
|
fn border <R: Content<TuiOut>, S: BorderStyle> (enable: bool, style: S, w: R) -> Bordered<S, R> {
|
||||||
Bordered(style, w)
|
Bordered(enable, style, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue