added a input element #19
This commit is contained in:
+12
-3
@@ -16,10 +16,14 @@ pub fn app(screen: Arc<Screen>) -> Rsx {
|
|||||||
rsx! {
|
rsx! {
|
||||||
@Handler::new({
|
@Handler::new({
|
||||||
let screen = screen.clone();
|
let screen = screen.clone();
|
||||||
move |_, _: &crossterm::event::Event| {
|
move |_, e: &crossterm::event::Event| {
|
||||||
|
if let crossterm::event::Event::Key(crossterm::event::KeyEvent { code, .. }) = e {
|
||||||
|
if *code == crossterm::event::KeyCode::Char('q') {
|
||||||
screen.close();
|
screen.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}});
|
}});
|
||||||
FlexRow, gap: 1, {
|
FlexRow {
|
||||||
FlexCol, gap: 3, {
|
FlexCol, gap: 3, {
|
||||||
Heading, smooth: false, { "OSUI" }
|
Heading, smooth: false, { "OSUI" }
|
||||||
@Transform::new().padding(2, 2);
|
@Transform::new().padding(2, 2);
|
||||||
@@ -37,11 +41,16 @@ pub fn app(screen: Arc<Screen>) -> Rsx {
|
|||||||
// TODO: div with width full
|
// TODO: div with width full
|
||||||
}
|
}
|
||||||
|
|
||||||
FlexCol {
|
FlexCol, gap: 2, {
|
||||||
|
@transform!{ y: Center };
|
||||||
static Div { // static only affects the element, not children
|
static Div { // static only affects the element, not children
|
||||||
%count
|
%count
|
||||||
"This will increment every second: {count}"
|
"This will increment every second: {count}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transform::new().padding(1, 1).dimensions(40, 1);
|
||||||
|
@Style { foreground: Some(0xffffff), background: Background::RoundedOutline(0xff0000) };
|
||||||
|
Input { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
use crossterm::event::{KeyCode, KeyEvent};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
state::{use_state, State},
|
||||||
|
widget::Element,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Input {
|
||||||
|
pub state: State<String>,
|
||||||
|
cursor: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Element for Input {
|
||||||
|
fn render(&mut self, scope: &mut crate::prelude::RenderScope) {
|
||||||
|
let s = self.state.get();
|
||||||
|
scope.draw_text(0, 0, &s);
|
||||||
|
if let Some(c) = s.chars().nth(self.cursor) {
|
||||||
|
scope.draw_text_inverted(self.cursor as u16, 0, &c.to_string());
|
||||||
|
} else {
|
||||||
|
scope.draw_text_inverted(s.len() as u16, 0, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(&mut self, event: &dyn crate::prelude::Event) {
|
||||||
|
if let Some(crossterm::event::Event::Key(KeyEvent { code, .. })) = event.get() {
|
||||||
|
match code {
|
||||||
|
KeyCode::Char(c) => {
|
||||||
|
self.state.get().insert(self.cursor, *c);
|
||||||
|
self.cursor += 1;
|
||||||
|
}
|
||||||
|
KeyCode::Backspace => {
|
||||||
|
if self.cursor > 0 {
|
||||||
|
self.state.get().remove(self.cursor - 1);
|
||||||
|
self.cursor -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeyCode::Delete => {
|
||||||
|
if self.cursor > 0 && self.state.get().len() > self.cursor {
|
||||||
|
self.state.get().remove(self.cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeyCode::Left => {
|
||||||
|
if self.cursor > 0 {
|
||||||
|
self.cursor -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeyCode::Right => {
|
||||||
|
if self.cursor < self.state.get().len() {
|
||||||
|
self.cursor += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state: use_state(String::new()),
|
||||||
|
cursor: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user