mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-28 13:48:51 +08:00
Allowing container.Option to report an error.
This commit is contained in:
parent
d39112bbad
commit
964d676e31
@ -64,7 +64,7 @@ func (c *Container) String() string {
|
|||||||
|
|
||||||
// New returns a new root container that will use the provided terminal and
|
// New returns a new root container that will use the provided terminal and
|
||||||
// applies the provided options.
|
// applies the provided options.
|
||||||
func New(t terminalapi.Terminal, opts ...Option) *Container {
|
func New(t terminalapi.Terminal, opts ...Option) (*Container, error) {
|
||||||
size := t.Size()
|
size := t.Size()
|
||||||
root := &Container{
|
root := &Container{
|
||||||
term: t,
|
term: t,
|
||||||
@ -75,8 +75,10 @@ func New(t terminalapi.Terminal, opts ...Option) *Container {
|
|||||||
|
|
||||||
// Initially the root is focused.
|
// Initially the root is focused.
|
||||||
root.focusTracker = newFocusTracker(root)
|
root.focusTracker = newFocusTracker(root)
|
||||||
applyOptions(root, opts...)
|
if err := applyOptions(root, opts...); err != nil {
|
||||||
return root
|
return nil, err
|
||||||
|
}
|
||||||
|
return root, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newChild creates a new child container of the given parent.
|
// newChild creates a new child container of the given parent.
|
||||||
|
@ -33,7 +33,7 @@ import (
|
|||||||
|
|
||||||
// Example demonstrates how to use the Container API.
|
// Example demonstrates how to use the Container API.
|
||||||
func Example() {
|
func Example() {
|
||||||
New(
|
if _, err := New(
|
||||||
/* terminal = */ nil,
|
/* terminal = */ nil,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
Left(
|
Left(
|
||||||
@ -58,20 +58,23 @@ func Example() {
|
|||||||
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNew(t *testing.T) {
|
func TestNew(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
termSize image.Point
|
termSize image.Point
|
||||||
container func(ft *faketerm.Terminal) *Container
|
container func(ft *faketerm.Terminal) (*Container, error)
|
||||||
|
wantContainerErr bool
|
||||||
want func(size image.Point) *faketerm.Terminal
|
want func(size image.Point) *faketerm.Terminal
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "empty container",
|
desc: "empty container",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(ft)
|
return New(ft)
|
||||||
},
|
},
|
||||||
want: func(size image.Point) *faketerm.Terminal {
|
want: func(size image.Point) *faketerm.Terminal {
|
||||||
@ -81,7 +84,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "container with a border",
|
desc: "container with a border",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -102,7 +105,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "horizontal split, children have borders",
|
desc: "horizontal split, children have borders",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
SplitHorizontal(
|
SplitHorizontal(
|
||||||
@ -127,7 +130,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "horizontal split, parent and children have borders",
|
desc: "horizontal split, parent and children have borders",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -158,7 +161,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "vertical split, children have borders",
|
desc: "vertical split, children have borders",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
@ -183,7 +186,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "vertical split, parent and children have borders",
|
desc: "vertical split, parent and children have borders",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -214,7 +217,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "multi level split",
|
desc: "multi level split",
|
||||||
termSize: image.Point{10, 16},
|
termSize: image.Point{10, 16},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
@ -255,7 +258,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "inherits border and focused color",
|
desc: "inherits border and focused color",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -296,7 +299,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "splitting a container removes the widget",
|
desc: "splitting a container removes the widget",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -328,7 +331,7 @@ func TestNew(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "placing a widget removes container split",
|
desc: "placing a widget removes container split",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
@ -360,7 +363,14 @@ func TestNew(t *testing.T) {
|
|||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tc.container(got).Draw(); err != nil {
|
cont, err := tc.container(got)
|
||||||
|
if (err != nil) != tc.wantContainerErr {
|
||||||
|
t.Errorf("tc.container => unexpected error:%v, wantErr:%v", err, tc.wantContainerErr)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := cont.Draw(); err != nil {
|
||||||
t.Fatalf("Draw => unexpected error: %v", err)
|
t.Fatalf("Draw => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +386,7 @@ func TestKeyboard(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
termSize image.Point
|
termSize image.Point
|
||||||
container func(ft *faketerm.Terminal) *Container
|
container func(ft *faketerm.Terminal) (*Container, error)
|
||||||
events []terminalapi.Event
|
events []terminalapi.Event
|
||||||
want func(size image.Point) *faketerm.Terminal
|
want func(size image.Point) *faketerm.Terminal
|
||||||
wantErr bool
|
wantErr bool
|
||||||
@ -384,7 +394,7 @@ func TestKeyboard(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event not forwarded if container has no widget",
|
desc: "event not forwarded if container has no widget",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(ft)
|
return New(ft)
|
||||||
},
|
},
|
||||||
events: []terminalapi.Event{
|
events: []terminalapi.Event{
|
||||||
@ -397,7 +407,7 @@ func TestKeyboard(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event forwarded to focused container only",
|
desc: "event forwarded to focused container only",
|
||||||
termSize: image.Point{40, 20},
|
termSize: image.Point{40, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
@ -450,7 +460,7 @@ func TestKeyboard(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event not forwarded if the widget didn't request it",
|
desc: "event not forwarded if the widget didn't request it",
|
||||||
termSize: image.Point{40, 20},
|
termSize: image.Point{40, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{WantKeyboard: false})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{WantKeyboard: false})),
|
||||||
@ -473,7 +483,7 @@ func TestKeyboard(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget returns an error when processing the event",
|
desc: "widget returns an error when processing the event",
|
||||||
termSize: image.Point{40, 20},
|
termSize: image.Point{40, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{WantKeyboard: true})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{WantKeyboard: true})),
|
||||||
@ -503,7 +513,10 @@ func TestKeyboard(t *testing.T) {
|
|||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := tc.container(got)
|
c, err := tc.container(got)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tc.container => unexpected error: %v", err)
|
||||||
|
}
|
||||||
for _, ev := range tc.events {
|
for _, ev := range tc.events {
|
||||||
switch e := ev.(type) {
|
switch e := ev.(type) {
|
||||||
case *terminalapi.Mouse:
|
case *terminalapi.Mouse:
|
||||||
@ -537,7 +550,7 @@ func TestMouse(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
termSize image.Point
|
termSize image.Point
|
||||||
container func(ft *faketerm.Terminal) *Container
|
container func(ft *faketerm.Terminal) (*Container, error)
|
||||||
events []terminalapi.Event
|
events []terminalapi.Event
|
||||||
want func(size image.Point) *faketerm.Terminal
|
want func(size image.Point) *faketerm.Terminal
|
||||||
wantErr bool
|
wantErr bool
|
||||||
@ -545,7 +558,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "mouse click outside of the terminal is ignored",
|
desc: "mouse click outside of the terminal is ignored",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: true})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: true})),
|
||||||
@ -569,7 +582,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event not forwarded if container has no widget",
|
desc: "event not forwarded if container has no widget",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(ft)
|
return New(ft)
|
||||||
},
|
},
|
||||||
events: []terminalapi.Event{
|
events: []terminalapi.Event{
|
||||||
@ -583,7 +596,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event forwarded to container at that point",
|
desc: "event forwarded to container at that point",
|
||||||
termSize: image.Point{50, 20},
|
termSize: image.Point{50, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
@ -636,7 +649,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event not forwarded if the widget didn't request it",
|
desc: "event not forwarded if the widget didn't request it",
|
||||||
termSize: image.Point{20, 20},
|
termSize: image.Point{20, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: false})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: false})),
|
||||||
@ -659,7 +672,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event not forwarded if it falls on the container's border",
|
desc: "event not forwarded if it falls on the container's border",
|
||||||
termSize: image.Point{20, 20},
|
termSize: image.Point{20, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -693,7 +706,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "event not forwarded if it falls outside of widget's canvas",
|
desc: "event not forwarded if it falls outside of widget's canvas",
|
||||||
termSize: image.Point{20, 20},
|
termSize: image.Point{20, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(
|
PlaceWidget(
|
||||||
@ -723,7 +736,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "mouse poisition adjusted relative to widget's canvas, vertical offset",
|
desc: "mouse poisition adjusted relative to widget's canvas, vertical offset",
|
||||||
termSize: image.Point{20, 20},
|
termSize: image.Point{20, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(
|
PlaceWidget(
|
||||||
@ -754,7 +767,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "mouse poisition adjusted relative to widget's canvas, horizontal offset",
|
desc: "mouse poisition adjusted relative to widget's canvas, horizontal offset",
|
||||||
termSize: image.Point{30, 20},
|
termSize: image.Point{30, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(
|
PlaceWidget(
|
||||||
@ -785,7 +798,7 @@ func TestMouse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget returns an error when processing the event",
|
desc: "widget returns an error when processing the event",
|
||||||
termSize: image.Point{40, 20},
|
termSize: image.Point{40, 20},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: true})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{WantMouse: true})),
|
||||||
@ -815,7 +828,10 @@ func TestMouse(t *testing.T) {
|
|||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := tc.container(got)
|
c, err := tc.container(got)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tc.container => unexpected error: %v", err)
|
||||||
|
}
|
||||||
for _, ev := range tc.events {
|
for _, ev := range tc.events {
|
||||||
switch e := ev.(type) {
|
switch e := ev.(type) {
|
||||||
case *terminalapi.Mouse:
|
case *terminalapi.Mouse:
|
||||||
|
@ -32,14 +32,14 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
termSize image.Point
|
termSize image.Point
|
||||||
container func(ft *faketerm.Terminal) *Container
|
container func(ft *faketerm.Terminal) (*Container, error)
|
||||||
want func(size image.Point) *faketerm.Terminal
|
want func(size image.Point) *faketerm.Terminal
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "draws widget with container border",
|
desc: "draws widget with container border",
|
||||||
termSize: image.Point{9, 5},
|
termSize: image.Point{9, 5},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -66,7 +66,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "draws widget with container border and title aligned on the left",
|
desc: "draws widget with container border and title aligned on the left",
|
||||||
termSize: image.Point{9, 5},
|
termSize: image.Point{9, 5},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -100,7 +100,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "draws widget with container border and title aligned in the center",
|
desc: "draws widget with container border and title aligned in the center",
|
||||||
termSize: image.Point{9, 5},
|
termSize: image.Point{9, 5},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -135,7 +135,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "draws widget with container border and title aligned on the right",
|
desc: "draws widget with container border and title aligned on the right",
|
||||||
termSize: image.Point{9, 5},
|
termSize: image.Point{9, 5},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -170,7 +170,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "draws widget with container border and title that is trimmed",
|
desc: "draws widget with container border and title that is trimmed",
|
||||||
termSize: image.Point{9, 5},
|
termSize: image.Point{9, 5},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -205,7 +205,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "draws widget without container border",
|
desc: "draws widget without container border",
|
||||||
termSize: image.Point{9, 5},
|
termSize: image.Point{9, 5},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
PlaceWidget(fakewidget.New(widgetapi.Options{})),
|
||||||
@ -225,7 +225,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget.Draw returns an error",
|
desc: "widget.Draw returns an error",
|
||||||
termSize: image.Point{5, 5}, // Too small for the widget's box.
|
termSize: image.Point{5, 5}, // Too small for the widget's box.
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -240,7 +240,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "container with border and no space isn't drawn",
|
desc: "container with border and no space isn't drawn",
|
||||||
termSize: image.Point{1, 1},
|
termSize: image.Point{1, 1},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -257,7 +257,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "container without the requested space for its widget isn't drawn",
|
desc: "container without the requested space for its widget isn't drawn",
|
||||||
termSize: image.Point{1, 1},
|
termSize: image.Point{1, 1},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
PlaceWidget(fakewidget.New(widgetapi.Options{
|
PlaceWidget(fakewidget.New(widgetapi.Options{
|
||||||
@ -276,7 +276,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget's canvas is limited to the requested maximum size",
|
desc: "widget's canvas is limited to the requested maximum size",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -308,7 +308,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget's canvas is limited to the requested maximum width",
|
desc: "widget's canvas is limited to the requested maximum width",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -340,7 +340,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget's canvas is limited to the requested maximum height",
|
desc: "widget's canvas is limited to the requested maximum height",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -372,7 +372,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget gets the requested aspect ratio",
|
desc: "widget gets the requested aspect ratio",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -404,7 +404,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "widget's canvas is limited to the requested maximum size and ratio",
|
desc: "widget's canvas is limited to the requested maximum size and ratio",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -436,7 +436,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "horizontal left align for the widget",
|
desc: "horizontal left align for the widget",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -467,7 +467,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "horizontal center align for the widget",
|
desc: "horizontal center align for the widget",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -498,7 +498,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "horizontal right align for the widget",
|
desc: "horizontal right align for the widget",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -529,7 +529,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "vertical top align for the widget",
|
desc: "vertical top align for the widget",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -560,7 +560,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "vertical middle align for the widget",
|
desc: "vertical middle align for the widget",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -591,7 +591,7 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "vertical bottom align for the widget",
|
desc: "vertical bottom align for the widget",
|
||||||
termSize: image.Point{22, 22},
|
termSize: image.Point{22, 22},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -624,8 +624,11 @@ func TestDrawWidget(t *testing.T) {
|
|||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.desc, func(t *testing.T) {
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
got := faketerm.MustNew(tc.termSize)
|
got := faketerm.MustNew(tc.termSize)
|
||||||
c := tc.container(got)
|
c, err := tc.container(got)
|
||||||
err := c.Draw()
|
if err != nil {
|
||||||
|
t.Fatalf("tc.container => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
err = c.Draw()
|
||||||
if (err != nil) != tc.wantErr {
|
if (err != nil) != tc.wantErr {
|
||||||
t.Errorf("Draw => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
t.Errorf("Draw => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
||||||
}
|
}
|
||||||
@ -647,7 +650,7 @@ func TestDrawHandlesTerminalResize(t *testing.T) {
|
|||||||
t.Errorf("faketerm.New => unexpected error: %v", err)
|
t.Errorf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cont := New(
|
cont, err := New(
|
||||||
got,
|
got,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
Left(
|
Left(
|
||||||
@ -672,6 +675,9 @@ func TestDrawHandlesTerminalResize(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// The following tests aren't hermetic, they all access the same container
|
// The following tests aren't hermetic, they all access the same container
|
||||||
// and fake terminal in order to retain state between resizes.
|
// and fake terminal in order to retain state between resizes.
|
||||||
|
@ -37,13 +37,13 @@ func TestPointCont(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
termSize image.Point
|
termSize image.Point
|
||||||
container func(ft *faketerm.Terminal) *Container
|
container func(ft *faketerm.Terminal) (*Container, error)
|
||||||
cases []pointCase
|
cases []pointCase
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "single container, no border",
|
desc: "single container, no border",
|
||||||
termSize: image.Point{3, 3},
|
termSize: image.Point{3, 3},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
BorderColor(cell.ColorBlue),
|
BorderColor(cell.ColorBlue),
|
||||||
@ -90,7 +90,7 @@ func TestPointCont(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "single container, border",
|
desc: "single container, border",
|
||||||
termSize: image.Point{3, 3},
|
termSize: image.Point{3, 3},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -113,7 +113,7 @@ func TestPointCont(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "split containers, parent has no border",
|
desc: "split containers, parent has no border",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
BorderColor(cell.ColorBlack),
|
BorderColor(cell.ColorBlack),
|
||||||
@ -160,7 +160,7 @@ func TestPointCont(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "split containers, parent has border",
|
desc: "split containers, parent has border",
|
||||||
termSize: image.Point{10, 10},
|
termSize: image.Point{10, 10},
|
||||||
container: func(ft *faketerm.Terminal) *Container {
|
container: func(ft *faketerm.Terminal) (*Container, error) {
|
||||||
return New(
|
return New(
|
||||||
ft,
|
ft,
|
||||||
Border(draw.LineStyleLight),
|
Border(draw.LineStyleLight),
|
||||||
@ -229,7 +229,10 @@ func TestPointCont(t *testing.T) {
|
|||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cont := tc.container(ft)
|
cont, err := tc.container(ft)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tc.container => unexpected error: %v", err)
|
||||||
|
}
|
||||||
for _, pc := range tc.cases {
|
for _, pc := range tc.cases {
|
||||||
gotCont := pointCont(cont, pc.point)
|
gotCont := pointCont(cont, pc.point)
|
||||||
if (gotCont == nil) != pc.wantNil {
|
if (gotCont == nil) != pc.wantNil {
|
||||||
@ -382,13 +385,16 @@ func TestFocusTrackerMouse(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.desc, func(t *testing.T) {
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
root := New(
|
root, err := New(
|
||||||
ft,
|
ft,
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
Left(),
|
Left(),
|
||||||
Right(),
|
Right(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, ev := range tc.events {
|
for _, ev := range tc.events {
|
||||||
root.Mouse(ev)
|
root.Mouse(ev)
|
||||||
|
@ -24,16 +24,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// applyOptions applies the options to the container.
|
// applyOptions applies the options to the container.
|
||||||
func applyOptions(c *Container, opts ...Option) {
|
func applyOptions(c *Container, opts ...Option) error {
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt.set(c)
|
if err := opt.set(c); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Option is used to provide options to a container.
|
// Option is used to provide options to a container.
|
||||||
type Option interface {
|
type Option interface {
|
||||||
// set sets the provided option.
|
// set sets the provided option.
|
||||||
set(*Container)
|
set(*Container) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// options stores the options provided to the container.
|
// options stores the options provided to the container.
|
||||||
@ -85,22 +88,24 @@ func newOptions(parent *options) *options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// option implements Option.
|
// option implements Option.
|
||||||
type option func(*Container)
|
type option func(*Container) error
|
||||||
|
|
||||||
// set implements Option.set.
|
// set implements Option.set.
|
||||||
func (o option) set(c *Container) {
|
func (o option) set(c *Container) error {
|
||||||
o(c)
|
return o(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SplitVertical splits the container along the vertical axis into two sub
|
// SplitVertical splits the container along the vertical axis into two sub
|
||||||
// containers. The use of this option removes any widget placed at this
|
// containers. The use of this option removes any widget placed at this
|
||||||
// container, containers with sub containers cannot contain widgets.
|
// container, containers with sub containers cannot contain widgets.
|
||||||
func SplitVertical(l LeftOption, r RightOption) Option {
|
func SplitVertical(l LeftOption, r RightOption) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.split = splitTypeVertical
|
c.opts.split = splitTypeVertical
|
||||||
c.opts.widget = nil
|
c.opts.widget = nil
|
||||||
applyOptions(c.createFirst(), l.lOpts()...)
|
if err := applyOptions(c.createFirst(), l.lOpts()...); err != nil {
|
||||||
applyOptions(c.createSecond(), r.rOpts()...)
|
return err
|
||||||
|
}
|
||||||
|
return applyOptions(c.createSecond(), r.rOpts()...)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,11 +113,13 @@ func SplitVertical(l LeftOption, r RightOption) Option {
|
|||||||
// containers. The use of this option removes any widget placed at this
|
// containers. The use of this option removes any widget placed at this
|
||||||
// container, containers with sub containers cannot contain widgets.
|
// container, containers with sub containers cannot contain widgets.
|
||||||
func SplitHorizontal(t TopOption, b BottomOption) Option {
|
func SplitHorizontal(t TopOption, b BottomOption) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.split = splitTypeHorizontal
|
c.opts.split = splitTypeHorizontal
|
||||||
c.opts.widget = nil
|
c.opts.widget = nil
|
||||||
applyOptions(c.createFirst(), t.tOpts()...)
|
if err := applyOptions(c.createFirst(), t.tOpts()...); err != nil {
|
||||||
applyOptions(c.createSecond(), b.bOpts()...)
|
return err
|
||||||
|
}
|
||||||
|
return applyOptions(c.createSecond(), b.bOpts()...)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +127,11 @@ func SplitHorizontal(t TopOption, b BottomOption) Option {
|
|||||||
// The use of this option removes any sub containers. Containers with sub
|
// The use of this option removes any sub containers. Containers with sub
|
||||||
// containers cannot have widgets.
|
// containers cannot have widgets.
|
||||||
func PlaceWidget(w widgetapi.Widget) Option {
|
func PlaceWidget(w widgetapi.Widget) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.widget = w
|
c.opts.widget = w
|
||||||
c.first = nil
|
c.first = nil
|
||||||
c.second = nil
|
c.second = nil
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,8 +139,9 @@ func PlaceWidget(w widgetapi.Widget) Option {
|
|||||||
// container. Has no effect if the container contains no widget.
|
// container. Has no effect if the container contains no widget.
|
||||||
// Defaults alignment in the center.
|
// Defaults alignment in the center.
|
||||||
func AlignHorizontal(h align.Horizontal) Option {
|
func AlignHorizontal(h align.Horizontal) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.hAlign = h
|
c.opts.hAlign = h
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,51 +149,58 @@ func AlignHorizontal(h align.Horizontal) Option {
|
|||||||
// Has no effect if the container contains no widget.
|
// Has no effect if the container contains no widget.
|
||||||
// Defaults to alignment in the middle.
|
// Defaults to alignment in the middle.
|
||||||
func AlignVertical(v align.Vertical) Option {
|
func AlignVertical(v align.Vertical) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.vAlign = v
|
c.opts.vAlign = v
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Border configures the container to have a border of the specified style.
|
// Border configures the container to have a border of the specified style.
|
||||||
func Border(ls draw.LineStyle) Option {
|
func Border(ls draw.LineStyle) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.border = ls
|
c.opts.border = ls
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderTitle sets a text title within the border.
|
// BorderTitle sets a text title within the border.
|
||||||
func BorderTitle(title string) Option {
|
func BorderTitle(title string) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.borderTitle = title
|
c.opts.borderTitle = title
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderTitleAlignLeft aligns the border title on the left.
|
// BorderTitleAlignLeft aligns the border title on the left.
|
||||||
func BorderTitleAlignLeft() Option {
|
func BorderTitleAlignLeft() Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.borderTitleHAlign = align.HorizontalLeft
|
c.opts.borderTitleHAlign = align.HorizontalLeft
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderTitleAlignCenter aligns the border title in the center.
|
// BorderTitleAlignCenter aligns the border title in the center.
|
||||||
func BorderTitleAlignCenter() Option {
|
func BorderTitleAlignCenter() Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.borderTitleHAlign = align.HorizontalCenter
|
c.opts.borderTitleHAlign = align.HorizontalCenter
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderTitleAlignRight aligns the border title on the right.
|
// BorderTitleAlignRight aligns the border title on the right.
|
||||||
func BorderTitleAlignRight() Option {
|
func BorderTitleAlignRight() Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.borderTitleHAlign = align.HorizontalRight
|
c.opts.borderTitleHAlign = align.HorizontalRight
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderColor sets the color of the border around the container.
|
// BorderColor sets the color of the border around the container.
|
||||||
// This option is inherited to sub containers created by container splits.
|
// This option is inherited to sub containers created by container splits.
|
||||||
func BorderColor(color cell.Color) Option {
|
func BorderColor(color cell.Color) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.inherited.borderColor = color
|
c.opts.inherited.borderColor = color
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +208,9 @@ func BorderColor(color cell.Color) Option {
|
|||||||
// keyboard focus.
|
// keyboard focus.
|
||||||
// This option is inherited to sub containers created by container splits.
|
// This option is inherited to sub containers created by container splits.
|
||||||
func FocusedColor(color cell.Color) Option {
|
func FocusedColor(color cell.Color) Option {
|
||||||
return option(func(c *Container) {
|
return option(func(c *Container) error {
|
||||||
c.opts.inherited.focusedColor = color
|
c.opts.inherited.focusedColor = color
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ func TestRoot(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
want := New(
|
want, err := New(
|
||||||
ft,
|
ft,
|
||||||
SplitHorizontal(
|
SplitHorizontal(
|
||||||
Top(
|
Top(
|
||||||
@ -42,6 +42,9 @@ func TestRoot(t *testing.T) {
|
|||||||
Bottom(),
|
Bottom(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if got := rootCont(want); got != want {
|
if got := rootCont(want); got != want {
|
||||||
t.Errorf("rootCont(root) => got %p, want %p", got, want)
|
t.Errorf("rootCont(root) => got %p, want %p", got, want)
|
||||||
@ -58,7 +61,7 @@ func TestTraversal(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
cont := New(
|
cont, err := New(
|
||||||
ft,
|
ft,
|
||||||
BorderColor(cell.ColorBlack),
|
BorderColor(cell.ColorBlack),
|
||||||
SplitVertical(
|
SplitVertical(
|
||||||
@ -86,6 +89,9 @@ func TestTraversal(t *testing.T) {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("New => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
desc string
|
desc string
|
||||||
|
@ -50,7 +50,7 @@ func Example() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the container with two fake widgets.
|
// Create the container with two fake widgets.
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.SplitVertical(
|
container.SplitVertical(
|
||||||
container.Left(
|
container.Left(
|
||||||
@ -61,6 +61,9 @@ func Example() {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Termdash runs until the context expires.
|
// Termdash runs until the context expires.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
@ -86,10 +89,13 @@ func Example_triggered() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the container with a widget.
|
// Create the container with a widget.
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.PlaceWidget(fakewidget.New(wOpts)),
|
container.PlaceWidget(fakewidget.New(wOpts)),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Create the controller and disable periodic redraw.
|
// Create the controller and disable periodic redraw.
|
||||||
ctrl, err := NewController(t, c)
|
ctrl, err := NewController(t, c)
|
||||||
@ -332,13 +338,16 @@ func TestRun(t *testing.T) {
|
|||||||
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
t.Fatalf("faketerm.New => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cont := container.New(
|
cont, err := container.New(
|
||||||
got,
|
got,
|
||||||
container.PlaceWidget(fakewidget.New(widgetapi.Options{
|
container.PlaceWidget(fakewidget.New(widgetapi.Options{
|
||||||
WantKeyboard: true,
|
WantKeyboard: true,
|
||||||
WantMouse: true,
|
WantMouse: true,
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("container.New => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)
|
||||||
err = Run(ctx, got, cont, tc.opts...)
|
err = Run(ctx, got, cont, tc.opts...)
|
||||||
@ -511,10 +520,13 @@ func TestController(t *testing.T) {
|
|||||||
WantKeyboard: true,
|
WantKeyboard: true,
|
||||||
WantMouse: true,
|
WantMouse: true,
|
||||||
})
|
})
|
||||||
cont := container.New(
|
cont, err := container.New(
|
||||||
got,
|
got,
|
||||||
container.PlaceWidget(mi),
|
container.PlaceWidget(mi),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("container.New => unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
ctrl, err := NewController(got, cont, tc.opts...)
|
ctrl, err := NewController(got, cont, tc.opts...)
|
||||||
if (err != nil) != tc.wantErr {
|
if (err != nil) != tc.wantErr {
|
||||||
|
@ -93,12 +93,15 @@ func main() {
|
|||||||
)
|
)
|
||||||
go playBarChart(ctx, bc, 1*time.Second)
|
go playBarChart(ctx, bc, 1*time.Second)
|
||||||
|
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.Border(draw.LineStyleLight),
|
container.Border(draw.LineStyleLight),
|
||||||
container.BorderTitle("PRESS Q TO QUIT"),
|
container.BorderTitle("PRESS Q TO QUIT"),
|
||||||
container.PlaceWidget(bc),
|
container.PlaceWidget(bc),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
quitter := func(k *terminalapi.Keyboard) {
|
quitter := func(k *terminalapi.Keyboard) {
|
||||||
if k.Key == 'q' || k.Key == 'Q' {
|
if k.Key == 'q' || k.Key == 'Q' {
|
||||||
|
@ -115,7 +115,7 @@ func main() {
|
|||||||
)
|
)
|
||||||
go playGauge(ctx, withLabel, 3, 500*time.Millisecond, playTypePercent)
|
go playGauge(ctx, withLabel, 3, 500*time.Millisecond, playTypePercent)
|
||||||
|
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.SplitVertical(
|
container.SplitVertical(
|
||||||
container.Left(
|
container.Left(
|
||||||
@ -147,6 +147,9 @@ func main() {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
quitter := func(k *terminalapi.Keyboard) {
|
quitter := func(k *terminalapi.Keyboard) {
|
||||||
if k.Key == 'q' || k.Key == 'Q' {
|
if k.Key == 'q' || k.Key == 'Q' {
|
||||||
|
@ -88,12 +88,15 @@ func main() {
|
|||||||
linechart.XLabelCellOpts(cell.FgColor(cell.ColorCyan)),
|
linechart.XLabelCellOpts(cell.FgColor(cell.ColorCyan)),
|
||||||
)
|
)
|
||||||
go playLineChart(ctx, lc, redrawInterval/3)
|
go playLineChart(ctx, lc, redrawInterval/3)
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.Border(draw.LineStyleLight),
|
container.Border(draw.LineStyleLight),
|
||||||
container.BorderTitle("PRESS Q TO QUIT"),
|
container.BorderTitle("PRESS Q TO QUIT"),
|
||||||
container.PlaceWidget(lc),
|
container.PlaceWidget(lc),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
quitter := func(k *terminalapi.Keyboard) {
|
quitter := func(k *terminalapi.Keyboard) {
|
||||||
if k.Key == 'q' || k.Key == 'Q' {
|
if k.Key == 'q' || k.Key == 'Q' {
|
||||||
|
@ -75,7 +75,7 @@ func main() {
|
|||||||
)
|
)
|
||||||
go playSparkLine(ctx, yellow, 1*time.Second)
|
go playSparkLine(ctx, yellow, 1*time.Second)
|
||||||
|
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.Border(draw.LineStyleLight),
|
container.Border(draw.LineStyleLight),
|
||||||
container.BorderTitle("PRESS Q TO QUIT"),
|
container.BorderTitle("PRESS Q TO QUIT"),
|
||||||
@ -103,6 +103,9 @@ func main() {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
quitter := func(k *terminalapi.Keyboard) {
|
quitter := func(k *terminalapi.Keyboard) {
|
||||||
if k.Key == 'q' || k.Key == 'Q' {
|
if k.Key == 'q' || k.Key == 'Q' {
|
||||||
|
@ -106,7 +106,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
go writeLines(ctx, rolled, 1*time.Second)
|
go writeLines(ctx, rolled, 1*time.Second)
|
||||||
|
|
||||||
c := container.New(
|
c, err := container.New(
|
||||||
t,
|
t,
|
||||||
container.Border(draw.LineStyleLight),
|
container.Border(draw.LineStyleLight),
|
||||||
container.BorderTitle("PRESS Q TO QUIT"),
|
container.BorderTitle("PRESS Q TO QUIT"),
|
||||||
@ -148,6 +148,9 @@ func main() {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
quitter := func(k *terminalapi.Keyboard) {
|
quitter := func(k *terminalapi.Keyboard) {
|
||||||
if k.Key == 'q' || k.Key == 'Q' {
|
if k.Key == 'q' || k.Key == 'Q' {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user