diff --git a/README.md b/README.md index f52e4a0..182c443 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# osui -A Component-based TUI library written in go! - -![OSUI](osui.gif) +

+

A Component-based TUI library written in go

+

+# Hello World ```go package main diff --git a/osui.gif b/assets/osui.gif similarity index 100% rename from osui.gif rename to assets/osui.gif diff --git a/assets/osui.png b/assets/osui.png new file mode 100644 index 0000000..52a23aa Binary files /dev/null and b/assets/osui.png differ diff --git a/example/main.go b/example/main.go index dd4e864..9076f2e 100644 --- a/example/main.go +++ b/example/main.go @@ -25,9 +25,8 @@ func App() *PaginatorComponent { WithPosition(0, 0, Text("This blue square is a div. A div stores multiple components into one")), WithPosition((w-30)/2, (h-4)/2, WithSize(30, 5, - WithStyle(&DivStyle{Outline: colors.Blue}, - Div(WithPosition(4, 1, Button("Hello, World!", BtnParams{Width: 19}))), - ))), + Div(WithPosition(4, 1, Button("Hello, World!").Params(BtnParams{Width: 19}))).Params(DivParams{Style: DivStyle{Outline: colors.Blue}}), + )), WithPosition(0, h-2, Text(colors.Blue+"Navigate: Ctrl+(W/A/S/D)")), ), @@ -41,14 +40,14 @@ func App() *PaginatorComponent { // Page 4 Div( WithPosition(0, 0, Text("This is a Button. To click it press Enter. "+colors.Red+colors.Bold+"NOTE: This Button is inside a div")), - WithPosition((w-20)/2, (h-3)/2, Button("This is a button", BtnParams{OnClick: func(bc *ButtonComponent) bool { return false }})), + WithPosition((w-20)/2, (h-3)/2, Button("This is a button")), WithPosition(0, h-2, Text(colors.Blue+"Navigate: Ctrl+(W/A/S/D). Click Button: Enter")), ), // Page 5 Div( WithPosition(0, 0, Text("This is a Menu. It prompts you to select a item. "+colors.Red+colors.Bold+"NOTE: This Menu is inside a div")), - WithPosition(0, 2, Menu("Item 1", "Item 2", "Item 3", "Item 4", "Item 5").OnSelected(func(m *MenuComponent, b bool) {})), + WithPosition(0, 2, Menu("Item 1", "Item 2", "Item 3", "Item 4", "Item 5").Params(MenuParams{})), WithPosition(0, h-2, Text(colors.Blue+"Navigate: Ctrl+(W/A/S/D). Navigate Menu: W/S. Select: Enter. Exit Menu: Q. ")), ), ) diff --git a/osui.go b/osui.go index 683f4ff..02006c8 100644 --- a/osui.go +++ b/osui.go @@ -21,7 +21,6 @@ type Component interface { Render() string GetComponentData() *ComponentData Update(string) bool - SetStyle(interface{}) } type Screen struct { diff --git a/ui/README.md b/ui/README.md index ab36921..b8624e6 100644 --- a/ui/README.md +++ b/ui/README.md @@ -24,8 +24,9 @@ func (h *HelloComponent) Update(key string) bool { return false } -func (h *HelloComponent) SetStyle(c interface{}) { - h.Style = osui.SetDefaults(c.(*HelloStyle)).(*HelloStyle) +func (b *MenuComponent) Params(param MenuParams) *MenuComponent { + b.Style = osui.SetDefaults(¶m.Style).(*MenuStyle) + return b } func Hello(name string) *HelloComponent { diff --git a/ui/button.go b/ui/button.go index a62c92c..96a3b78 100644 --- a/ui/button.go +++ b/ui/button.go @@ -10,6 +10,13 @@ import ( "github.com/orus-dev/osui/isKey" ) +type BtnParams struct { + Style ButtonStyle + Toggle bool + OnClick func(*ButtonComponent) bool + Width int +} + type ButtonStyle struct { Background string `default:"" type:"bg"` Foreground string `default:"" type:"fg"` @@ -25,12 +32,12 @@ type ButtonStyle struct { } type ButtonComponent struct { - Data osui.ComponentData - Style *ButtonStyle - Text string - Toggle bool - Clicked bool - OnClick func(*ButtonComponent) bool + Data osui.ComponentData + Style *ButtonStyle + Text string + Toggle bool + Clicked bool + on_click func(*ButtonComponent) bool } func (b *ButtonComponent) Render() string { @@ -67,7 +74,7 @@ func (b *ButtonComponent) Render() string { func (b *ButtonComponent) Update(key string) bool { if isKey.Enter(key) { - if !b.OnClick(b) { + if !b.on_click(b) { if b.Toggle { b.Clicked = !b.Clicked return false @@ -85,35 +92,22 @@ func (b *ButtonComponent) GetComponentData() *osui.ComponentData { return &b.Data } -func (b *ButtonComponent) SetStyle(style interface{}) { - b.Style = osui.SetDefaults(style).(*ButtonStyle) -} - -type BtnParams struct { - Style ButtonStyle - Toggle bool - OnClick func(*ButtonComponent) bool - Width int -} - -func Button(text string, p ...BtnParams) *ButtonComponent { - if len(p) > 0 { - param := p[0] - return &ButtonComponent{Text: text, Style: osui.SetDefaults(¶m.Style).(*ButtonStyle), - Data: osui.ComponentData{ - Width: osui.LogicValueInt(param.Width == 0, 20, param.Width), - Height: 1, - }, - OnClick: fnLogicValue(param.OnClick), - } - +func (b *ButtonComponent) Params(param BtnParams) *ButtonComponent { + b.Style = osui.SetDefaults(¶m.Style).(*ButtonStyle) + if param.OnClick != nil { + b.on_click = param.OnClick } + b.Data.Width = osui.LogicValueInt(param.Width == 0, 20, param.Width) + return b +} + +func Button(text string) *ButtonComponent { return &ButtonComponent{Text: text, Style: osui.SetDefaults(&ButtonStyle{}).(*ButtonStyle), Data: osui.ComponentData{ Width: 20, Height: 1, }, - OnClick: func(bc *ButtonComponent) bool { return false }, + on_click: func(bc *ButtonComponent) bool { return false }, } } diff --git a/ui/div.go b/ui/div.go index 5f576e3..d372c0d 100644 --- a/ui/div.go +++ b/ui/div.go @@ -8,6 +8,12 @@ import ( "github.com/orus-dev/osui/isKey" ) +type DivParams struct { + Style DivStyle + Width int + Height int +} + type DivStyle struct { Background string `default:"" type:"bg"` Foreground string `default:"" type:"fg"` @@ -82,8 +88,10 @@ func (d *DivComponent) Update(key string) bool { return false } -func (d *DivComponent) SetStyle(c interface{}) { - d.Style = osui.SetDefaults(c.(*DivStyle)).(*DivStyle) +func (b *DivComponent) Params(param DivParams) *DivComponent { + b.Style = osui.SetDefaults(¶m.Style).(*DivStyle) + b.Data.Width = osui.LogicValueInt(param.Width == 0, 20, param.Width) + return b } func (d *DivComponent) updateActive(newIndex int) { @@ -92,11 +100,6 @@ func (d *DivComponent) updateActive(newIndex int) { } } -func (d *DivComponent) AddTo(c *DivComponent) *DivComponent { - *c = *d - return d -} - func Div(components ...osui.Component) *DivComponent { return &DivComponent{ Components: components, diff --git a/ui/inputBox.go b/ui/inputBox.go index cc2c4f4..59ee388 100644 --- a/ui/inputBox.go +++ b/ui/inputBox.go @@ -9,6 +9,12 @@ import ( "github.com/orus-dev/osui/isKey" ) +type InputBoxParams struct { + Style DivStyle + Width int + Height int +} + type InputBoxStyle struct { Background string `default:"" type:"bg"` Foreground string `default:"" type:"fg"` @@ -77,8 +83,11 @@ func (s *InputBoxComponent) Update(key string) bool { return false } -func (d *InputBoxComponent) SetStyle(c interface{}) { - d.Style = osui.SetDefaults(c.(*InputBoxStyle)).(*InputBoxStyle) +func (b *InputBoxComponent) Params(p interface{}) *InputBoxComponent { + param := p.(InputBoxParams) + b.Style = osui.SetDefaults(¶m.Style).(*InputBoxStyle) + b.Data.Width = osui.LogicValueInt(param.Width == 0, 20, param.Width) + return b } func InputBox(max_size uint) *InputBoxComponent { diff --git a/ui/menu.go b/ui/menu.go index e9c85f6..a4a10c0 100644 --- a/ui/menu.go +++ b/ui/menu.go @@ -8,6 +8,11 @@ import ( "github.com/orus-dev/osui/isKey" ) +type MenuParams struct { + Style MenuStyle + OnSelected func(*MenuComponent, bool) +} + type MenuStyle struct { Fg string `default:"" type:"fg"` Bg string `default:"" type:"bg"` @@ -74,13 +79,9 @@ func (m *MenuComponent) Update(key string) bool { return false } -func (m *MenuComponent) SetStyle(c interface{}) { - m.Style = osui.SetDefaults(c.(*MenuStyle)).(*MenuStyle) -} - -func (m *MenuComponent) OnSelected(f func(*MenuComponent, bool)) *MenuComponent { - m.onSelected = f - return m +func (b *MenuComponent) Params(param MenuParams) *MenuComponent { + b.Style = osui.SetDefaults(¶m.Style).(*MenuStyle) + return b } func Menu(items ...string) *MenuComponent { diff --git a/ui/paginator.go b/ui/paginator.go index 2221ba0..97f36a5 100644 --- a/ui/paginator.go +++ b/ui/paginator.go @@ -9,6 +9,12 @@ import ( "github.com/orus-dev/osui/isKey" ) +type PaginatorParams struct { + Style DivStyle + Width int + Height int +} + type PaginatorStyle struct { Active string `default:"\033[32m"` Inactive string `default:""` @@ -92,8 +98,10 @@ func (p *PaginatorComponent) updateActive(newIndex int) { } } -func (p *PaginatorComponent) SetStyle(c interface{}) { - p.Style = osui.SetDefaults(c.(*PaginatorStyle)).(*PaginatorStyle) +func (b *PaginatorComponent) Params(p interface{}) *PaginatorComponent { + param := p.(PaginatorParams) + b.Style = osui.SetDefaults(¶m.Style).(*PaginatorStyle) + return b } func Paginator(pages ...osui.Component) *PaginatorComponent { diff --git a/ui/text.go b/ui/text.go index b90ae14..0ddeb19 100644 --- a/ui/text.go +++ b/ui/text.go @@ -21,8 +21,6 @@ func (t TextComponent) Render() string { return t.Text } -func (t *TextComponent) SetStyle(interface{}) {} - func Text(text string) *TextComponent { return &TextComponent{Text: text} } diff --git a/ui/utils.go b/ui/utils.go index cb7d76a..568a954 100644 --- a/ui/utils.go +++ b/ui/utils.go @@ -8,6 +8,20 @@ import ( "github.com/orus-dev/osui" ) +func WithPosition(x, y int, c osui.Component) osui.Component { + data := c.GetComponentData() + data.X = x + data.Y = y + return c +} + +func WithSize(width, height int, c osui.Component) osui.Component { + data := c.GetComponentData() + data.Width = width + data.Height = height + return c +} + func centerText(text string, width int) string { if len(text) > width { return text[:width] @@ -19,33 +33,6 @@ func centerText(text string, width int) string { return fmt.Sprintf("%s%s%s", leftPadding, text, rightPadding) } -func fnLogicValue(f func(*ButtonComponent) bool) func(*ButtonComponent) bool { - if f == nil { - return func(*ButtonComponent) bool { return false } - } else { - return f - } -} - -func WithPosition(x, y int, c osui.Component) osui.Component { - data := c.GetComponentData() - data.X = x - data.Y = y - return c -} - -func WithStyle(style interface{}, c osui.Component) osui.Component { - c.SetStyle(style) - return c -} - -func WithSize(width, height int, c osui.Component) osui.Component { - data := c.GetComponentData() - data.Width = width - data.Height = height - return c -} - func findClosestComponent(a []osui.Component, i int, d string) int { if len(a) == 0 || i < 0 || i >= len(a) { return -1 // Invalid input diff --git a/utils.go b/utils.go index 6cd7d55..db96c9f 100644 --- a/utils.go +++ b/utils.go @@ -174,7 +174,7 @@ func LogicValueInt(b bool, _if, _else int) int { } func GetTerminalSize() (int, int) { - w, h, err := term.GetSize(0) + w, h, err := term.GetSize(int(os.Stdin.Fd())) if err != nil { panic(err) }