1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-03 06:20:43 +00:00

Add checkboxes, checkbox test scene

This commit is contained in:
Ian Ling 2020-12-31 20:07:51 -08:00
parent 3731e631cf
commit 0cf47b9b57
14 changed files with 510 additions and 34 deletions

View File

@ -39,8 +39,10 @@ type Sprite interface {
SetPlaySpeed(playSpeed time.Duration)
SetPlayLength(playLength time.Duration)
SetColorMod(colorMod color.Color)
GetColorMod() color.Color
GetPlayedCount() int
ResetPlayedCount()
SetEffect(effect d2enum.DrawEffect)
GetEffect() d2enum.DrawEffect
SetShadow(shadow bool)
}

View File

@ -395,6 +395,10 @@ func (a *Sprite) SetColorMod(colorMod color.Color) {
a.colorMod = colorMod
}
func (a *Sprite) GetColorMod() color.Color {
return a.colorMod
}
// GetPlayedCount gets the number of times the application played
func (a *Sprite) GetPlayedCount() int {
return a.playedCount
@ -410,6 +414,10 @@ func (a *Sprite) SetEffect(e d2enum.DrawEffect) {
a.effect = e
}
func (a *Sprite) GetEffect() d2enum.DrawEffect {
return a.effect
}
// SetShadow sets bool for whether or not to draw a shadow
func (a *Sprite) SetShadow(shadow bool) {
a.hasShadow = shadow

View File

@ -0,0 +1,150 @@
package d2checkbox
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom/rectangle"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2label"
"github.com/gravestench/akara"
"image/color"
"math/rand"
)
type callbackFunc = func(this akara.Component) (preventPropagation bool)
// Button defines a standard wide UI button
type Checkbox struct {
Layout CheckboxLayout
Sprite d2interface.Sprite
Label *d2label.Label
callback callbackFunc
width, height int
pressed bool
enabled bool
}
// CheckboxLayout defines the type of buttons
type CheckboxLayout struct {
X float64
Y float64
SpritePath string
PalettePath string
FontPath string
ClickableRect *rectangle.Rectangle
XSegments int
YSegments int
BaseFrame int
DisabledFrame int
DisabledColor uint32
TextOffset float64
FixedWidth int
FixedHeight int
LabelColor uint32
Toggleable bool
AllowFrameChange bool
HasImage bool
Tooltip int
TooltipXOffset int
TooltipYOffset int
}
// New creates an instance of Button
func New() *Checkbox {
checkbox := &Checkbox{
Layout: GetDefaultLayout(),
}
return checkbox
}
func GetDefaultLayout() CheckboxLayout {
return CheckboxLayout{
X: 0,
Y: 0,
SpritePath: d2resource.Checkbox,
PalettePath: d2resource.PaletteFechar,
FontPath: d2resource.FontExocet10,
XSegments: 1,
YSegments: 1,
BaseFrame: 0,
DisabledFrame: -1,
DisabledColor: lightGreyAlpha75,
TextOffset: 18,
FixedWidth: 16,
FixedHeight: 15,
LabelColor: goldAlpha100,
Toggleable: true,
AllowFrameChange: true,
HasImage: true,
Tooltip: 0,
TooltipXOffset: 0,
TooltipYOffset: 0,
}
}
// OnActivated defines the callback handler for the activate event
func (v *Checkbox) OnActivated(callback callbackFunc) {
v.callback = callback
}
// Activate calls the on activated callback handler, if any
func (v *Checkbox) Activate(thisComponent akara.Component) bool {
if v.GetEnabled() {
v.Toggle()
}
if v.callback != nil {
return v.callback(thisComponent)
}
return false
}
// Toggle negates the toggled state of the button
func (v *Checkbox) Toggle() {
v.SetPressed(!v.GetPressed())
}
// GetEnabled returns the enabled state
func (v *Checkbox) GetEnabled() bool {
return v.enabled
}
// SetEnabled sets the enabled state
func (v *Checkbox) SetEnabled(enabled bool) {
v.enabled = enabled
}
// GetChecked returns the enabled state
func (v *Checkbox) GetPressed() bool {
return v.pressed
}
// SetEnabled sets the enabled state
func (v *Checkbox) SetPressed(pressed bool) {
v.pressed = pressed
}
func (v *Checkbox) Update() {
if v.Sprite == nil {
return
}
if v.GetEnabled() && v.GetPressed() {
// checked, enabled
_ = v.Sprite.SetCurrentFrame(1)
} else if v.GetEnabled() {
// unchecked, enabled
_ = v.Sprite.SetCurrentFrame(0)
} else if v.GetPressed() {
// checked, disabled
_ = v.Sprite.SetCurrentFrame(1)
v.Sprite.SetColorMod(color.RGBA{R: uint8(rand.Uint32() % 255), B: uint8(rand.Uint32() % 255), G: uint8(rand.Uint32() % 255), A: 0xff})
v.Sprite.SetEffect(d2enum.DrawEffectPctTransparency25)
} else {
// unchecked, disabled
_ = v.Sprite.SetCurrentFrame(0)
v.Sprite.SetColorMod(color.RGBA{R: uint8(rand.Uint32() % 255), B: uint8(rand.Uint32() % 255), G: uint8(rand.Uint32() % 255), A: 0xff})
}
}

View File

@ -0,0 +1,8 @@
package d2checkbox
const (
greyAlpha100 = 0x646464ff
lightGreyAlpha75 = 0x808080c3
whiteAlpha100 = 0xffffffff
goldAlpha100 = 0xc7_b3_77_ff
)

View File

@ -1,6 +1,7 @@
package d2components
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom/rectangle"
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2input"
@ -13,19 +14,21 @@ func noop() bool {
return false
}
// Interactive is used to flag file entities with a file type
// Interactive is used to define an input state and a callback function to execute when that state is reached
type Interactive struct {
Enabled bool
*d2input.InputVector
Callback func() (preventPropagation bool)
CursorPosition *rectangle.Rectangle
Callback func() (preventPropagation bool)
}
// New returns a Interactive component. By default, it contains a nil instance.
func (*Interactive) New() akara.Component {
return &Interactive{
Enabled: true,
InputVector: d2input.NewInputVector(),
Callback: noop,
Enabled: true,
InputVector: d2input.NewInputVector(),
CursorPosition: nil,
Callback: noop,
}
}

View File

@ -0,0 +1,43 @@
//nolint:dupl,golint,stylecheck // component declarations are supposed to look the same
package d2components
import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2checkbox"
"github.com/gravestench/akara"
)
// static check that Checkbox implements Component
var _ akara.Component = &Checkbox{}
// Checkbox represents a UI checkbox. It contains an embedded *d2checkbox.Checkbox
type Checkbox struct {
*d2checkbox.Checkbox
}
// New returns a Checkbox component. This contains an embedded *d2checkbox.Checkbox
func (*Checkbox) New() akara.Component {
return &Checkbox{
Checkbox: d2checkbox.New(),
}
}
// CheckboxFactory is a wrapper for the generic component factory that returns Checkbox component instances.
// This can be embedded inside of a system to give them the methods for adding, retrieving, and removing a Checkbox.
type CheckboxFactory struct {
*akara.ComponentFactory
}
// Add adds a Checkbox component to the given entity and returns it
func (m *CheckboxFactory) Add(id akara.EID) *Checkbox {
return m.ComponentFactory.Add(id).(*Checkbox)
}
// Get returns the Button component for the given entity, and a bool for whether or not it exists
func (m *CheckboxFactory) Get(id akara.EID) (*Checkbox, bool) {
component, found := m.ComponentFactory.Get(id)
if !found {
return nil, found
}
return component.(*Checkbox), found
}

