Testing elements conform to new API

This commit is contained in:
Sasha Koshka 2023-04-12 23:46:29 -04:00
parent 99c890e6cd
commit 407b957687
2 changed files with 83 additions and 90 deletions

View File

@ -4,11 +4,11 @@ import "fmt"
import "time" import "time"
import "image" import "image"
import "image/color" import "image/color"
import "git.tebibyte.media/sashakoshka/tomo"
import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/canvas"
import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/artist"
import "git.tebibyte.media/sashakoshka/tomo/shatter" import "git.tebibyte.media/sashakoshka/tomo/shatter"
import "git.tebibyte.media/sashakoshka/tomo/textdraw" import "git.tebibyte.media/sashakoshka/tomo/textdraw"
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
import "git.tebibyte.media/sashakoshka/tomo/artist/shapes" import "git.tebibyte.media/sashakoshka/tomo/artist/shapes"
import "git.tebibyte.media/sashakoshka/tomo/artist/patterns" import "git.tebibyte.media/sashakoshka/tomo/artist/patterns"
import defaultfont "git.tebibyte.media/sashakoshka/tomo/default/font" import defaultfont "git.tebibyte.media/sashakoshka/tomo/default/font"
@ -16,49 +16,50 @@ import defaultfont "git.tebibyte.media/sashakoshka/tomo/default/font"
// Artist is an element that displays shapes and patterns drawn by the artist // Artist is an element that displays shapes and patterns drawn by the artist
// package in order to test it. // package in order to test it.
type Artist struct { type Artist struct {
*core.Core entity tomo.Entity
core core.CoreControl
} }
// NewArtist creates a new artist test element. // NewArtist creates a new artist test element.
func NewArtist () (element *Artist) { func NewArtist () *Artist {
element = &Artist { } return &Artist { }
element.Core, element.core = core.NewCore(element, element.draw)
element.core.SetMinimumSize(240, 240)
return
} }
func (element *Artist) draw () { func (element *Artist) Bind (entity tomo.Entity) {
bounds := element.Bounds() element.entity = entity
patterns.Uhex(0x000000FF).Draw(element.core, bounds) entity.SetMinimumSize(240, 240)
}
func (element *Artist) Draw (destination canvas.Canvas) {
bounds := element.entity.Bounds()
patterns.Uhex(0x000000FF).Draw(destination, bounds)
drawStart := time.Now() drawStart := time.Now()
// 0, 0 - 3, 0 // 0, 0 - 3, 0
for x := 0; x < 4; x ++ { for x := 0; x < 4; x ++ {
element.colorLines(x + 1, element.cellAt(x, 0).Bounds()) element.colorLines(destination, x + 1, element.cellAt(destination, x, 0).Bounds())
} }
// 4, 0 // 4, 0
c40 := element.cellAt(4, 0) c40 := element.cellAt(destination, 4, 0)
shapes.StrokeColorRectangle(c40, artist.Hex(0x888888FF), c40.Bounds(), 1) shapes.StrokeColorRectangle(c40, artist.Hex(0x888888FF), c40.Bounds(), 1)
shapes.ColorLine ( shapes.ColorLine (
c40, artist.Hex(0xFF0000FF), 1, c40, artist.Hex(0xFF0000FF), 1,
c40.Bounds().Min, c40.Bounds().Max) c40.Bounds().Min, c40.Bounds().Max)
// 0, 1 // 0, 1
c01 := element.cellAt(0, 1) c01 := element.cellAt(destination, 0, 1)
shapes.StrokeColorRectangle(c01, artist.Hex(0x888888FF), c01.Bounds(), 1) shapes.StrokeColorRectangle(c01, artist.Hex(0x888888FF), c01.Bounds(), 1)
shapes.FillColorEllipse(element.core, artist.Hex(0x00FF00FF), c01.Bounds()) shapes.FillColorEllipse(destination, artist.Hex(0x00FF00FF), c01.Bounds())
// 1, 1 - 3, 1 // 1, 1 - 3, 1
for x := 1; x < 4; x ++ { for x := 1; x < 4; x ++ {
c := element.cellAt(x, 1) c := element.cellAt(destination, x, 1)
shapes.StrokeColorRectangle ( shapes.StrokeColorRectangle (
element.core, artist.Hex(0x888888FF), destination, artist.Hex(0x888888FF),
c.Bounds(), 1) c.Bounds(), 1)
shapes.StrokeColorEllipse ( shapes.StrokeColorEllipse (
element.core, destination,
[]color.RGBA { []color.RGBA {
artist.Hex(0xFF0000FF), artist.Hex(0xFF0000FF),
artist.Hex(0x00FF00FF), artist.Hex(0x00FF00FF),
@ -68,7 +69,7 @@ func (element *Artist) draw () {
} }
// 4, 1 // 4, 1
c41 := element.cellAt(4, 1) c41 := element.cellAt(destination, 4, 1)
shatterPos := c41.Bounds().Min shatterPos := c41.Bounds().Min
rocks := []image.Rectangle { rocks := []image.Rectangle {
image.Rect(3, 12, 13, 23).Add(shatterPos), image.Rect(3, 12, 13, 23).Add(shatterPos),
@ -85,46 +86,46 @@ func (element *Artist) draw () {
patterns.Uhex(0xFF00FFFF), patterns.Uhex(0xFF00FFFF),
patterns.Uhex(0xFFFF00FF), patterns.Uhex(0xFFFF00FF),
patterns.Uhex(0x00FFFFFF), patterns.Uhex(0x00FFFFFF),
} [index % 5].Draw(element.core, tile) } [index % 5].Draw(destination, tile)
} }
// 0, 2 // 0, 2
c02 := element.cellAt(0, 2) c02 := element.cellAt(destination, 0, 2)
shapes.StrokeColorRectangle(c02, artist.Hex(0x888888FF), c02.Bounds(), 1) shapes.StrokeColorRectangle(c02, artist.Hex(0x888888FF), c02.Bounds(), 1)
shapes.FillEllipse(c02, c41, c02.Bounds()) shapes.FillEllipse(c02, c41, c02.Bounds())
// 1, 2 // 1, 2
c12 := element.cellAt(1, 2) c12 := element.cellAt(destination, 1, 2)
shapes.StrokeColorRectangle(c12, artist.Hex(0x888888FF), c12.Bounds(), 1) shapes.StrokeColorRectangle(c12, artist.Hex(0x888888FF), c12.Bounds(), 1)
shapes.StrokeEllipse(c12, c41, c12.Bounds(), 5) shapes.StrokeEllipse(c12, c41, c12.Bounds(), 5)
// 2, 2 // 2, 2
c22 := element.cellAt(2, 2) c22 := element.cellAt(destination, 2, 2)
shapes.FillRectangle(c22, c41, c22.Bounds()) shapes.FillRectangle(c22, c41, c22.Bounds())
// 3, 2 // 3, 2
c32 := element.cellAt(3, 2) c32 := element.cellAt(destination, 3, 2)
shapes.StrokeRectangle(c32, c41, c32.Bounds(), 5) shapes.StrokeRectangle(c32, c41, c32.Bounds(), 5)
// 4, 2 // 4, 2
c42 := element.cellAt(4, 2) c42 := element.cellAt(destination, 4, 2)
// 0, 3 // 0, 3
c03 := element.cellAt(0, 3) c03 := element.cellAt(destination, 0, 3)
patterns.Border { patterns.Border {
Canvas: element.thingy(c42), Canvas: element.thingy(c42),
Inset: artist.Inset { 8, 8, 8, 8 }, Inset: artist.Inset { 8, 8, 8, 8 },
}.Draw(c03, c03.Bounds()) }.Draw(c03, c03.Bounds())
// 1, 3 // 1, 3
c13 := element.cellAt(1, 3) c13 := element.cellAt(destination, 1, 3)
patterns.Border { patterns.Border {
Canvas: element.thingy(c42), Canvas: element.thingy(c42),
Inset: artist.Inset { 8, 8, 8, 8 }, Inset: artist.Inset { 8, 8, 8, 8 },
}.Draw(c13, c13.Bounds().Inset(10)) }.Draw(c13, c13.Bounds().Inset(10))
// 2, 3 // 2, 3
c23 := element.cellAt(2, 3) c23 := element.cellAt(destination, 2, 3)
patterns.Border { patterns.Border {
Canvas: element.thingy(c42), Canvas: element.thingy(c42),
Inset: artist.Inset { 8, 8, 8, 8 }, Inset: artist.Inset { 8, 8, 8, 8 },
@ -143,51 +144,51 @@ func (element *Artist) draw () {
drawTime.Milliseconds(), drawTime.Milliseconds(),
drawTime.Microseconds()))) drawTime.Microseconds())))
textDrawer.Draw ( textDrawer.Draw (
element.core, artist.Hex(0xFFFFFFFF), destination, artist.Hex(0xFFFFFFFF),
image.Pt(bounds.Min.X + 8, bounds.Max.Y - 24)) image.Pt(bounds.Min.X + 8, bounds.Max.Y - 24))
} }
func (element *Artist) colorLines (weight int, bounds image.Rectangle) { func (element *Artist) colorLines (destination canvas.Canvas, weight int, bounds image.Rectangle) {
bounds = bounds.Inset(4) bounds = bounds.Inset(4)
c := artist.Hex(0xFFFFFFFF) c := artist.Hex(0xFFFFFFFF)
shapes.ColorLine(element.core, c, weight, bounds.Min, bounds.Max) shapes.ColorLine(destination, c, weight, bounds.Min, bounds.Max)
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Max.X, bounds.Min.Y), image.Pt(bounds.Max.X, bounds.Min.Y),
image.Pt(bounds.Min.X, bounds.Max.Y)) image.Pt(bounds.Min.X, bounds.Max.Y))
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Max.X, bounds.Min.Y + 16), image.Pt(bounds.Max.X, bounds.Min.Y + 16),
image.Pt(bounds.Min.X, bounds.Max.Y - 16)) image.Pt(bounds.Min.X, bounds.Max.Y - 16))
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Min.X, bounds.Min.Y + 16), image.Pt(bounds.Min.X, bounds.Min.Y + 16),
image.Pt(bounds.Max.X, bounds.Max.Y - 16)) image.Pt(bounds.Max.X, bounds.Max.Y - 16))
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Min.X + 20, bounds.Min.Y), image.Pt(bounds.Min.X + 20, bounds.Min.Y),
image.Pt(bounds.Max.X - 20, bounds.Max.Y)) image.Pt(bounds.Max.X - 20, bounds.Max.Y))
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Max.X - 20, bounds.Min.Y), image.Pt(bounds.Max.X - 20, bounds.Min.Y),
image.Pt(bounds.Min.X + 20, bounds.Max.Y)) image.Pt(bounds.Min.X + 20, bounds.Max.Y))
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Min.X, bounds.Min.Y + bounds.Dy() / 2), image.Pt(bounds.Min.X, bounds.Min.Y + bounds.Dy() / 2),
image.Pt(bounds.Max.X, bounds.Min.Y + bounds.Dy() / 2)) image.Pt(bounds.Max.X, bounds.Min.Y + bounds.Dy() / 2))
shapes.ColorLine ( shapes.ColorLine (
element.core, c, weight, destination, c, weight,
image.Pt(bounds.Min.X + bounds.Dx() / 2, bounds.Min.Y), image.Pt(bounds.Min.X + bounds.Dx() / 2, bounds.Min.Y),
image.Pt(bounds.Min.X + bounds.Dx() / 2, bounds.Max.Y)) image.Pt(bounds.Min.X + bounds.Dx() / 2, bounds.Max.Y))
} }
func (element *Artist) cellAt (x, y int) (canvas.Canvas) { func (element *Artist) cellAt (destination canvas.Canvas, x, y int) (canvas.Canvas) {
bounds := element.Bounds() bounds := element.entity.Bounds()
cellBounds := image.Rectangle { } cellBounds := image.Rectangle { }
cellBounds.Min = bounds.Min cellBounds.Min = bounds.Min
cellBounds.Max.X = bounds.Min.X + bounds.Dx() / 5 cellBounds.Max.X = bounds.Min.X + bounds.Dx() / 5
cellBounds.Max.Y = bounds.Min.Y + (bounds.Dy() - 48) / 4 cellBounds.Max.Y = bounds.Min.Y + (bounds.Dy() - 48) / 4
return canvas.Cut (element.core, cellBounds.Add (image.Pt ( return canvas.Cut (destination, cellBounds.Add (image.Pt (
x * cellBounds.Dx(), x * cellBounds.Dx(),
y * cellBounds.Dy()))) y * cellBounds.Dy())))
} }

