From c0fb0ee9fbdb797657707f77a0f040e42f2b8502 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Thu, 19 Dec 2024 12:09:51 +0100 Subject: [PATCH] added outlines --- src/examples.rs | 13 +++++++++++++ src/lib.rs | 45 ++++++++++++++++++++++++++++++++++++++------- src/ui/mod.rs | 3 ++- src/ui/styles.rs | 3 +++ src/utils.rs | 39 ++++++++++++++------------------------- 5 files changed, 70 insertions(+), 33 deletions(-) diff --git a/src/examples.rs b/src/examples.rs index a0d4bd8..c775252 100644 --- a/src/examples.rs +++ b/src/examples.rs @@ -5,7 +5,11 @@ pub mod counter_example { let count = State::new(0); rsx! { + @SetStyle(styling()) + button { + class: "outline", + on_click: fn(_, _, _) @count { count += 1; }, @@ -14,6 +18,15 @@ pub mod counter_example { } } } + + pub fn styling() -> Css { + css! { + "outline" { + outline: true, + outline_color: Red + } + } + } } pub mod todo_example { diff --git a/src/lib.rs b/src/lib.rs index d8d0a06..a929a6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -333,19 +333,50 @@ impl Writer { } pub fn write(&mut self, s: &str) { + let outline_ch = self.style.write_outline("|"); for (i, line) in s.lines().enumerate() { - print!( - "\x1B[{};{}H{}", - self.absolute.1 + 1 + i as u16, - self.absolute.0 + 1, - self.style.write(line) - ); + if self.style.outline.1 { + print!( + "\x1B[{};{}H{outline_ch}{}{outline_ch}", + self.absolute.1 + 2 + i as u16, + self.absolute.0 + 1, + self.style.write(line) + ); + } else { + print!( + "\x1B[{};{}H{}", + self.absolute.1 + 1 + i as u16, + self.absolute.0 + 1, + self.style.write(line) + ); + } let line_len = line.len() as u16; if line_len > self.written.0 { self.written.0 = line_len; } self.written.1 += 1; } + + if self.style.outline.1 { + print!( + "\x1B[{};{}H{}", + self.absolute.1 + 1, + self.absolute.0 + 1, + self.style.write_outline(&format!( + "╭{}╮", + "─".repeat(self.get_size_root().0 as usize) + )) + ); + print!( + "\x1B[{};{}H{}", + self.absolute.1 + self.written.1 + 2, + self.absolute.0 + 1, + self.style.write_outline(&format!( + "╰{}╯", + "─".repeat(self.get_size_root().0 as usize) + )) + ); + } } pub fn get_focused(&self) -> bool { @@ -378,7 +409,7 @@ impl Writer { ) } - pub fn new_frame(&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 }) } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 2272adc..c77600e 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -34,11 +34,12 @@ pub struct Div { impl ElementWidget for Div<'_> { fn render(&self, writer: &mut crate::Writer) { + let focused = writer.get_focused(); let mut frame = writer.new_frame(); if let Children::Children(children, child) = &self.children { for (i, elem) in children.iter().enumerate() { - frame.render(writer.get_focused() && i == *child, elem); + frame.render(focused && i == *child, elem); } } } diff --git a/src/ui/styles.rs b/src/ui/styles.rs index d096e62..1ac029a 100644 --- a/src/ui/styles.rs +++ b/src/ui/styles.rs @@ -137,6 +137,9 @@ impl StyleElement { .collect::>() .join("\n") } + pub fn write_outline(&self, outline: &str) -> String { + format!("{}{outline}\x1b[0m", self.outline_color.1.ansi(),) + } } impl Default for StyleElement { diff --git a/src/utils.rs b/src/utils.rs index 265e8a5..e4b764e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,20 +1,18 @@ use std::io::{stdout, Write}; -use crossterm::terminal::disable_raw_mode; - use crate::ui; -pub struct Frame { +pub struct Frame<'a> { used: Vec, width: u16, height: u16, x: u16, y: u16, - css: *const ui::Css, + css: &'a ui::Css, } -impl Frame { - pub fn new((x, y): (u16, u16), (width, height): (u16, u16), css: &crate::ui::Css) -> Self { +impl<'a> Frame<'a> { + pub fn new((x, y): (u16, u16), (width, height): (u16, u16), css: &'a crate::ui::Css) -> Self { Frame { used: vec![0; height as usize], width, @@ -28,21 +26,18 @@ impl Frame { let style = element.get_style(); let mut style_element = style.clone().get(focused); - if let Some(upper) = unsafe { (*self.css).get(&ui::StyleName::Class(element.get_class())) } - { + if let Some(upper) = self.css.get(&ui::StyleName::Class(element.get_class())) { style_element.merge(upper); } - if let Some(upper) = unsafe { - (*self.css).get(&ui::StyleName::ClassState( - element.get_class(), - if style.2 == "" && focused { - "hover".to_string() - } else { - style.2.clone() - }, - )) - } { + if let Some(upper) = self.css.get(&ui::StyleName::ClassState( + element.get_class(), + if style.2 == "" && focused { + "hover".to_string() + } else { + style.2.clone() + }, + )) { style_element.merge(upper); } @@ -64,16 +59,10 @@ impl Frame { style_element.clone(), (x + self.x, y + self.y), (self.width, self.height), - unsafe { &*self.css }, + self.css, ); element.render(&mut writer); let (width, height) = writer.get_size_root(); - if style_element.outline.1 { - clear(); - show_cursor(); - disable_raw_mode().unwrap(); - panic!("the 'outline' option isn't available right now. please set 'outline' to 'false'") - } for i in y..y + height { if let Some(o) = self.used.get_mut(i as usize) { *o += x + width;