From d04f8acaf86a51275c14abb031161a68b638ba3c Mon Sep 17 00:00:00 2001 From: sxyazi Date: Tue, 17 Oct 2023 12:34:35 +0800 Subject: [PATCH] feat: add new `Border` component --- plugin/preset/ui.lua | 14 ++++- plugin/src/components/components.rs | 4 +- plugin/src/layout/bar.rs | 4 +- plugin/src/layout/border.rs | 82 +++++++++++++++++++++++++++++ plugin/src/layout/layout.rs | 10 ++-- plugin/src/layout/mod.rs | 2 + plugin/src/plugin.rs | 1 + 7 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 plugin/src/layout/border.rs diff --git a/plugin/preset/ui.lua b/plugin/preset/ui.lua index 563cb916..f9e3720c 100644 --- a/plugin/preset/ui.lua +++ b/plugin/preset/ui.lua @@ -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, }), diff --git a/plugin/src/components/components.rs b/plugin/src/components/components.rs index 9009a54a..f23386c3 100644 --- a/plugin/src/components/components.rs +++ b/plugin/src/components/components.rs @@ -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 = RoCell::new(); pub(super) static COMP_HEADER: RoCell
= RoCell::new(); @@ -31,6 +31,8 @@ pub(super) fn layout( c.render(buf) } else if let Ok(c) = value.take::() { c.render(cx, buf) + } else if let Ok(c) = value.take::() { + c.render(buf) } else if let Ok(c) = value.take::() { c.render(buf) } diff --git a/plugin/src/layout/bar.rs b/plugin/src/layout/bar.rs index b7f98ac9..6f53dc97 100644 --- a/plugin/src/layout/bar.rs +++ b/plugin/src/layout/bar.rs @@ -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(), diff --git a/plugin/src/layout/border.rs b/plugin/src/layout/border.rs new file mode 100644 index 00000000..8b68035a --- /dev/null +++ b/plugin/src/layout/border.rs @@ -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, +} + +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 { + match value { + Value::UserData(ud) => Ok(ud.borrow::()?.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::()?.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::()?; + 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::