mirror of https://github.com/sayanarijit/xplr
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
6.8 KiB
Rust
225 lines
6.8 KiB
Rust
// Things of the past, mostly bad decisions, which cannot erased, stays in this
|
|
// haunted module.
|
|
|
|
use crate::app;
|
|
use crate::lua;
|
|
use crate::ui::block;
|
|
use crate::ui::string_to_text;
|
|
use crate::ui::Constraint;
|
|
use crate::ui::ContentRendererArg;
|
|
use mlua::Lua;
|
|
use serde::{Deserialize, Serialize};
|
|
use tui::backend::Backend;
|
|
use tui::layout::Constraint as TuiConstraint;
|
|
use tui::layout::Rect as TuiRect;
|
|
use tui::widgets::Cell;
|
|
use tui::widgets::List;
|
|
use tui::widgets::ListItem;
|
|
use tui::widgets::Paragraph;
|
|
use tui::widgets::Row;
|
|
use tui::widgets::Table;
|
|
use tui::Frame;
|
|
|
|
/// A cursed enum from crate::ui.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub enum ContentBody {
|
|
/// A paragraph to render
|
|
StaticParagraph { render: String },
|
|
|
|
/// A Lua function that returns a paragraph to render
|
|
DynamicParagraph { render: String },
|
|
|
|
/// List to render
|
|
StaticList { render: Vec<String> },
|
|
|
|
/// A Lua function that returns lines to render
|
|
DynamicList { render: String },
|
|
|
|
/// A table to render
|
|
StaticTable {
|
|
widths: Vec<Constraint>,
|
|
col_spacing: Option<u16>,
|
|
render: Vec<Vec<String>>,
|
|
},
|
|
|
|
/// A Lua function that returns a table to render
|
|
DynamicTable {
|
|
widths: Vec<Constraint>,
|
|
col_spacing: Option<u16>,
|
|
render: String,
|
|
},
|
|
}
|
|
|
|
/// A cursed struct from crate::ui.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct CustomContent {
|
|
pub title: Option<String>,
|
|
pub body: ContentBody,
|
|
}
|
|
|
|
/// A cursed function from crate::ui.
|
|
pub fn draw_custom_content<B: Backend>(
|
|
f: &mut Frame<B>,
|
|
screen_size: TuiRect,
|
|
layout_size: TuiRect,
|
|
app: &app::App,
|
|
content: CustomContent,
|
|
lua: &Lua,
|
|
) {
|
|
let config = app.config.general.panel_ui.default.clone();
|
|
let title = content.title;
|
|
let body = content.body;
|
|
|
|
match body {
|
|
ContentBody::StaticParagraph { render } => {
|
|
let render = string_to_text(render);
|
|
let content = Paragraph::new(render).block(block(
|
|
config,
|
|
title.map(|t| format!(" {t} ")).unwrap_or_default(),
|
|
));
|
|
f.render_widget(content, layout_size);
|
|
}
|
|
|
|
ContentBody::DynamicParagraph { render } => {
|
|
let ctx = ContentRendererArg {
|
|
app: app.to_lua_ctx_light(),
|
|
layout_size: layout_size.into(),
|
|
screen_size: screen_size.into(),
|
|
};
|
|
|
|
let render = lua::serialize(lua, &ctx)
|
|
.map(|arg| {
|
|
lua::call(lua, &render, arg).unwrap_or_else(|e| format!("{e:?}"))
|
|
})
|
|
.unwrap_or_else(|e| e.to_string());
|
|
|
|
let render = string_to_text(render);
|
|
|
|
let content = Paragraph::new(render).block(block(
|
|
config,
|
|
title.map(|t| format!(" {t} ")).unwrap_or_default(),
|
|
));
|
|
f.render_widget(content, layout_size);
|
|
}
|
|
|
|
ContentBody::StaticList { render } => {
|
|
let items = render
|
|
.into_iter()
|
|
.map(string_to_text)
|
|
.map(ListItem::new)
|
|
.collect::<Vec<ListItem>>();
|
|
|
|
let content = List::new(items).block(block(
|
|
config,
|
|
title.map(|t| format!(" {t} ")).unwrap_or_default(),
|
|
));
|
|
f.render_widget(content, layout_size);
|
|
}
|
|
|
|
ContentBody::DynamicList { render } => {
|
|
let ctx = ContentRendererArg {
|
|
app: app.to_lua_ctx_light(),
|
|
layout_size: layout_size.into(),
|
|
screen_size: screen_size.into(),
|
|
};
|
|
|
|
let items = lua::serialize(lua, &ctx)
|
|
.map(|arg| {
|
|
lua::call(lua, &render, arg)
|
|
.unwrap_or_else(|e| vec![format!("{e:?}")])
|
|
})
|
|
.unwrap_or_else(|e| vec![e.to_string()])
|
|
.into_iter()
|
|
.map(string_to_text)
|
|
.map(ListItem::new)
|
|
.collect::<Vec<ListItem>>();
|
|
|
|
let content = List::new(items).block(block(
|
|
config,
|
|
title.map(|t| format!(" {t} ")).unwrap_or_default(),
|
|
));
|
|
f.render_widget(content, layout_size);
|
|
}
|
|
|
|
ContentBody::StaticTable {
|
|
widths,
|
|
col_spacing,
|
|
render,
|
|
} => {
|
|
let rows = render
|
|
.into_iter()
|
|
.map(|cols| {
|
|
Row::new(
|
|
cols.into_iter()
|
|
.map(string_to_text)
|
|
.map(Cell::from)
|
|
.collect::<Vec<Cell>>(),
|
|
)
|
|
})
|
|
.collect::<Vec<Row>>();
|
|
|
|
let widths = widths
|
|
.into_iter()
|
|
.map(|w| w.to_tui(screen_size, layout_size))
|
|
.collect::<Vec<TuiConstraint>>();
|
|
|
|
let content = Table::new(rows)
|
|
.widths(&widths)
|
|
.column_spacing(col_spacing.unwrap_or(1))
|
|
.block(block(
|
|
config,
|
|
title.map(|t| format!(" {t} ")).unwrap_or_default(),
|
|
));
|
|
|
|
f.render_widget(content, layout_size);
|
|
}
|
|
|
|
ContentBody::DynamicTable {
|
|
widths,
|
|
col_spacing,
|
|
render,
|
|
} => {
|
|
let ctx = ContentRendererArg {
|
|
app: app.to_lua_ctx_light(),
|
|
layout_size: layout_size.into(),
|
|
screen_size: screen_size.into(),
|
|
};
|
|
|
|
let rows = lua::serialize(lua, &ctx)
|
|
.map(|arg| {
|
|
lua::call(lua, &render, arg)
|
|
.unwrap_or_else(|e| vec![vec![format!("{e:?}")]])
|
|
})
|
|
.unwrap_or_else(|e| vec![vec![e.to_string()]])
|
|
.into_iter()
|
|
.map(|cols| {
|
|
Row::new(
|
|
cols.into_iter()
|
|
.map(string_to_text)
|
|
.map(Cell::from)
|
|
.collect::<Vec<Cell>>(),
|
|
)
|
|
})
|
|
.collect::<Vec<Row>>();
|
|
|
|
let widths = widths
|
|
.into_iter()
|
|
.map(|w| w.to_tui(screen_size, layout_size))
|
|
.collect::<Vec<TuiConstraint>>();
|
|
|
|
let mut content = Table::new(rows).widths(&widths).block(block(
|
|
config,
|
|
title.map(|t| format!(" {t} ")).unwrap_or_default(),
|
|
));
|
|
|
|
if let Some(col_spacing) = col_spacing {
|
|
content = content.column_spacing(col_spacing);
|
|
};
|
|
|
|
f.render_widget(content, layout_size);
|
|
}
|
|
}
|
|
}
|