small improvements
This commit is contained in:
+2
-36
@@ -1,41 +1,7 @@
|
|||||||
use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind};
|
|
||||||
|
|
||||||
use crate::Element;
|
use crate::Element;
|
||||||
|
|
||||||
impl Element for &str {
|
impl Element for &str {
|
||||||
fn render(&self) -> String {
|
fn render(&self, frame: &mut dyn crate::Framing) {
|
||||||
self.to_string()
|
frame.draw_str("test");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Element for String {
|
|
||||||
fn render(&self) -> String {
|
|
||||||
self.to_owned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Button {
|
|
||||||
pub on_click: crate::Handler<dyn FnMut()>,
|
|
||||||
pub text: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Element for Button {
|
|
||||||
fn render(&self) -> String {
|
|
||||||
self.text.to_owned()
|
|
||||||
}
|
|
||||||
fn event(&self, event: crossterm::event::Event) {
|
|
||||||
match event {
|
|
||||||
Event::Mouse(MouseEvent {
|
|
||||||
kind: MouseEventKind::Down(MouseButton::Left),
|
|
||||||
..
|
|
||||||
}) => (self.on_click.clone().lock().unwrap())(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Element for crate::Ui {
|
|
||||||
fn render(&self) -> String {
|
|
||||||
String::new()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-36
@@ -9,7 +9,6 @@ use std::{io::Write, sync::Arc};
|
|||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
elements::*,
|
|
||||||
func,
|
func,
|
||||||
style::{Color, Style},
|
style::{Color, Style},
|
||||||
utils::init,
|
utils::init,
|
||||||
@@ -18,15 +17,20 @@ pub mod prelude {
|
|||||||
|
|
||||||
#[cfg(feature = "state")]
|
#[cfg(feature = "state")]
|
||||||
pub use crate::state::use_state;
|
pub use crate::state::use_state;
|
||||||
|
|
||||||
|
pub use crossterm::event::read;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traits
|
// Traits
|
||||||
pub trait Framing {
|
pub trait Framing {
|
||||||
fn draw(&mut self, element: &mut dyn Element, props: &Props);
|
fn draw(&mut self, element: &mut dyn Element, props: &Props);
|
||||||
|
fn draw_str(&mut self, s: &str) {
|
||||||
|
_ = s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Element {
|
pub trait Element {
|
||||||
fn render(&self) -> String;
|
fn render(&self, frame: &mut dyn Framing);
|
||||||
fn event(&self, event: crossterm::event::Event) {
|
fn event(&self, event: crossterm::event::Event) {
|
||||||
_ = event
|
_ = event
|
||||||
}
|
}
|
||||||
@@ -43,7 +47,6 @@ pub struct Props {
|
|||||||
width: style::Dimension,
|
width: style::Dimension,
|
||||||
height: style::Dimension,
|
height: style::Dimension,
|
||||||
style: style::Style,
|
style: style::Style,
|
||||||
style_state: std::collections::HashMap<String, style::Style>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the console state, containing a frame for rendering and a mouse capture flag.
|
/// Represents the console state, containing a frame for rendering and a mouse capture flag.
|
||||||
@@ -53,7 +56,6 @@ pub struct Console<'a> {
|
|||||||
height: u16,
|
height: u16,
|
||||||
handle: Option<std::io::StdoutLock<'a>>,
|
handle: Option<std::io::StdoutLock<'a>>,
|
||||||
pub mouse_position: Option<(u16, u16)>,
|
pub mouse_position: Option<(u16, u16)>,
|
||||||
pub event: Option<crossterm::event::Event>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Props {
|
impl Props {
|
||||||
@@ -64,7 +66,6 @@ impl Props {
|
|||||||
width: style::Dimension::Auto,
|
width: style::Dimension::Auto,
|
||||||
height: style::Dimension::Auto,
|
height: style::Dimension::Auto,
|
||||||
style: style::Style::default(),
|
style: style::Style::default(),
|
||||||
style_state: std::collections::HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +80,6 @@ impl Props {
|
|||||||
width: style::Dimension::Auto,
|
width: style::Dimension::Auto,
|
||||||
height: style::Dimension::Auto,
|
height: style::Dimension::Auto,
|
||||||
style: style::Style::default(),
|
style: style::Style::default(),
|
||||||
style_state: std::collections::HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,6 @@ impl Props {
|
|||||||
width: style::Dimension::Auto,
|
width: style::Dimension::Auto,
|
||||||
height: style::Dimension::Auto,
|
height: style::Dimension::Auto,
|
||||||
style: style::Style::default(),
|
style: style::Style::default(),
|
||||||
style_state: std::collections::HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +100,6 @@ impl Props {
|
|||||||
width: style::Dimension::Auto,
|
width: style::Dimension::Auto,
|
||||||
height: style::Dimension::Auto,
|
height: style::Dimension::Auto,
|
||||||
style: style::Style::default(),
|
style: style::Style::default(),
|
||||||
style_state: std::collections::HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,11 +118,6 @@ impl Props {
|
|||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(&mut self, state: &str, style: style::Style) -> Self {
|
|
||||||
self.style_state.insert(state.to_string(), style);
|
|
||||||
self.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn width(&mut self, w: u16) -> Self {
|
pub fn width(&mut self, w: u16) -> Self {
|
||||||
self.width = style::Dimension::Num(w);
|
self.width = style::Dimension::Num(w);
|
||||||
self.clone()
|
self.clone()
|
||||||
@@ -148,7 +141,8 @@ impl Props {
|
|||||||
|
|
||||||
impl Framing for Console<'_> {
|
impl Framing for Console<'_> {
|
||||||
fn draw(&mut self, element: &mut dyn Element, props: &Props) {
|
fn draw(&mut self, element: &mut dyn Element, props: &Props) {
|
||||||
let mut written = element.render();
|
let mut written = String::new();
|
||||||
|
element.render(&mut written);
|
||||||
|
|
||||||
let (written_width, written_height) = utils::str_size(&written);
|
let (written_width, written_height) = utils::str_size(&written);
|
||||||
|
|
||||||
@@ -162,36 +156,23 @@ impl Framing for Console<'_> {
|
|||||||
props.y.get(height, self.height),
|
props.y.get(height, self.height),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut style = props.style;
|
let ansi = if props.style.background == style::Color::NoColor {
|
||||||
|
format!("\x1b[{}m", props.style.color.ansi_number(true))
|
||||||
if let Some((mouse_x, mouse_y)) = self.mouse_position {
|
|
||||||
if (x..x + width).contains(&mouse_x) && (y..y + height).contains(&mouse_y) {
|
|
||||||
if let Some(hover_style) = props.style_state.get("hover") {
|
|
||||||
style = hover_style.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ansi = if style.background == style::Color::NoColor {
|
|
||||||
format!("\x1b[{}m", style.color.ansi_number(true))
|
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"\x1b[{};{}m",
|
"\x1b[{};{}m",
|
||||||
style.color.ansi_number(true),
|
props.style.color.ansi_number(true),
|
||||||
style.background.ansi_number(false)
|
props.style.background.ansi_number(false)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(event) = &self.event {
|
let (x, y) = (x - props.style.px, y - props.style.py);
|
||||||
element.event(event.clone());
|
let px = " ".repeat(props.style.px as usize);
|
||||||
}
|
written
|
||||||
|
.push_str(&format!("\n{}", " ".repeat(width as usize)).repeat(props.style.py as usize));
|
||||||
let (x, y) = (x - style.px, y - style.py);
|
|
||||||
let px = " ".repeat(style.px as usize);
|
|
||||||
written.push_str(&format!("\n{}", " ".repeat(width as usize)).repeat(style.py as usize));
|
|
||||||
written.insert_str(
|
written.insert_str(
|
||||||
0,
|
0,
|
||||||
&format!("{}\n", " ".repeat(width as usize)).repeat(style.py as usize),
|
&format!("{}\n", " ".repeat(width as usize)).repeat(props.style.py as usize),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(handle) = &mut self.handle {
|
if let Some(handle) = &mut self.handle {
|
||||||
@@ -234,6 +215,16 @@ impl Console<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::Framing for String {
|
||||||
|
fn draw(&mut self, element: &mut dyn crate::Element, _props: &crate::Props) {
|
||||||
|
element.render(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_str(&mut self, s: &str) {
|
||||||
|
*self += s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn func<T>(t: T) -> Handler<T> {
|
pub fn func<T>(t: T) -> Handler<T> {
|
||||||
std::sync::Arc::new(std::sync::Mutex::new(t))
|
std::sync::Arc::new(std::sync::Mutex::new(t))
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-27
@@ -3,42 +3,19 @@ use std::sync::Arc;
|
|||||||
use osmium_engine::prelude::*;
|
use osmium_engine::prelude::*;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut console = init(true)?;
|
let mut console = init(false)?;
|
||||||
|
|
||||||
let ui = app();
|
let ui = app();
|
||||||
|
|
||||||
loop {
|
|
||||||
console.render(ui.clone())?;
|
console.render(ui.clone())?;
|
||||||
match crossterm::event::read()? {
|
|
||||||
crossterm::event::Event::Mouse(crossterm::event::MouseEvent {
|
read()?;
|
||||||
kind: crossterm::event::MouseEventKind::Moved,
|
|
||||||
row,
|
|
||||||
column,
|
|
||||||
..
|
|
||||||
}) => console.mouse_position = Some((column, row)),
|
|
||||||
crossterm::event::Event::Resize(_, _) => {}
|
|
||||||
e => console.event = Some(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.close()
|
console.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app() -> Ui {
|
pub fn app() -> Ui {
|
||||||
let mut count = use_state(0);
|
|
||||||
Arc::new(move |frame| {
|
Arc::new(move |frame| {
|
||||||
frame.draw(
|
frame.draw(&mut "test", &Props::center());
|
||||||
&mut Button {
|
|
||||||
on_click: func(move || count += 1),
|
|
||||||
text: format!("Count: {count}"),
|
|
||||||
},
|
|
||||||
&Props::center().state(
|
|
||||||
"hover",
|
|
||||||
Style {
|
|
||||||
color: Color::Red,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,5 @@ pub fn init<'a>(mouse: bool) -> crate::Result<crate::Console<'a>> {
|
|||||||
mouse,
|
mouse,
|
||||||
handle: None,
|
handle: None,
|
||||||
mouse_position: None,
|
mouse_position: None,
|
||||||
event: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user