Skip to content

Commit

Permalink
feat: complete and consistent support for the ui.Style() API (#1637)
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi authored Sep 12, 2024
1 parent 61c0db8 commit 0ee4c36
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 182 deletions.
40 changes: 9 additions & 31 deletions yazi-plugin/src/elements/bar.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use mlua::{AnyUserData, ExternalError, Lua, Table, UserData, Value};
use mlua::{AnyUserData, Lua, Table, UserData};
use ratatui::widgets::Borders;

use super::{RectRef, Renderable, Style};
use super::{RectRef, Renderable};

#[derive(Clone)]
pub struct Bar {
area: ratatui::layout::Rect,

direction: ratatui::widgets::Borders,
symbol: String,
style: Option<ratatui::style::Style>,
style: ratatui::style::Style,
}

impl Bar {
Expand Down Expand Up @@ -42,22 +42,12 @@ impl Bar {

impl UserData for Bar {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
crate::impl_style_method!(methods, style);

methods.add_function("symbol", |_, (ud, symbol): (AnyUserData, String)| {
ud.borrow_mut::<Self>()?.symbol = symbol;
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(tb) => me.style = Some(Style::try_from(tb)?.0),
Value::UserData(ud) => me.style = Some(ud.borrow::<Style>()?.0),
_ => return Err("expected a Style or Table or nil".into_lua_err()),
}
}
Ok(ud)
});
}
}

Expand All @@ -81,36 +71,24 @@ impl Renderable for Bar {

if self.direction.contains(Borders::LEFT) {
for y in self.area.top()..self.area.bottom() {
let cell = buf[(self.area.left(), y)].set_symbol(symbol);
if let Some(style) = self.style {
cell.set_style(style);
}
buf[(self.area.left(), y)].set_style(self.style).set_symbol(symbol);
}
}
if self.direction.contains(Borders::TOP) {
for x in self.area.left()..self.area.right() {
let cell = buf[(x, self.area.top())].set_symbol(symbol);
if let Some(style) = self.style {
cell.set_style(style);
}
buf[(x, self.area.top())].set_style(self.style).set_symbol(symbol);
}
}
if self.direction.contains(Borders::RIGHT) {
let x = self.area.right() - 1;
for y in self.area.top()..self.area.bottom() {
let cell = buf[(x, y)].set_symbol(symbol);
if let Some(style) = self.style {
cell.set_style(style);
}
buf[(x, y)].set_style(self.style).set_symbol(symbol);
}
}
if self.direction.contains(Borders::BOTTOM) {
let y = self.area.bottom() - 1;
for x in self.area.left()..self.area.right() {
let cell = buf[(x, y)].set_symbol(symbol);
if let Some(style) = self.style {
cell.set_style(style);
}
buf[(x, y)].set_style(self.style).set_symbol(symbol);
}
}
}
Expand Down
33 changes: 10 additions & 23 deletions yazi-plugin/src/elements/border.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use mlua::{AnyUserData, ExternalError, Lua, Table, UserData, Value};
use mlua::{AnyUserData, Lua, Table, UserData};
use ratatui::widgets::{Borders, Widget};

use super::{RectRef, Renderable, Style};
use super::{RectRef, Renderable};

// Type
const PLAIN: u8 = 0;
Expand All @@ -17,7 +17,7 @@ pub struct Border {

position: ratatui::widgets::Borders,
type_: ratatui::widgets::BorderType,
style: Option<ratatui::style::Style>,
style: ratatui::style::Style,
}

impl Border {
Expand Down Expand Up @@ -55,6 +55,8 @@ impl Border {

impl UserData for Border {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
crate::impl_style_method!(methods, style);

methods.add_function("type", |_, (ud, value): (AnyUserData, u8)| {
ud.borrow_mut::<Self>()?.type_ = match value {
ROUNDED => ratatui::widgets::BorderType::Rounded,
Expand All @@ -66,33 +68,18 @@ impl UserData for Border {
};
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(tb) => me.style = Some(Style::try_from(tb)?.0),
Value::UserData(ud) => me.style = Some(ud.borrow::<Style>()?.0),
_ => return Err("expected a Style or Table or nil".into_lua_err()),
}
}
Ok(ud)
});
}
}

