Widgets API adaption

This commit is contained in:
gizak 2015-10-08 22:11:26 -04:00
parent e0dec9dbb9
commit ca69e25d1b
19 changed files with 173 additions and 270 deletions

View File

@ -15,12 +15,12 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
bc := termui.NewBarChart() 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} 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"} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"}
bc.Border.Label = "Bar Chart" bc.BorderLabel = "Bar Chart"
bc.Data = data bc.Data = data
bc.Width = 26 bc.Width = 26
bc.Height = 10 bc.Height = 10
@ -31,5 +31,9 @@ func main() {
termui.Render(bc) termui.Render(bc)
<-termui.EventCh() termui.Handle("/sys/kbd/q", func(termui.Event) {
termui.StopLoop()
})
termui.Loop()
} }

View File

@ -1,90 +0,0 @@
// +build ignore
package main
import "github.com/gizak/termui"
import "github.com/nsf/termbox-go"
func markdownList() *termui.List {
strs := []string{
"[0] github.com/gizak/termui",
"[1] 笀耔 [澉 灊灅甗](RED) 郔镺 笀耔 澉 [灊灅甗](yellow) 郔镺",
"[2] こんにちは世界",
"[3] keyboard.go",
"[4] [output](RED).go",
"[5] random_out.go",
"[6] [dashboard](BOLD).go",
"[7] nsf/termbox-go",
"[8] OVERFLOW!!!!!!![!!!!!!!!!!!!](red,bold)!!!"}
list := termui.NewList()
list.Items = strs
list.Height = 15
list.Width = 26
list.RendererFactory = termui.MarkdownTextRendererFactory{}
return list
}
func hideList(list *termui.List) *termui.List {
list.Border.Label = "List - Hidden"
list.Overflow = "hidden"
return list
}
func wrapList(list *termui.List) *termui.List {
list.Border.Label = "List - Wrapped"
list.Overflow = "wrap"
list.X = 30
return list
}
func escapeList() *termui.List {
strs := []string{
"[0] github.com/gizak/termui",
"[1] 笀耔 \033[31m澉 灊灅甗 \033[0m郔镺 笀耔 澉 \033[33m灊灅甗 郔镺",
"[2] こんにちは世界",
"[3] keyboard.go",
"[4] \033[31moutput\033[0m.go",
"[5] random_out.go",
"[6] \033[1mdashboard\033[0m.go",
"[7] nsf/termbox-go",
"[8] OVERFLOW!!!!!!!\033[31;1m!!!!!!!!!!!!\033[0m!!!",
}
list := termui.NewList()
list.RendererFactory = termui.EscapeCodeRendererFactory{}
list.Items = strs
list.Height = 15
list.Width = 26
list.Y = 15
return list
}
func main() {
err := termui.Init()
if err != nil {
panic(err)
}
defer termui.Close()
hiddenMarkdownList := hideList(markdownList())
wrappedMarkdownList := wrapList(markdownList())
hiddenEscapeList := hideList(escapeList())
wrappedEscapeList := wrapList(escapeList())
lists := []termui.Bufferer{
hiddenEscapeList,
hiddenMarkdownList,
wrappedMarkdownList,
wrappedEscapeList,
}
termui.UseTheme("helloworld")
termui.Render(lists...)
termbox.PollEvent()
}

View File

