///|
pub(all) struct Size {
width : Int
height : Int
} derive(Eq, Debug)
///|
pub(all) struct Point {
x : Int
y : Int
} derive(Eq, Debug)
///|
pub(all) enum Color {
Default
Ansi(Int)
Rgb(Int, Int, Int)
} derive(Eq, Debug)
///|
pub(all) enum Align {
Start
Center
End
} derive(Eq, Debug)
///|
pub(all) struct Edge {
top : Int
right : Int
bottom : Int
left : Int
} derive(Eq, Debug)
///|
pub fn Edge::all(value : Int) -> Edge {
{ top: value, right: value, bottom: value, left: value }
}
///|
pub fn Edge::zero() -> Edge {
Edge::all(0)
}
///|
pub fn Edge::xy(x : Int, y : Int) -> Edge {
{ top: y, right: x, bottom: y, left: x }
}
///|
pub fn Edge::horizontal(value : Int) -> Edge {
{ top: 0, right: value, bottom: 0, left: value }
}
///|
pub fn Edge::vertical(value : Int) -> Edge {
{ top: value, right: 0, bottom: value, left: 0 }
}
///|
pub fn Edge::trbl(top : Int, right : Int, bottom : Int, left : Int) -> Edge {
{ top, right, bottom, left }
}
///|
pub(all) enum Border {
NoBorder
Normal
Rounded
Square
Double
Thick
} derive(Eq, Debug)
///|
pub(all) struct Style {
fg : Color
bg : Color
bold : Bool
dim : Bool
italic : Bool
underline : Bool
blink : Bool
reverse : Bool
strikethrough : Bool
width : Int
height : Int
padding : Edge
border : Border
align_horizontal : Align
align_vertical : Align
align_set : Bool
clip_width : Int
clip_height : Int
} derive(Eq, Debug)
///|
pub fn Style::default() -> Style {
{
fg: Default,
bg: Default,
bold: false,
dim: false,
italic: false,
underline: false,
blink: false,
reverse: false,
strikethrough: false,
width: -1,
height: -1,
padding: Edge::zero(),
border: NoBorder,
align_horizontal: Start,
align_vertical: Start,
align_set: false,
clip_width: -1,
clip_height: -1,
}
}
///|
pub fn Style::fg(self : Style, color : Color) -> Style {
{ ..self, fg: color }
}
///|
pub fn Style::bg(self : Style, color : Color) -> Style {
{ ..self, bg: color }
}
///|
pub fn Style::bold(self : Style) -> Style {
{ ..self, bold: true }
}
///|
pub fn Style::dim(self : Style) -> Style {
{ ..self, dim: true }
}
///|
pub fn Style::italic(self : Style) -> Style {
{ ..self, italic: true }
}
///|
pub fn Style::underline(self : Style) -> Style {
{ ..self, underline: true }
}
///|
pub fn Style::blink(self : Style) -> Style {
{ ..self, blink: true }
}
///|
pub fn Style::reverse(self : Style) -> Style {
{ ..self, reverse: true }
}
///|
pub fn Style::strikethrough(self : Style) -> Style {
{ ..self, strikethrough: true }
}
///|
pub fn Style::width(self : Style, width : Int) -> Style {
{ ..self, width, }
}
///|
pub fn Style::height(self : Style, height : Int) -> Style {
{ ..self, height, }
}
///|
pub fn Style::size(
self : Style,
width? : Int = -1,
height? : Int = -1,
) -> Style {
{ ..self, width, height }
}
///|
pub fn Style::padding(self : Style, edge : Edge) -> Style {
{ ..self, padding: edge }
}
///|
pub fn Style::border(self : Style, kind? : Border = Rounded) -> Style {
{ ..self, border: kind }
}
///|
pub fn Style::align(
self : Style,
horizontal? : Align = Start,
vertical? : Align = Start,
) -> Style {
{
..self,
align_horizontal: horizontal,
align_vertical: vertical,
align_set: true,
}
}
///|
pub fn Style::clip(self : Style, size : Size) -> Style {
{ ..self, clip_width: size.width, clip_height: size.height }
}
///|
pub fn Style::merge(self : Style, next : Style) -> Style {
{
fg: if next.fg == Default {
self.fg
} else {
next.fg
},
bg: if next.bg == Default {
self.bg
} else {
next.bg
},
bold: self.bold || next.bold,
dim: self.dim || next.dim,
italic: self.italic || next.italic,
underline: self.underline || next.underline,
blink: self.blink || next.blink,
reverse: self.reverse || next.reverse,
strikethrough: self.strikethrough || next.strikethrough,
width: if next.width >= 0 {
next.width
} else {
self.width
},
height: if next.height >= 0 {
next.height
} else {
self.height
},
padding: if next.padding == Edge::zero() {
self.padding
} else {
next.padding
},
border: if next.border == NoBorder {
self.border
} else {
next.border
},
align_horizontal: if next.align_set {
next.align_horizontal
} else {
self.align_horizontal
},
align_vertical: if next.align_set {
next.align_vertical
} else {
self.align_vertical
},
align_set: self.align_set || next.align_set,
clip_width: if next.clip_width >= 0 {
next.clip_width
} else {
self.clip_width
},
clip_height: if next.clip_height >= 0 {
next.clip_height
} else {
self.clip_height
},
}
}
///|
enum Node {
Empty
Text(String, Style)
Fragment(Array[Node])
VStack(Array[Node], Int)
HStack(Array[Node], Int)
Pad(Node, Edge)
Styled(Node, Style)
Bordered(Node, Border, Style)
Clip(Node, Size)
Sized(Node, Size)
Aligned(Node, Align, Align)
Placed(Node, Size, Align, Align)
Fill(String, Style)
} derive(Eq, Debug)
///|
pub(all) enum Key {
Char(String)
Enter
Escape
Backspace
Tab
BackTab
Up
Down
Left
Right
Home
End
Delete
PageUp
PageDown
Ctrl(String)
Alt(String)
Modified(Key, KeyModifiers)
Function(Int)
Unknown(String)
} derive(Eq, Debug)
///|
pub(all) struct KeyModifiers {
shift : Bool
alt : Bool
ctrl : Bool
super_key : Bool
hyper : Bool
meta : Bool
} derive(Eq, Debug)
///|
pub fn KeyModifiers::none() -> KeyModifiers {
{
shift: false,
alt: false,
ctrl: false,
super_key: false,
hyper: false,
meta: false,
}
}
///|
pub fn KeyModifiers::shift(self : KeyModifiers, enabled : Bool) -> KeyModifiers {
{ ..self, shift: enabled }
}
///|
pub fn KeyModifiers::alt(self : KeyModifiers, enabled : Bool) -> KeyModifiers {
{ ..self, alt: enabled }
}
///|
pub fn KeyModifiers::ctrl(self : KeyModifiers, enabled : Bool) -> KeyModifiers {
{ ..self, ctrl: enabled }
}
///|
pub fn KeyModifiers::super_key(
self : KeyModifiers,
enabled : Bool,
) -> KeyModifiers {
{ ..self, super_key: enabled }
}
///|
pub fn KeyModifiers::hyper(self : KeyModifiers, enabled : Bool) -> KeyModifiers {
{ ..self, hyper: enabled }
}
///|
pub fn KeyModifiers::meta(self : KeyModifiers, enabled : Bool) -> KeyModifiers {
{ ..self, meta: enabled }
}
///|
pub(all) enum MouseButton {
Primary
Middle
Secondary
WheelUp
WheelDown
Other(Int)
} derive(Eq, Debug)
///|
pub(all) enum MouseAction {
Press
Release
Drag
} derive(Eq, Debug)
///|
pub(all) enum MouseMode {
MouseOff
MouseCellMotion
MouseButtonMotion
MouseAllMotion
} derive(Eq, Debug)
///|
pub(all) struct Mouse {
button : MouseButton
action : MouseAction
x : Int
y : Int
} derive(Eq, Debug)
///|
pub(all) enum Event {
Key(Key)
Mouse(Mouse)
Resize(Size)
FocusGained
FocusLost
Paste(String)
Tick(Int64)
Quit
UnknownEvent(String)
} derive(Eq, Debug)
///|
pub(all) struct CancelToken {
mut cancelled : Bool
} derive(Debug)
///|
pub fn CancelToken::new() -> CancelToken {
{ cancelled: false }
}
///|
pub fn CancelToken::cancel(self : CancelToken) -> Unit {
self.cancelled = true
}
///|
pub fn CancelToken::is_cancelled(self : CancelToken) -> Bool {
self.cancelled
}
///|
pub(all) struct ProgramOptions {
alternate_screen : Bool
mouse_mode : MouseMode
bracketed_paste : Bool
focus_events : Bool
hide_cursor : Bool
renderer_enabled : Bool
renderer_fps : Int
max_messages_per_frame : Int
resize_poll_millis : Int
} derive(Eq, Debug)
///|
pub fn ProgramOptions::default() -> ProgramOptions {
{
alternate_screen: true,
mouse_mode: MouseOff,
bracketed_paste: false,
focus_events: false,
hide_cursor: true,
renderer_enabled: true,
renderer_fps: 60,
max_messages_per_frame: 64,
resize_poll_millis: 100,
}
}
///|
pub fn ProgramOptions::inline() -> ProgramOptions {
{
alternate_screen: false,
mouse_mode: MouseOff,
bracketed_paste: false,
focus_events: false,
hide_cursor: false,
renderer_enabled: true,
renderer_fps: 60,
max_messages_per_frame: 64,
resize_poll_millis: 100,
}
}
///|
pub fn ProgramOptions::alternate_screen(
self : ProgramOptions,
enabled : Bool,
) -> ProgramOptions {
{ ..self, alternate_screen: enabled }
}
///|
pub fn ProgramOptions::mouse(
self : ProgramOptions,
mode : MouseMode,
) -> ProgramOptions {
{ ..self, mouse_mode: mode }
}
///|
pub fn ProgramOptions::bracketed_paste(
self : ProgramOptions,
enabled : Bool,
) -> ProgramOptions {
{ ..self, bracketed_paste: enabled }
}
///|
pub fn ProgramOptions::focus_events(
self : ProgramOptions,
enabled : Bool,
) -> ProgramOptions {
{ ..self, focus_events: enabled }
}
///|
pub fn ProgramOptions::hide_cursor(
self : ProgramOptions,
enabled : Bool,
) -> ProgramOptions {
{ ..self, hide_cursor: enabled }
}
///|
pub fn ProgramOptions::renderer(
self : ProgramOptions,
enabled : Bool,
) -> ProgramOptions {
{ ..self, renderer_enabled: enabled }
}
///|
pub fn ProgramOptions::without_renderer(
self : ProgramOptions,
) -> ProgramOptions {
{ ..self, renderer_enabled: false }
}
///|
pub fn ProgramOptions::fps(
self : ProgramOptions,
value : Int,
) -> ProgramOptions {
{ ..self, renderer_fps: Int::max(0, value) }
}
///|
pub fn ProgramOptions::max_messages_per_frame(
self : ProgramOptions,
value : Int,
) -> ProgramOptions {
{ ..self, max_messages_per_frame: Int::max(1, value) }
}
///|
pub fn ProgramOptions::resize_poll_millis(
self : ProgramOptions,
value : Int,
) -> ProgramOptions {
{ ..self, resize_poll_millis: Int::max(16, value) }
}
///|
pub(all) enum TerminalCommand {
QuitProgram
Repaint
Print(String)
PrintLine(String)
PrintErr(String)
PrintErrLine(String)
ClearScreen
EnterAlternateScreen
LeaveAlternateScreen
HideCursor
ShowCursor
EnableMouse(MouseMode)
DisableMouse
EnableBracketedPaste
DisableBracketedPaste
EnableFocusEvents
DisableFocusEvents
SetWindowTitle(String)
} derive(Eq, Debug)
///|
pub(all) suberror TerminalError {
UnsupportedPlatform
NotATty(String)
NativeError(String)
} derive(Eq, Debug)