added outline support (still not done yet)
This commit is contained in:
+80
-63
@@ -119,6 +119,7 @@ pub struct Writer {
|
|||||||
size: (u16, u16),
|
size: (u16, u16),
|
||||||
pos: (u16, u16),
|
pos: (u16, u16),
|
||||||
written: (u16, u16),
|
written: (u16, u16),
|
||||||
|
parent: Option<*mut Writer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State<T>(Arc<Mutex<T>>);
|
pub struct State<T>(Arc<Mutex<T>>);
|
||||||
@@ -178,16 +179,22 @@ impl Document {
|
|||||||
pub fn render(&self) {
|
pub fn render(&self) {
|
||||||
if !self.element.is_null() {
|
if !self.element.is_null() {
|
||||||
let (width, height) = crossterm::terminal::size().unwrap();
|
let (width, height) = crossterm::terminal::size().unwrap();
|
||||||
let mut writer = Writer::new(
|
let mut writer = Writer {
|
||||||
true,
|
css: &self.css,
|
||||||
ui::StyleElement::default(),
|
focused: true,
|
||||||
(0, 0),
|
style: ui::StyleElement {
|
||||||
(width, height),
|
// outline: (true, true),
|
||||||
&self.css,
|
..Default::default()
|
||||||
);
|
},
|
||||||
|
size: (width, height),
|
||||||
|
pos: (1, 1),
|
||||||
|
written: (0, 0),
|
||||||
|
parent: None,
|
||||||
|
};
|
||||||
let mut frame = writer.new_frame();
|
let mut frame = writer.new_frame();
|
||||||
utils::clear();
|
utils::clear();
|
||||||
frame.render(true, unsafe { &*self.element });
|
frame.render(true, unsafe { &*self.element });
|
||||||
|
writer.after_render(width, height);
|
||||||
utils::flush();
|
utils::flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,73 +359,83 @@ impl<T> Handler<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Writer {
|
impl Writer {
|
||||||
pub fn new(
|
pub fn after_render(&self, width: u16, height: u16) {
|
||||||
focused: bool,
|
if self.style.outline.1 {
|
||||||
style: ui::StyleElement,
|
let ol = self.style.write_outline("│");
|
||||||
pos: (u16, u16),
|
let hl = "─".repeat(width as usize - 2);
|
||||||
size: (u16, u16),
|
self.write_abs_outline(&self.style.write_outline(&format!("╭{}╮", hl)), (0, 0));
|
||||||
css: &ui::Css,
|
for i in 1..height {
|
||||||
) -> Writer {
|
self.write_abs_outline(&ol, (0, i));
|
||||||
Writer {
|
self.write_abs_outline(&ol, (width - 1, i));
|
||||||
css,
|
}
|
||||||
style,
|
self.write_abs_outline(&self.style.write_outline(&format!("╰{}╯", hl)), (0, height));
|
||||||
focused,
|
|
||||||
size,
|
|
||||||
pos,
|
|
||||||
written: (0, 0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&mut self, s: &str) {
|
pub fn write(&mut self, s: &str) {
|
||||||
let outline_ch = self.style.write_outline("│");
|
// let width = self.get_size().0 as usize;
|
||||||
for (i, line) in s.lines().enumerate() {
|
// let s = s
|
||||||
if self.style.outline.1 {
|
// .lines()
|
||||||
print!(
|
// .map(|l| {
|
||||||
"\x1B[{};{}H{outline_ch}{}",
|
// if l.len() > width {
|
||||||
self.pos.1 + 2 + i as u16,
|
// l.chars().take(width).collect::<String>()
|
||||||
self.pos.0 + 1,
|
// } else {
|
||||||
self.style.write(line),
|
// l.to_string()
|
||||||
);
|
// }
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<String>>()
|
||||||
|
// .join("\n");
|
||||||
|
self.write_abs(&self.style.write(&s), (0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_abs_outline(&self, s: &str, pos: (u16, u16)) {
|
||||||
|
if let Some(parent) = self.parent {
|
||||||
|
let parent = unsafe { &mut *parent };
|
||||||
|
parent.write_abs_outline(s, (self.pos.0 + pos.0, self.pos.1 + pos.1));
|
||||||
} else {
|
} else {
|
||||||
print!(
|
print!(
|
||||||
"\x1B[{};{}H{}",
|
"\x1b[{};{}H{}",
|
||||||
self.pos.1 + 1 + i as u16,
|
self.pos.1 + pos.1 - 1,
|
||||||
self.pos.0 + 1,
|
self.pos.0 + pos.0 - 1,
|
||||||
self.style.write(line)
|
self.style.write_outline(s)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
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 {
|
pub fn write_abs(&mut self, s: &str, pos: (u16, u16)) {
|
||||||
print!(
|
let width = self.get_size().0 as usize;
|
||||||
"\x1B[{};{}H{}",
|
let mut max_written = self.written.0;
|
||||||
self.pos.1 + 1,
|
let mut lines_written = 0;
|
||||||
self.pos.0 + 1,
|
|
||||||
self.style.write_outline(&format!(
|
|
||||||
"╭{}╮",
|
|
||||||
"─".repeat(self.get_size_root().0 as usize)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
print!(
|
|
||||||
"\x1B[{};{}H{}",
|
|
||||||
self.pos.1 + self.written.1 + 2,
|
|
||||||
self.pos.0 + 1,
|
|
||||||
self.style.write_outline(&format!(
|
|
||||||
"╰{}╯",
|
|
||||||
"─".repeat(self.get_size_root().0 as usize)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
for i in 0..self.written.1 {
|
let truncated_lines: Vec<_> = s
|
||||||
|
.lines()
|
||||||
|
.map(|l| {
|
||||||
|
let truncated = if l.len() > width {
|
||||||
|
l.chars().take(width).collect::<String>()
|
||||||
|
} else {
|
||||||
|
l.to_string()
|
||||||
|
};
|
||||||
|
max_written = max_written.max(truncated.len() as u16);
|
||||||
|
lines_written += 1;
|
||||||
|
truncated
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.written.0 = max_written;
|
||||||
|
self.written.1 += lines_written;
|
||||||
|
|
||||||
|
if let Some(parent) = self.parent {
|
||||||
|
let parent = unsafe { &mut *parent };
|
||||||
|
let combined_pos = (self.pos.0 + pos.0, self.pos.1 + pos.1);
|
||||||
|
let s_combined = truncated_lines.join("\n");
|
||||||
|
parent.write_abs(&s_combined, combined_pos);
|
||||||
|
} else {
|
||||||
|
for (i, line) in truncated_lines.iter().enumerate() {
|
||||||
print!(
|
print!(
|
||||||
"\x1B[{};{}H{outline_ch}",
|
"\x1b[{};{}H{}",
|
||||||
self.pos.1 + i + 2,
|
self.pos.1 + pos.1 + i as u16,
|
||||||
self.pos.0 + self.get_size_root().0 + 2,
|
self.pos.0 + pos.0,
|
||||||
|
line
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +472,7 @@ 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, unsafe { &*self.css })
|
crate::utils::Frame::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn caret(&self) -> String {
|
pub fn caret(&self) -> String {
|
||||||
|
|||||||
+8
-4
@@ -6,10 +6,14 @@ fn main() {
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn App() {
|
pub fn App() {
|
||||||
ersx! {
|
rsx! {
|
||||||
text { style: style!{
|
text { style: style!{
|
||||||
x: 30 px,
|
outline: true,
|
||||||
y: 4 px
|
}, "Hello, World!\nabc" }
|
||||||
}, "hello, world" }
|
|
||||||
|
text { style: style!{
|
||||||
|
outline: true,
|
||||||
|
width: 3 px
|
||||||
|
}, "Hello, World!\nabc testing" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,7 +322,11 @@ impl Number {
|
|||||||
}
|
}
|
||||||
pub fn as_size(&self, written: u16, frame_size: u16, outline: bool) -> u16 {
|
pub fn as_size(&self, written: u16, frame_size: u16, outline: bool) -> u16 {
|
||||||
if *self == Number::Auto {
|
if *self == Number::Auto {
|
||||||
|
if written > 0 {
|
||||||
|
written - 1
|
||||||
|
} else {
|
||||||
written
|
written
|
||||||
|
}
|
||||||
} else if outline {
|
} else if outline {
|
||||||
self.as_size_raw(frame_size) - 2
|
self.as_size_raw(frame_size) - 2
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+27
-15
@@ -2,31 +2,27 @@ use std::io::{stdout, Write};
|
|||||||
|
|
||||||
pub struct Frame<'a> {
|
pub struct Frame<'a> {
|
||||||
used: Vec<u16>,
|
used: Vec<u16>,
|
||||||
css: &'a crate::ui::Css,
|
|
||||||
writer: &'a mut crate::Writer,
|
writer: &'a mut crate::Writer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Frame<'a> {
|
impl<'a> Frame<'a> {
|
||||||
pub fn new(writer: &'a mut crate::Writer, css: &'a crate::ui::Css) -> Self {
|
pub fn new(writer: &'a mut crate::Writer) -> Self {
|
||||||
Frame {
|
Frame {
|
||||||
used: vec![0; writer.size.1 as usize],
|
used: vec![0; writer.size.1 as usize],
|
||||||
css,
|
|
||||||
writer,
|
writer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn render(&mut self, focused: bool, element: &crate::Element) {
|
pub fn render(&mut self, focused: bool, element: &crate::Element) {
|
||||||
let style = element.get_style();
|
let style = element.get_style();
|
||||||
let mut style_element = style.clone().get(focused);
|
let mut style_element = style.clone().get(focused);
|
||||||
|
let css = unsafe { &*self.writer.css };
|
||||||
|
|
||||||
for class in element.get_class().split(" ") {
|
for class in element.get_class().split(" ") {
|
||||||
if let Some(upper) = self
|
if let Some(upper) = css.get(&crate::ui::StyleName::Class(class.to_string())) {
|
||||||
.css
|
|
||||||
.get(&crate::ui::StyleName::Class(class.to_string()))
|
|
||||||
{
|
|
||||||
style_element.merge(upper);
|
style_element.merge(upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(upper) = self.css.get(&crate::ui::StyleName::ClassState(
|
if let Some(upper) = css.get(&crate::ui::StyleName::ClassState(
|
||||||
class.to_string(),
|
class.to_string(),
|
||||||
if style.2 == "" && focused {
|
if style.2 == "" && focused {
|
||||||
"hover".to_string()
|
"hover".to_string()
|
||||||
@@ -56,25 +52,41 @@ impl<'a> Frame<'a> {
|
|||||||
.x
|
.x
|
||||||
.1
|
.1
|
||||||
.as_position(style_element.outline.1, y_, self.writer.size.0);
|
.as_position(style_element.outline.1, y_, self.writer.size.0);
|
||||||
let mut writer = crate::Writer::new(
|
let mut writer = crate::Writer {
|
||||||
focused,
|
focused,
|
||||||
style_element.clone(),
|
style: style_element.clone(),
|
||||||
(x, y),
|
pos: (x, y),
|
||||||
self.writer.size,
|
size: self.writer.size,
|
||||||
self.css,
|
css,
|
||||||
);
|
parent: Some(self.writer),
|
||||||
|
written: (0, 0),
|
||||||
|
};
|
||||||
element.render(&mut writer);
|
element.render(&mut writer);
|
||||||
let (mut width, mut height) = writer.get_size_root();
|
let (mut width, mut height) = writer.get_size_root();
|
||||||
if style_element.outline.1 {
|
if style_element.outline.1 {
|
||||||
width += 2;
|
width += 2;
|
||||||
height += 2;
|
height += 2;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
let (mut x, mut y) = (x, y);
|
||||||
|
if style_element.outline.1 {
|
||||||
|
x -= 1;
|
||||||
|
y -= 1;
|
||||||
|
}
|
||||||
|
let height = if style_element.outline.1 {
|
||||||
|
height + 1
|
||||||
|
} else {
|
||||||
|
height
|
||||||
|
};
|
||||||
|
|
||||||
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 + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writer.after_render(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user