feat: add new Border component

This commit is contained in:
sxyazi 2023-10-17 12:34:35 +08:00
parent a45a8642b2
commit d04f8acaf8
No known key found for this signature in database
7 changed files with 107 additions and 10 deletions

View file

@ -12,8 +12,9 @@ ui = {
NONE = 0,
TOP = 1,
RIGHT = 2,
BOTTOM = 3,
LEFT = 4,
BOTTOM = 4,
LEFT = 8,
ALL = 15,
},
Base = setmetatable({
@ -21,6 +22,14 @@ ui = {
}, {
__call = function(_, ...) return ui.Base.new(...) end,
}),
Border = setmetatable({
PLAIN = 0,
ROUNDED = 1,
DOUBLE = 2,
THICK = 3,
}, {
__call = function(_, ...) return ui.Border.new(...) end,
}),
Padding = setmetatable({
left = function(left) return ui.Padding.new(left, 0, 0, 0) end,
right = function(right) return ui.Padding.new(0, right, 0, 0) end,
@ -28,6 +37,7 @@ ui = {
bottom = function(bottom) return ui.Padding.new(0, 0, 0, bottom) end,
x = function(x) return ui.Padding.new(x, x, 0, 0) end,
y = function(y) return ui.Padding.new(0, 0, y, y) end,
xy = function(xy) return ui.Padding.new(xy, xy, xy, xy) end,
}, {
__call = function(_, ...) return ui.Padding.new(...) end,
}),

View file

@ -2,7 +2,7 @@ use mlua::{AnyUserData, Table};
use shared::RoCell;
use super::Base;
use crate::{layout::{Bar, Gauge, List, Paragraph}, GLOBALS};
use crate::{layout::{Bar, Border, Gauge, List, Paragraph}, GLOBALS};
pub(super) static COMP_FOLDER: RoCell<Table> = RoCell::new();
pub(super) static COMP_HEADER: RoCell<Table> = RoCell::new();
@ -31,6 +31,8 @@ pub(super) fn layout(
c.render(buf)
} else if let Ok(c) = value.take::<Base>() {
c.render(cx, buf)
} else if let Ok(c) = value.take::<Border>() {
c.render(buf)
} else if let Ok(c) = value.take::<Gauge>() {
c.render(buf)
}

View file

@ -24,8 +24,8 @@ impl Bar {
position: match direction {
1 => ratatui::widgets::Borders::TOP,
2 => ratatui::widgets::Borders::RIGHT,
3 => ratatui::widgets::Borders::BOTTOM,
4 => ratatui::widgets::Borders::LEFT,
4 => ratatui::widgets::Borders::BOTTOM,
8 => ratatui::widgets::Borders::LEFT,
_ => ratatui::widgets::Borders::NONE,
},
symbol: Default::default(),

View file

@ -0,0 +1,82 @@
use mlua::{AnyUserData, FromLua, Lua, Table, UserData, Value};
use ratatui::widgets::Widget;
use super::{Rect, Style};
use crate::{GLOBALS, LUA};
#[derive(Clone)]
pub struct Border {
area: ratatui::layout::Rect,
position: ratatui::widgets::Borders,
type_: ratatui::widgets::BorderType,
style: Option<ratatui::style::Style>,
}
impl Border {
pub(crate) fn install() -> mlua::Result<()> {
let ui: Table = GLOBALS.get("ui")?;
let border: Table = ui.get("Border")?;
border.set(
"new",
LUA.create_function(|_, (area, position): (Rect, u8)| {
Ok(Self {
area: area.0,
position: ratatui::widgets::Borders::from_bits_truncate(position),
type_: Default::default(),
style: Default::default(),
})
})?,
)
}
pub fn render(self, buf: &mut ratatui::buffer::Buffer) {
let mut block =
ratatui::widgets::Block::default().borders(self.position).border_type(self.type_);
if let Some(style) = self.style {
block = block.border_style(style);
}
block.render(self.area, buf);
}
}
impl<'lua> FromLua<'lua> for Border {
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> mlua::Result<Self> {
match value {
Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
_ => Err(mlua::Error::FromLuaConversionError {
from: value.type_name(),
to: "Border",
message: Some("expected a Border".to_string()),
}),
}
}
}
impl UserData for Border {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_function("type", |_, (ud, value): (AnyUserData, u8)| {
ud.borrow_mut::<Self>()?.type_ = match value {
1 => ratatui::widgets::BorderType::Rounded,
2 => ratatui::widgets::BorderType::Double,
3 => ratatui::widgets::BorderType::Thick,
_ => ratatui::widgets::BorderType::Plain,
};
Ok(ud)
});
methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
{
let mut me = ud.borrow_mut::<Self>()?;
match value {
Value::Nil => me.style = None,
Value::Table(tbl) => me.style = Some(Style::from(tbl).0),
Value::UserData(ud) => me.style = Some(ud.borrow::<Style>()?.0),
_ => return Err(mlua::Error::external("expected a Style or Table or nil")),
}
}
Ok(ud)
});
}
}

View file

@ -70,11 +70,11 @@ impl UserData for Layout {
let me = ud.borrow::<Self>()?;
let mut layout = ratatui::layout::Layout::new()
.direction(
me.direction
.then_some(ratatui::layout::Direction::Vertical)
.unwrap_or(ratatui::layout::Direction::Horizontal),
)
.direction(if me.direction {
ratatui::layout::Direction::Vertical
} else {
ratatui::layout::Direction::Horizontal
})
.constraints(me.constraints.as_slice());
if let Some(margin) = me.margin {

View file

@ -1,6 +1,7 @@
#![allow(clippy::module_inception)]
mod bar;
mod border;
mod constraint;
mod gauge;
mod layout;
@ -13,6 +14,7 @@ mod span;
mod style;
pub(super) use bar::*;
pub(super) use border::*;
pub(super) use constraint::*;
pub(super) use gauge::*;
pub(super) use layout::*;

View file

@ -36,6 +36,7 @@ pub fn init() {
components::Base::install()?;
layout::Bar::install()?;
layout::Border::install()?;
layout::Constraint::install()?;
layout::Gauge::install()?;
layout::Layout::install()?;