mirror of
https://github.com/mum4k/termdash.git
synced 2025-05-01 22:17:51 +08:00
Adding canvas function that sets area of cells.
This commit is contained in:
parent
0490734d1e
commit
417eee0799
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/mum4k/termdash/area"
|
||||
"github.com/mum4k/termdash/cell"
|
||||
"github.com/mum4k/termdash/cell/runewidth"
|
||||
"github.com/mum4k/termdash/terminalapi"
|
||||
)
|
||||
|
||||
@ -117,6 +118,32 @@ func (c *Canvas) SetCellOpts(p image.Point, opts ...cell.Option) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAreaCells is like SetCell, but sets the specified rune and options on all
|
||||
// the cells within the provided area.
|
||||
// This method is idempotent.
|
||||
func (c *Canvas) SetAreaCells(cellArea image.Rectangle, r rune, opts ...cell.Option) error {
|
||||
haveArea := c.Area()
|
||||
if !cellArea.In(haveArea) {
|
||||
return fmt.Errorf("unable to set cell runes in area %v, it must fit inside the available cell area is %v", cellArea, haveArea)
|
||||
}
|
||||
|
||||
rw := runewidth.RuneWidth(r)
|
||||
for row := cellArea.Min.Y; row < cellArea.Max.Y; row++ {
|
||||
for col := cellArea.Min.X; col < cellArea.Max.X; {
|
||||
p := image.Point{col, row}
|
||||
if col+rw > cellArea.Max.X {
|
||||
break
|
||||
}
|
||||
cells, err := c.SetCell(p, r, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
col += cells
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAreaCellOpts is like SetCellOpts, but sets the specified options on all
|
||||
// the cells within the provided area.
|
||||
func (c *Canvas) SetAreaCellOpts(cellArea image.Rectangle, opts ...cell.Option) error {
|
||||
|
@ -317,6 +317,173 @@ func TestCanvas(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ft, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells sets cells in the full canvas",
|
||||
canvas: image.Rect(0, 0, 1, 1),
|
||||
ops: func(cvs *Canvas) error {
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 1, 1), 'r')
|
||||
},
|
||||
want: func(size image.Point) (*faketerm.Terminal, error) {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs, err := New(ft.Area())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := cvs.SetCell(image.Point{0, 0}, 'r'); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ft, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells is idempotent",
|
||||
canvas: image.Rect(0, 0, 1, 1),
|
||||
ops: func(cvs *Canvas) error {
|
||||
if err := cvs.SetAreaCells(image.Rect(0, 0, 1, 1), 'r'); err != nil {
|
||||
return err
|
||||
}
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 1, 1), 'r')
|
||||
},
|
||||
want: func(size image.Point) (*faketerm.Terminal, error) {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs, err := New(ft.Area())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := cvs.SetCell(image.Point{0, 0}, 'r'); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ft, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells fails on area too large",
|
||||
canvas: image.Rect(0, 0, 1, 1),
|
||||
ops: func(cvs *Canvas) error {
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 2, 2), 'r', cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorBlue))
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells sets cell options",
|
||||
canvas: image.Rect(0, 0, 1, 1),
|
||||
ops: func(cvs *Canvas) error {
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 1, 1), 'r', cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorBlue))
|
||||
},
|
||||
want: func(size image.Point) (*faketerm.Terminal, error) {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs, err := New(ft.Area())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := cvs.SetCell(image.Point{0, 0}, 'r', cell.FgColor(cell.ColorRed), cell.BgColor(cell.ColorBlue)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ft, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells sets cell in a sub-area",
|
||||
canvas: image.Rect(0, 0, 3, 3),
|
||||
ops: func(cvs *Canvas) error {
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 2, 2), 'p')
|
||||
},
|
||||
want: func(size image.Point) (*faketerm.Terminal, error) {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs, err := New(ft.Area())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range []image.Point{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
{1, 0},
|
||||
{1, 1},
|
||||
} {
|
||||
if _, err := cvs.SetCell(p, 'p'); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ft, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells sets full-width runes that fit",
|
||||
canvas: image.Rect(0, 0, 3, 3),
|
||||
ops: func(cvs *Canvas) error {
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 2, 2), '世')
|
||||
},
|
||||
want: func(size image.Point) (*faketerm.Terminal, error) {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs, err := New(ft.Area())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range []image.Point{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
} {
|
||||
if _, err := cvs.SetCell(p, '世'); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ft, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "SetAreaCells sets full-width runes that will leave a gap at the end of each row",
|
||||
canvas: image.Rect(0, 0, 3, 3),
|
||||
ops: func(cvs *Canvas) error {
|
||||
return cvs.SetAreaCells(image.Rect(0, 0, 3, 3), '世')
|
||||
},
|
||||
want: func(size image.Point) (*faketerm.Terminal, error) {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs, err := New(ft.Area())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, p := range []image.Point{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
{0, 2},
|
||||
} {
|
||||
if _, err := cvs.SetCell(p, '世'); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := cvs.Apply(ft); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user