diff --git a/common/elements/v1/base/base.go b/common/elements/v1/base/base.go new file mode 100644 index 0000000..7f5e1d7 --- /dev/null +++ b/common/elements/v1/base/base.go @@ -0,0 +1,38 @@ +package base + +import ( + "image/color" + + "git.vezzani.net/ben/games/common/elements/v1" + "git.vezzani.net/ben/games/common/elements/v1/mouse" +) + +type Element struct { + mouse.NopHandler + + anchor elements.Point + children []elements.Element + + backgroundColor color.Color + name string // For debugging +} + +func (e *Element) Anchor() elements.Point { + return e.anchor +} + +func (e *Element) SetAnchor(a elements.Point) { + d := e.Anchor().Delta(a) + for _, ch := range e.Children() { + ch.SetAnchor(ch.Anchor().Add(d)) + } + e.anchor = a +} + +func (e *Element) Children() []elements.Element { + return e.children +} + +func (e *Element) BackgroundColor() color.Color { + return e.backgroundColor +} diff --git a/common/elements/v1/base/config.go b/common/elements/v1/base/config.go new file mode 100644 index 0000000..66cfcea --- /dev/null +++ b/common/elements/v1/base/config.go @@ -0,0 +1,29 @@ +package base + +import ( + "image/color" + + "git.vezzani.net/ben/games/common/elements/v1" +) + +type OptFunc func(*Element) + +func Children(children ...elements.Element) OptFunc { + return func(c *Element) { + c.children = children + } +} + +func Name(name string) OptFunc { + return func(s *Element) { + s.name = name + } +} + +func (b elements.Builder) BackgroundColor(c color.Color) elements.Builder { + return func() elements.Element { + ce := b().(*Element) + ce.backgroundColor = c + return ce + } +} diff --git a/common/elements/v1/blocks/block.go b/common/elements/v1/blocks/block.go index cbfd734..241d3c8 100644 --- a/common/elements/v1/blocks/block.go +++ b/common/elements/v1/blocks/block.go @@ -1,28 +1,27 @@ package blocks import ( - "image/color" - "git.vezzani.net/ben/games/common/elements/v1" - "git.vezzani.net/ben/games/common/elements/v1/mouse" + "git.vezzani.net/ben/games/common/elements/v1/base" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/vector" ) -func New(ops ...OptFunc) elements.Element { - b := Block{} - for i := range ops { - ops[i](&b) +type Builder elements.Builder + +func New(ops ...OptFunc) Builder { + return func() elements.Element { + b := Block{} + for i := range ops { + ops[i](&b) + } + return &b } - return &b } type Block struct { - elements.Core - - backgroundColor *color.Color - mouse.NopHandler + base.Element width, height int name string } @@ -41,7 +40,7 @@ func (b *Block) Size() (w, h int) { func (b *Block) Draw(image *ebiten.Image) { bnd := b.Bounds() - if b.backgroundColor != nil { + if b.BackgroundColor() != nil { vector.DrawFilledRect( image, float32(b.Anchor().X), diff --git a/common/elements/v1/blocks/options.go b/common/elements/v1/blocks/options.go index 9644f5f..3c8a011 100644 --- a/common/elements/v1/blocks/options.go +++ b/common/elements/v1/blocks/options.go @@ -1,28 +1,23 @@ package blocks import ( - "image/color" - "git.vezzani.net/ben/games/common/elements/v1" + "git.vezzani.net/ben/games/common/elements/v1/base" ) type OptFunc func(*Block) -func Core(f elements.OptFunc) OptFunc { +func Core(f base.OptFunc) OptFunc { return func(b *Block) { - f(&b.Core) + f(&b.Element) } } -func Size(w, h int) OptFunc { - return func(b *Block) { - b.width, b.height = w, h - } -} - -func BackgroundColor(c color.Color) OptFunc { - return func(b *Block) { - b.backgroundColor = &c +func (b Builder) Size(w, h int) Builder { + return func() elements.Element { + bl := b().(*Block) + bl.width, bl.height = w, h + return bl } } diff --git a/common/elements/v1/buttons/options.go b/common/elements/v1/buttons/options.go index afcde1c..bbb84a2 100644 --- a/common/elements/v1/buttons/options.go +++ b/common/elements/v1/buttons/options.go @@ -3,16 +3,16 @@ package buttons import ( "image/color" - "git.vezzani.net/ben/games/common/elements/v1" + "git.vezzani.net/ben/games/common/elements/v1/base" "git.vezzani.net/ben/games/common/elements/v1/blocks" "git.vezzani.net/ben/games/common/elements/v1/mouse" ) type OptFunc func(button *Button) -func Core(f elements.OptFunc) OptFunc { +func Core(f base.OptFunc) OptFunc { return func(b *Button) { - f(&b.Core) + f(&b.Element) } } diff --git a/common/elements/v1/config.go b/common/elements/v1/config.go deleted file mode 100644 index 193596e..0000000 --- a/common/elements/v1/config.go +++ /dev/null @@ -1,15 +0,0 @@ -package elements - -type OptFunc func(*Core) - -func Children(children ...Element) OptFunc { - return func(c *Core) { - c.children = children - } -} - -func Name(name string) OptFunc { - return func(s *Core) { - s.name = name - } -} diff --git a/common/elements/v1/element.go b/common/elements/v1/element.go index 3f33463..6c04531 100644 --- a/common/elements/v1/element.go +++ b/common/elements/v1/element.go @@ -12,6 +12,8 @@ type Element interface { Children() []Element } +type Builder func() Element + type Point struct { X, Y int } @@ -38,26 +40,3 @@ type Bounds struct { func (b *Bounds) Contains(p Point) bool { return p.X >= b.Min.X && p.X <= b.Min.X+b.Width && p.Y >= b.Min.Y && p.Y <= b.Min.Y+b.Height } - -type Core struct { - anchor Point - children []Element - - name string // For debugging -} - -func (c *Core) Anchor() Point { - return c.anchor -} - -func (c *Core) SetAnchor(a Point) { - d := c.Anchor().Delta(a) - for _, ch := range c.Children() { - ch.SetAnchor(ch.Anchor().Add(d)) - } - c.anchor = a -} - -func (c *Core) Children() []Element { - return c.children -} diff --git a/common/elements/v1/stacks/options.go b/common/elements/v1/stacks/options.go index cefb6c9..bfd77d1 100644 --- a/common/elements/v1/stacks/options.go +++ b/common/elements/v1/stacks/options.go @@ -1,12 +1,14 @@ package stacks -import "git.vezzani.net/ben/games/common/elements/v1" +import ( + "git.vezzani.net/ben/games/common/elements/v1/base" +) type OptFunc func(*Stack) -func Core(f elements.OptFunc) OptFunc { +func Core(f base.OptFunc) OptFunc { return func(s *Stack) { - f(&s.Core) + f(&s.Base) } } diff --git a/common/elements/v1/stacks/stack.go b/common/elements/v1/stacks/stack.go index d4792af..98ecd7b 100644 --- a/common/elements/v1/stacks/stack.go +++ b/common/elements/v1/stacks/stack.go @@ -29,7 +29,7 @@ func New(ops ...OptFunc) elements.Element { } type Stack struct { - elements.Core + elements.Base mouse.NopHandler horizontal bool } diff --git a/tools/component_test/editor.go b/tools/component_test/editor.go index 35faa44..a03b832 100644 --- a/tools/component_test/editor.go +++ b/tools/component_test/editor.go @@ -3,52 +3,54 @@ package main import ( "git.vezzani.net/ben/games/common/elements/v1" "git.vezzani.net/ben/games/common/elements/v1/blocks" - "git.vezzani.net/ben/games/common/elements/v1/buttons" "git.vezzani.net/ben/games/common/elements/v1/mouse" - "git.vezzani.net/ben/games/common/elements/v1/stacks" "git.vezzani.net/ben/games/common/sprites/v1" "github.com/hajimehoshi/ebiten/v2" "golang.org/x/image/colornames" ) -var root = stacks.New( - stacks.Horizontal(), - //stacks.Core(blocks.BackgroundColor(color.White)), - stacks.Core(elements.Name("parent")), - stacks.Core(elements.Children( - stacks.New( - stacks.Core(elements.Name("left")), - stacks.Core(elements.Children( - buttons.New( - buttons.BlockOpt(blocks.Size(100, 100)), - buttons.Label("hello"), - buttons.BlockOpt(blocks.BackgroundColor(colornames.Green)), - buttons.OnClick(func(ms mouse.State) { - println("green") - }), - ), - blocks.New( - blocks.Size(100, 100), - blocks.BackgroundColor(colornames.Yellow), - ), - )), - ), - stacks.New( - stacks.Core(elements.Name("right")), - stacks.Core(elements.Children( - blocks.New( - blocks.Size(100, 100), - blocks.BackgroundColor(colornames.Blue), - ), - blocks.New( - blocks.Size(100, 100), - blocks.BackgroundColor(colornames.Red), - ), - )), - ), - )), -) +//var root = stacks.New( +// stacks.Horizontal(), +// //stacks.Element(blocks.BackgroundColor(color.White)), +// stacks.Element(elements.Name("parent")), +// stacks.Element(elements.Children( +// stacks.New( +// stacks.Element(elements.Name("left")), +// stacks.Element(elements.Children( +// buttons.New( +// buttons.BlockOpt(blocks.Size(100, 100)), +// buttons.Label("hello"), +// buttons.BlockOpt(blocks.BackgroundColor(colornames.Green)), +// buttons.OnClick(func(ms mouse.State) { +// println("green") +// }), +// ), +// blocks.New( +// blocks.Size(100, 100), +// blocks.BackgroundColor(colornames.Yellow), +// ), +// )), +// ), +// stacks.New( +// stacks.Element(elements.Name("right")), +// stacks.Element(elements.Children( +// blocks.New( +// blocks.Size(100, 100), +// blocks.BackgroundColor(colornames.Blue), +// ), +// blocks.New( +// blocks.Size(100, 100), +// blocks.BackgroundColor(colornames.Red), +// ), +// )), +// ), +// )), +//) + +var root = blocks.New(). + Size(100, 100). + BackgroundColor(colornames.Red) func newEditor() *editor { return &editor{} @@ -57,6 +59,7 @@ func newEditor() *editor { type editor struct { bounds elements.Bounds handleMouse func() bool + root elements.Element } func (e *editor) Update() error { @@ -66,7 +69,7 @@ func (e *editor) Update() error { } func (e *editor) Draw(screen *ebiten.Image) { - root.Draw(screen) + e.root.Draw(screen) } func (e *editor) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) { @@ -76,7 +79,8 @@ func (e *editor) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHei Width: outsideWidth, Height: outsideHeight, } - e.handleMouse = mouse.Handler(root) + e.root = root() + e.handleMouse = mouse.Handler(e.root) } return outsideWidth, outsideHeight