Support setting of different colors for container's border and title.

This commit is contained in:
Andreea Sobon 2021-01-04 12:20:40 -05:00
parent f4b0d03624
commit 22ae449020
4 changed files with 224 additions and 4 deletions

View File

@ -1003,6 +1003,155 @@ func TestNew(t *testing.T) {
return ft return ft
}, },
}, },
{
desc: "sets border title on root container of different color",
termSize: image.Point{10, 10},
container: func(ft *faketerm.Terminal) (*Container, error) {
return New(
ft,
Border(linestyle.Light),
BorderTitle("Ab"),
BorderColor(cell.ColorRed),
FocusedColor(cell.ColorBlue),
TitleColor(cell.ColorMagenta),
TitleFocusedColor(cell.ColorCyan),
SplitVertical(
Left(
Border(linestyle.Light),
),
Right(
Border(linestyle.Light),
),
),
)
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
cvs := testcanvas.MustNew(ft.Area())
testdraw.MustBorder(
cvs,
image.Rect(0, 0, 10, 10),
draw.BorderCellOpts(cell.FgColor(cell.ColorBlue)),
)
testdraw.MustBorder(
cvs,
image.Rect(1, 1, 5, 9),
draw.BorderCellOpts(cell.FgColor(cell.ColorRed)),
)
testdraw.MustBorder(
cvs,
image.Rect(5, 1, 9, 9),
draw.BorderCellOpts(cell.FgColor(cell.ColorRed)),
)
testdraw.MustText(
cvs,
"Ab",
image.Point{1, 0},
draw.TextCellOpts(cell.FgColor(cell.ColorCyan)),
)
testcanvas.MustApply(cvs, ft)
return ft
},
},
{
desc: "sets different color title on left child container",
termSize: image.Point{10, 10},
container: func(ft *faketerm.Terminal) (*Container, error) {
return New(
ft,
Border(linestyle.Light),
BorderColor(cell.ColorRed),
FocusedColor(cell.ColorBlue),
SplitVertical(
Left(
Border(linestyle.Light),
BorderTitle("Ab"),
TitleColor(cell.ColorMagenta),
TitleFocusedColor(cell.ColorCyan),
),
Right(
Border(linestyle.Light),
),
),
)
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
cvs := testcanvas.MustNew(ft.Area())
testdraw.MustBorder(
cvs,
image.Rect(0, 0, 10, 10),
draw.BorderCellOpts(cell.FgColor(cell.ColorBlue)),
)
testdraw.MustBorder(
cvs,
image.Rect(1, 1, 5, 9),
draw.BorderCellOpts(cell.FgColor(cell.ColorRed)),
)
testdraw.MustBorder(
cvs,
image.Rect(5, 1, 9, 9),
draw.BorderCellOpts(cell.FgColor(cell.ColorRed)),
)
testdraw.MustText(
cvs,
"Ab",
image.Point{2, 1},
draw.TextCellOpts(cell.FgColor(cell.ColorMagenta)),
)
testcanvas.MustApply(cvs, ft)
return ft
},
},
{
desc: "inherits title color on left child container",
termSize: image.Point{10, 10},
container: func(ft *faketerm.Terminal) (*Container, error) {
return New(
ft,
Border(linestyle.Light),
BorderColor(cell.ColorRed),
FocusedColor(cell.ColorBlue),
SplitVertical(
Left(
Border(linestyle.Light),
BorderTitle("Ab"),
),
Right(
Border(linestyle.Light),
),
),
)
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
cvs := testcanvas.MustNew(ft.Area())
testdraw.MustBorder(
cvs,
image.Rect(0, 0, 10, 10),
draw.BorderCellOpts(cell.FgColor(cell.ColorBlue)),
)
testdraw.MustBorder(
cvs,
image.Rect(1, 1, 5, 9),
draw.BorderCellOpts(cell.FgColor(cell.ColorRed)),
)
testdraw.MustBorder(
cvs,
image.Rect(5, 1, 9, 9),
draw.BorderCellOpts(cell.FgColor(cell.ColorRed)),
)
testdraw.MustText(
cvs,
"Ab",
image.Point{2, 1},
draw.TextCellOpts(cell.FgColor(cell.ColorRed)),
)
testcanvas.MustApply(cvs, ft)
return ft
},
},
{ {
desc: "splitting a container removes the widget", desc: "splitting a container removes the widget",
termSize: image.Point{10, 10}, termSize: image.Point{10, 10},

View File

@ -84,16 +84,26 @@ func drawBorder(c *Container) error {
return err return err
} }
var cOpts []cell.Option var cOpts, titleCOpts []cell.Option
if c.focusTracker.isActive(c) { if c.focusTracker.isActive(c) {
cOpts = append(cOpts, cell.FgColor(c.opts.inherited.focusedColor)) cOpts = append(cOpts, cell.FgColor(c.opts.inherited.focusedColor))
} else { if c.opts.inherited.titleFocusedColor != nil {
titleCOpts = append(titleCOpts, cell.FgColor(*c.opts.inherited.titleFocusedColor))
} else {
titleCOpts = cOpts
}
} else {
cOpts = append(cOpts, cell.FgColor(c.opts.inherited.borderColor)) cOpts = append(cOpts, cell.FgColor(c.opts.inherited.borderColor))
} if c.opts.inherited.titleColor != nil {
titleCOpts = append(titleCOpts, cell.FgColor(*c.opts.inherited.titleColor))
} else {
titleCOpts = cOpts
}
}
if err := draw.Border(cvs, ar, if err := draw.Border(cvs, ar,
draw.BorderLineStyle(c.opts.border), draw.BorderLineStyle(c.opts.border),
draw.BorderTitle(c.opts.borderTitle, draw.OverrunModeThreeDot, cOpts...), draw.BorderTitle(c.opts.borderTitle, draw.OverrunModeThreeDot, titleCOpts...),
draw.BorderTitleAlign(c.opts.borderTitleHAlign), draw.BorderTitleAlign(c.opts.borderTitleHAlign),
draw.BorderCellOpts(cOpts...), draw.BorderCellOpts(cOpts...),
); err != nil { ); err != nil {

View File

@ -502,6 +502,44 @@ func TestDrawWidget(t *testing.T) {
return ft return ft
}, },
}, },
{
desc: "draws widget with container border and title with different color and focus color",
termSize: image.Point{9, 5},
container: func(ft *faketerm.Terminal) (*Container, error) {
return New(
ft,
Border(linestyle.Light),
BorderTitle("ab"),
TitleColor(cell.ColorBlue),
// The created container is in focus so we must set the focus color
// in order to see the difference.
TitleFocusedColor(cell.ColorBlue),
BorderTitleAlignLeft(),
PlaceWidget(fakewidget.New(widgetapi.Options{})),
)
},
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
cvs := testcanvas.MustNew(ft.Area())
// Container border.
testdraw.MustBorder(
cvs,
cvs.Area(),
draw.BorderCellOpts(cell.FgColor(cell.ColorYellow)),
draw.BorderTitle(
"ab",
draw.OverrunModeThreeDot,
cell.FgColor(cell.ColorBlue),
),
)
// Fake widget border.
testdraw.MustBorder(cvs, image.Rect(1, 1, 8, 4))
testdraw.MustText(cvs, "(7,3)", image.Point{2, 2})
testcanvas.MustApply(cvs, ft)
return ft
},
},
{ {
desc: "draws widget without container border", desc: "draws widget without container border",
termSize: image.Point{9, 5}, termSize: image.Point{9, 5},

View File

@ -194,6 +194,10 @@ type inherited struct {
borderColor cell.Color borderColor cell.Color
// focusedColor is the color used for the border when focused. // focusedColor is the color used for the border when focused.
focusedColor cell.Color focusedColor cell.Color
// titleColor is the color used for the title.
titleColor *cell.Color
// titleFocusedColor is the color used for the title when focused.
titleFocusedColor *cell.Color
} }
// focusGroups maps focus group numbers that have the same key assigned. // focusGroups maps focus group numbers that have the same key assigned.
@ -749,6 +753,25 @@ func FocusedColor(color cell.Color) Option {
}) })
} }
// TitleColor sets the color of the title around the container.
// This option is inherited to sub containers created by container splits.
func TitleColor(color cell.Color) Option {
return option(func(c *Container) error {
c.opts.inherited.titleColor = &color
return nil
})
}
// TitleFocusedColor sets the color of the container title when it has
// keyboard focus.
// This option is inherited to sub containers created by container splits.
func TitleFocusedColor(color cell.Color) Option {
return option(func(c *Container) error {
c.opts.inherited.titleFocusedColor = &color
return nil
})
}
// splitType identifies how a container is split. // splitType identifies how a container is split.
type splitType int type splitType int