diff --git a/elements/basic/button.go b/elements/basic/button.go index 62e39c2..55e0c15 100644 --- a/elements/basic/button.go +++ b/elements/basic/button.go @@ -25,7 +25,7 @@ type Button struct { // NewButton creates a new button with the specified label text. func NewButton (text string) (element *Button) { element = &Button { } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.draw) element.FocusableCore, element.focusableControl = core.NewFocusableCore (func () { if element.core.HasImage () { @@ -38,11 +38,6 @@ func NewButton (text string) (element *Button) { return } -func (element *Button) Resize (width, height int) { - element.core.AllocateCanvas(width, height) - element.draw() -} - func (element *Button) HandleMouseDown (x, y int, button tomo.Button) { if !element.Enabled() { return } if !element.Focused() { element.Focus() } diff --git a/elements/basic/checkbox.go b/elements/basic/checkbox.go index 115b79a..c3bbae9 100644 --- a/elements/basic/checkbox.go +++ b/elements/basic/checkbox.go @@ -26,7 +26,7 @@ type Checkbox struct { // NewCheckbox creates a new cbeckbox with the specified label text. func NewCheckbox (text string, checked bool) (element *Checkbox) { element = &Checkbox { checked: checked } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.draw) element.FocusableCore, element.focusableControl = core.NewFocusableCore (func () { if element.core.HasImage () { @@ -39,12 +39,6 @@ func NewCheckbox (text string, checked bool) (element *Checkbox) { return } -// Resize changes this element's size. -func (element *Checkbox) Resize (width, height int) { - element.core.AllocateCanvas(width, height) - element.draw() -} - func (element *Checkbox) HandleMouseDown (x, y int, button tomo.Button) { if !element.Enabled() { return } element.Focus() diff --git a/elements/basic/container.go b/elements/basic/container.go index a223e70..822f282 100644 --- a/elements/basic/container.go +++ b/elements/basic/container.go @@ -30,7 +30,7 @@ type Container struct { // NewContainer creates a new container. func NewContainer (layout tomo.Layout) (element *Container) { element = &Container { } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.redoAll) element.SetLayout(layout) return } @@ -39,8 +39,7 @@ func NewContainer (layout tomo.Layout) (element *Container) { func (element *Container) SetLayout (layout tomo.Layout) { element.layout = layout if element.core.HasImage() { - element.recalculate() - element.draw() + element.redoAll() element.core.DamageAll() } } @@ -51,7 +50,7 @@ func (element *Container) SetLayout (layout tomo.Layout) { func (element *Container) Adopt (child tomo.Element, expand bool) { // set event handlers child.OnDamage (func (region tomo.Canvas) { - element.drawChildRegion(child, region) + element.core.DamageRegion(region.Bounds()) }) child.OnMinimumSizeChange(element.updateMinimumSize) if child0, ok := child.(tomo.Flexible); ok { @@ -78,8 +77,7 @@ func (element *Container) Adopt (child tomo.Element, expand bool) { element.updateMinimumSize() element.reflectChildProperties() if element.core.HasImage() && !element.warping { - element.recalculate() - element.draw() + element.redoAll() element.core.DamageAll() } } @@ -101,8 +99,7 @@ func (element *Container) Warp (callback func ()) { // and redraw every time, because although that is the most likely use // case, it is not the only one. if element.core.HasImage() { - element.recalculate() - element.draw() + element.redoAll() element.core.DamageAll() } } @@ -123,13 +120,13 @@ func (element *Container) Disown (child tomo.Element) { element.updateMinimumSize() element.reflectChildProperties() if element.core.HasImage() && !element.warping { - element.recalculate() - element.draw() + element.redoAll() element.core.DamageAll() } } func (element *Container) clearChildEventHandlers (child tomo.Element) { + child.DrawTo(nil) child.OnDamage(nil) child.OnMinimumSizeChange(nil) if child0, ok := child.(tomo.Focusable); ok { @@ -151,8 +148,7 @@ func (element *Container) DisownAll () { element.updateMinimumSize() element.reflectChildProperties() if element.core.HasImage() && !element.warping { - element.recalculate() - element.draw() + element.redoAll() element.core.DamageAll() } } @@ -182,7 +178,7 @@ func (element *Container) Child (index int) (child tomo.Element) { // there are no children at the coordinates, this method will return nil. func (element *Container) ChildAt (point image.Point) (child tomo.Element) { for _, entry := range element.children { - if point.In(entry.Bounds().Add(entry.Position)) { + if point.In(entry.Bounds) { child = entry.Element } } @@ -192,7 +188,7 @@ func (element *Container) ChildAt (point image.Point) (child tomo.Element) { func (element *Container) childPosition (child tomo.Element) (position image.Point) { for _, entry := range element.children { if entry.Element == child { - position = entry.Position + position = entry.Bounds.Min break } } @@ -200,10 +196,21 @@ func (element *Container) childPosition (child tomo.Element) (position image.Poi return } -func (element *Container) Resize (width, height int) { - element.core.AllocateCanvas(width, height) +func (element *Container) redoAll () { + // do a layout element.recalculate() - element.draw() + + // draw a background + bounds := element.core.Bounds() + pattern, _ := theme.BackgroundPattern (theme.PatternState { + Case: containerCase, + }) + artist.FillRectangle(element.core, pattern, bounds) + + // resize all elements, having them draw onto us + for _, entry := range element.children { + entry.DrawTo(tomo.Cut(element, entry.Bounds)) + } } func (element *Container) HandleMouseDown (x, y int, button tomo.Button) { @@ -471,28 +478,3 @@ func (element *Container) recalculate () { bounds := element.Bounds() element.layout.Arrange(element.children, bounds.Dx(), bounds.Dy()) } - -func (element *Container) draw () { - bounds := element.core.Bounds() - - pattern, _ := theme.BackgroundPattern (theme.PatternState { - Case: containerCase, - }) - artist.FillRectangle(element.core, pattern, bounds) - - for _, entry := range element.children { - artist.Paste(element.core, entry, entry.Position) - } -} - -func (element *Container) drawChildRegion (child tomo.Element, region tomo.Canvas) { - if element.warping { return } - for _, entry := range element.children { - if entry.Element == child { - artist.Paste(element.core, region, entry.Position) - element.core.DamageRegion ( - region.Bounds().Add(entry.Position)) - break - } - } -} diff --git a/elements/basic/label.go b/elements/basic/label.go index d5a9e5d..70c5a21 100644 --- a/elements/basic/label.go +++ b/elements/basic/label.go @@ -23,7 +23,7 @@ type Label struct { // wrapped. func NewLabel (text string, wrap bool) (element *Label) { element = &Label { } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.handleResize) face := theme.FontFaceRegular() element.drawer.SetFace(face) element.SetWrap(wrap) @@ -31,12 +31,11 @@ func NewLabel (text string, wrap bool) (element *Label) { return } -// Resize resizes the label and re-wraps the text if wrapping is enabled. -func (element *Label) Resize (width, height int) { - element.core.AllocateCanvas(width, height) +func (element *Label) handleResize () { + bounds := element.Bounds() if element.wrap { - element.drawer.SetMaxWidth(width) - element.drawer.SetMaxHeight(height) + element.drawer.SetMaxWidth(bounds.Dx()) + element.drawer.SetMaxHeight(bounds.Dy()) } element.draw() return diff --git a/elements/basic/list.go b/elements/basic/list.go index a871c94..aebdd67 100644 --- a/elements/basic/list.go +++ b/elements/basic/list.go @@ -33,7 +33,7 @@ type List struct { // NewList creates a new list element with the specified entries. func NewList (entries ...ListEntry) (element *List) { element = &List { selectedEntry: -1 } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.handleResize) element.FocusableCore, element.focusableControl = core.NewFocusableCore (func () { if element.core.HasImage () { @@ -51,10 +51,7 @@ func NewList (entries ...ListEntry) (element *List) { return } -// Resize changes the element's size. -func (element *List) Resize (width, height int) { - element.core.AllocateCanvas(width, height) - +func (element *List) handleResize () { for index, entry := range element.entries { element.entries[index] = element.resizeEntryToFit(entry) } diff --git a/elements/basic/progressbar.go b/elements/basic/progressbar.go index 717320d..24e3307 100644 --- a/elements/basic/progressbar.go +++ b/elements/basic/progressbar.go @@ -16,18 +16,11 @@ type ProgressBar struct { // level. func NewProgressBar (progress float64) (element *ProgressBar) { element = &ProgressBar { progress: progress } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.draw) element.core.SetMinimumSize(theme.Padding() * 2, theme.Padding() * 2) return } -// Resize resizes the progress bar. -func (element *ProgressBar) Resize (width, height int) { - element.core.AllocateCanvas(width, height) - element.draw() - return -} - // SetProgress sets the progress level of the bar. func (element *ProgressBar) SetProgress (progress float64) { if progress == element.progress { return } diff --git a/elements/basic/scrollcontainer.go b/elements/basic/scrollcontainer.go index ad18cf5..69d8250 100644 --- a/elements/basic/scrollcontainer.go +++ b/elements/basic/scrollcontainer.go @@ -48,20 +48,16 @@ type ScrollContainer struct { // bars. func NewScrollContainer (horizontal, vertical bool) (element *ScrollContainer) { element = &ScrollContainer { } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.handleResize) element.updateMinimumSize() element.horizontal.exists = horizontal element.vertical.exists = vertical return } -// Resize resizes the scroll box. -func (element *ScrollContainer) Resize (width, height int) { - element.core.AllocateCanvas(width, height) +func (element *ScrollContainer) handleResize () { element.recalculate() - element.child.Resize ( - element.childWidth, - element.childHeight) + element.child.DrawTo(tomo.Cut(element, element.child.Bounds())) element.draw() } @@ -95,10 +91,7 @@ func (element *ScrollContainer) Adopt (child tomo.Scrollable) { element.vertical.enabled = element.child.ScrollAxes() if element.core.HasImage() { - element.child.Resize ( - element.childWidth, - element.childHeight) - element.core.DamageAll() + element.child.DrawTo(tomo.Cut(element, element.child.Bounds())) } } } @@ -259,6 +252,7 @@ func (element *ScrollContainer) childFocusMotionRequestCallback ( } func (element *ScrollContainer) clearChildEventHandlers (child tomo.Scrollable) { + child.DrawTo(nil) child.OnDamage(nil) child.OnMinimumSizeChange(nil) child.OnScrollBoundsChange(nil) diff --git a/elements/basic/spacer.go b/elements/basic/spacer.go index 31883e5..bf56979 100644 --- a/elements/basic/spacer.go +++ b/elements/basic/spacer.go @@ -18,18 +18,11 @@ type Spacer struct { // will appear as a line. func NewSpacer (line bool) (element *Spacer) { element = &Spacer { line: line } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.draw) element.core.SetMinimumSize(1, 1) return } -// Resize resizes the label and re-wraps the text if wrapping is enabled. -func (element *Spacer) Resize (width, height int) { - element.core.AllocateCanvas(width, height) - element.draw() - return -} - /// SetLine sets whether or not the spacer will appear as a colored line. func (element *Spacer) SetLine (line bool) { if element.line == line { return } diff --git a/elements/basic/switch.go b/elements/basic/switch.go index 9fdf1b2..85610ba 100644 --- a/elements/basic/switch.go +++ b/elements/basic/switch.go @@ -27,7 +27,7 @@ type Switch struct { // NewSwitch creates a new switch with the specified label text. func NewSwitch (text string, on bool) (element *Switch) { element = &Switch { checked: on, text: text } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.draw) element.FocusableCore, element.focusableControl = core.NewFocusableCore (func () { if element.core.HasImage () { @@ -41,12 +41,6 @@ func NewSwitch (text string, on bool) (element *Switch) { return } -// Resize changes this element's size. -func (element *Switch) Resize (width, height int) { - element.core.AllocateCanvas(width, height) - element.draw() -} - func (element *Switch) HandleMouseDown (x, y int, button tomo.Button) { if !element.Enabled() { return } element.Focus() diff --git a/elements/basic/textbox.go b/elements/basic/textbox.go index 703f504..fab0bb8 100644 --- a/elements/basic/textbox.go +++ b/elements/basic/textbox.go @@ -34,7 +34,7 @@ type TextBox struct { // text. func NewTextBox (placeholder, value string) (element *TextBox) { element = &TextBox { } - element.Core, element.core = core.NewCore(element) + element.Core, element.core = core.NewCore(element.handleResize) element.FocusableCore, element.focusableControl = core.NewFocusableCore (func () { if element.core.HasImage () { @@ -51,8 +51,7 @@ func NewTextBox (placeholder, value string) (element *TextBox) { return } -func (element *TextBox) Resize (width, height int) { - element.core.AllocateCanvas(width, height) +func (element *TextBox) handleResize () { element.scrollToCursor() element.draw() if element.onScrollBoundsChange != nil {