zntg/ui/dockpanel.go

153 lines
3.4 KiB
Go
Raw Normal View History

2018-08-03 06:46:10 +00:00
package ui
import (
"opslag.de/schobers/geom"
)
type DockPanel interface {
Container
Append(o Dock, children ...Control) error
AppendCreate(ctx Context, o Dock, children ...Control) error
}
type Dock int
const (
DockLeft Dock = iota
DockTop
DockRight
DockBottom
)
type dockPanel struct {
ContainerBase
docks []Dock
}
func NewDockPanel(parent Container) DockPanel {
return &dockPanel{ContainerBase: ContainerBase{parent: parent}}
}
func NewDockPanelContent(parent Container, d Dock, controls ...Control) DockPanel {
var p = NewDockPanel(parent)
for _, c := range controls {
p.Append(d, c)
}
return p
}
2018-08-03 06:46:10 +00:00
func (p *dockPanel) Append(d Dock, children ...Control) error {
for _, child := range children {
p.ContainerBase.Append(child)
p.docks = append(p.docks, d)
}
return nil
}
func (p *dockPanel) AppendCreate(ctx Context, d Dock, children ...Control) error {
for _, child := range children {
err := p.ContainerBase.AppendCreate(ctx, child)
if nil != err {
return err
}
p.docks = append(p.docks, d)
}
return nil
}
2018-09-23 07:42:23 +00:00
func (p *dockPanel) DesiredSize(ctx Context) geom.PointF32 {
var width, height float32 = 0, 0
2018-08-03 06:46:10 +00:00
for i, child := range p.children {
var d = p.docks[i]
var desired = child.DesiredSize(ctx)
switch {
case d == DockLeft || d == DockRight:
2018-09-23 07:42:23 +00:00
if !geom.IsNaN32(width) {
if geom.IsNaN32(desired.X) {
2018-08-03 06:46:10 +00:00
width = desired.X
} else {
width += desired.X
}
}
2018-09-23 07:42:23 +00:00
if !geom.IsNaN32(desired.Y) {
height = geom.Max32(height, desired.Y)
2018-08-03 06:46:10 +00:00
}
case d == DockTop || d == DockBottom:
2018-09-23 07:42:23 +00:00
if !geom.IsNaN32(height) {
if geom.IsNaN32(desired.Y) {
2018-08-03 06:46:10 +00:00
height = desired.Y
} else {
height += desired.Y
}
}
2018-09-23 07:42:23 +00:00
if !geom.IsNaN32(desired.X) {
width = geom.Max32(width, desired.X)
2018-08-03 06:46:10 +00:00
}
}
}
2018-09-23 07:42:23 +00:00
return geom.PtF32(width, height)
2018-08-03 06:46:10 +00:00
}
2018-09-23 07:42:23 +00:00
func (p *dockPanel) arrangeChildren(ctx Context) []geom.RectangleF32 {
2018-08-03 06:46:10 +00:00
var n = len(p.children)
2018-09-23 07:42:23 +00:00
var rects = make([]geom.RectangleF32, n)
2018-08-03 06:46:10 +00:00
var rem = p.Bounds
var last = n - 1
for i, child := range p.children {
if last == i {
rects[i] = rem
} else {
var d = p.docks[i]
var desired = child.DesiredSize(ctx)
2018-09-23 07:42:23 +00:00
var width, height, top, left float32
2018-08-03 06:46:10 +00:00
switch {
case d == DockLeft || d == DockRight:
width = rem.Dx()
2018-09-23 07:42:23 +00:00
if !geom.IsNaN32(desired.X) {
width = geom.Min32(desired.X, width)
2018-08-03 06:46:10 +00:00
}
if d == DockLeft {
left = rem.Min.X
} else {
left = rem.Max.X - width
}
top = rem.Min.Y
height = rem.Dy()
case d == DockTop || d == DockBottom:
height = rem.Dy()
2018-09-23 07:42:23 +00:00
if !geom.IsNaN32(desired.Y) {
height = geom.Min32(desired.Y, height)
2018-08-03 06:46:10 +00:00
}
if d == DockTop {
top = rem.Min.Y
} else {
top = rem.Max.Y - height
}
left = rem.Min.X
width = rem.Dx()
}
2018-09-23 07:42:23 +00:00
rects[i] = geom.RectF32(left, top, left+width, top+height)
2018-08-03 06:46:10 +00:00
switch d {
case DockLeft:
2018-09-23 07:42:23 +00:00
rem = geom.RectF32(rem.Min.X+width, rem.Min.Y, rem.Max.X, rem.Max.Y)
2018-08-03 06:46:10 +00:00
case DockTop:
2018-09-23 07:42:23 +00:00
rem = geom.RectF32(rem.Min.X, rem.Min.Y+height, rem.Max.X, rem.Max.Y)
2018-08-03 06:46:10 +00:00
case DockRight:
2018-09-23 07:42:23 +00:00
rem = geom.RectF32(rem.Min.X, rem.Min.Y, rem.Max.X-width, rem.Max.Y)
2018-08-03 06:46:10 +00:00
case DockBottom:
2018-09-23 07:42:23 +00:00
rem = geom.RectF32(rem.Min.X, rem.Min.Y, rem.Max.X, rem.Max.Y-height)
2018-08-03 06:46:10 +00:00
}
}
}
return rects
}
2018-09-23 07:42:23 +00:00
func (p *dockPanel) Arrange(ctx Context, rect geom.RectangleF32) {
2018-08-03 06:46:10 +00:00
p.ContainerBase.SetRect(rect)
var rects = p.arrangeChildren(ctx)
for i, child := range p.children {
Arrange(ctx, child, rects[i])
}
}