Basic elements conform to new API

This commit is contained in:
Sasha Koshka 2023-01-31 14:54:43 -05:00
parent 81fc82c46e
commit ee424b9125
10 changed files with 43 additions and 103 deletions

View File

@ -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() }

View File

@ -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()

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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)
}

View File

@ -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 }

View File

@ -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)

View File

@ -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 }

View File

@ -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()

View File

@ -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 {