View File

@ -37,9 +37,9 @@ const (
skipSplashArg = "nosplash"
skipSplashDesc = "skip the ebiten splash screen"
logLevelArg = "loglevel"
logLevelShort = 'l'
logLevelDesc = "sets the logging level for all loggers at startup"
logLevelArg = "loglevel"
logLevelShort = 'l'
logLevelDesc = "sets the logging level for all loggers at startup"
profilerArg = "profile"
profilerDesc = "Profiles the program, one of (cpu, mem, block, goroutine, trace, thread, mutex)"
@ -285,6 +285,9 @@ func (m *AppBootstrap) parseCommandLineArgs() {
case "buttons":
m.Info("running button test scene")
m.World.AddSystem(NewButtonTestScene())
case "checkbox":
m.Info("running checkbox test scene")
m.World.AddSystem(NewCheckboxTestScene())
default:
m.World.AddSystem(&GameClientBootstrap{})
}

View File

@ -25,9 +25,9 @@ type InputSystem struct {
d2interface.InputService
configs *akara.Subscription
interactives *akara.Subscription
inputState *d2input.InputVector
Components struct {
GameConfig d2components.GameConfigFactory
inputState *d2input.InputVector
Components struct {
GameConfig d2components.GameConfigFactory
Interactive d2components.InteractiveFactory
}
}
@ -143,9 +143,18 @@ func (m *InputSystem) applyInputState(id akara.EID) (preventPropagation bool) {
return false
}
// verify that the current inputState matches the state specified in the InputVector
if !v.Enabled || !m.inputState.Contains(v.InputVector) {
return false
}
// check if this Interactive specified a particular cursor position that the input must occur in
if v.CursorPosition != nil {
cursorX, cursorY := m.CursorPosition()
if !v.CursorPosition.Contains(float64(cursorX), float64(cursorY)) {
return false
}
}
return v.Callback()
}

View File

@ -60,10 +60,12 @@ type sceneComponents struct {
Alpha d2components.AlphaFactory
DrawEffect d2components.DrawEffectFactory
Rectangle d2components.RectangleFactory
Label d2components.LabelFactory
Checkbox d2components.CheckboxFactory
Color d2components.ColorFactory
CommandRegistration d2components.CommandRegistrationFactory
Dirty d2components.DirtyFactory
GameConfig d2components.GameConfigFactory
GameConfig d2components.GameConfigFactory
}
// BaseScene encapsulates common behaviors for systems that are considered "scenes",
@ -87,7 +89,7 @@ type BaseScene struct {
SceneObjects []akara.EID
Graph *d2scene.Node // the root node
backgroundColor color.Color
gameConfigs *akara.Subscription
gameConfigs *akara.Subscription
}
// Booted returns whether or not the scene has booted
@ -218,6 +220,8 @@ func (s *BaseScene) setupFactories() {
s.InjectComponent(&d2components.Sprite{}, &s.Components.Sprite.ComponentFactory)
s.InjectComponent(&d2components.SegmentedSprite{}, &s.Components.SegmentedSprite.ComponentFactory)
s.InjectComponent(&d2components.Rectangle{}, &s.Components.Rectangle.ComponentFactory)
s.InjectComponent(&d2components.Checkbox{}, &s.Components.Checkbox.ComponentFactory)
s.InjectComponent(&d2components.Label{}, &s.Components.Label.ComponentFactory)
s.InjectComponent(&d2components.Color{}, &s.Components.Color.ComponentFactory)
s.InjectComponent(&d2components.CommandRegistration{}, &s.Components.CommandRegistration.ComponentFactory)
s.InjectComponent(&d2components.Dirty{}, &s.Components.Dirty.ComponentFactory)

View File

@ -98,13 +98,6 @@ func (s *MouseCursorScene) updateCursorTransform() {
if int(tx) != cx || int(ty) != cy {
s.lastTimeMoved = time.Now()
switch s.debug.enabled {
case true:
s.Infof("transform: (%d, %d)", int(tx), int(ty))
default:
s.Debugf("transform: (%d, %d)", int(tx), int(ty))
}
}
transform.Translation.X, transform.Translation.Y = float64(cx), float64(cy)

View File

@ -2,6 +2,7 @@ package d2systems
import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2button"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2checkbox"
"image/color"
"path/filepath"
@ -126,3 +127,30 @@ func (s *sceneObjectFactory) Label(text, fontSpritePath, palettePath string) aka
return eid
}
// Checkbox creates a Checkbox in the scene, with an attached Label
func (s *sceneObjectFactory) Checkbox(x, y float64, checkedState bool, enabled bool, text string, callback func(akara.Component) bool) akara.EID {
checkboxEID := s.sceneSystems.UI.Checkbox(x, y, checkedState, enabled, callback)
s.SceneObjects = append(s.SceneObjects, checkboxEID)
s.addBasicComponents(checkboxEID)
checkboxNode := s.Components.SceneGraphNode.Add(checkboxEID)
// create a Label as a child of the Checkbox if text was given
if text != "" {
layout := d2checkbox.GetDefaultLayout()
labelEID := s.Label(text, layout.FontPath, layout.PalettePath)
labelNode := s.Components.SceneGraphNode.Add(labelEID)
labelNode.SetParent(checkboxNode.Node)
labelTrs := s.Components.Transform.Add(labelEID)
labelTrs.Translation.X = layout.TextOffset
label, _ := s.Components.Label.Get(labelEID)
checkbox, _ := s.Components.Checkbox.Get(checkboxEID)
checkbox.Label = label.Label
}
return checkboxEID
}

View File

@ -98,7 +98,7 @@ func (t *SpriteFactory) setupSubscriptions() {
Build()
spritesToUpdate := t.NewComponentFilter().
Require(&d2components.Sprite{}). // we want to process entities that have an sprite ...
Require(&d2components.Sprite{}). // we want to process entities that have an sprite ...
Require(&d2components.Texture{}). // ... but are missing a surface
Build()
@ -316,8 +316,15 @@ func (t *SpriteFactory) renderSegmentedSprite(id akara.EID, seg *d2components.Se
}
target.PushTranslation(x+offsetX, y+offsetY)
// TODO: PushEffect and PushColor don't seem to be working?
// see d2sprite/sprite.go for old implementation
//target.PushEffect(sprite.GetEffect())
//target.PushColor(sprite.GetColorMod())
target.Render(sprite.GetCurrentFrameSurface())
target.Pop()
//target.Pop()
//target.Pop()
frameWidth, frameHeight := sprite.GetCurrentFrameSize()
maxFrameHeight = d2math.MaxInt(maxFrameHeight, frameHeight)

View File

@ -0,0 +1,97 @@
package d2systems
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2components"
"github.com/gravestench/akara"
"image/color"
"log"
)
const (
sceneKeyCheckboxTest = "Checkbox Test Scene"
)
// NewCheckboxTestScene creates a new main menu scene. This is the first screen that the user
// will see when launching the game.
func NewCheckboxTestScene() *CheckboxTestScene {
scene := &CheckboxTestScene{
BaseScene: NewBaseScene(sceneKeyCheckboxTest),
}
return scene
}
// static check that CheckboxTestScene implements the scene interface
var _ d2interface.Scene = &CheckboxTestScene{}
// CheckboxTestScene represents the game's main menu, where users can select single or multi player,
// or start the map engine test.
type CheckboxTestScene struct {
*BaseScene
booted bool
checkboxes *akara.Subscription
}
// Init the main menu scene
func (s *CheckboxTestScene) Init(world *akara.World) {
s.World = world
checkboxes := s.World.NewComponentFilter().
Require(&d2components.Checkbox{}).
Require(&d2components.Ready{}).
Build()
s.checkboxes = s.World.AddSubscription(checkboxes)
s.Debug("initializing ...")
}
func (s *CheckboxTestScene) boot() {
if !s.BaseScene.booted {
s.BaseScene.boot()
return
}
s.AddSystem(NewMouseCursorScene())
s.Add.Rectangle(0, 0, 640, 480, color.RGBA{R: 0xcc, G: 0xcc, B: 0xcc, A: 0xff})
s.createCheckboxes()
s.booted = true
}
func (s *CheckboxTestScene) createCheckboxes() {
s.Add.Checkbox(100, 100, true, true, "Expansion character", checkboxClickCallback)
s.Add.Checkbox(100, 120, false, true, "Hardcore", checkboxClickCallback)
s.Add.Checkbox(100, 140, true, false, "disabled checked test", checkboxClickCallback)
s.Add.Checkbox(100, 160, false, false, "disabled unchecked test", checkboxClickCallback)
}
// Update the main menu scene
func (s *CheckboxTestScene) Update() {
if s.Paused() {
return
}
if !s.booted {
s.boot()
}
s.BaseScene.Update()
}
func checkboxClickCallback(thisComponent akara.Component) bool {
this := thisComponent.(*d2components.Checkbox)
if this.Checkbox.GetEnabled() {
text := this.Checkbox.Label.GetText()
if this.Checkbox.GetPressed() {
log.Printf("%s enabled", text)
} else {
log.Printf("%s disabled", text)
}
}
return false
}

View File

@ -3,6 +3,8 @@ package d2systems
import (
"fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2cache"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom/rectangle"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
@ -27,12 +29,13 @@ func NewUIWidgetFactory(
shapeFactory *ShapeSystem,
) *UIWidgetFactory {
sys := &UIWidgetFactory{
Logger: l,
SpriteFactory: spriteFactory,
ShapeSystem: shapeFactory,
bitmapFontCache: d2cache.CreateCache(fontCacheBudget),
buttonLoadQueue: make(buttonLoadQueue),
labelLoadQueue: make(labelLoadQueue),
Logger: l,
SpriteFactory: spriteFactory,
ShapeSystem: shapeFactory,
bitmapFontCache: d2cache.CreateCache(fontCacheBudget),
buttonLoadQueue: make(buttonLoadQueue),
checkboxLoadQueue: make(checkboxLoadQueue),
labelLoadQueue: make(labelLoadQueue),
}
sys.BaseSystem = b
@ -48,6 +51,12 @@ type buttonLoadQueueEntry struct {
type buttonLoadQueue = map[akara.EID]buttonLoadQueueEntry
type checkboxLoadQueueEntry struct {
sprite akara.EID
}
type checkboxLoadQueue = map[akara.EID]checkboxLoadQueueEntry
type labelLoadQueueEntry struct {
table, sprite akara.EID
}
@ -62,12 +71,14 @@ type UIWidgetFactory struct {
*SpriteFactory
*ShapeSystem
buttonLoadQueue
checkboxLoadQueue
labelLoadQueue
bitmapFontCache d2interface.Cache
labelsToUpdate *akara.Subscription
buttonsToUpdate *akara.Subscription
booted bool
Components struct {
bitmapFontCache d2interface.Cache
labelsToUpdate *akara.Subscription
buttonsToUpdate *akara.Subscription
checkboxesToUpdate *akara.Subscription
booted bool
Components struct {
File d2components.FileFactory
Transform d2components.TransformFactory
Interactive d2components.InteractiveFactory
@ -76,6 +87,7 @@ type UIWidgetFactory struct {
BitmapFont d2components.BitmapFontFactory
Label d2components.LabelFactory
Button d2components.ButtonFactory
Checkbox d2components.CheckboxFactory
Sprite d2components.SpriteFactory
Color d2components.ColorFactory
Texture d2components.TextureFactory
@ -103,6 +115,7 @@ func (t *UIWidgetFactory) setupFactories() {
t.InjectComponent(&d2components.BitmapFont{}, &t.Components.BitmapFont.ComponentFactory)
t.InjectComponent(&d2components.Label{}, &t.Components.Label.ComponentFactory)
t.InjectComponent(&d2components.Button{}, &t.Components.Button.ComponentFactory)
t.InjectComponent(&d2components.Checkbox{}, &t.Components.Checkbox.ComponentFactory)
t.InjectComponent(&d2components.Sprite{}, &t.Components.Sprite.ComponentFactory)
t.InjectComponent(&d2components.Color{}, &t.Components.Color.ComponentFactory)
t.InjectComponent(&d2components.Ready{}, &t.Components.Ready.ComponentFactory)
@ -121,8 +134,14 @@ func (t *UIWidgetFactory) setupSubscriptions() {
Require(&d2components.Ready{}).
Build()
checkboxesToUpdate := t.NewComponentFilter().
Require(&d2components.Checkbox{}).
Require(&d2components.Ready{}).
Build()
t.labelsToUpdate = t.AddSubscription(labelsToUpdate)
t.buttonsToUpdate = t.AddSubscription(buttonsToUpdate)
t.checkboxesToUpdate = t.AddSubscription(checkboxesToUpdate)
}
func (t *UIWidgetFactory) boot() {
@ -155,6 +174,14 @@ func (t *UIWidgetFactory) Update() {
t.processButton(buttonEID)
}
for checkboxEID := range t.checkboxLoadQueue {
if time.Since(start) > maxTimePerUpdate {
return
}
t.processCheckbox(checkboxEID)
}
for labelEID := range t.labelLoadQueue {
if time.Since(start) > maxTimePerUpdate {
return
@ -171,6 +198,14 @@ func (t *UIWidgetFactory) Update() {
t.updateButton(buttonEID)
}
for _, checkboxEID := range t.checkboxesToUpdate.GetEntities() {
if time.Since(start) > maxTimePerUpdate {
return
}
t.updateCheckbox(checkboxEID)
}
for _, labelEID := range t.labelsToUpdate.GetEntities() {
if time.Since(start) > maxTimePerUpdate {
return
@ -481,11 +516,10 @@ func (t *UIWidgetFactory) renderButtonStates(buttonEID akara.EID) {
delete(t.buttonLoadQueue, buttonEID)
}
func (t *UIWidgetFactory) updateButton(buttonEID akara.EID) {
button, btnFound := t.Components.Button.Get(buttonEID)
if ! btnFound {
if !btnFound {
return
}
@ -512,3 +546,90 @@ func (t *UIWidgetFactory) updateButton(buttonEID akara.EID) {
texture.Texture = button.GetCurrentTexture()
}
// Checkbox creates a checkbox ui widget. A Checkbox widget is composed of a Checkbox component that tracks the logic,
// and a SegmentedSprite to be displayed in the scene.
func (t *UIWidgetFactory) Checkbox(x, y float64, checkedState bool, enabled bool, callback func(akara.Component) bool) akara.EID {
checkboxEID := t.NewEntity()
checkbox := t.Components.Checkbox.Add(checkboxEID)
checkbox.Layout.X, checkbox.Layout.Y = x, y
checkbox.Layout.ClickableRect = rectangle.New(x, y, float64(checkbox.Layout.FixedWidth), float64(checkbox.Layout.FixedHeight))
checkboxTrs := t.Components.Transform.Add(checkboxEID)
checkboxTrs.Translation.X, checkboxTrs.Translation.Y = x, y
checkbox.Checkbox.SetPressed(checkedState)
checkbox.Checkbox.SetEnabled(enabled)
checkbox.Checkbox.OnActivated(callback)
img, pal := checkbox.Layout.SpritePath, checkbox.Layout.PalettePath
sx, sy, base := checkbox.Layout.XSegments, checkbox.Layout.YSegments, checkbox.Layout.BaseFrame
spriteEID := t.SpriteFactory.SegmentedSprite(x, y, img, pal, sx, sy, base)
entry := checkboxLoadQueueEntry{
sprite: spriteEID,
}
t.checkboxLoadQueue[checkboxEID] = entry
return checkboxEID
}
// processCheckbox creates a checkbox after all of the prerequisite components are ready.
// This adds interactivity and prepares the checkbox for rendering in the scene.
func (t *UIWidgetFactory) processCheckbox(checkboxEID akara.EID) {
// get the queue entry
entry, found := t.checkboxLoadQueue[checkboxEID]
if !found {
return
}
spriteEID := entry.sprite
// check if sprite is ready to be used
if _, spriteReady := t.Components.Ready.Get(spriteEID); !spriteReady {
return
}
checkbox, found := t.Components.Checkbox.Get(checkboxEID)
if !found {
checkbox = t.Components.Checkbox.Add(checkboxEID)
}
checkboxNode := t.Components.SceneGraphNode.Add(checkboxEID)
sprite, found := t.Components.Sprite.Get(spriteEID)
if found {
checkbox.Sprite = sprite.Sprite
t.Components.SceneGraphNode.Add(spriteEID).SetParent(checkboxNode.Node)
}
interactive := t.Components.Interactive.Add(checkboxEID)
interactive.InputVector.SetMouseButton(d2input.MouseButtonLeft)
interactive.CursorPosition = checkbox.Layout.ClickableRect
interactive.Callback = func() bool {
return checkbox.Activate(checkbox)
}
t.Components.Texture.Add(checkboxEID)
t.Components.Ready.Add(checkboxEID)
delete(t.checkboxLoadQueue, checkboxEID)
}
// updateCheckbox refreshes the rendering logic for a checkbox,
// causing any changes that have occurred to appear in the scene.
func (t *UIWidgetFactory) updateCheckbox(checkboxEID akara.EID) {
checkbox, found := t.Components.Checkbox.Get(checkboxEID)
if !found {
return
}
checkbox.Update()
checkboxTexture, _ := t.Components.Texture.Get(checkboxEID)
checkboxTexture.Texture = checkbox.Sprite.GetCurrentFrameSurface()
}