@ -19,7 +19,7 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
sinps := (func() []float64 { sinps := (func() []float64 {
n := 220 n := 220
@ -31,7 +31,7 @@ func main() {
})() })()
lc0 := termui.NewLineChart() lc0 := termui.NewLineChart()
lc0.Border.Label = "braille-mode Line Chart" lc0.BorderLabel = "braille-mode Line Chart"
lc0.Data = sinps lc0.Data = sinps
lc0.Width = 50 lc0.Width = 50
lc0.Height = 12 lc0.Height = 12
@ -41,7 +41,7 @@ func main() {
lc0.LineColor = termui.ColorGreen | termui.AttrBold lc0.LineColor = termui.ColorGreen | termui.AttrBold
lc1 := termui.NewLineChart() lc1 := termui.NewLineChart()
lc1.Border.Label = "dot-mode Line Chart" lc1.BorderLabel = "dot-mode Line Chart"
lc1.Mode = "dot" lc1.Mode = "dot"
lc1.Data = sinps lc1.Data = sinps
lc1.Width = 26 lc1.Width = 26
@ -52,7 +52,7 @@ func main() {
lc1.LineColor = termui.ColorYellow | termui.AttrBold lc1.LineColor = termui.ColorYellow | termui.AttrBold
lc2 := termui.NewLineChart() lc2 := termui.NewLineChart()
lc2.Border.Label = "dot-mode Line Chart" lc2.BorderLabel = "dot-mode Line Chart"
lc2.Mode = "dot" lc2.Mode = "dot"
lc2.Data = sinps[4:] lc2.Data = sinps[4:]
lc2.Width = 77 lc2.Width = 77
@ -63,6 +63,9 @@ func main() {
lc2.LineColor = termui.ColorCyan | termui.AttrBold lc2.LineColor = termui.ColorCyan | termui.AttrBold
termui.Render(lc0, lc1, lc2) termui.Render(lc0, lc1, lc2)
termui.Handle("/sys/kbd/q", func(termui.Event) {
termui.StopLoop()
})
termui.Loop()
<-termui.EventCh()
} }

View File

@ -15,13 +15,13 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
strs := []string{ strs := []string{
"[0] github.com/gizak/termui", "[0] github.com/gizak/termui",
"[1] 你好,世界", "[1] [你好,世界](fg-blue)",
"[2] こんにちは世界", "[2] [こんにちは世界](fg-red)",
"[3] keyboard.go", "[3] [color output](fg-white,bg-green)",
"[4] output.go", "[4] output.go",
"[5] random_out.go", "[5] random_out.go",
"[6] dashboard.go", "[6] dashboard.go",
@ -30,12 +30,15 @@ func main() {
ls := termui.NewList() ls := termui.NewList()
ls.Items = strs ls.Items = strs
ls.ItemFgColor = termui.ColorYellow ls.ItemFgColor = termui.ColorYellow
ls.Border.Label = "List" ls.BorderLabel = "List"
ls.Height = 7 ls.Height = 7
ls.Width = 25 ls.Width = 25
ls.Y = 0 ls.Y = 0
termui.Render(ls) termui.Render(ls)
termui.Handle("/sys/kbd/q", func(termui.Event) {
termui.StopLoop()
})
termui.Loop()
<-termui.EventCh()
} }

View File

@ -15,7 +15,7 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
bc := termui.NewMBarChart() bc := termui.NewMBarChart()
math := []int{90, 85, 90, 80} math := []int{90, 85, 90, 80}
@ -27,10 +27,10 @@ func main() {
bc.Data[2] = science bc.Data[2] = science
bc.Data[3] = compsci bc.Data[3] = compsci
studentsName := []string{"Ken", "Rob", "Dennis", "Linus"} studentsName := []string{"Ken", "Rob", "Dennis", "Linus"}
bc.Border.Label = "Student's Marks X-Axis=Name Y-Axis=Marks[Math,English,Science,ComputerScience] in %" bc.BorderLabel = "Student's Marks X-Axis=Name Y-Axis=Marks[Math,English,Science,ComputerScience] in %"
bc.Width = 100 bc.Width = 100
bc.Height = 50 bc.Height = 30
bc.Y = 10 bc.Y = 0
bc.BarWidth = 10 bc.BarWidth = 10
bc.DataLabels = studentsName bc.DataLabels = studentsName
bc.ShowScale = true //Show y_axis scale value (min and max) bc.ShowScale = true //Show y_axis scale value (min and max)
@ -46,5 +46,9 @@ func main() {
termui.Render(bc) termui.Render(bc)
<-termui.EventCh() termui.Handle("/sys/kbd/q", func(termui.Event) {
termui.StopLoop()
})
termui.Loop()
} }

View File

@ -15,35 +15,38 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
par0 := termui.NewPar("Borderless Text") par0 := termui.NewPar("Borderless Text")
par0.Height = 1 par0.Height = 1
par0.Width = 20 par0.Width = 20
par0.Y = 1 par0.Y = 1
par0.HasBorder = false par0.Border = false
par1 := termui.NewPar("你好,世界。") par1 := termui.NewPar("你好,世界。")
par1.Height = 3 par1.Height = 3
par1.Width = 17 par1.Width = 17
par1.X = 20 par1.X = 20
par1.Border.Label = "标签" par1.BorderLabel = "标签"
par2 := termui.NewPar("Simple colored text\nwith label. It [can be](RED) multilined with \\n or [break automatically](GREEN, BOLD)") par2 := termui.NewPar("Simple colored text\nwith label. It [can be](fg-red) multilined with \\n or [break automatically](fg-red,fg-bold)")
par2.RendererFactory = termui.MarkdownTextRendererFactory{}
par2.Height = 5 par2.Height = 5
par2.Width = 37 par2.Width = 37
par2.Y = 4 par2.Y = 4
par2.Border.Label = "Multiline" par2.BorderLabel = "Multiline"
par2.Border.FgColor = termui.ColorYellow par2.BorderFg = termui.ColorYellow
par3 := termui.NewPar("Long text with label and it is auto trimmed.") par3 := termui.NewPar("Long text with label and it is auto trimmed.")
par3.Height = 3 par3.Height = 3
par3.Width = 37 par3.Width = 37
par3.Y = 9 par3.Y = 9
par3.Border.Label = "Auto Trim" par3.BorderLabel = "Auto Trim"
termui.Render(par0, par1, par2, par3) termui.Render(par0, par1, par2, par3)
<-termui.EventCh() termui.Handle("/sys/kbd/q", func(termui.Event) {
termui.StopLoop()
})
termui.Loop()
} }

View File

@ -15,7 +15,7 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6} data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6}
spl0 := termui.NewSparkline() spl0 := termui.NewSparkline()
@ -27,7 +27,7 @@ func main() {
spls0 := termui.NewSparklines(spl0) spls0 := termui.NewSparklines(spl0)
spls0.Height = 2 spls0.Height = 2
spls0.Width = 20 spls0.Width = 20
spls0.HasBorder = false spls0.Border = false
spl1 := termui.NewSparkline() spl1 := termui.NewSparkline()
spl1.Data = data spl1.Data = data
@ -44,7 +44,7 @@ func main() {
spls1.Height = 8 spls1.Height = 8
spls1.Width = 20 spls1.Width = 20
spls1.Y = 3 spls1.Y = 3
spls1.Border.Label = "Group Sparklines" spls1.BorderLabel = "Group Sparklines"
spl3 := termui.NewSparkline() spl3 := termui.NewSparkline()
spl3.Data = data spl3.Data = data
@ -55,11 +55,15 @@ func main() {
spls2 := termui.NewSparklines(spl3) spls2 := termui.NewSparklines(spl3)
spls2.Height = 11 spls2.Height = 11
spls2.Width = 30 spls2.Width = 30
spls2.Border.FgColor = termui.ColorCyan spls2.BorderFg = termui.ColorCyan
spls2.X = 21 spls2.X = 21
spls2.Border.Label = "Tweeked Sparkline" spls2.BorderLabel = "Tweeked Sparkline"
termui.Render(spls0, spls1, spls2) termui.Render(spls0, spls1, spls2)
<-termui.EventCh() termui.Handle("/sys/kbd/q", func(termui.Event) {
termui.StopLoop()
})
termui.Loop()
} }

View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.
@ -107,13 +105,14 @@ func (bc *BarChart) Buffer() Buffer {
// plot text // plot text
for j, k := 0, 0; j < len(bc.labels[i]); j++ { for j, k := 0, 0; j < len(bc.labels[i]); j++ {
w := charWidth(bc.labels[i][j]) w := charWidth(bc.labels[i][j])
c := Cell{} c := Cell{
p.Ch = bc.labels[i][j] Ch: bc.labels[i][j],
p.Bg = bc.BgColor Bg: bc.Bg,
p.Fg = bc.TextColor Fg: bc.TextColor,
p.Y = bc.innerArea.Min.Y + bc.innerArea.Dy() - 1 }
p.X = bc.innerArea.Min.X + oftX + k y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 1
ps = append(ps, p) x := bc.innerArea.Min.X + oftX + k
buf.Set(x, y, c)
k += w k += w
} }
// plot num // plot num
@ -127,7 +126,7 @@ func (bc *BarChart) Buffer() Buffer {
c.Bg |= AttrReverse c.Bg |= AttrReverse
} }
if h == 0 { if h == 0 {
c.Bg = bc.BgColor c.Bg = bc.Bg
} }
x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2

View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.
@ -65,12 +63,10 @@ func (c Canvas) Unset(x, y int) {
} }
// Buffer returns un-styled points // Buffer returns un-styled points
func (c Canvas) Buffer() []Point { func (c Canvas) Buffer() Buffer {
ps := make([]Point, len(c)) buf := NewBuffer()
i := 0
for k, v := range c { for k, v := range c {
ps[i] = newPoint(v+brailleBase, k[0], k[1]) buf.Set(k[0], k[1], Cell{Ch: v + brailleBase})
i++
} }
return ps return buf
} }

