Rework the UI framework

Interface is now Driver, and Widget is now a set of interfaces with a
struct per widget type. This should make it easier to add other types.
This commit is contained in:
2020-03-24 20:21:55 +00:00
parent bcee07e8f7
commit 69971b2825
14 changed files with 791 additions and 669 deletions

136
internal/ui/interfaces.go Normal file
View File

@@ -0,0 +1,136 @@
package ui
import (
"image"
"github.com/hajimehoshi/ebiten"
)
type region struct {
offset image.Point
image *ebiten.Image
}
func oneRegion(offset image.Point, image *ebiten.Image) []region {
return []region{{offset: offset, image: image}}
}
type idable interface {
id() string
}
// Clickable can be clicked by the left button of a mouse. Specify code to run
// with OnClick().
type clickable interface {
idable
bounds() image.Rectangle
onClick(f func())
// These are used to drive the state of the item
mouseDownState() bool
setMouseDownState(bool)
registerMouseClick()
}
// This implements the clickable interface except id(), bounds(), and registerMouseClick()
type clickImpl struct {
f func()
mouseDown bool
}
func (c *clickImpl) onClick(f func()) {
c.f = f
}
func (c *clickImpl) mouseDownState() bool {
return c.mouseDown
}
func (c *clickImpl) setMouseDownState(down bool) {
c.mouseDown = down
}
func (c *clickImpl) registerMouseClick() {
if c.f != nil {
c.f()
}
}
// Freezable represents a widget that can be enabled or disabled
type freezable interface {
idable
isFrozen() bool
setFreezeState(bool)
}
// This implements the freezable interface except id()
type freezeImpl struct {
frozen bool
}
func (f *freezeImpl) isFrozen() bool {
return f.frozen
}
func (f *freezeImpl) setFreezeState(frozen bool) {
f.frozen = frozen
}
// Hoverable can be hovered over by the mouse cursor.
//
// If something can be hovered, it can have a tooltip, so that is implemented
// here too.
type hoverable interface {
bounds() image.Rectangle
tooltip() string
// These are used to drive the state of the item
hoverState() bool
setHoverState(bool)
}
// Implements the hoverable interface with the exception of bounds()
type hoverImpl struct {
hovering bool
text string
}
func (h *hoverImpl) tooltip() string {
return h.text
}
func (h *hoverImpl) hoverState() bool {
return h.hovering
}
func (h *hoverImpl) setHoverState(hovering bool) {
h.hovering = hovering
}
// Paintable encapsulates one or more regions to be painted to the screen
type paintable interface {
regions(tick int) []region
}
// Valueable encapsulates the idea of an element with a value. Only strings are
// supported - #dealwithit for bools, ints, etc
type valueable interface {
idable
value() string
setValue(string)
}
type valueImpl struct {
str string
}
func (v *valueImpl) value() string {
return v.str
}
func (v *valueImpl) setValue(value string) {
v.str = value
}