diff --git a/src/examples.rs b/src/examples.rs
index c775252..480b721 100644
--- a/src/examples.rs
+++ b/src/examples.rs
@@ -8,7 +8,7 @@ pub mod counter_example {
@SetStyle(styling())
button {
- class: "outline",
+ class: "btn",
on_click: fn(_, _, _) @count {
count += 1;
@@ -21,7 +21,7 @@ pub mod counter_example {
pub fn styling() -> Css {
css! {
- "outline" {
+ "btn" {
outline: true,
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::
();
+ 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::("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("█"),
+ }
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 121eeb5..d131c3a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,7 +27,7 @@ use std::{
};
use crossterm::event::Event;
-use ui::Style;
+use ui::{Style, StyleCore};
pub mod css;
pub mod examples;
@@ -138,6 +138,9 @@ impl Document {
}
}
}
+ pub fn get_root(&self) -> &mut Box {
+ unsafe { &mut *(self.element as *mut Element as *mut Box) }
+ }
pub fn get_element_by_id(&self, id: &str) -> Option<&mut Box> {
if let Some(e) = self.get_element_by_id_raw(id) {
Some(unsafe { &mut *(e as *mut Element as *mut Box) })
@@ -170,8 +173,10 @@ impl Document {
pub fn set_css(&mut self, css: ui::Css) {
self.css = css;
}
- pub fn draw(&mut self, element: &mut Element) {
- self.element = element;
+ pub fn draw(&self, element: Element) {
+ unsafe {
+ *self.element = element;
+ }
}
pub fn run(&mut self) -> bool {
unsafe { *self.running = None }
@@ -275,7 +280,7 @@ impl Children {
(None, 0)
}
}
- pub fn set_child(&mut self, index: usize) {
+ pub fn set_index(&mut self, index: usize) {
if let Children::Children(_, child) = self {
*child = index;
}
@@ -337,10 +342,10 @@ impl Writer {
for (i, line) in s.lines().enumerate() {
if self.style.outline.1 {
print!(
- "\x1B[{};{}H{outline_ch}{}{outline_ch}",
+ "\x1B[{};{}H{outline_ch}{}",
self.absolute.1 + 2 + i as u16,
self.absolute.0 + 1,
- self.style.write(line)
+ self.style.write(line),
);
} else {
print!(
@@ -376,6 +381,14 @@ impl Writer {
"─".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 {
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 Default for Handler {
diff --git a/src/main.rs b/src/main.rs
index e7b091e..87b503d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,5 @@
-use osui::{examples::counter_example::app, launch};
+use osui::{examples::*, launch};
fn main() {
- launch!(app());
+ launch!(login_example::app());
}
diff --git a/src/rsx.rs b/src/rsx.rs
index 7902c1d..18a0b9f 100644
--- a/src/rsx.rs
+++ b/src/rsx.rs
@@ -110,14 +110,14 @@ macro_rules! ersx {
#[allow(unused_mut)]
let mut elem = $elem();
$crate::parse_rsx_param!(elem, $($inner)*);
- elem as $crate::Element
+ elem
}};
($elem:path as $t:ty { $($inner:tt)* }) => {{
#[allow(unused_mut)]
let mut elem = paste::paste!{$elem::<$t>}();
$crate::parse_rsx_param!(elem, $($inner)*);
- elem as $crate::Element
+ elem
}};
}
diff --git a/src/ui/mod.rs b/src/ui/mod.rs
index c77600e..68b170c 100644
--- a/src/ui/mod.rs
+++ b/src/ui/mod.rs
@@ -116,3 +116,52 @@ impl ElementWidget for Button<'_> {
}
}
}
+
+#[element]
+#[elem_fn]
+#[derive(Default, Debug)]
+pub struct Input {
+ pub on_click: Handler>,
+ 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);
+ }
+ _ => {}
+ },
+ _ => {}
+ }
+ }
+}
diff --git a/src/ui/styles.rs b/src/ui/styles.rs
index 1ac029a..b6b6c1c 100644
--- a/src/ui/styles.rs
+++ b/src/ui/styles.rs
@@ -81,6 +81,8 @@ pub struct StyleElement {
pub height: (bool, Number),
pub visible: (bool, bool),
pub outline: (bool, bool),
+ pub cursor: (bool, Color),
+ pub caret: (bool, String),
}
#[derive(Debug, Clone)]
@@ -147,6 +149,7 @@ impl Default for StyleElement {
StyleElement {
color: (false, Color::NoColor),
background: (false, Color::NoColor),
+ cursor: (false, Color::NoColor),
font: (false, Vec::new()),
outline_color: (false, Color::NoColor),
x: (false, Number::Default),
@@ -155,6 +158,7 @@ impl Default for StyleElement {
height: (false, Number::Default),
visible: (false, true),
outline: (false, false),
+ caret: (false, String::from("█")),
}
}
}
@@ -191,6 +195,12 @@ impl StyleElement {
if upper.outline.0 {
self.outline = upper.outline.clone();
}
+ if upper.cursor.0 {
+ self.cursor = upper.cursor.clone();
+ }
+ if upper.caret.0 {
+ self.caret = upper.caret.clone();
+ }
}
}
diff --git a/src/utils.rs b/src/utils.rs
index e4b764e..38098e6 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -62,7 +62,11 @@ impl<'a> Frame<'a> {
self.css,
);
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 {
if let Some(o) = self.used.get_mut(i as usize) {
*o += x + width;