View File

@ -1,5 +1,3 @@
//+build ignore
package termui package termui
import ( import (
@ -49,9 +47,5 @@ func TestCanvasBuffer(t *testing.T) {
c.Set(8, 1) c.Set(8, 1)
c.Set(9, 0) c.Set(9, 0)
bufs := c.Buffer() bufs := c.Buffer()
rs := make([]rune, len(bufs)) spew.Dump(bufs)
for i, v := range bufs {
rs[i] = v.Ch
}
spew.Dump(string(rs))
} }

View File

@ -201,10 +201,12 @@ func DTrimTxCls(cs []Cell, w int) []Cell {
c := cs[i] c := cs[i]
cw := c.Width() cw := c.Width()
if cw+csw <= w { if cw+csw < w {
rt = append(rt, c) rt = append(rt, c)
csw += cw
} else { } else {
rt = append(rt, Cell{'…', c.Fg, c.Bg}) rt = append(rt, Cell{'…', c.Fg, c.Bg})
break
} }
} }

View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.
@ -76,8 +74,8 @@ type LineChart struct {
// NewLineChart returns a new LineChart with current theme. // NewLineChart returns a new LineChart with current theme.
func NewLineChart() *LineChart { func NewLineChart() *LineChart {
lc := &LineChart{Block: *NewBlock()} lc := &LineChart{Block: *NewBlock()}
lc.AxesColor = theme.LineChartAxes lc.AxesColor = ThemeAttr("linechart.axes.fg")
lc.LineColor = theme.LineChartLine lc.LineColor = ThemeAttr("linechart.line.fg")
lc.Mode = "braille" lc.Mode = "braille"
lc.DotStyle = '•' lc.DotStyle = '•'
lc.axisXLebelGap = 2 lc.axisXLebelGap = 2
@ -108,7 +106,7 @@ func (lc *LineChart) renderBraille() Buffer {
if b0 == b1 { if b0 == b1 {
c := Cell{ c := Cell{
Ch: braillePatterns[[2]int{m0, m1}], Ch: braillePatterns[[2]int{m0, m1}],
Bg: lc.BgColor, Bg: lc.Bg,
Fg: lc.LineColor, Fg: lc.LineColor,
} }
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0 y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0
@ -117,7 +115,7 @@ func (lc *LineChart) renderBraille() Buffer {
} else { } else {
c0 := Cell{Ch: lSingleBraille[m0], c0 := Cell{Ch: lSingleBraille[m0],
Fg: lc.LineColor, Fg: lc.LineColor,
Bg: lc.BgColor} Bg: lc.Bg}
x0 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i x0 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
y0 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0 y0 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0
buf.Set(x0, y0, c0) buf.Set(x0, y0, c0)
@ -140,7 +138,7 @@ func (lc *LineChart) renderDot() Buffer {
c := Cell{ c := Cell{
Ch: lc.DotStyle, Ch: lc.DotStyle,
Fg: lc.LineColor, Fg: lc.LineColor,
Bg: lc.BgColor, Bg: lc.Bg,
} }
x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5) y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5)
@ -289,7 +287,7 @@ func (lc *LineChart) plotAxes() Buffer {
c := Cell{ c := Cell{
Ch: r, Ch: r,
Fg: lc.AxesColor, Fg: lc.AxesColor,
Bg: lc.BgColor, Bg: lc.Bg,
} }
x := origX + oft + j x := origX + oft + j
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 1 y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 1
@ -312,11 +310,11 @@ func (lc *LineChart) plotAxes() Buffer {
} }
// Buffer implements Bufferer interface. // Buffer implements Bufferer interface.
func (lc *LineChart) Buffer() []Point { func (lc *LineChart) Buffer() Buffer {
buf := lc.Block.Buffer() buf := lc.Block.Buffer()
if lc.Data == nil || len(lc.Data) == 0 { if lc.Data == nil || len(lc.Data) == 0 {
return ps return buf
} }
lc.calcLayout() lc.calcLayout()
buf.Merge(lc.plotAxes()) buf.Merge(lc.plotAxes())
@ -324,7 +322,7 @@ func (lc *LineChart) Buffer() []Point {
if lc.Mode == "dot" { if lc.Mode == "dot" {
buf.Merge(lc.renderDot()) buf.Merge(lc.renderDot())
} else { } else {
buf.Merge(ps, lc.renderBraille()) buf.Merge(lc.renderBraille())
} }
return buf return buf

View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.

View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.

80
list.go
View File

@ -1,11 +1,11 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.
package termui package termui
import "strings"
// List displays []string as its items, // List displays []string as its items,
// it has a Overflow option (default is "hidden"), when set to "hidden", // it has a Overflow option (default is "hidden"), when set to "hidden",
// the item exceeding List's width is truncated, but when set to "wrap", // the item exceeding List's width is truncated, but when set to "wrap",
@ -35,63 +35,55 @@ type List struct {
Overflow string Overflow string
ItemFgColor Attribute ItemFgColor Attribute
ItemBgColor Attribute ItemBgColor Attribute
RendererFactory TextRendererFactory
} }
// NewList returns a new *List with current theme. // NewList returns a new *List with current theme.
func NewList() *List { func NewList() *List {
l := &List{Block: *NewBlock()} l := &List{Block: *NewBlock()}
l.Overflow = "hidden" l.Overflow = "hidden"
l.ItemFgColor = theme.ListItemFg l.ItemFgColor = ThemeAttr("list.item.fg")
l.ItemBgColor = theme.ListItemBg l.ItemBgColor = ThemeAttr("list.item.bg")
l.RendererFactory = PlainRendererFactory{}
return l return l
} }
// Buffer implements Bufferer interface. // Buffer implements Bufferer interface.
func (l *List) Buffer() []Point { func (l *List) Buffer() Buffer {
buffer := l.Block.Buffer() buf := l.Block.Buffer()
breakLoop := func(y int) bool { switch l.Overflow {
return y+1 > l.innerArea.Dy() case "wrap":
cs := DefaultTxBuilder.Build(strings.Join(l.Items, "\n"), l.ItemFgColor, l.ItemBgColor)
i, j, k := 0, 0, 0
for i < l.innerArea.Dy() && k < len(cs) {
w := cs[k].Width()
if cs[k].Ch == '\n' || j+w > l.innerArea.Dx() {
i++
j = 0
if cs[k].Ch == '\n' {
k++
} }
y := 0 continue
}
buf.Set(l.innerArea.Min.X+j, l.innerArea.Min.Y+i, cs[k])
MainLoop: k++
for _, item := range l.Items { j++
x := 0
bg, fg := l.ItemFgColor, l.ItemBgColor
renderer := l.RendererFactory.TextRenderer(item)
sequence := renderer.Render(bg, fg)
for n := range []rune(sequence.NormalizedText) {
point, width := sequence.PointAt(n, x+l.innerArea.Min.X, y+l.innerArea.Min.Y)
if width+x <= l.innerArea.Dx() {
buffer = append(buffer, point)
x += width
} else {
if l.Overflow == "wrap" {
y++
if breakLoop(y) {
break MainLoop
}
x = 0
} else {
dotR := []rune(dot)[0]
dotX := l.innerArea.Dx() + l.innerArea.Min.X - charWidth(dotR)
p := newPointWithAttrs(dotR, dotX, y+l.innerArea.Min.Y, bg, fg)
buffer = append(buffer, p)
break
}
}
} }
y++ case "hidden":
if breakLoop(y) { trimItems := l.Items
break MainLoop if len(trimItems) > l.innerArea.Dy() {
trimItems = trimItems[:l.innerArea.Dy()]
}
for i, v := range trimItems {
cs := DTrimTxCls(DefaultTxBuilder.Build(v, l.ItemFgColor, l.ItemBgColor), l.innerArea.Dx())
j := 0
for _, vv := range cs {
w := vv.Width()
buf.Set(l.innerArea.Min.X+j, l.innerArea.Min.Y+i, vv)
j += w
} }
} }
}
return l.Block.chopOverflow(buffer) return buf
} }

37
par.go
View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.
@ -18,7 +16,6 @@ type Par struct {
Text string Text string
TextFgColor Attribute TextFgColor Attribute
TextBgColor Attribute TextBgColor Attribute
RendererFactory TextRendererFactory
} }
// NewPar returns a new *Par with given text as its content. // NewPar returns a new *Par with given text as its content.
@ -26,46 +23,42 @@ func NewPar(s string) *Par {
return &Par{ return &Par{
Block: *NewBlock(), Block: *NewBlock(),
Text: s, Text: s,
TextFgColor: theme.ParTextFg, TextFgColor: ThemeAttr("par.text.fg"),
TextBgColor: theme.ParTextBg, TextBgColor: ThemeAttr("par.text.bg"),
RendererFactory: PlainRendererFactory{},
} }
} }
// Buffer implements Bufferer interface. // Buffer implements Bufferer interface.
func (p *Par) Buffer() []Point { func (p *Par) Buffer() Buffer {
ps := p.Block.Buffer() buf := p.Block.Buffer()
fg, bg := p.TextFgColor, p.TextBgColor fg, bg := p.TextFgColor, p.TextBgColor
sequence := p.RendererFactory.TextRenderer(p.Text).Render(fg, bg) cs := DefaultTxBuilder.Build(p.Text, fg, bg)
runes := []rune(sequence.NormalizedText)
y, x, n := 0, 0, 0 y, x, n := 0, 0, 0
for y < p.innerArea.Dy() && n < len(runes) { for y < p.innerArea.Dy() && n < len(cs) {
point, width := sequence.PointAt(n, x+p.innerArea.Min.X, y+p.innerArea.Min.Y) w := cs[n].Width()
if cs[n].Ch == '\n' || x+w > p.innerArea.Dx() {
if runes[n] == '\n' || x+width > p.innerArea.Dx() {
y++ y++
x = 0 // set x = 0 x = 0 // set x = 0
if runes[n] == '\n' { if cs[n].Ch == '\n' {
n++ n++
} }
if y >= p.innerArea.Dy() { if y >= p.innerArea.Dy() {
ps = append(ps, newPointWithAttrs('…', buf.Set(p.innerArea.Min.X+p.innerArea.Dx()-1,
p.innerArea.Min.X+p.innerArea.Dx()-1,
p.innerArea.Min.Y+p.innerArea.Dy()-1, p.innerArea.Min.Y+p.innerArea.Dy()-1,
p.TextFgColor, p.TextBgColor)) Cell{Ch: '…', Fg: p.TextFgColor, Bg: p.TextBgColor})
break break
} }
continue continue
} }
ps = append(ps, point) buf.Set(p.innerArea.Min.X+x, p.innerArea.Min.Y+y, cs[n])
n++ n++
x += width x += w
} }
return p.Block.chopOverflow(ps) return buf
} }

View File

@ -1,5 +1,3 @@
// +build ignore
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved. // Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
// Use of this source code is governed by a MIT license that can // Use of this source code is governed by a MIT license that can
// be found in the LICENSE file. // be found in the LICENSE file.
@ -51,8 +49,8 @@ func (s *Sparklines) Add(sl Sparkline) {
func NewSparkline() Sparkline { func NewSparkline() Sparkline {
return Sparkline{ return Sparkline{
Height: 1, Height: 1,
TitleColor: theme.SparklineTitle, TitleColor: ThemeAttr("sparkline.title.fg"),
LineColor: theme.SparklineLine} LineColor: ThemeAttr("sparkline.line.fg")}
} }
// NewSparklines return a new *Spaklines with given Sparkline(s), you can always add a new Sparkline later. // NewSparklines return a new *Spaklines with given Sparkline(s), you can always add a new Sparkline later.
@ -98,8 +96,8 @@ func (sl *Sparklines) update() {
} }
// Buffer implements Bufferer interface. // Buffer implements Bufferer interface.
func (sl *Sparklines) Buffer() []Point { func (sl *Sparklines) Buffer() Buffer {
ps := sl.Block.Buffer() buf := sl.Block.Buffer()
sl.update() sl.update()
oftY := 0 oftY := 0
@ -116,13 +114,14 @@ func (sl *Sparklines) Buffer() []Point {
oftX := 0 oftX := 0
for _, v := range rs { for _, v := range rs {
w := charWidth(v) w := charWidth(v)
c := Cell{} c := Cell{
p.Ch = v Ch: v,
p.Fg = l.TitleColor Fg: l.TitleColor,
p.Bg = sl.BgColor Bg: sl.Bg,
p.X = sl.innerArea.Min.X + oftX }
p.Y = sl.innerArea.Min.Y + oftY x := sl.innerArea.Min.X + oftX
ps = append(ps, p) y := sl.innerArea.Min.Y + oftY
buf.Set(x, y, c)
oftX += w oftX += w
} }
} }
@ -132,27 +131,30 @@ func (sl *Sparklines) Buffer() []Point {
barCnt := h / 8 barCnt := h / 8
barMod := h % 8 barMod := h % 8
for jj := 0; jj < barCnt; jj++ { for jj := 0; jj < barCnt; jj++ {
c := Cell{} c := Cell{
p.X = sl.innerArea.Min.X + j Ch: ' ', // => sparks[7]
p.Y = sl.innerArea.Min.Y + oftY + l.Height - jj Bg: l.LineColor,
p.Ch = ' ' // => sparks[7] }
p.Bg = l.LineColor x := sl.innerArea.Min.X + j
y := sl.innerArea.Min.Y + oftY + l.Height - jj
//p.Bg = sl.BgColor //p.Bg = sl.BgColor
ps = append(ps, p) buf.Set(x, y, c)
} }
if barMod != 0 { if barMod != 0 {
c := Cell{} c := Cell{
p.X = sl.innerArea.Min.X + j Ch: sparks[barMod-1],
p.Y = sl.innerArea.Min.Y + oftY + l.Height - barCnt Fg: l.LineColor,
p.Ch = sparks[barMod-1] Bg: sl.Bg,
p.Fg = l.LineColor }
p.Bg = sl.BgColor x := sl.innerArea.Min.X + j
ps = append(ps, p) y := sl.innerArea.Min.Y + oftY + l.Height - barCnt
buf.Set(x, y, c)
} }
} }
oftY += l.displayHeight oftY += l.displayHeight
} }
return sl.Block.chopOverflow(ps) return buf
} }

View File

@ -23,7 +23,7 @@ func main() {
} }
defer termui.Close() defer termui.Close()
termui.UseTheme("helloworld") //termui.UseTheme("helloworld")
b := termui.NewBlock() b := termui.NewBlock()
b.Width = 20 b.Width = 20
b.Height = 30 b.Height = 30