mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-07-17 15:56:57 +02:00
compiles, once again.
now 616 errors downstream...
This commit is contained in:
parent
eb899906f9
commit
cdc513060d
8 changed files with 196 additions and 201 deletions
206
src/term.rs
206
src/term.rs
|
|
@ -131,26 +131,10 @@ impl Coord for u16 {
|
|||
}
|
||||
|
||||
impl Draw<Tui> for u64 {
|
||||
fn draw (&self, _to: &mut Tui) -> Usually<XYWH<u16>> { todo!() }
|
||||
fn draw (self, _to: &mut Tui) -> Usually<XYWH<u16>> { todo!() }
|
||||
}
|
||||
impl Draw<Tui> for f64 {
|
||||
fn draw (&self, _to: &mut Tui) -> Usually<XYWH<u16>> { todo!() }
|
||||
}
|
||||
impl Draw<Tui> for &str {
|
||||
fn draw (&self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
let XYWH(x, y, w, ..) = to.1.centered_xy([width_chars_max(to.w(), self), 1]);
|
||||
to.text(&self, x, y, w)
|
||||
}
|
||||
}
|
||||
impl Draw<Tui> for String {
|
||||
fn draw (&self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
self.as_str().draw(to)
|
||||
}
|
||||
}
|
||||
impl Draw<Tui> for Arc<str> {
|
||||
fn draw (&self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
self.as_ref().draw(to)
|
||||
}
|
||||
fn draw (self, _to: &mut Tui) -> Usually<XYWH<u16>> { todo!() }
|
||||
}
|
||||
|
||||
mod phat {
|
||||
|
|
@ -223,7 +207,7 @@ pub const fn button_2 <'a> (key: impl Draw<Tui>, label: impl Draw<Tui>, hide: bo
|
|||
let c2 = tui_g(0);
|
||||
let c3 = tui_g(96);
|
||||
let c4 = tui_g(255);
|
||||
bold(true, fg_bg(c1, c2, east(fg(c2, east(key, fg(c3, &"▐"))), when(!hide, fg_bg(c4, c3, label)))))
|
||||
bold(true, fg_bg(c1, c2, east(fg(c2, east(key, fg(c3, "▐"))), when(!hide, fg_bg(c4, c3, label)))))
|
||||
}
|
||||
|
||||
/// ```
|
||||
|
|
@ -235,10 +219,10 @@ pub const fn button_3 <'a> (
|
|||
) -> impl Draw<Tui> {
|
||||
bold(true, east(
|
||||
fg_bg(tui_orange(), tui_g(0),
|
||||
east(fg(tui_g(0), &"▐"), east(key, fg(if editing { tui_g(128) } else { tui_g(96) }, "▐")))),
|
||||
east(fg(tui_g(0), "▐"), east(key, fg(if editing { tui_g(128) } else { tui_g(96) }, "▐")))),
|
||||
east(
|
||||
when(!editing, east(fg_bg(tui_g(255), tui_g(96), label), fg_bg(tui_g(128), tui_g(96), &"▐"),)),
|
||||
east(fg_bg(tui_g(224), tui_g(128), value), fg_bg(tui_g(128), Reset, &"▌"), ))))
|
||||
when(!editing, east(fg_bg(tui_g(255), tui_g(96), label), fg_bg(tui_g(128), tui_g(96), "▐"),)),
|
||||
east(fg_bg(tui_g(224), tui_g(128), value), fg_bg(tui_g(128), Reset, "▌"), ))))
|
||||
}
|
||||
|
||||
macro_rules! border {
|
||||
|
|
@ -261,7 +245,7 @@ macro_rules! border {
|
|||
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
|
||||
//impl Layout<Tui> for $T {}
|
||||
impl Draw<Tui> for $T {
|
||||
fn draw (&self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
when(self.enabled(), thunk(|to: &mut Tui|BorderStyle::draw(self, to))).draw(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -385,7 +369,7 @@ pub trait BorderStyle: Draw<Tui> + Copy {
|
|||
fn border_sw (&self) -> &str { Self::SW }
|
||||
fn border_se (&self) -> &str { Self::SE }
|
||||
|
||||
#[inline] fn draw <'a> (&self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
#[inline] fn draw <'a> (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
if self.enabled() {
|
||||
self.draw_h(to, None)?;
|
||||
self.draw_v(to, None)?;
|
||||
|
|
@ -393,7 +377,7 @@ pub trait BorderStyle: Draw<Tui> + Copy {
|
|||
}
|
||||
Ok(to.1)
|
||||
}
|
||||
#[inline] fn draw_h (&self, to: &mut Tui, style: Option<Style>) -> Usually<XYWH<u16>> {
|
||||
#[inline] fn draw_h (self, to: &mut Tui, style: Option<Style>) -> Usually<XYWH<u16>> {
|
||||
let style = style.or_else(||self.style_horizontal());
|
||||
let y1 = to.y_north();
|
||||
let y2 = to.y_south().saturating_sub(1);
|
||||
|
|
@ -403,7 +387,7 @@ pub trait BorderStyle: Draw<Tui> + Copy {
|
|||
}
|
||||
Ok(to.xywh())
|
||||
}
|
||||
#[inline] fn draw_v (&self, to: &mut Tui, style: Option<Style>) -> Usually<XYWH<u16>> {
|
||||
#[inline] fn draw_v (self, to: &mut Tui, style: Option<Style>) -> Usually<XYWH<u16>> {
|
||||
let area = to.1;
|
||||
let style = style.or_else(||self.style_vertical());
|
||||
let [x, x2, y, y2] = area.lrtb();
|
||||
|
|
@ -419,7 +403,7 @@ pub trait BorderStyle: Draw<Tui> + Copy {
|
|||
}
|
||||
Ok(area)
|
||||
}
|
||||
#[inline] fn draw_c (&self, to: &mut Tui, style: Option<Style>) -> Usually<XYWH<u16>> {
|
||||
#[inline] fn draw_c (self, to: &mut Tui, style: Option<Style>) -> Usually<XYWH<u16>> {
|
||||
let area = to.1;
|
||||
let style = style.or_else(||self.style_corners());
|
||||
let XYWH(x, y, w, h) = area;
|
||||
|
|
@ -520,52 +504,27 @@ fn y_scroll () -> impl Draw<Tui> {
|
|||
}
|
||||
|
||||
/// Spawn the TUI output thread which writes colored characters to the terminal.
|
||||
pub fn tui_output <W: Write + Send + Sync, T: Draw<Tui> + Send + Sync + 'static> (
|
||||
pub fn tui_output <W: Write + Send + Sync + 'static, T: Draw<Tui> + Send + Sync + 'static> (
|
||||
output: W,
|
||||
exited: &Arc<AtomicBool>,
|
||||
state: &Arc<RwLock<T>>,
|
||||
sleep: Duration
|
||||
) -> Result<Thread, std::io::Error> {
|
||||
) -> Usually<Thread> {
|
||||
let state = state.clone();
|
||||
tui_setup(&mut output)?;
|
||||
tui_setup()?;
|
||||
let mut backend = CrosstermBackend::new(output);
|
||||
let Size { width, height } = backend.size().expect("get size failed");
|
||||
let mut buffer_a = Buffer::empty(Rect { x: 0, y: 0, width, height });
|
||||
let mut buffer_b = Buffer::empty(Rect { x: 0, y: 0, width, height });
|
||||
Thread::new_sleep(exited.clone(), sleep, move |perf| {
|
||||
let size = backend.size().expect("get size failed");
|
||||
Ok(Thread::new_sleep(exited.clone(), sleep, move |perf| {
|
||||
let Size { width, height } = backend.size().expect("get size failed");
|
||||
if let Ok(state) = state.try_read() {
|
||||
tui_resize(&mut backend, &mut buffer_a, size);
|
||||
buffer_a = tui_redraw(&mut backend, &mut buffer_a, &mut buffer_b);
|
||||
tui_resize(&mut backend, &mut buffer_a, Rect { x: 0, y: 0, width, height });
|
||||
tui_redraw(&mut backend, &mut buffer_a, &mut buffer_b);
|
||||
}
|
||||
let timer = format!("{:>3.3}ms", perf.used.load(Relaxed));
|
||||
buffer_a.set_string(0, 0, &timer, Style::default());
|
||||
})
|
||||
}
|
||||
|
||||
pub fn tui_setup <T: Write + Send + Sync> (output: &mut T) -> Usually<()> {
|
||||
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
||||
std::panic::set_hook(Box::new(move |info: &std::panic::PanicHookInfo|{
|
||||
output.execute(LeaveAlternateScreen).unwrap();
|
||||
CrosstermBackend::new(output).show_cursor().unwrap();
|
||||
disable_raw_mode().unwrap();
|
||||
better_panic_handler(info);
|
||||
}));
|
||||
output.execute(EnterAlternateScreen)?;
|
||||
CrosstermBackend::new(output).hide_cursor()?;
|
||||
enable_raw_mode().map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn tui_resize <W: Write> (
|
||||
backend: &mut CrosstermBackend<W>,
|
||||
buffer: &mut Buffer,
|
||||
size: XYWH<u16>
|
||||
) {
|
||||
if buffer.1 != size {
|
||||
backend.clear_region(ClearType::All).unwrap();
|
||||
buffer.resize(size);
|
||||
buffer.reset();
|
||||
}
|
||||
})?)
|
||||
}
|
||||
|
||||
pub fn tui_redraw <'b, W: Write> (
|
||||
|
|
@ -578,7 +537,31 @@ pub fn tui_redraw <'b, W: Write> (
|
|||
Backend::flush(backend).expect("failed to flush output new_buffer");
|
||||
std::mem::swap(&mut prev_buffer, &mut next_buffer);
|
||||
next_buffer.reset();
|
||||
next_buffer
|
||||
}
|
||||
|
||||
pub fn tui_setup () -> Usually<()> {
|
||||
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
||||
std::panic::set_hook(Box::new(move |info: &std::panic::PanicHookInfo|{
|
||||
stdout().execute(LeaveAlternateScreen).unwrap();
|
||||
CrosstermBackend::new(stdout()).show_cursor().unwrap();
|
||||
disable_raw_mode().unwrap();
|
||||
better_panic_handler(info);
|
||||
}));
|
||||
stdout().execute(EnterAlternateScreen)?;
|
||||
CrosstermBackend::new(stdout()).hide_cursor()?;
|
||||
enable_raw_mode().map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn tui_resize <W: Write> (
|
||||
backend: &mut CrosstermBackend<W>,
|
||||
buffer: &mut Buffer,
|
||||
size: Rect
|
||||
) {
|
||||
if buffer.area != size {
|
||||
backend.clear_region(ClearType::All).unwrap();
|
||||
buffer.resize(size);
|
||||
buffer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tui_teardown <W: Write> (backend: &mut CrosstermBackend<W>) -> Usually<()> {
|
||||
|
|
@ -628,7 +611,7 @@ pub const fn border <T, S: BorderStyle> (on: bool, style: S, draw: impl Draw<Tui
|
|||
/// let _ = tengri::tui::catcher(Err("draw fail".into()));
|
||||
/// ```
|
||||
pub fn catcher <T: Draw<Tui>> (result: Usually<T>) -> impl Draw<Tui> {
|
||||
thunk(move|to: &mut Tui|match result.as_ref() {
|
||||
thunk(move|to: &mut Tui|match result {
|
||||
Ok(content) => content.draw(to),
|
||||
Err(e) => {
|
||||
let err_fg = Color::Rgb(255,224,244);
|
||||
|
|
@ -690,102 +673,3 @@ use self::colors::*; mod colors {
|
|||
pub const fn tui_title_fg (f: bool) -> Color { if f { tui_ti1() } else { tui_ti2() } }
|
||||
pub const fn tui_yellow () -> Color { Color::Rgb(255,255,0) }
|
||||
}
|
||||
|
||||
/// Spawn the TUI input thread which reads keys from the terminal.
|
||||
pub fn tui_input <T: Do<TuiEvent, T> + Send + Sync + 'static> (
|
||||
exited: &Arc<AtomicBool>, state: &Arc<RwLock<T>>, poll: Duration
|
||||
) -> Result<Thread, std::io::Error> {
|
||||
let exited = exited.clone();
|
||||
let state = state.clone();
|
||||
Thread::new_poll(exited.clone(), poll, move |_| {
|
||||
let event = read().unwrap();
|
||||
match event {
|
||||
|
||||
// Hardcoded exit.
|
||||
Event::Key(KeyEvent {
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
code: KeyCode::Char('c'),
|
||||
kind: KeyEventKind::Press,
|
||||
state: KeyEventState::NONE
|
||||
}) => { exited.store(true, Relaxed); },
|
||||
|
||||
// Handle all other events by the state:
|
||||
_ => {
|
||||
let event = TuiEvent(TuiKey::from_crossterm(event));
|
||||
if let Err(e) = state.write().unwrap().apply(&event) {
|
||||
panic!("{e}")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// TUI input loop event.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd)]
|
||||
pub struct TuiEvent(pub Event);
|
||||
impl_from!(TuiEvent: |e: Event| TuiEvent(e));
|
||||
impl_from!(TuiEvent: |c: char| TuiEvent(Event::Key(KeyEvent::new(KeyCode::Char(c), KeyModifiers::NONE))));
|
||||
impl Ord for TuiEvent {
|
||||
fn cmp (&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.partial_cmp(other)
|
||||
.unwrap_or_else(||format!("{:?}", self).cmp(&format!("{other:?}"))) // FIXME perf
|
||||
}
|
||||
}
|
||||
|
||||
/// TUI key spec.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd)]
|
||||
pub struct TuiKey(pub Option<KeyCode>, pub KeyModifiers);
|
||||
impl TuiKey {
|
||||
const SPLIT: char = '/';
|
||||
pub fn to_crossterm (&self) -> Option<Event> {
|
||||
self.0.map(|code|Event::Key(KeyEvent {
|
||||
code,
|
||||
modifiers: self.1,
|
||||
kind: KeyEventKind::Press,
|
||||
state: KeyEventState::NONE,
|
||||
}))
|
||||
}
|
||||
pub fn named (token: &str) -> Option<KeyCode> {
|
||||
use KeyCode::*;
|
||||
Some(match token {
|
||||
"up" => Up,
|
||||
"down" => Down,
|
||||
"left" => Left,
|
||||
"right" => Right,
|
||||
"esc" | "escape" => Esc,
|
||||
"enter" | "return" => Enter,
|
||||
"delete" | "del" => Delete,
|
||||
"backspace" => Backspace,
|
||||
"tab" => Tab,
|
||||
"space" => Char(' '),
|
||||
"comma" => Char(','),
|
||||
"period" => Char('.'),
|
||||
"plus" => Char('+'),
|
||||
"minus" | "dash" => Char('-'),
|
||||
"equal" | "equals" => Char('='),
|
||||
"underscore" => Char('_'),
|
||||
"backtick" => Char('`'),
|
||||
"lt" => Char('<'),
|
||||
"gt" => Char('>'),
|
||||
"cbopen" | "openbrace" => Char('{'),
|
||||
"cbclose" | "closebrace" => Char('}'),
|
||||
"bropen" | "openbracket" => Char('['),
|
||||
"brclose" | "closebracket" => Char(']'),
|
||||
"pgup" | "pageup" => PageUp,
|
||||
"pgdn" | "pagedown" => PageDown,
|
||||
"f1" => F(1),
|
||||
"f2" => F(2),
|
||||
"f3" => F(3),
|
||||
"f4" => F(4),
|
||||
"f5" => F(5),
|
||||
"f6" => F(6),
|
||||
"f7" => F(7),
|
||||
"f8" => F(8),
|
||||
"f9" => F(9),
|
||||
"f10" => F(10),
|
||||
"f11" => F(11),
|
||||
"f12" => F(12),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue