added input

This commit is contained in:
2024-12-19 13:16:14 +01:00
parent 4e90454edb
commit e8bcb9a31f
7 changed files with 139 additions and 13 deletions
+44 -2
View File
@@ -8,7 +8,7 @@ pub mod counter_example {
@SetStyle(styling()) @SetStyle(styling())
button { button {
class: "outline", class: "btn",
on_click: fn(_, _, _) @count { on_click: fn(_, _, _) @count {
count += 1; count += 1;
@@ -21,7 +21,7 @@ pub mod counter_example {
pub fn styling() -> Css { pub fn styling() -> Css {
css! { css! {
"outline" { "btn" {
outline: true, outline: true,
outline_color: Red outline_color: Red
} }
@@ -79,3 +79,45 @@ pub mod todo_example {
} }
} }
} }
pub mod login_example {
use crate::prelude::*;
pub fn second_screen(usr: String, psw: String) -> Element {
rsx! {
text { "Username: {usr}\nPassword: {psw}" }
}
}
pub fn app() -> Element {
rsx! {
@SetStyle(styling())
input { class: "input", id: "usr", on_click: fn(_, _, document) {
let root = document.get_root::<Div>();
root.children.set_index(1);
}, "username: " }
input { class: "input", id: "psw", on_click: fn(psw: &mut Input, _, document) {
if let Some(usr) = document.get_element_by_id::<Input>("usr") {
document.draw(second_screen(usr.text.clone(), psw.text.clone()));
}
}, "password: " }
}
}
pub fn styling() -> Css {
css! {
"input" {
width: 50 px,
outline: true,
y: Auto,
x: 0 px,
caret: String::new(),
}
"input": "hover" {
outline_color: Red,
caret: String::from("█"),
}
}
}
}
+27 -6
View File
@@ -27,7 +27,7 @@ use std::{
}; };
use crossterm::event::Event; use crossterm::event::Event;
use ui::Style; use ui::{Style, StyleCore};
pub mod css; pub mod css;
pub mod examples; pub mod examples;
@@ -138,6 +138,9 @@ impl Document {
} }
} }
} }
pub fn get_root<T>(&self) -> &mut Box<T> {
unsafe { &mut *(self.element as *mut Element as *mut Box<T>) }
}
pub fn get_element_by_id<T>(&self, id: &str) -> Option<&mut Box<T>> { pub fn get_element_by_id<T>(&self, id: &str) -> Option<&mut Box<T>> {
if let Some(e) = self.get_element_by_id_raw(id) { if let Some(e) = self.get_element_by_id_raw(id) {
Some(unsafe { &mut *(e as *mut Element as *mut Box<T>) }) Some(unsafe { &mut *(e as *mut Element as *mut Box<T>) })
@@ -170,8 +173,10 @@ impl Document {
pub fn set_css(&mut self, css: ui::Css) { pub fn set_css(&mut self, css: ui::Css) {
self.css = css; self.css = css;
} }
pub fn draw(&mut self, element: &mut Element) { pub fn draw(&self, element: Element) {
self.element = element; unsafe {
*self.element = element;
}
} }
pub fn run(&mut self) -> bool { pub fn run(&mut self) -> bool {
unsafe { *self.running = None } unsafe { *self.running = None }
@@ -275,7 +280,7 @@ impl Children {
(None, 0) (None, 0)
} }
} }
pub fn set_child(&mut self, index: usize) { pub fn set_index(&mut self, index: usize) {
if let Children::Children(_, child) = self { if let Children::Children(_, child) = self {
*child = index; *child = index;
} }
@@ -337,10 +342,10 @@ impl Writer {
for (i, line) in s.lines().enumerate() { for (i, line) in s.lines().enumerate() {
if self.style.outline.1 { if self.style.outline.1 {
print!( print!(
"\x1B[{};{}H{outline_ch}{}{outline_ch}", "\x1B[{};{}H{outline_ch}{}",
self.absolute.1 + 2 + i as u16, self.absolute.1 + 2 + i as u16,
self.absolute.0 + 1, self.absolute.0 + 1,
self.style.write(line) self.style.write(line),
); );
} else { } else {
print!( print!(
@@ -376,6 +381,14 @@ impl Writer {
"─".repeat(self.get_size_root().0 as usize) "─".repeat(self.get_size_root().0 as usize)
)) ))
); );
for i in 0..self.written.1 {
print!(
"\x1B[{};{}H{outline_ch}",
self.absolute.1 + i + 2,
self.absolute.0 + self.get_size_root().0 + 2,
);
}
} }
} }
@@ -412,6 +425,14 @@ impl Writer {
pub fn new_frame(&mut self) -> crate::utils::Frame { pub fn new_frame(&mut self) -> crate::utils::Frame {
crate::utils::Frame::new(self.absolute, self.get_size(), unsafe { &*self.css }) crate::utils::Frame::new(self.absolute, self.get_size(), unsafe { &*self.css })
} }
pub fn caret(&self) -> String {
format!(
"{}{}\x1b[0m",
self.style.cursor.1.ansi(),
self.style.caret.1
)
}
} }
impl<T> Default for Handler<T> { impl<T> Default for Handler<T> {
+2 -2
View File
@@ -1,5 +1,5 @@
use osui::{examples::counter_example::app, launch}; use osui::{examples::*, launch};
fn main() { fn main() {
launch!(app()); launch!(login_example::app());
} }
+2 -2
View File
@@ -110,14 +110,14 @@ macro_rules! ersx {
#[allow(unused_mut)] #[allow(unused_mut)]
let mut elem = $elem(); let mut elem = $elem();
$crate::parse_rsx_param!(elem, $($inner)*); $crate::parse_rsx_param!(elem, $($inner)*);
elem as $crate::Element elem
}}; }};
($elem:path as $t:ty { $($inner:tt)* }) => {{ ($elem:path as $t:ty { $($inner:tt)* }) => {{
#[allow(unused_mut)] #[allow(unused_mut)]
let mut elem = paste::paste!{$elem::<$t>}(); let mut elem = paste::paste!{$elem::<$t>}();
$crate::parse_rsx_param!(elem, $($inner)*); $crate::parse_rsx_param!(elem, $($inner)*);
elem as $crate::Element elem
}}; }};
} }
+49
View File
@@ -116,3 +116,52 @@ impl ElementWidget for Button<'_> {
} }
} }
} }
#[element]
#[elem_fn]
#[derive(Default, Debug)]
pub struct Input {
pub on_click: Handler<Input<'a>>,
pub text: String,
pub placeholder: &'a str,
}
impl ElementWidget for Input<'_> {
fn render(&self, writer: &mut crate::Writer) {
if self.text.is_empty() {
writer.write(&format!(
"{}{}{}",
self.children.get_text(),
self.placeholder,
writer.caret()
));
} else {
writer.write(&format!(
"{}{}{}",
self.children.get_text(),
self.text,
writer.caret()
));
}
}
fn event(&mut self, event: crossterm::event::Event, document: &Document) {
match event {
Event::Key(k) => match k.code {
KeyCode::Backspace => {
if self.text.len() > 0 {
self.text.remove(self.text.len() - 1);
}
}
KeyCode::Enter => {
self.on_click.clone().call(self, event, document);
}
KeyCode::Char(c) => {
self.text.push(c);
}
_ => {}
},
_ => {}
}
}
}
+10
View File
@@ -81,6 +81,8 @@ pub struct StyleElement {
pub height: (bool, Number), pub height: (bool, Number),
pub visible: (bool, bool), pub visible: (bool, bool),
pub outline: (bool, bool), pub outline: (bool, bool),
pub cursor: (bool, Color),
pub caret: (bool, String),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -147,6 +149,7 @@ impl Default for StyleElement {
StyleElement { StyleElement {
color: (false, Color::NoColor), color: (false, Color::NoColor),
background: (false, Color::NoColor), background: (false, Color::NoColor),
cursor: (false, Color::NoColor),
font: (false, Vec::new()), font: (false, Vec::new()),
outline_color: (false, Color::NoColor), outline_color: (false, Color::NoColor),
x: (false, Number::Default), x: (false, Number::Default),
@@ -155,6 +158,7 @@ impl Default for StyleElement {
height: (false, Number::Default), height: (false, Number::Default),
visible: (false, true), visible: (false, true),
outline: (false, false), outline: (false, false),
caret: (false, String::from("█")),
} }
} }
} }
@@ -191,6 +195,12 @@ impl StyleElement {
if upper.outline.0 { if upper.outline.0 {
self.outline = upper.outline.clone(); self.outline = upper.outline.clone();
} }
if upper.cursor.0 {
self.cursor = upper.cursor.clone();
}
if upper.caret.0 {
self.caret = upper.caret.clone();
}
} }
} }
+5 -1
View File
@@ -62,7 +62,11 @@ impl<'a> Frame<'a> {
self.css, self.css,
); );
element.render(&mut writer); element.render(&mut writer);
let (width, height) = writer.get_size_root(); let (mut width, mut height) = writer.get_size_root();
if style_element.outline.1 {
width += 2;
height += 2;
}
for i in y..y + height { for i in y..y + height {
if let Some(o) = self.used.get_mut(i as usize) { if let Some(o) = self.used.get_mut(i as usize) {
*o += x + width; *o += x + width;