impl Renderable for Border {
fn area(&self) -> ratatui::layout::Rect { self.area }

fn render(self: Box<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);
ratatui::widgets::Block::default()
.borders(self.position)
.border_type(self.type_)
.border_style(self.style)
.render(self.area, buf);
}

fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf); }
Expand Down
44 changes: 14 additions & 30 deletions yazi-plugin/src/elements/gauge.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use mlua::{AnyUserData, ExternalError, Lua, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget;

use super::{RectRef, Renderable, Span, Style};
use super::{RectRef, Renderable, Span};
use crate::elements::Style;

#[derive(Clone, Default)]
pub struct Gauge {
area: ratatui::layout::Rect,

ratio: f64,
label: Option<ratatui::text::Span<'static>>,
style: Option<ratatui::style::Style>,
gauge_style: Option<ratatui::style::Style>,
style: ratatui::style::Style,
gauge_style: ratatui::style::Style,
}

impl Gauge {
Expand All @@ -24,6 +25,8 @@ impl Gauge {

impl UserData for Gauge {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
crate::impl_style_method!(methods, style);

methods.add_function("percent", |_, (ud, percent): (AnyUserData, u8)| {
if percent > 100 {
return Err("percent must be between 0 and 100".into_lua_err());
Expand All @@ -47,23 +50,8 @@ impl UserData for Gauge {
Ok(ud)
});

methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
ud.borrow_mut::<Self>()?.style = match value {
Value::Nil => None,
Value::Table(tb) => Some(Style::try_from(tb)?.0),
Value::UserData(ud) => Some(ud.borrow::<Style>()?.0),
_ => return Err("expected a Style or Table or nil".into_lua_err()),
};
Ok(ud)
});

methods.add_function("gauge_style", |_, (ud, value): (AnyUserData, Value)| {
ud.borrow_mut::<Self>()?.gauge_style = match value {
Value::Nil => None,
Value::Table(tb) => Some(Style::try_from(tb)?.0),
Value::UserData(ud) => Some(ud.borrow::<Style>()?.0),
_ => return Err("expected a Style or Table or nil".into_lua_err()),
};
ud.borrow_mut::<Self>()?.gauge_style = Style::try_from(value)?.0;
Ok(ud)
});
}
Expand All @@ -73,20 +61,16 @@ impl Renderable for Gauge {
fn area(&self) -> ratatui::layout::Rect { self.area }

fn render(self: Box<Self>, buf: &mut ratatui::buffer::Buffer) {
let mut gauge = ratatui::widgets::Gauge::default();
let mut gauge = ratatui::widgets::Gauge::default()
.ratio(self.ratio)
.style(self.style)
.gauge_style(self.gauge_style);

gauge = gauge.ratio(self.ratio);
if let Some(label) = self.label {
gauge = gauge.label(label);
}
if let Some(style) = self.style {
gauge = gauge.style(style);
}
if let Some(gauge_style) = self.gauge_style {
gauge = gauge.gauge_style(gauge_style);
if let Some(s) = self.label {
gauge = gauge.label(s)
}

gauge.render(self.area, buf)
gauge.render(self.area, buf);
}

fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf) }
Expand Down
15 changes: 2 additions & 13 deletions yazi-plugin/src/elements/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ansi_to_tui::IntoText;
use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, Table, UserData, UserDataMethods, Value};
use unicode_width::UnicodeWidthChar;

use super::{Span, Style};
use super::Span;

const LEFT: u8 = 0;
const CENTER: u8 = 1;
Expand Down Expand Up @@ -83,21 +83,10 @@ impl Line {

impl UserData for Line {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
crate::impl_style_method!(methods, 0.style);
crate::impl_style_shorthands!(methods, 0.style);

methods.add_method("width", |_, me, ()| Ok(me.0.width()));
methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
{
let mut me = ud.borrow_mut::<Self>()?;
me.0.style = match value {
Value::Nil => ratatui::style::Style::default(),
Value::Table(tb) => Style::try_from(tb)?.0,
Value::UserData(ud) => ud.borrow::<Style>()?.0,
_ => return Err("expected a Style or Table or nil".into_lua_err()),
};
}
Ok(ud)
});
methods.add_function("align", |_, (ud, align): (AnyUserData, u8)| {
ud.borrow_mut::<Self>()?.0.alignment = Some(match align {
CENTER => ratatui::layout::Alignment::Center,
Expand Down
57 changes: 20 additions & 37 deletions yazi-plugin/src/elements/list.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use mlua::{AnyUserData, ExternalError, FromLua, Lua, Table, UserData, Value};
use mlua::{ExternalError, FromLua, Lua, Table, UserData, Value};
use ratatui::widgets::Widget;

use super::{Line, RectRef, Renderable, Span, Style};
use super::{Line, RectRef, Renderable, Span};

// --- List
#[derive(Clone)]
Expand Down Expand Up @@ -35,59 +35,42 @@ impl Renderable for List {
}

// --- ListItem
#[derive(Clone, FromLua)]
#[derive(Clone, Default, FromLua)]
pub struct ListItem {
content: ratatui::text::Text<'static>,
style: Option<ratatui::style::Style>,
style: ratatui::style::Style,
}

impl ListItem {
pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> {
ui.raw_set(
"ListItem",
lua.create_function(|_, value: Value| {
match value {
Value::UserData(ud) => {
let content: ratatui::text::Text = if let Ok(line) = ud.take::<Line>() {
line.0.into()
} else if let Ok(span) = ud.take::<Span>() {
span.0.into()
} else {
return Err("expected a String, Line or Span".into_lua_err());
};
return Ok(Self { content, style: None });
}
Value::String(s) => {
return Ok(Self { content: s.to_string_lossy().into_owned().into(), style: None });
}
_ => {}
lua.create_function(|_, value: Value| match value {
Value::String(s) => {
Ok(Self { content: s.to_string_lossy().into_owned().into(), ..Default::default() })
}
Err("expected a String, Line or Span".into_lua_err())
Value::UserData(ud) => {
let content: ratatui::text::Text = if let Ok(line) = ud.take::<Line>() {
line.0.into()
} else if let Ok(span) = ud.take::<Span>() {
span.0.into()
} else {
return Err("expected a String, Line or Span".into_lua_err());
};
Ok(Self { content, ..Default::default() })
}
_ => Err("expected a String, Line or Span".into_lua_err()),
})?,
)
}
}

impl From<ListItem> for ratatui::widgets::ListItem<'static> {
fn from(value: ListItem) -> Self {
let mut item = Self::new(value.content);
if let Some(style) = value.style {
item = item.style(style)
}
item
}
fn from(value: ListItem) -> Self { Self::new(value.content).style(value.style) }
}

impl UserData for ListItem {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
ud.borrow_mut::<Self>()?.style = match value {
Value::Nil => None,
Value::Table(tb) => Some(Style::try_from(tb)?.0),
Value::UserData(ud) => Some(ud.borrow::<Style>()?.0),
_ => return Err("expected a Style or Table or nil".into_lua_err()),
};
Ok(ud)
});
crate::impl_style_method!(methods, style);
}
}
17 changes: 3 additions & 14 deletions yazi-plugin/src/elements/paragraph.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use ansi_to_tui::IntoText;
use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, Table, UserData, Value};
use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, Table, UserData};
use ratatui::widgets::Widget;

use super::{Line, RectRef, Renderable, Style};
use super::{Line, RectRef, Renderable};

// Alignment
const LEFT: u8 = 0;
Expand Down Expand Up @@ -58,20 +58,9 @@ impl Paragraph {

impl UserData for Paragraph {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
crate::impl_style_method!(methods, style);
crate::impl_style_shorthands!(methods, style);

methods.add_function("style", |_, (ud, value): (AnyUserData, Value)| {
{
let mut me = ud.borrow_mut::<Self>()?;
match value {
Value::Nil => me.style = ratatui::style::Style::default(),
Value::Table(tb) => me.style = Style::try_from(tb)?.0,
Value::UserData(ud) => me.style = ud.borrow::<Style>()?.0,
_ => return Err("expected a Style or Table or nil".into_lua_err()),
}
}
Ok(ud)
});
methods.add_function("align", |_, (ud, align): (AnyUserData, u8)| {
ud.borrow_mut::<Self>()?.alignment = match align {
CENTER => ratatui::layout::Alignment::Center,
Expand Down
Loading

0 comments on commit 0ee4c36

Please sign in to comment.