View File

@ -4,17 +4,16 @@ import "image"
import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo"
import "git.tebibyte.media/sashakoshka/tomo/input" import "git.tebibyte.media/sashakoshka/tomo/input"
import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/artist"
import "git.tebibyte.media/sashakoshka/tomo/canvas"
import "git.tebibyte.media/sashakoshka/tomo/artist/shapes" import "git.tebibyte.media/sashakoshka/tomo/artist/shapes"
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
import "git.tebibyte.media/sashakoshka/tomo/default/theme" import "git.tebibyte.media/sashakoshka/tomo/default/theme"
import "git.tebibyte.media/sashakoshka/tomo/default/config" import "git.tebibyte.media/sashakoshka/tomo/default/config"
// Mouse is an element capable of testing mouse input. When the mouse is clicked // Mouse is an element capable of testing mouse input. When the mouse is clicked
// and dragged on it, it draws a trail. // and dragged on it, it draws a trail.
type Mouse struct { type Mouse struct {
*core.Core entity tomo.Entity
core core.CoreControl pressed bool
drawing bool
lastMousePos image.Point lastMousePos image.Point
config config.Wrapped config config.Wrapped
@ -24,69 +23,62 @@ type Mouse struct {
// NewMouse creates a new mouse test element. // NewMouse creates a new mouse test element.
func NewMouse () (element *Mouse) { func NewMouse () (element *Mouse) {
element = &Mouse { } element = &Mouse { }
element.theme.Case = tomo.C("tomo", "piano") element.theme.Case = tomo.C("tomo", "mouse")
element.Core, element.core = core.NewCore(element, element.draw)
element.core.SetMinimumSize(32, 32)
return return
} }
func (element *Mouse) Bind (entity tomo.Entity) {
element.entity = entity
entity.SetMinimumSize(32, 32)
}
func (element *Mouse) Draw (destination canvas.Canvas) {
bounds := element.entity.Bounds()
accent := element.theme.Color (
tomo.ColorAccent,
tomo.State { })
shapes.FillColorRectangle(destination, accent, bounds)
shapes.StrokeColorRectangle (
destination,
artist.Hex(0x000000FF),
bounds, 1)
shapes.ColorLine (
destination, artist.Hex(0xFFFFFFFF), 1,
bounds.Min.Add(image.Pt(1, 1)),
bounds.Min.Add(image.Pt(bounds.Dx() - 2, bounds.Dy() - 2)))
shapes.ColorLine (
destination, artist.Hex(0xFFFFFFFF), 1,
bounds.Min.Add(image.Pt(1, bounds.Dy() - 2)),
bounds.Min.Add(image.Pt(bounds.Dx() - 2, 1)))
if element.pressed {
shapes.ColorLine (
destination, artist.Hex(0x000000FF), 1,
bounds.Min, element.lastMousePos)
}
}
// SetTheme sets the element's theme. // SetTheme sets the element's theme.
func (element *Mouse) SetTheme (new tomo.Theme) { func (element *Mouse) SetTheme (new tomo.Theme) {
element.theme.Theme = new element.theme.Theme = new
element.redo() element.entity.Invalidate()
} }
// SetConfig sets the element's configuration. // SetConfig sets the element's configuration.
func (element *Mouse) SetConfig (new tomo.Config) { func (element *Mouse) SetConfig (new tomo.Config) {
element.config.Config = new element.config.Config = new
element.redo() element.entity.Invalidate()
}
func (element *Mouse) redo () {
if !element.core.HasImage() { return }
element.draw()
element.core.DamageAll()
}
func (element *Mouse) draw () {
bounds := element.Bounds()
accent := element.theme.Color (
tomo.ColorAccent,
tomo.State { })
shapes.FillColorRectangle(element.core, accent, bounds)
shapes.StrokeColorRectangle (
element.core,
artist.Hex(0x000000FF),
bounds, 1)
shapes.ColorLine (
element.core, artist.Hex(0xFFFFFFFF), 1,
bounds.Min.Add(image.Pt(1, 1)),
bounds.Min.Add(image.Pt(bounds.Dx() - 2, bounds.Dy() - 2)))
shapes.ColorLine (
element.core, artist.Hex(0xFFFFFFFF), 1,
bounds.Min.Add(image.Pt(1, bounds.Dy() - 2)),
bounds.Min.Add(image.Pt(bounds.Dx() - 2, 1)))
} }
func (element *Mouse) HandleMouseDown (x, y int, button input.Button) { func (element *Mouse) HandleMouseDown (x, y int, button input.Button) {
element.drawing = true element.pressed = true
element.lastMousePos = image.Pt(x, y)
} }
func (element *Mouse) HandleMouseUp (x, y int, button input.Button) { func (element *Mouse) HandleMouseUp (x, y int, button input.Button) {
element.drawing = false element.pressed = false
mousePos := image.Pt(x, y)
element.core.DamageRegion (shapes.ColorLine (
element.core, artist.Hex(0x000000FF), 1,
element.lastMousePos, mousePos))
element.lastMousePos = mousePos
} }
func (element *Mouse) HandleMotion (x, y int) { func (element *Mouse) HandleMotion (x, y int) {
if !element.drawing { return } if !element.pressed { return }
mousePos := image.Pt(x, y) element.lastMousePos = image.Pt(x, y)
element.core.DamageRegion (shapes.ColorLine ( element.entity.Invalidate()
element.core, artist.Hex(0x000000FF), 1,
element.lastMousePos, mousePos))
element.lastMousePos = mousePos
} }