From a6fbfcb5c7770ae3fdbfe406222c417205c55bfd Mon Sep 17 00:00:00 2001 From: wanzysky Date: Thu, 10 Nov 2016 18:46:23 +0800 Subject: [PATCH 1/6] feature: support table --- _example/table.go | 34 +++++++++++++++ _example/table.png | Bin 0 -> 21789 bytes table.go | 101 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 _example/table.go create mode 100644 _example/table.png create mode 100644 table.go diff --git a/_example/table.go b/_example/table.go new file mode 100644 index 0000000..07e70ed --- /dev/null +++ b/_example/table.go @@ -0,0 +1,34 @@ +package main + +import "termui" + +func main() { + err := termui.Init() + if err != nil { + panic(err) + } + defer termui.Close() + + rows := [][]string{ + []string{"header1", "header2", "header3"}, + []string{"I love Veronica", "Go-lang is so cool", "Im working on Ruby"}, + []string{"2016", "11", "11"}, + } + + table := termui.NewTable() + table.Rows = rows + table.FgColor = termui.ColorWhite + table.BgColor = termui.ColorDefault + table.TextAlign = "center" + table.Analysis() + table.SetSize() + table.Y = 0 + table.X = 0 + table.Border = true + + termui.Render(table) + termui.Handle("/sys/kbd/q", func(termui.Event) { + termui.StopLoop() + }) + termui.Loop() +} diff --git a/_example/table.png b/_example/table.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c0f3b04c91858c08540cad1c36dccb15dd6156 GIT binary patch literal 21789 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
5t?t{NT=Cq3 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 AN&o-= literal 0 HcmV?d00001 diff --git a/table.go b/table.go new file mode 100644 index 0000000..267ff95 --- /dev/null +++ b/table.go @@ -0,0 +1,101 @@ +package termui + +import ( + "fmt" + "strings" +) + +/* + table := termui.NewTable() + table.Rows = rows + table.FgColor = termui.ColorWhite + table.BgColor = termui.ColorDefault + table.Height = 7 + table.Width = 62 + table.Y = 0 + table.X = 0 + table.Border = true +*/ + +type Table struct { + Block + Rows [][]string + FgColor Attribute + BgColor Attribute + TextAlign string +} + +func NewTable() *Table { + table := &Table{Block: *NewBlock()} + table.FgColor = ColorWhite + table.BgColor = ColorDefault + table.TextAlign = "left" + return table +} + +func (table *Table) Analysis() { + length := len(table.Rows) + if length < 1 { + return + } + + row_width := len(table.Rows[0]) + cellWidthes := make([]int, row_width) + + for _, row := range table.Rows { + for i, str := range row { + if cellWidthes[i] < len(str) { + cellWidthes[i] = len(str) + } + } + } + + width_sum := 2 + for i, width := range cellWidthes { + width_sum += (width + 2) + for u, row := range table.Rows { + switch table.TextAlign { + case "right": + row[i] = fmt.Sprintf(" %*s ", width, table.Rows[u][i]) + case "center": + word_width := len(table.Rows[u][i]) + offset := (width - word_width) / 2 + row[i] = fmt.Sprintf(" %*s ", width, fmt.Sprintf("%-*s", offset+word_width, table.Rows[u][i])) + default: // left + row[i] = fmt.Sprintf(" %-*s ", width, table.Rows[u][i]) + } + } + } + + if table.Width == 0 { + table.Width = width_sum + } +} + +func (table *Table) SetSize() { + length := len(table.Rows) + table.Height = length*2 + 1 + table.Width = 2 + if length != 0 { + for _, str := range table.Rows[0] { + table.Width += len(str) + 2 + 1 + } + } +} + +func (table *Table) Buffer() Buffer { + buffer := table.Block.Buffer() + table.Analysis() + for i, row := range table.Rows { + cells := DefaultTxBuilder.Build(strings.Join(row, "|"), table.FgColor, table.BgColor) + border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) + for x, cell := range cells { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2, cell) + } + + for x, cell := range border { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2+1, cell) + } + } + return buffer +} From 25c85a59b08d4e978f2e60c5817ea8dd59223968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=87=E6=98=AD=E7=A5=8E?= Date: Thu, 10 Nov 2016 18:55:42 +0800 Subject: [PATCH 2/6] feature: support table (#1) --- _example/table.go | 34 +++++++++++++++ _example/table.png | Bin 0 -> 21789 bytes table.go | 101 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 _example/table.go create mode 100644 _example/table.png create mode 100644 table.go diff --git a/_example/table.go b/_example/table.go new file mode 100644 index 0000000..07e70ed --- /dev/null +++ b/_example/table.go @@ -0,0 +1,34 @@ +package main + +import "termui" + +func main() { + err := termui.Init() + if err != nil { + panic(err) + } + defer termui.Close() + + rows := [][]string{ + []string{"header1", "header2", "header3"}, + []string{"I love Veronica", "Go-lang is so cool", "Im working on Ruby"}, + []string{"2016", "11", "11"}, + } + + table := termui.NewTable() + table.Rows = rows + table.FgColor = termui.ColorWhite + table.BgColor = termui.ColorDefault + table.TextAlign = "center" + table.Analysis() + table.SetSize() + table.Y = 0 + table.X = 0 + table.Border = true + + termui.Render(table) + termui.Handle("/sys/kbd/q", func(termui.Event) { + termui.StopLoop() + }) + termui.Loop() +} diff --git a/_example/table.png b/_example/table.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c0f3b04c91858c08540cad1c36dccb15dd6156 GIT binary patch literal 21789 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
5t?t{NT=Cq3 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 AN&o-= literal 0 HcmV?d00001 diff --git a/table.go b/table.go new file mode 100644 index 0000000..267ff95 --- /dev/null +++ b/table.go @@ -0,0 +1,101 @@ +package termui + +import ( + "fmt" + "strings" +) + +/* + table := termui.NewTable() + table.Rows = rows + table.FgColor = termui.ColorWhite + table.BgColor = termui.ColorDefault + table.Height = 7 + table.Width = 62 + table.Y = 0 + table.X = 0 + table.Border = true +*/ + +type Table struct { + Block + Rows [][]string + FgColor Attribute + BgColor Attribute + TextAlign string +} + +func NewTable() *Table { + table := &Table{Block: *NewBlock()} + table.FgColor = ColorWhite + table.BgColor = ColorDefault + table.TextAlign = "left" + return table +} + +func (table *Table) Analysis() { + length := len(table.Rows) + if length < 1 { + return + } + + row_width := len(table.Rows[0]) + cellWidthes := make([]int, row_width) + + for _, row := range table.Rows { + for i, str := range row { + if cellWidthes[i] < len(str) { + cellWidthes[i] = len(str) + } + } + } + + width_sum := 2 + for i, width := range cellWidthes { + width_sum += (width + 2) + for u, row := range table.Rows { + switch table.TextAlign { + case "right": + row[i] = fmt.Sprintf(" %*s ", width, table.Rows[u][i]) + case "center": + word_width := len(table.Rows[u][i]) + offset := (width - word_width) / 2 + row[i] = fmt.Sprintf(" %*s ", width, fmt.Sprintf("%-*s", offset+word_width, table.Rows[u][i])) + default: // left + row[i] = fmt.Sprintf(" %-*s ", width, table.Rows[u][i]) + } + } + } + + if table.Width == 0 { + table.Width = width_sum + } +} + +func (table *Table) SetSize() { + length := len(table.Rows) + table.Height = length*2 + 1 + table.Width = 2 + if length != 0 { + for _, str := range table.Rows[0] { + table.Width += len(str) + 2 + 1 + } + } +} + +func (table *Table) Buffer() Buffer { + buffer := table.Block.Buffer() + table.Analysis() + for i, row := range table.Rows { + cells := DefaultTxBuilder.Build(strings.Join(row, "|"), table.FgColor, table.BgColor) + border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) + for x, cell := range cells { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2, cell) + } + + for x, cell := range border { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2+1, cell) + } + } + return buffer +} From f5d3d35ce00d3653318fa4a88e8ce7859b89c263 Mon Sep 17 00:00:00 2001 From: wanzysky Date: Thu, 10 Nov 2016 18:59:13 +0800 Subject: [PATCH 3/6] fix importation --- _example/table.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_example/table.go b/_example/table.go index 07e70ed..dbb06b2 100644 --- a/_example/table.go +++ b/_example/table.go @@ -1,6 +1,6 @@ package main -import "termui" +import "github.com/gizak/termui" func main() { err := termui.Init() From 7ce2564652a033392b18d1b8565f2b1a3a7f08ac Mon Sep 17 00:00:00 2001 From: wanzysky Date: Wed, 23 Nov 2016 15:55:22 +0800 Subject: [PATCH 4/6] optional seperators and specific color for row --- _example/table.go | 22 ++++++++++++++++++++-- table.go | 47 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/_example/table.go b/_example/table.go index dbb06b2..2e44229 100644 --- a/_example/table.go +++ b/_example/table.go @@ -1,6 +1,6 @@ package main -import "github.com/gizak/termui" +import "termui" func main() { err := termui.Init() @@ -8,6 +8,22 @@ func main() { panic(err) } defer termui.Close() + rows_1 := [][]string{ + []string{"header1", "header2", "header3"}, + []string{"I love Veronica", "Go-lang is so cool", "Im working on Ruby"}, + []string{"2016", "11", "11"}, + } + + table_1 := termui.NewTable() + table_1.Rows = rows_1 + table_1.FgColor = termui.ColorWhite + table_1.BgColor = termui.ColorDefault + table_1.Y = 0 + table_1.X = 0 + table_1.Width = 62 + table_1.Height = 7 + + termui.Render(table_1) rows := [][]string{ []string{"header1", "header2", "header3"}, @@ -20,9 +36,11 @@ func main() { table.FgColor = termui.ColorWhite table.BgColor = termui.ColorDefault table.TextAlign = "center" + table.Seperator = false table.Analysis() table.SetSize() - table.Y = 0 + table.BgColors[2] = termui.ColorRed + table.Y = 20 table.X = 0 table.Border = true diff --git a/table.go b/table.go index 267ff95..663305c 100644 --- a/table.go +++ b/table.go @@ -22,6 +22,9 @@ type Table struct { Rows [][]string FgColor Attribute BgColor Attribute + FgColors []Attribute + BgColors []Attribute + Seperator bool TextAlign string } @@ -30,6 +33,7 @@ func NewTable() *Table { table.FgColor = ColorWhite table.BgColor = ColorDefault table.TextAlign = "left" + table.Seperator = true return table } @@ -39,15 +43,30 @@ func (table *Table) Analysis() { return } + if len(table.FgColors) == 0 { + table.FgColors = make([]Attribute, len(table.Rows)) + } + if len(table.BgColors) == 0 { + table.BgColors = make([]Attribute, len(table.Rows)) + } + row_width := len(table.Rows[0]) cellWidthes := make([]int, row_width) - for _, row := range table.Rows { + for index, row := range table.Rows { for i, str := range row { if cellWidthes[i] < len(str) { cellWidthes[i] = len(str) } } + + if table.FgColors[index] == 0 { + table.FgColors[index] = table.FgColor + } + + if table.BgColors[index] == 0 { + table.BgColors[index] = table.BgColor + } } width_sum := 2 @@ -74,7 +93,11 @@ func (table *Table) Analysis() { func (table *Table) SetSize() { length := len(table.Rows) - table.Height = length*2 + 1 + if table.Seperator { + table.Height = length*2 + 1 + } else { + table.Height = length + 2 + } table.Width = 2 if length != 0 { for _, str := range table.Rows[0] { @@ -87,14 +110,20 @@ func (table *Table) Buffer() Buffer { buffer := table.Block.Buffer() table.Analysis() for i, row := range table.Rows { - cells := DefaultTxBuilder.Build(strings.Join(row, "|"), table.FgColor, table.BgColor) - border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) - for x, cell := range cells { - buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2, cell) - } + cells := DefaultTxBuilder.Build(strings.Join(row, "|"), table.FgColors[i], table.BgColors[i]) + if table.Seperator { + border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) + for x, cell := range cells { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2, cell) + } - for x, cell := range border { - buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2+1, cell) + for x, cell := range border { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2+1, cell) + } + } else { + for x, cell := range cells { + buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i, cell) + } } } return buffer From 0d2f54137b8dba4cd2d1ad975e0eb1e473f19552 Mon Sep 17 00:00:00 2001 From: wanzysky Date: Fri, 25 Nov 2016 16:35:00 +0800 Subject: [PATCH 5/6] uft8 characters support --- _example/table.go | 6 +-- table.go | 112 +++++++++++++++++++++++++++++++--------------- 2 files changed, 79 insertions(+), 39 deletions(-) diff --git a/_example/table.go b/_example/table.go index 2e44229..76916f5 100644 --- a/_example/table.go +++ b/_example/table.go @@ -10,8 +10,8 @@ func main() { defer termui.Close() rows_1 := [][]string{ []string{"header1", "header2", "header3"}, - []string{"I love Veronica", "Go-lang is so cool", "Im working on Ruby"}, - []string{"2016", "11", "11"}, + []string{"孙嘉你好吗", "Go-lang is so cool", "Im working on Ruby"}, + []string{"2016", "10", "11"}, } table_1 := termui.NewTable() @@ -27,7 +27,7 @@ func main() { rows := [][]string{ []string{"header1", "header2", "header3"}, - []string{"I love Veronica", "Go-lang is so cool", "Im working on Ruby"}, + []string{"Foundations", "Go-lang is so cool", "Im working on Ruby"}, []string{"2016", "11", "11"}, } diff --git a/table.go b/table.go index 663305c..cde3ae7 100644 --- a/table.go +++ b/table.go @@ -1,9 +1,6 @@ package termui -import ( - "fmt" - "strings" -) +import "strings" /* table := termui.NewTable() @@ -20,6 +17,7 @@ import ( type Table struct { Block Rows [][]string + CellWidth []int FgColor Attribute BgColor Attribute FgColors []Attribute @@ -69,26 +67,28 @@ func (table *Table) Analysis() { } } - width_sum := 2 - for i, width := range cellWidthes { - width_sum += (width + 2) - for u, row := range table.Rows { - switch table.TextAlign { - case "right": - row[i] = fmt.Sprintf(" %*s ", width, table.Rows[u][i]) - case "center": - word_width := len(table.Rows[u][i]) - offset := (width - word_width) / 2 - row[i] = fmt.Sprintf(" %*s ", width, fmt.Sprintf("%-*s", offset+word_width, table.Rows[u][i])) - default: // left - row[i] = fmt.Sprintf(" %-*s ", width, table.Rows[u][i]) - } - } - } + table.CellWidth = cellWidthes - if table.Width == 0 { - table.Width = width_sum - } + //width_sum := 2 + //for i, width := range cellWidthes { + // width_sum += (width + 2) + // for u, row := range table.Rows { + // switch table.TextAlign { + // case "right": + // row[i] = fmt.Sprintf(" %*s ", width, table.Rows[u][i]) + // case "center": + // word_width := len(table.Rows[u][i]) + // offset := (width - word_width) / 2 + // row[i] = fmt.Sprintf(" %*s ", width, fmt.Sprintf("%-*s", offset+word_width, table.Rows[u][i])) + // default: // left + // row[i] = fmt.Sprintf(" %-*s ", width, table.Rows[u][i]) + // } + // } + //} + + //if table.Width == 0 { + // table.Width = width_sum + //} } func (table *Table) SetSize() { @@ -100,31 +100,71 @@ func (table *Table) SetSize() { } table.Width = 2 if length != 0 { - for _, str := range table.Rows[0] { - table.Width += len(str) + 2 + 1 + for _, cell_width := range table.CellWidth { + table.Width += cell_width + 3 } } } +func (table *Table) CalculatePosition(x int, y int, x_coordinate *int, y_coordibate *int, cell_beginning *int) { + if table.Seperator { + *y_coordibate = table.innerArea.Min.Y + y*2 + } else { + *y_coordibate = table.innerArea.Min.Y + y + } + if x == 0 { + *cell_beginning = table.innerArea.Min.X + } else { + *cell_beginning += table.CellWidth[x-1] + 3 + } + + if table.TextAlign == "right" { + *x_coordinate = *cell_beginning + (table.CellWidth[x] - len(table.Rows[y][x])) + 2 + } else if table.TextAlign == "center" { + *x_coordinate = *cell_beginning + (table.CellWidth[x]-len(table.Rows[y][x]))/2 + 2 + } else { + *x_coordinate = *cell_beginning + 2 + } +} + func (table *Table) Buffer() Buffer { buffer := table.Block.Buffer() table.Analysis() - for i, row := range table.Rows { - cells := DefaultTxBuilder.Build(strings.Join(row, "|"), table.FgColors[i], table.BgColors[i]) - if table.Seperator { - border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) - for x, cell := range cells { - buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2, cell) + + pointer_x := table.innerArea.Min.X + 2 + pointer_y := table.innerArea.Min.Y + border_pointer_x := table.innerArea.Min.X + for y, row := range table.Rows { + for x, cell := range row { + table.CalculatePosition(x, y, &pointer_x, &pointer_y, &border_pointer_x) + backgraound := DefaultTxBuilder.Build(strings.Repeat(" ", table.CellWidth[x]+2), table.BgColors[y], table.BgColors[y]) + cells := DefaultTxBuilder.Build(cell, table.FgColors[y], table.BgColors[y]) + + for i, back := range backgraound { + buffer.Set(border_pointer_x+i, pointer_y, back) } - for x, cell := range border { - buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i*2+1, cell) + coordinate_x := pointer_x + for _, printer := range cells { + buffer.Set(coordinate_x, pointer_y, printer) + coordinate_x += printer.Width() } - } else { - for x, cell := range cells { - buffer.Set(table.innerArea.Min.X+x, table.innerArea.Min.Y+i, cell) + + if x != 0 { + devidors := DefaultTxBuilder.Build("|", table.FgColors[y], table.BgColors[y]) + for _, devidor := range devidors { + buffer.Set(border_pointer_x, pointer_y, devidor) + } + } + } + + if table.Seperator { + border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) + for i, cell := range border { + buffer.Set(i+1, pointer_y+1, cell) } } } + return buffer } From c0ca4244445b0e20b12921890eeb3f4eb68459a5 Mon Sep 17 00:00:00 2001 From: wanzysky Date: Tue, 29 Nov 2016 12:21:02 +0800 Subject: [PATCH 6/6] change TextAlign type to Align\n fix backgound full fill --- _example/table.go | 4 ++-- table.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/_example/table.go b/_example/table.go index 76916f5..7c86493 100644 --- a/_example/table.go +++ b/_example/table.go @@ -1,6 +1,6 @@ package main -import "termui" +import "github.com/gizak/termui" func main() { err := termui.Init() @@ -35,7 +35,7 @@ func main() { table.Rows = rows table.FgColor = termui.ColorWhite table.BgColor = termui.ColorDefault - table.TextAlign = "center" + table.TextAlign = termui.AlignCenter table.Seperator = false table.Analysis() table.SetSize() diff --git a/table.go b/table.go index cde3ae7..319b897 100644 --- a/table.go +++ b/table.go @@ -23,14 +23,13 @@ type Table struct { FgColors []Attribute BgColors []Attribute Seperator bool - TextAlign string + TextAlign Align } func NewTable() *Table { table := &Table{Block: *NewBlock()} table.FgColor = ColorWhite table.BgColor = ColorDefault - table.TextAlign = "left" table.Seperator = true return table } @@ -118,11 +117,12 @@ func (table *Table) CalculatePosition(x int, y int, x_coordinate *int, y_coordib *cell_beginning += table.CellWidth[x-1] + 3 } - if table.TextAlign == "right" { + switch table.TextAlign { + case AlignRight: *x_coordinate = *cell_beginning + (table.CellWidth[x] - len(table.Rows[y][x])) + 2 - } else if table.TextAlign == "center" { + case AlignCenter: *x_coordinate = *cell_beginning + (table.CellWidth[x]-len(table.Rows[y][x]))/2 + 2 - } else { + default: *x_coordinate = *cell_beginning + 2 } } @@ -137,7 +137,7 @@ func (table *Table) Buffer() Buffer { for y, row := range table.Rows { for x, cell := range row { table.CalculatePosition(x, y, &pointer_x, &pointer_y, &border_pointer_x) - backgraound := DefaultTxBuilder.Build(strings.Repeat(" ", table.CellWidth[x]+2), table.BgColors[y], table.BgColors[y]) + backgraound := DefaultTxBuilder.Build(strings.Repeat(" ", table.CellWidth[x]+3), table.BgColors[y], table.BgColors[y]) cells := DefaultTxBuilder.Build(cell, table.FgColors[y], table.BgColors[y]) for i, back := range backgraound {