A TUIs package written in MoonBit
moon add FrozenLemonTee/LunarTUIimport {
"FrozenLemonTee/LunarTUI@0.0.1",
}///|
test {
// 创建组件
let title = @widgets.Label::new(
"Welcome to the LunarTUI framework",
left=2,
top=1,
)
let progress = @widgets.ProgressBar::new(
20,
value=0.75,
left=2,
top=3,
prefix="Loading progress:",
suffix="Complete",
)
// 创建带布局的容器
let container = @widgets.Container::new(
0,
0,
80,
24,
layout=@layouts.VLayout::new(),
children=[title, progress],
)
// 创建终端实例
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
// 渲染界面
@terminal.Terminal::clear()
terminal.draw(container)
@terminal.Terminal::newline()
}///|
test {
let layout = @layouts.HLayout::new()
let labels : Array[&@base.Widget] = []
for i in 0..<3 {
labels.push(@widgets.Label::new("Label\{i}"))
}
let container = @widgets.Container::new(
0,
0,
60,
10,
layout~,
children=labels,
)
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(container)
@terminal.Terminal::newline()
}///|
test {
let layout = @layouts.VLayout::new()
let labels : Array[&@base.Widget] = []
for i in 0..<3 {
labels.push(@widgets.Label::new("Label\{i}"))
}
let container = @widgets.Container::new(
0,
0,
60,
10,
layout~,
children=labels,
)
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(container)
@terminal.Terminal::newline()
}///|
test {
let layout = @layouts.GridLayout::new(2, 3) // 2行3列
let labels : Array[&@base.Widget] = []
for i in 0..<6 {
labels.push(@widgets.Label::new("Label\{i}"))
}
let container = @widgets.Container::new(
0,
0,
60,
10,
layout~,
children=labels,
)
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(container)
@terminal.Terminal::newline()
}///|
test {
let layout = @layouts.FlexLayout::new(
direction=Row,
justify=SpaceBetween,
align=Center,
)
let labels : Array[&@base.Widget] = []
for i in 0..<3 {
labels.push(@widgets.Label::new("Label\{i}"))
}
let container = @widgets.Container::new(
0,
0,
60,
10,
layout~,
children=labels,
)
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(container)
@terminal.Terminal::newline()
}///|
test {
let label = @widgets.Label::new("Hello World", left=5, top=3)
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(label)
@terminal.Terminal::newline()
}///|
test {
let text = "This is a multi-line text paragraph that supports automatic line breaks and alignment features."
let para = @widgets.Paragraph::new(2, 2, 40, 5, text, align=Center)
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(para)
@terminal.Terminal::newline()
}///|
test {
let progress = @widgets.ProgressBar::new(
25,
value=0.65,
left=5,
top=5,
prefix="Processing:",
mode=Percentage,
)
progress.set_value(0.8) // 更新进度
let terminal = @terminal.Terminal::new(@base.Area::new(80, 24))
@terminal.Terminal::clear()
terminal.draw(progress)
@terminal.Terminal::newline()
}///|
test {
let area = @base.Area::new(50, 50)
// 水平分割线
let hdiv = @widgets.Divider::new(
30,
left=5,
top=2,
line='=',
edge='+',
direction=Row,
)
// 垂直分割线
let vdiv = @widgets.Divider::new(
10,
left=15,
top=0,
line='|',
edge='+',
direction=Column,
)
let container = @widgets.Container::new(
0,
0,
area.width,
area.height,
layout=@layouts.VLayout::new(),
)
container.add(hdiv)
container.add(vdiv)
let ter = @terminal.Terminal::new(area)
@terminal.Terminal::clear()
ter.draw(container)
@terminal.Terminal::newline()
}///|
test {
let area = @base.Area::new(100, 50)
// 从字符串创建
let ascii_art = " /\\\n/ \\\n\\ /\n \\/"
let image1 = @widgets.Image::from_string(ascii_art, left=10, top=2)
let container = @widgets.Container::new(
0,
0,
area.width,
area.height,
layout=@layouts.VLayout::new(),
)
container.add(image1)
// 从文件加载
let cwd = @env.current_dir()
match cwd {
None => ()
Some(cwd) => {
let file_name = "test/ascii_pic.txt"
let file_dir = @path.Path::new(cwd)
file_dir.push(file_name)
let image2 = @widgets.Image::from_file(file_dir.to_string())
container.add(image2)
}
}
let ter = @terminal.Terminal::new(area)
@terminal.Terminal::clear()
ter.draw(container)
@terminal.Terminal::newline()
}///|
test {
let area = @base.Area::new(30, 12)
let block = @widgets.Block::new(
0,
0,
area.width,
area.height,
title="Control Panel",
layout=@layouts.VLayout::new(),
)
let l1 = @widgets.Label::new("l1")
let d1 = @widgets.Divider::new(10)
let l2 = @widgets.Label::new("l2")
block.add(l1)
block.add(d1)
block.add(l2)
let ter = @terminal.Terminal::new(area)
@terminal.Terminal::clear()
ter.draw(block)
@terminal.Terminal::newline()
}///|
pub struct CustomWidget {
// 组件状态
}
///|
pub impl @base.Widget for CustomWidget with fn width(self : CustomWidget) -> Int {
// 返回宽度
...
}
///|
pub impl @base.Widget for CustomWidget with fn height(self : CustomWidget) -> Int {
// 返回高度
...
}
///|
pub impl @base.Widget for CustomWidget with fn render(
self : CustomWidget,
frame : @base.Frame,
) -> Unit {
// 渲染逻辑
...
}///|
pub struct CustomLayout {}
///|
pub impl @base.Layout for CustomLayout with fn split(
self : CustomLayout,
area : @base.Area,
children : Array[&@base.Widget],
) -> Array[@base.Section] {
// 布局算法
...
}
///|
pub impl @base.Layout for CustomLayout with fn width(
self : CustomLayout,
area : @base.Area,
children : Array[&@base.Widget],
) -> Int {
...
}
///|
pub impl @base.Layout for CustomLayout with fn height(
self : CustomLayout,
area : @base.Area,
children : Array[&@base.Widget],
) -> Int {
...
}| 类型 | 说明 |
|---|---|
| Terminal | 终端渲染引擎,管理双缓冲和差异更新 |
| Buffer | 字符缓冲区,存储终端内容状态 |
| Frame | 渲染视图,提供坐标转换和裁剪 |
| Area | 二维区域定义 |
| Section | 带位置的区域定义 |
///|
pub(open) trait Widget {
fn width(self : Self) -> Int
fn height(self : Self) -> Int
fn render(self : Self, frame : @base.Frame) -> Unit
}///|
pub(open) trait Layout {
fn split(self : Self, area : @base.Area, children : Array[&Widget]) -> Array[
@base.Section,
]
fn width(self : Self, area : @base.Area, children : Array[&Widget]) -> Int
fn height(self : Self, area : @base.Area, children : Array[&Widget]) -> Int
}git checkout -b feature/AmazingFeaturegit commit -m 'Add some AmazingFeature'git push origin feature/AmazingFeature