5 Commits

2 changed files with 59 additions and 21 deletions

38
box.go
View File

@@ -117,14 +117,34 @@ func (this *box) SetColor (c color.Color) {
} }
func (this *box) SetTexture (texture canvas.Texture) { func (this *box) SetTexture (texture canvas.Texture) {
if this.texture == texture { return }
this.texture = xcanvas.AssertTexture(texture) this.texture = xcanvas.AssertTexture(texture)
this.invalidateDraw() this.invalidateDraw()
} }
func (this *box) SetBorder (border ...tomo.Border) { func (this *box) SetBorder (borders ...tomo.Border) {
this.border = border previousBorderSum := this.borderSum()
this.invalidateLayout() previousBorders := this.border
this.invalidateMinimum() this.border = borders
// only invalidate the layout if the border is sized differently
if this.borderSum() != previousBorderSum {
this.invalidateLayout()
this.invalidateMinimum()
return
}
// if the border takes up the same amount of space, only invalidate the
// drawing if it looks different
for index, newBorder := range this.border {
different :=
index >= len(previousBorders) ||
newBorder != previousBorders[index]
if different {
this.invalidateDraw()
return
}
}
} }
func (this *box) SetMinimumSize (size image.Point) { func (this *box) SetMinimumSize (size image.Point) {
@@ -285,7 +305,7 @@ func (this *box) Draw (can canvas.Canvas) {
if this.transparent() && this.parent != nil { if this.transparent() && this.parent != nil {
this.parent.drawBackgroundPart(can) this.parent.drawBackgroundPart(can)
} }
pen.Rectangle(can.Bounds()) pen.Rectangle(this.Bounds())
} }
func (this *box) drawBorders (can canvas.Canvas) { func (this *box) drawBorders (can canvas.Canvas) {
@@ -356,7 +376,11 @@ func (this *box) doMinimumSize () {
} }
} }
// var drawcnt int
func (this *box) doDraw () { func (this *box) doDraw () {
// println("DRAW", drawcnt)
// drawcnt ++
if this.canvas == nil { return } if this.canvas == nil { return }
if this.drawer != nil { if this.drawer != nil {
this.drawBorders(this.canvas) this.drawBorders(this.canvas)
@@ -364,7 +388,11 @@ func (this *box) doDraw () {
} }
} }
// var laycnt int
func (this *box) doLayout () { func (this *box) doLayout () {
// println("LAYOUT", laycnt)
// laycnt ++
this.innerClippingBounds = this.borderSum().Apply(this.bounds) this.innerClippingBounds = this.borderSum().Apply(this.bounds)
if this.parent == nil { this.canvas = nil; return } if this.parent == nil { this.canvas = nil; return }
parentCanvas := this.parent.canvas() parentCanvas := this.parent.canvas()

View File

@@ -31,11 +31,13 @@ func (backend *Backend) NewContainerBox() tomo.ContainerBox {
} }
func (this *containerBox) SetColor (c color.Color) { func (this *containerBox) SetColor (c color.Color) {
if this.color == c { return }
this.box.SetColor(c) this.box.SetColor(c)
this.invalidateTransparentChildren() this.invalidateTransparentChildren()
} }
func (this *containerBox) SetTexture (texture canvas.Texture) { func (this *containerBox) SetTexture (texture canvas.Texture) {
if this.texture == texture { return }
this.box.SetTexture(texture) this.box.SetTexture(texture)
this.invalidateTransparentChildren() this.invalidateTransparentChildren()
} }
@@ -225,12 +227,6 @@ func (this *containerBox) notifyMinimumSizeChange (child anyBox) {
} }
} }
func (this *containerBox) boundedLayoutHints () tomo.LayoutHints {
hints := this.layoutHints()
hints.Bounds = this.ContentBounds().Add(this.InnerBounds().Min)
return hints
}
func (this *containerBox) layoutHints () tomo.LayoutHints { func (this *containerBox) layoutHints () tomo.LayoutHints {
return tomo.LayoutHints { return tomo.LayoutHints {
OverflowX: this.hOverflow, OverflowX: this.hOverflow,
@@ -245,7 +241,7 @@ func (this *containerBox) contentMinimum () image.Point {
minimum := this.box.contentMinimum() minimum := this.box.contentMinimum()
if this.layout != nil { if this.layout != nil {
layoutMinimum := this.layout.MinimumSize ( layoutMinimum := this.layout.MinimumSize (
this.boundedLayoutHints(), this.layoutHints(),
this.children) this.children)
if this.hOverflow { layoutMinimum.X = 0 } if this.hOverflow { layoutMinimum.X = 0 }
if this.vOverflow { layoutMinimum.Y = 0 } if this.vOverflow { layoutMinimum.Y = 0 }
@@ -258,8 +254,8 @@ func (this *containerBox) doLayout () {
this.box.doLayout() this.box.doLayout()
previousContentBounds := this.contentBounds previousContentBounds := this.contentBounds
// by default, use innerBounds for contentBounds. if a direction // by default, use innerBounds (translated to 0, 0) for contentBounds.
// overflows, use the layout's minimum size for it. // if a direction overflows, use the layout's minimum size for it.
var minimum image.Point var minimum image.Point
if this.layout != nil { if this.layout != nil {
minimum = this.layout.MinimumSize ( minimum = this.layout.MinimumSize (
@@ -267,19 +263,33 @@ func (this *containerBox) doLayout () {
this.children) this.children)
} }
innerBounds := this.InnerBounds() innerBounds := this.InnerBounds()
this.contentBounds = innerBounds this.contentBounds = innerBounds.Sub(innerBounds.Min)
if this.hOverflow { this.contentBounds.Max.X = this.contentBounds.Min.X + minimum.X } if this.hOverflow { this.contentBounds.Max.X = this.contentBounds.Min.X + minimum.X }
if this.vOverflow { this.contentBounds.Max.Y = this.contentBounds.Min.Y + minimum.Y } if this.vOverflow { this.contentBounds.Max.Y = this.contentBounds.Min.Y + minimum.Y }
// offset the content bounds by the scroll so children can be positioned
// accordingly.
this.constrainScroll()
this.contentBounds = this.contentBounds.Add(this.scroll).Sub(innerBounds.Min)
// arrange children // arrange children
if this.layout != nil { if this.layout != nil {
this.layout.Arrange(this.boundedLayoutHints(), this.children) layoutHints := this.layoutHints()
layoutHints.Bounds = this.contentBounds
this.layout.Arrange(layoutHints, this.children)
} }
// build an accurate contentBounds by unioning the bounds of all child
// boxes
this.contentBounds = image.Rectangle { }
for _, box := range this.children {
bounds := box.Bounds()
this.contentBounds = this.contentBounds.Union(bounds)
}
// constrain the scroll
this.constrainScroll()
// offset children and contentBounds by scroll
for _, box := range this.children {
box.SetBounds(box.Bounds().Add(this.scroll).Add(innerBounds.Min))
}
this.contentBounds = this.contentBounds.Add(this.scroll)
if previousContentBounds != this.contentBounds { if previousContentBounds != this.contentBounds {
this.on.contentBoundsChange.Broadcast() this.on.contentBoundsChange.Broadcast()