mirror of https://github.com/mum4k/termdash.git
parent
ea2e0b7855
commit
d31b767d5d
|
@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
executed.
|
||||
- The SegmentDisplay widget now has a method that returns the observed character
|
||||
capacity the last time Draw was called.
|
||||
- The grid.Builder API now allows users to specify options for intermediate
|
||||
containers, i.e. containers that don't have widgets, but represent rows and
|
||||
columns.
|
||||
|
||||
#### Breaking API changes
|
||||
|
||||
|
|
|
@ -109,18 +109,19 @@ func build(elems []Element, parentHeightPerc, parentWidthPerc int) []container.O
|
|||
|
||||
switch e := elem.(type) {
|
||||
case *row:
|
||||
|
||||
if len(elems) > 0 {
|
||||
perc := innerPerc(e.heightPerc, parentHeightPerc)
|
||||
childHeightPerc := parentHeightPerc - e.heightPerc
|
||||
return []container.Option{
|
||||
container.SplitHorizontal(
|
||||
container.Top(build(e.subElem, 100, parentWidthPerc)...),
|
||||
container.Top(append(e.cOpts, build(e.subElem, 100, parentWidthPerc)...)...),
|
||||
container.Bottom(build(elems, childHeightPerc, parentWidthPerc)...),
|
||||
container.SplitPercent(perc),
|
||||
),
|
||||
}
|
||||
}
|
||||
return build(e.subElem, 100, parentWidthPerc)
|
||||
return append(e.cOpts, build(e.subElem, 100, parentWidthPerc)...)
|
||||
|
||||
case *col:
|
||||
if len(elems) > 0 {
|
||||
|
@ -128,13 +129,13 @@ func build(elems []Element, parentHeightPerc, parentWidthPerc int) []container.O
|
|||
childWidthPerc := parentWidthPerc - e.widthPerc
|
||||
return []container.Option{
|
||||
container.SplitVertical(
|
||||
container.Left(build(e.subElem, parentHeightPerc, 100)...),
|
||||
container.Left(append(e.cOpts, build(e.subElem, parentHeightPerc, 100)...)...),
|
||||
container.Right(build(elems, parentHeightPerc, childWidthPerc)...),
|
||||
container.SplitPercent(perc),
|
||||
),
|
||||
}
|
||||
}
|
||||
return build(e.subElem, parentHeightPerc, 100)
|
||||
return append(e.cOpts, build(e.subElem, parentHeightPerc, 100)...)
|
||||
|
||||
case *widget:
|
||||
opts := e.cOpts
|
||||
|
@ -186,6 +187,9 @@ type row struct {
|
|||
|
||||
// subElem are the sub Rows or Columns or a single widget.
|
||||
subElem []Element
|
||||
|
||||
// cOpts are the options for the row's container.
|
||||
cOpts []container.Option
|
||||
}
|
||||
|
||||
// isElement implements Element.isElement.
|
||||
|
@ -204,6 +208,9 @@ type col struct {
|
|||
|
||||
// subElem are the sub Rows or Columns or a single widget.
|
||||
subElem []Element
|
||||
|
||||
// cOpts are the options for the column's container.
|
||||
cOpts []container.Option
|
||||
}
|
||||
|
||||
// isElement implements Element.isElement.
|
||||
|
@ -244,6 +251,16 @@ func RowHeightPerc(heightPerc int, subElements ...Element) Element {
|
|||
}
|
||||
}
|
||||
|
||||
// RowHeightPercWithOpts is like RowHeightPerc, but also allows to apply
|
||||
// additional options to the container that represents the row.
|
||||
func RowHeightPercWithOpts(heightPerc int, cOpts []container.Option, subElements ...Element) Element {
|
||||
return &row{
|
||||
heightPerc: heightPerc,
|
||||
subElem: subElements,
|
||||
cOpts: cOpts,
|
||||
}
|
||||
}
|
||||
|
||||
// ColWidthPerc creates a column of the specified width.
|
||||
// The width is supplied as width percentage of the parent element.
|
||||
// The sum of all widths at the same level cannot be larger than 100%. If it
|
||||
|
@ -257,6 +274,16 @@ func ColWidthPerc(widthPerc int, subElements ...Element) Element {
|
|||
}
|
||||
}
|
||||
|
||||
// ColWidthPercWithOpts is like ColWidthPerc, but also allows to apply
|
||||
// additional options to the container that represents the column.
|
||||
func ColWidthPercWithOpts(widthPerc int, cOpts []container.Option, subElements ...Element) Element {
|
||||
return &col{
|
||||
widthPerc: widthPerc,
|
||||
subElem: subElements,
|
||||
cOpts: cOpts,
|
||||
}
|
||||
}
|
||||
|
||||
// Widget adds a widget into the Row or Column.
|
||||
// The options will be applied to the container that directly holds this
|
||||
// widget.
|
||||
|
|
|
@ -389,6 +389,45 @@ func TestBuilder(t *testing.T) {
|
|||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "two equal rows with options",
|
||||
termSize: image.Point{10, 10},
|
||||
builder: func() *Builder {
|
||||
b := New()
|
||||
b.Add(RowHeightPercWithOpts(
|
||||
50,
|
||||
[]container.Option{
|
||||
container.Border(linestyle.Double),
|
||||
},
|
||||
Widget(mirror()),
|
||||
))
|
||||
b.Add(RowHeightPercWithOpts(
|
||||
50,
|
||||
[]container.Option{
|
||||
container.Border(linestyle.Double),
|
||||
},
|
||||
Widget(mirror()),
|
||||
))
|
||||
return b
|
||||
}(),
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
|
||||
top, bot := mustHSplit(ft.Area(), 50)
|
||||
topCvs := testcanvas.MustNew(top)
|
||||
botCvs := testcanvas.MustNew(bot)
|
||||
testdraw.MustBorder(topCvs, topCvs.Area(), draw.BorderLineStyle(linestyle.Double))
|
||||
testdraw.MustBorder(botCvs, botCvs.Area(), draw.BorderLineStyle(linestyle.Double))
|
||||
testcanvas.MustApply(topCvs, ft)
|
||||
testcanvas.MustApply(botCvs, ft)
|
||||
|
||||
topWidget := testcanvas.MustNew(area.ExcludeBorder(top))
|
||||
botWidget := testcanvas.MustNew(area.ExcludeBorder(bot))
|
||||
fakewidget.MustDraw(ft, topWidget, &widgetapi.Meta{}, widgetapi.Options{})
|
||||
fakewidget.MustDraw(ft, botWidget, &widgetapi.Meta{}, widgetapi.Options{})
|
||||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "two unequal rows",
|
||||
termSize: image.Point{10, 10},
|
||||
|
@ -406,6 +445,45 @@ func TestBuilder(t *testing.T) {
|
|||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "two equal columns with options",
|
||||
termSize: image.Point{20, 10},
|
||||
builder: func() *Builder {
|
||||
b := New()
|
||||
b.Add(ColWidthPercWithOpts(
|
||||
50,
|
||||
[]container.Option{
|
||||
container.Border(linestyle.Double),
|
||||
},
|
||||
Widget(mirror()),
|
||||
))
|
||||
b.Add(ColWidthPercWithOpts(
|
||||
50,
|
||||
[]container.Option{
|
||||
container.Border(linestyle.Double),
|
||||
},
|
||||
Widget(mirror()),
|
||||
))
|
||||
return b
|
||||
}(),
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
|
||||
left, right := mustVSplit(ft.Area(), 50)
|
||||
leftCvs := testcanvas.MustNew(left)
|
||||
rightCvs := testcanvas.MustNew(right)
|
||||
testdraw.MustBorder(leftCvs, leftCvs.Area(), draw.BorderLineStyle(linestyle.Double))
|
||||
testdraw.MustBorder(rightCvs, rightCvs.Area(), draw.BorderLineStyle(linestyle.Double))
|
||||
testcanvas.MustApply(leftCvs, ft)
|
||||
testcanvas.MustApply(rightCvs, ft)
|
||||
|
||||
leftWidget := testcanvas.MustNew(area.ExcludeBorder(left))
|
||||
rightWidget := testcanvas.MustNew(area.ExcludeBorder(right))
|
||||
fakewidget.MustDraw(ft, leftWidget, &widgetapi.Meta{}, widgetapi.Options{})
|
||||
fakewidget.MustDraw(ft, rightWidget, &widgetapi.Meta{}, widgetapi.Options{})
|
||||
return ft
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "two equal columns",
|
||||
termSize: image.Point{20, 10},
|
||||
|
|
|
@ -166,16 +166,18 @@ func gridLayout(w *widgets, lt layoutType) ([]container.Option, error) {
|
|||
container.BorderTitle("A rolling text"),
|
||||
),
|
||||
),
|
||||
grid.RowHeightPerc(50,
|
||||
grid.Widget(w.spGreen,
|
||||
container.Border(linestyle.Light),
|
||||
container.BorderTitle("Green SparkLine"),
|
||||
grid.ColWidthPerc(50,
|
||||
grid.RowHeightPerc(50,
|
||||
grid.Widget(w.spGreen,
|
||||
container.Border(linestyle.Light),
|
||||
container.BorderTitle("Green SparkLine"),
|
||||
),
|
||||
),
|
||||
),
|
||||
grid.RowHeightPerc(50,
|
||||
grid.Widget(w.spRed,
|
||||
container.Border(linestyle.Light),
|
||||
container.BorderTitle("Red SparkLine"),
|
||||
grid.RowHeightPerc(50,
|
||||
grid.Widget(w.spRed,
|
||||
container.Border(linestyle.Light),
|
||||
container.BorderTitle("Red SparkLine"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue