Fixed transparent boxes not redrawing sometimes

This commit is contained in:
Sasha Koshka 2023-09-07 18:22:04 -04:00
parent 0c0b8ae475
commit db2ed06daf
2 changed files with 36 additions and 13 deletions

View File

@ -1,6 +1,7 @@
package x package x
import "image" import "image"
import "image/color"
import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/tomo/event" import "git.tebibyte.media/tomo/tomo/event"
import "git.tebibyte.media/tomo/tomo/canvas" import "git.tebibyte.media/tomo/tomo/canvas"
@ -12,7 +13,7 @@ type containerBox struct {
hAlign, vAlign tomo.Align hAlign, vAlign tomo.Align
contentBounds image.Rectangle contentBounds image.Rectangle
scroll image.Point scroll image.Point
gap image.Point gap image.Point
children []tomo.Box children []tomo.Box
layout tomo.Layout layout tomo.Layout
@ -29,6 +30,16 @@ func (backend *Backend) NewContainerBox() tomo.ContainerBox {
return this return this
} }
func (this *containerBox) SetColor (c color.Color) {
this.box.SetColor(c)
this.invalidateTransparentChildren()
}
func (this *containerBox) SetTexture (texture canvas.Texture) {
this.box.SetTexture(texture)
this.invalidateTransparentChildren()
}
func (this *containerBox) SetOverflow (horizontal, vertical bool) { func (this *containerBox) SetOverflow (horizontal, vertical bool) {
if this.hOverflow == horizontal && this.vOverflow == vertical { return } if this.hOverflow == horizontal && this.vOverflow == vertical { return }
this.hOverflow = horizontal this.hOverflow = horizontal
@ -71,7 +82,7 @@ func (this *containerBox) SetGap (gap image.Point) {
func (this *containerBox) Add (child tomo.Object) { func (this *containerBox) Add (child tomo.Object) {
box := assertAnyBox(child.GetBox()) box := assertAnyBox(child.GetBox())
if indexOf(this.children, tomo.Box(box)) > -1 { return } if indexOf(this.children, tomo.Box(box)) > -1 { return }
box.setParent(this) box.setParent(this)
box.flushActionQueue() box.flushActionQueue()
this.children = append(this.children, box) this.children = append(this.children, box)
@ -83,7 +94,7 @@ func (this *containerBox) Delete (child tomo.Object) {
box := assertAnyBox(child.GetBox()) box := assertAnyBox(child.GetBox())
index := indexOf(this.children, tomo.Box(box)) index := indexOf(this.children, tomo.Box(box))
if index < 0 { return } if index < 0 { return }
box.setParent(nil) box.setParent(nil)
this.children = remove(this.children, index) this.children = remove(this.children, index)
this.invalidateLayout() this.invalidateLayout()
@ -97,7 +108,7 @@ func (this *containerBox) Insert (child, before tomo.Object) {
beforeBox := assertAnyBox(before.GetBox()) beforeBox := assertAnyBox(before.GetBox())
index := indexOf(this.children, tomo.Box(beforeBox)) index := indexOf(this.children, tomo.Box(beforeBox))
if index < 0 { return } if index < 0 { return }
box.setParent(this) box.setParent(this)
this.children = insert(this.children, index, tomo.Box(box)) this.children = insert(this.children, index, tomo.Box(box))
this.invalidateLayout() this.invalidateLayout()
@ -155,13 +166,24 @@ func (this *containerBox) drawBackgroundPart (can canvas.Canvas) {
pen := can.Pen() pen := can.Pen()
pen.Fill(this.color) pen.Fill(this.color)
pen.Texture(this.texture) pen.Texture(this.texture)
if this.transparent() && this.parent != nil { if this.transparent() && this.parent != nil {
this.parent.drawBackgroundPart(can) this.parent.drawBackgroundPart(can)
} }
pen.Rectangle(this.innerClippingBounds) pen.Rectangle(this.innerClippingBounds)
} }
func (this *containerBox) invalidateTransparentChildren () {
window := this.window()
if this.window == nil { return }
for _, box := range this.children {
box := assertAnyBox(box)
if box.transparent() {
window.invalidateDraw(box)
}
}
}
func (this *containerBox) flushActionQueue () { func (this *containerBox) flushActionQueue () {
for _, box := range this.children { for _, box := range this.children {
box.(anyBox).flushActionQueue() box.(anyBox).flushActionQueue()
@ -251,11 +273,11 @@ func (this *containerBox) propagate (callback func (anyBox) bool) bool {
func (this *containerBox) propagateAlt (callback func (anyBox) bool) bool { func (this *containerBox) propagateAlt (callback func (anyBox) bool) bool {
if !callback(this) { return false} if !callback(this) { return false}
for _, box := range this.children { for _, box := range this.children {
box := box.(anyBox) box := box.(anyBox)
if !box.propagateAlt(callback) { return false } if !box.propagateAlt(callback) { return false }
} }
return true return true
} }

View File

@ -42,7 +42,7 @@ type parent interface {
type anyBox interface { type anyBox interface {
tomo.Box tomo.Box
canvas.Drawer canvas.Drawer
doDraw () doDraw ()
doLayout () doLayout ()
doMinimumSize () doMinimumSize ()
@ -52,6 +52,7 @@ type anyBox interface {
recursiveRedo () recursiveRedo ()
canBeFocused () bool canBeFocused () bool
boxUnder (image.Point) anyBox boxUnder (image.Point) anyBox
transparent () bool
propagate (func (anyBox) bool) bool propagate (func (anyBox) bool) bool
propagateAlt (func (anyBox) bool) bool propagateAlt (func (anyBox) bool) bool
@ -122,10 +123,10 @@ func (window *window) invalidateLayout (box anyBox) {
func (window *window) focus (box anyBox) { func (window *window) focus (box anyBox) {
if window.focused == box { return } if window.focused == box { return }
previous := window.focused previous := window.focused
window.focused = box window.focused = box
if previous != nil { if previous != nil {
previous.handleFocusLeave() previous.handleFocusLeave()
} }
@ -136,10 +137,10 @@ func (window *window) focus (box anyBox) {
func (window *window) hover (box anyBox) { func (window *window) hover (box anyBox) {
if window.hovered == box { return } if window.hovered == box { return }
previous := window.hovered previous := window.hovered
window.hovered = box window.hovered = box
if previous != nil { if previous != nil {
previous.handleMouseLeave() previous.handleMouseLeave()
} }
@ -213,7 +214,7 @@ func (window *window) afterEvent () {
childBounds = childBounds.Sub(childBounds.Min) childBounds = childBounds.Sub(childBounds.Min)
window.root.SetBounds(childBounds) window.root.SetBounds(childBounds)
// full relayout/redraw // full relayout/redraw
if window.root != nil { if window.root != nil {
window.root.recursiveRedo() window.root.recursiveRedo()
} }