Refactor fixed container feature to `SplitFixed()` which takes one arg

This commit is contained in:
nijynot 2019-05-06 21:42:24 +02:00
parent 7c5232b662
commit 4aa60fe8e7
6 changed files with 44 additions and 35 deletions

View File

@ -172,9 +172,9 @@ func (c *Container) split() (image.Rectangle, image.Rectangle, error) {
return image.ZR, image.ZR, err
}
if c.opts.split == splitTypeVertical {
return area.VSplit(ar, c.opts.splitPercent)
return area.VSplit(ar, c.opts.splitPercent, c.opts.splitFixed)
}
return area.HSplit(ar, c.opts.splitPercent, c.opts.topHeight, c.opts.bottomHeight)
return area.HSplit(ar, c.opts.splitPercent, c.opts.splitFixed)
}
// createFirst creates and returns the first sub container of this container.

View File

@ -127,7 +127,7 @@ func mirror() *fakewidget.Mirror {
// mustHSplit splits the area or panics.
func mustHSplit(ar image.Rectangle, heightPerc int) (top image.Rectangle, bottom image.Rectangle) {
t, b, err := area.HSplit(ar, heightPerc)
t, b, err := area.HSplit(ar, heightPerc, -1)
if err != nil {
panic(err)
}
@ -136,7 +136,7 @@ func mustHSplit(ar image.Rectangle, heightPerc int) (top image.Rectangle, bottom
// mustVSplit splits the area or panics.
func mustVSplit(ar image.Rectangle, widthPerc int) (left image.Rectangle, right image.Rectangle) {
l, r, err := area.VSplit(ar, widthPerc)
l, r, err := area.VSplit(ar, widthPerc, -1)
if err != nil {
panic(err)
}

View File

@ -77,8 +77,7 @@ type options struct {
// split identifies how is this container split.
split splitType
splitPercent int
topHeight int
bottomHeight int
splitFixed int
// widget is the widget in the container.
// A container can have either two sub containers (left and right) or a
@ -169,8 +168,7 @@ func newOptions(parent *options) *options {
hAlign: align.HorizontalCenter,
vAlign: align.VerticalMiddle,
splitPercent: DefaultSplitPercent,
topHeight: -1,
bottomHeight: -1,
splitFixed: -1,
}
if parent != nil {
opts.inherited = parent.inherited
@ -220,16 +218,15 @@ func SplitPercent(p int) SplitOption {
})
}
// FixHeight sets the heights of the top and the bottom containers.
// If an argument is equal to -1, then the height will be set automatically,
// i.e. will fill the rest of the space that is available.
func FixHeight(th int, bh int) SplitOption {
// SplitFixed sets the heights of the top and the bottom containers.
// The first container will be fixed and the second one will fill the rest of the space.
// Allows values greater or equal to zero.
func SplitFixed(cells int) SplitOption {
return splitOption(func(opts *options) error {
if th < -1 || bh < -1 {
return fmt.Errorf("invalid fixed height %d or %d, must be in range %d <= th, bh", th, bh, -1)
if cells < 0 {
return fmt.Errorf("invalid fixed value %d, must be in range %d <= cells", cells, 0)
}
opts.topHeight = th
opts.bottomHeight = bh
opts.splitFixed = cells
return nil
})
}

View File

@ -42,22 +42,21 @@ func FromSize(size image.Point) (image.Rectangle, error) {
// specified percentage of its width. The percentage must be in the range
// 0 <= heightPerc <= 100.
// Can return zero size areas.
func HSplit(area image.Rectangle, heightPerc int, topHeight int, bottomHeight int) (top image.Rectangle, bottom image.Rectangle, err error) {
//
// The fixed value must by in the range -1 <= heightFixed.
// If fixed value is -1 (default value), heightPerc is used instead.
func HSplit(area image.Rectangle, heightPerc int, heightFixed int) (top image.Rectangle, bottom image.Rectangle, err error) {
if min, max := 0, 100; heightPerc < min || heightPerc > max {
return image.ZR, image.ZR, fmt.Errorf("invalid heightPerc %d, must be in range %d <= heightPerc <= %d", heightPerc, min, max)
}
if topHeight < -1 || bottomHeight < -1 {
return image.ZR, image.ZR, fmt.Errorf("invalid fixed height %d or %d, must be in range %d <= topHeight, bottomHeight", topHeight, bottomHeight, -1)
if heightFixed < -1 {
return image.ZR, image.ZR, fmt.Errorf("invalid heightFixed %d, must be in range %d <= heightFixed", heightFixed, -1)
}
if topHeight >= 0 && bottomHeight >= 0 {
top = image.Rect(area.Min.X, area.Min.Y, area.Max.X, area.Min.Y+topHeight)
bottom = image.Rect(area.Min.X, area.Min.Y+topHeight, area.Max.X, area.Min.Y+topHeight+bottomHeight)
} else if topHeight >= 0 {
top = image.Rect(area.Min.X, area.Min.Y, area.Max.X, area.Min.Y+topHeight)
bottom = image.Rect(area.Min.X, area.Min.Y+topHeight, area.Max.X, area.Max.Y)
} else if bottomHeight >= 0 {
top = image.Rect(area.Min.X, area.Min.Y, area.Max.X, area.Max.Y-bottomHeight)
bottom = image.Rect(area.Min.X, area.Max.Y-bottomHeight, area.Max.X, area.Max.Y)
// Prioritize `SplitFixed()` over `SplitPercent()`.
if heightFixed >= 0 {
top = image.Rect(area.Min.X, area.Min.Y, area.Max.X, area.Min.Y+heightFixed)
bottom = image.Rect(area.Min.X, area.Min.Y+heightFixed, area.Max.X, area.Max.Y)
} else {
height := area.Dy() * heightPerc / 100
top = image.Rect(area.Min.X, area.Min.Y, area.Max.X, area.Min.Y+height)
@ -76,16 +75,29 @@ func HSplit(area image.Rectangle, heightPerc int, topHeight int, bottomHeight in
// specified percentage of its width. The percentage must be in the range
// 0 <= widthPerc <= 100.
// Can return zero size areas.
func VSplit(area image.Rectangle, widthPerc int) (left image.Rectangle, right image.Rectangle, err error) {
//
// The fixed value must by in the range -1 <= heightFixed.
// If fixed value is -1 (default value), heightPerc is used instead.
func VSplit(area image.Rectangle, widthPerc int, widthFixed int) (left image.Rectangle, right image.Rectangle, err error) {
if min, max := 0, 100; widthPerc < min || widthPerc > max {
return image.ZR, image.ZR, fmt.Errorf("invalid widthPerc %d, must be in range %d <= widthPerc <= %d", widthPerc, min, max)
}
width := area.Dx() * widthPerc / 100
left = image.Rect(area.Min.X, area.Min.Y, area.Min.X+width, area.Max.Y)
if widthFixed < -1 {
return image.ZR, image.ZR, fmt.Errorf("invalid widthFixed %d, must be in range %d <= widthFixed", widthFixed, -1)
}
// Prioritize `SplitFixed()` over `SplitPercent()`.
if widthFixed >= 0 {
left = image.Rect(area.Min.X, area.Min.Y, area.Min.X+widthFixed, area.Max.Y)
right = image.Rect(area.Min.X+widthFixed, area.Min.Y, area.Max.X, area.Max.Y)
} else {
width := area.Dx() * widthPerc / 100
left = image.Rect(area.Min.X, area.Min.Y, area.Min.X+width, area.Max.Y)
right = image.Rect(area.Min.X+width, area.Min.Y, area.Max.X, area.Max.Y)
}
if left.Dx() == 0 {
left = image.ZR
}
right = image.Rect(area.Min.X+width, area.Min.Y, area.Max.X, area.Max.Y)
if right.Dx() == 0 {
right = image.ZR
}

View File

@ -184,7 +184,7 @@ func TestHSplit(t *testing.T) {
for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) {
gotTop, gotBot, err := HSplit(tc.area, tc.heightPerc)
gotTop, gotBot, err := HSplit(tc.area, tc.heightPerc, -1)
if (err != nil) != tc.wantErr {
t.Errorf("VSplit => unexpected error:%v, wantErr:%v", err, tc.wantErr)
}
@ -265,7 +265,7 @@ func TestVSplit(t *testing.T) {
for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) {
gotLeft, gotRight, err := VSplit(tc.area, tc.widthPerc)
gotLeft, gotRight, err := VSplit(tc.area, tc.widthPerc, -1)
if (err != nil) != tc.wantErr {
t.Errorf("VSplit => unexpected error:%v, wantErr:%v", err, tc.wantErr)
}

View File

@ -330,7 +330,7 @@ func split(cvsAr image.Rectangle, label string, widthPerc *int) (labelAr, textAr
switch {
case widthPerc != nil:
splitP := 100 - *widthPerc
labelAr, textAr, err := area.VSplit(cvsAr, splitP)
labelAr, textAr, err := area.VSplit(cvsAr, splitP, -1)
if err != nil {
return image.ZR, image.ZR, err
}