2019-11-06 22:12:15 -05:00
|
|
|
package ui
|
2019-10-25 19:12:42 -04:00
|
|
|
|
|
|
|
import (
|
2019-11-06 22:12:15 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/common"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/palettedefs"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/resourcepaths"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/sound"
|
2019-10-25 19:12:42 -04:00
|
|
|
"github.com/hajimehoshi/ebiten"
|
|
|
|
)
|
|
|
|
|
2019-10-25 20:28:14 -04:00
|
|
|
// CursorButton represents a mouse button
|
|
|
|
type CursorButton uint8
|
|
|
|
|
|
|
|
const (
|
|
|
|
// CursorButtonLeft represents the left mouse button
|
|
|
|
CursorButtonLeft CursorButton = 1
|
|
|
|
// CursorButtonRight represents the right mouse button
|
|
|
|
CursorButtonRight CursorButton = 2
|
|
|
|
)
|
|
|
|
|
2019-10-25 19:12:42 -04:00
|
|
|
// Manager represents the UI manager
|
|
|
|
type Manager struct {
|
2019-10-27 19:00:38 -04:00
|
|
|
widgets []Widget
|
2019-11-06 22:12:15 -05:00
|
|
|
cursorSprite *common.Sprite
|
2019-10-27 19:00:38 -04:00
|
|
|
cursorButtons CursorButton
|
|
|
|
pressedIndex int
|
|
|
|
CursorX int
|
|
|
|
CursorY int
|
2019-11-06 22:12:15 -05:00
|
|
|
clickSfx *sound.SoundEffect
|
2019-10-27 19:00:38 -04:00
|
|
|
waitForLeftMouseUp bool
|
2019-10-25 19:12:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateManager creates a new instance of a UI manager
|
2019-11-06 22:12:15 -05:00
|
|
|
func CreateManager(fileProvider common.FileProvider, soundManager sound.Manager) *Manager {
|
2019-10-25 19:12:42 -04:00
|
|
|
result := &Manager{
|
2019-10-27 19:00:38 -04:00
|
|
|
pressedIndex: -1,
|
|
|
|
widgets: make([]Widget, 0),
|
2019-11-06 22:12:15 -05:00
|
|
|
cursorSprite: fileProvider.LoadSprite(resourcepaths.CursorDefault, palettedefs.Units),
|
|
|
|
clickSfx: soundManager.LoadSoundEffect(resourcepaths.SFXButtonClick),
|
2019-10-27 19:00:38 -04:00
|
|
|
waitForLeftMouseUp: false,
|
2019-10-25 19:12:42 -04:00
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset resets the state of the UI manager. Typically called for new scenes
|
|
|
|
func (v *Manager) Reset() {
|
2019-10-25 22:20:36 -04:00
|
|
|
v.widgets = make([]Widget, 0)
|
2019-10-25 23:41:54 -04:00
|
|
|
v.pressedIndex = -1
|
2019-10-27 19:00:38 -04:00
|
|
|
v.waitForLeftMouseUp = true
|
2019-10-25 19:12:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddWidget adds a widget to the UI manager
|
2019-10-25 22:20:36 -04:00
|
|
|
func (v *Manager) AddWidget(widget Widget) {
|
2019-10-25 19:12:42 -04:00
|
|
|
v.widgets = append(v.widgets, widget)
|
|
|
|
}
|
|
|
|
|
2019-10-27 19:00:38 -04:00
|
|
|
func (v *Manager) WaitForMouseRelease() {
|
|
|
|
v.waitForLeftMouseUp = true
|
|
|
|
}
|
|
|
|
|
2019-10-25 19:12:42 -04:00
|
|
|
// Draw renders all of the UI elements
|
|
|
|
func (v *Manager) Draw(screen *ebiten.Image) {
|
2019-10-25 22:20:36 -04:00
|
|
|
for _, widget := range v.widgets {
|
|
|
|
if !widget.GetVisible() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
widget.Draw(screen)
|
|
|
|
}
|
|
|
|
|
2019-10-25 19:12:42 -04:00
|
|
|
cx, cy := ebiten.CursorPosition()
|
|
|
|
v.cursorSprite.MoveTo(cx, cy)
|
|
|
|
v.cursorSprite.Draw(screen)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update updates all of the UI elements
|
|
|
|
func (v *Manager) Update() {
|
2019-10-25 20:28:14 -04:00
|
|
|
v.cursorButtons = 0
|
|
|
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
2019-10-27 19:00:38 -04:00
|
|
|
if !v.waitForLeftMouseUp {
|
|
|
|
v.cursorButtons |= CursorButtonLeft
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if v.waitForLeftMouseUp {
|
|
|
|
v.waitForLeftMouseUp = false
|
|
|
|
}
|
2019-10-25 20:28:14 -04:00
|
|
|
}
|
|
|
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonRight) {
|
|
|
|
v.cursorButtons |= CursorButtonRight
|
|
|
|
}
|
|
|
|
v.CursorX, v.CursorY = ebiten.CursorPosition()
|
2019-10-25 23:41:54 -04:00
|
|
|
if v.CursorButtonPressed(CursorButtonLeft) {
|
|
|
|
found := false
|
|
|
|
for i, widget := range v.widgets {
|
|
|
|
if !widget.GetVisible() || !widget.GetEnabled() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
wx, wy := widget.GetLocation()
|
|
|
|
ww, wh := widget.GetSize()
|
|
|
|
if v.CursorX >= wx && v.CursorX <= wx+int(ww) && v.CursorY >= wy && v.CursorY <= wy+int(wh) {
|
|
|
|
widget.SetPressed(true)
|
|
|
|
if v.pressedIndex == -1 {
|
|
|
|
found = true
|
|
|
|
v.pressedIndex = i
|
2019-10-26 20:09:33 -04:00
|
|
|
v.clickSfx.Play()
|
2019-10-25 23:41:54 -04:00
|
|
|
} else if v.pressedIndex > -1 && v.pressedIndex != i {
|
|
|
|
v.widgets[i].SetPressed(false)
|
|
|
|
} else {
|
|
|
|
found = true
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
widget.SetPressed(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
if v.pressedIndex > -1 {
|
|
|
|
v.widgets[v.pressedIndex].SetPressed(false)
|
|
|
|
} else {
|
|
|
|
v.pressedIndex = -2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if v.pressedIndex > -1 {
|
|
|
|
widget := v.widgets[v.pressedIndex]
|
|
|
|
wx, wy := widget.GetLocation()
|
|
|
|
ww, wh := widget.GetSize()
|
|
|
|
if v.CursorX >= wx && v.CursorX <= wx+int(ww) && v.CursorY >= wy && v.CursorY <= wy+int(wh) {
|
|
|
|
widget.Activate()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _, widget := range v.widgets {
|
|
|
|
if !widget.GetVisible() || !widget.GetEnabled() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
widget.SetPressed(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v.pressedIndex = -1
|
|
|
|
}
|
2019-10-25 20:28:14 -04:00
|
|
|
}
|
2019-10-25 19:12:42 -04:00
|
|
|
|
2019-10-25 20:28:14 -04:00
|
|
|
// CursorButtonPressed determines if the specified button has been pressed
|
|
|
|
func (v *Manager) CursorButtonPressed(button CursorButton) bool {
|
|
|
|
return v.cursorButtons&button > 0
|
2019-10-25 19:12:42 -04:00
|
|
|
}
|
2019-11-01 14:12:23 -04:00
|
|
|
|
|
|
|
func (v *Manager) KeyPressed(key ebiten.Key) bool {
|
|
|
|
return ebiten.IsKeyPressed(key)
|
|
|
|
}
|