diff --git a/_example/barchart.go b/_example/barchart.go index 867627c..9f7784e 100644 --- a/_example/barchart.go +++ b/_example/barchart.go @@ -9,14 +9,11 @@ package main import "github.com/gizak/termui" func main() { - err := termui.Init() - if err != nil { + if termui.Init() != nil { panic(err) } defer termui.Close() - //termui.UseTheme("helloworld") - bc := termui.NewBarChart() data := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} diff --git a/_example/dashboard.go b/_example/dashboard.go index c14bb44..1cdd68a 100644 --- a/_example/dashboard.go +++ b/_example/dashboard.go @@ -9,11 +9,8 @@ package main import ui "github.com/gizak/termui" import "math" -import "time" - func main() { - err := ui.Init() - if err != nil { + if err := ui.Init(); err != nil { panic(err) } defer ui.Close() @@ -22,14 +19,14 @@ func main() { p.Height = 3 p.Width = 50 p.TextFgColor = ui.ColorWhite - p.Border.Label = "Text Box" - p.Border.FgColor = ui.ColorCyan + p.BorderLabel = "Text Box" + p.BorderFg = ui.ColorCyan strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"} list := ui.NewList() list.Items = strs list.ItemFgColor = ui.ColorYellow - list.Border.Label = "List" + list.BorderLabel = "List" list.Height = 7 list.Width = 25 list.Y = 4 @@ -39,10 +36,10 @@ func main() { g.Width = 50 g.Height = 3 g.Y = 11 - g.Border.Label = "Gauge" + g.BorderLabel = "Gauge" g.BarColor = ui.ColorRed - g.Border.FgColor = ui.ColorWhite - g.Border.LabelFgColor = ui.ColorCyan + g.BorderFg = ui.ColorWhite + g.BorderLabelFg = ui.ColorCyan spark := ui.Sparkline{} spark.Height = 1 @@ -62,7 +59,7 @@ func main() { sp := ui.NewSparklines(spark, spark1) sp.Width = 25 sp.Height = 7 - sp.Border.Label = "Sparkline" + sp.BorderLabel = "Sparkline" sp.Y = 4 sp.X = 25 @@ -76,7 +73,7 @@ func main() { })() lc := ui.NewLineChart() - lc.Border.Label = "dot-mode Line Chart" + lc.BorderLabel = "dot-mode Line Chart" lc.Data = sinps lc.Width = 50 lc.Height = 11 @@ -89,7 +86,7 @@ func main() { bc := ui.NewBarChart() bcdata := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} - bc.Border.Label = "Bar Chart" + bc.BorderLabel = "Bar Chart" bc.Width = 26 bc.Height = 10 bc.X = 51 @@ -99,7 +96,7 @@ func main() { bc.NumColor = ui.ColorBlack lc1 := ui.NewLineChart() - lc1.Border.Label = "braille-mode Line Chart" + lc1.BorderLabel = "braille-mode Line Chart" lc1.Data = sinps lc1.Width = 26 lc1.Height = 11 @@ -109,7 +106,7 @@ func main() { lc1.LineColor = ui.ColorYellow | ui.AttrBold p1 := ui.NewPar("Hey!\nI am a borderless block!") - p1.HasBorder = false + p1.Border = false p1.Width = 26 p1.Height = 2 p1.TextFgColor = ui.ColorMagenta @@ -126,23 +123,12 @@ func main() { bc.Data = bcdata[t/2%10:] ui.Render(p, list, g, sp, lc, bc, lc1, p1) } - - evt := ui.EventCh() - - i := 0 - for { - select { - case e := <-evt: - if e.Type == ui.EventKey && e.Ch == 'q' { - return - } - default: - draw(i) - i++ - if i == 102 { - return - } - time.Sleep(time.Second / 2) - } - } + ui.Handle("/sys/kbd/q", func(ui.Event) { + ui.StopLoop() + }) + ui.Handle("/timer/1s", func(e ui.Event) { + t := e.Data.(ui.EvtTimer) + draw(int(t.Count)) + }) + ui.Loop() } diff --git a/_example/grid.go b/_example/grid.go index 4912141..0c97ab9 100644 --- a/_example/grid.go +++ b/_example/grid.go @@ -7,12 +7,11 @@ package main import ui "github.com/gizak/termui" + import "math" -import "time" func main() { - err := ui.Init() - if err != nil { + if err := ui.Init(); err != nil { panic(err) } defer ui.Close() @@ -33,8 +32,6 @@ func main() { return ps })() - ui.UseTheme("helloworld") - spark := ui.Sparkline{} spark.Height = 8 spdata := sinpsint @@ -44,10 +41,10 @@ func main() { sp := ui.NewSparklines(spark) sp.Height = 11 - sp.Border.Label = "Sparkline" + sp.BorderLabel = "Sparkline" lc := ui.NewLineChart() - lc.Border.Label = "braille-mode Line Chart" + lc.BorderLabel = "braille-mode Line Chart" lc.Data = sinps lc.Height = 11 lc.AxesColor = ui.ColorWhite @@ -56,15 +53,16 @@ func main() { gs := make([]*ui.Gauge, 3) for i := range gs { gs[i] = ui.NewGauge() + //gs[i].LabelAlign = ui.AlignCenter gs[i].Height = 2 - gs[i].HasBorder = false + gs[i].Border = false gs[i].Percent = i * 10 gs[i].PaddingBottom = 1 gs[i].BarColor = ui.ColorRed } ls := ui.NewList() - ls.HasBorder = false + ls.Border = false ls.Items = []string{ "[1] Downloading File 1", "", // == \newline @@ -76,7 +74,7 @@ func main() { par := ui.NewPar("<> This row has 3 columns\n<- Widgets can be stacked up like left side\n<- Stacked widgets are treated as a single widget") par.Height = 5 - par.Border.Label = "Demonstration" + par.BorderLabel = "Demonstration" // build layout ui.Body.AddRows( @@ -91,44 +89,33 @@ func main() { // calculate layout ui.Body.Align() - done := make(chan bool) - redraw := make(chan bool) - - update := func() { - for i := 0; i < 103; i++ { - for _, g := range gs { - g.Percent = (g.Percent + 3) % 100 - } - - sp.Lines[0].Data = spdata[:100+i] - lc.Data = sinps[2*i:] - - time.Sleep(time.Second / 2) - redraw <- true - } - done <- true - } - - evt := ui.EventCh() - ui.Render(ui.Body) - go update() - for { - select { - case e := <-evt: - if e.Type == ui.EventKey && e.Ch == 'q' { - return - } - if e.Type == ui.EventResize { - ui.Body.Width = ui.TermWidth() - ui.Body.Align() - go func() { redraw <- true }() - } - case <-done: + ui.Handle("/sys/kbd/q", func(ui.Event) { + ui.StopLoop() + }) + ui.Handle("/timer/1s", func(e ui.Event) { + t := e.Data.(ui.EvtTimer) + i := t.Count + if i > 103 { + ui.StopLoop() return - case <-redraw: - ui.Render(ui.Body) } - } + + for _, g := range gs { + g.Percent = (g.Percent + 3) % 100 + } + + sp.Lines[0].Data = spdata[:100+i] + lc.Data = sinps[2*i:] + ui.Render(ui.Body) + }) + + ui.Handle("/sys/wnd/resize", func(e ui.Event) { + ui.Body.Width = ui.TermWidth() + ui.Body.Align() + ui.Render(ui.Body) + }) + + ui.Loop() } diff --git a/buffer.go b/buffer.go index 3cc562f..6eabc02 100644 --- a/buffer.go +++ b/buffer.go @@ -66,7 +66,7 @@ func NewCell(ch rune, fg, bg Attribute) Cell { } // Merge merges bs Buffers onto b -func (b Buffer) Merge(bs ...Buffer) { +func (b *Buffer) Merge(bs ...Buffer) { for _, buf := range bs { for p, v := range buf.CellMap { b.Set(p.X, p.Y, v) diff --git a/buffer_test.go b/buffer_test.go new file mode 100644 index 0000000..8fbf812 --- /dev/null +++ b/buffer_test.go @@ -0,0 +1,19 @@ +package termui + +import ( + "image" + "testing" +) + +func TestBufferUnion(t *testing.T) { + b0 := NewBuffer() + b1 := NewBuffer() + + b1.Area.Max.X = 100 + b1.Area.Max.Y = 100 + b0.Area.Max.X = 50 + b0.Merge(b1) + if b0.Area.Max.X != 100 { + t.Errorf("Buffer.Merge unions Area failed: should:%v, actual %v,%v", image.Rect(0, 0, 50, 0).Union(image.Rect(0, 0, 100, 100)), b1.Area, b0.Area) + } +} diff --git a/canvas_test.go b/canvas_test.go index 55cc14e..a955587 100644 --- a/canvas_test.go +++ b/canvas_test.go @@ -1,3 +1,5 @@ +// +build ignore + package termui import ( diff --git a/gauge.go b/gauge.go index 4a9f66f..5816d05 100644 --- a/gauge.go +++ b/gauge.go @@ -86,8 +86,9 @@ func (g *Gauge) Buffer() Buffer { pos = (g.innerArea.Dx() - strWidth(s)) / 2 case AlignRight: - pos = g.innerArea.Dx() - strWidth(s) + pos = g.innerArea.Dx() - strWidth(s) - 1 } + pos += g.innerArea.Min.X for i, v := range rs { c := Cell{ diff --git a/grid.go b/grid.go index dfacc38..264b760 100644 --- a/grid.go +++ b/grid.go @@ -276,4 +276,4 @@ func (g Grid) Buffer() Buffer { return buf } -var Body = NewGrid() +var Body *Grid diff --git a/render.go b/render.go index b64a18d..57415ad 100644 --- a/render.go +++ b/render.go @@ -24,13 +24,20 @@ func Init() error { sysEvtChs = make([]chan Event, 0) go hookTermboxEvt() + renderJobs = make(chan []Bufferer) go func() { for bs := range renderJobs { - Render(bs...) + render(bs...) } }() + Body = NewGrid() + Body.X = 0 + Body.Y = 0 + Body.BgColor = ThemeAttr("bg") + Body.Width = TermWidth() + DefaultEvtStream.Init() DefaultEvtStream.Merge("termbox", NewSysEvtCh()) DefaultEvtStream.Merge("timer", NewTimerCh(time.Second)) @@ -67,7 +74,7 @@ func TermHeight() int { // Render renders all Bufferer in the given order from left to right, // right could overlap on left ones. -func Render(bs ...Bufferer) { +func render(bs ...Bufferer) { // set tm bg tm.Clear(tm.ColorDefault, toTmAttr(ThemeAttr("bg"))) for _, b := range bs { @@ -85,6 +92,6 @@ func Render(bs ...Bufferer) { var renderJobs chan []Bufferer -func SendBufferToRender(bs ...Bufferer) { +func Render(bs ...Bufferer) { go func() { renderJobs <- bs }() }