1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-13 15:56:03 -05:00
OpenDiablo2/d2core/d2ui/textbox.go
lord 854fce3b14
remove d2asset singleton (#726)
* export d2asset singleton

* add *d2asset.AssetManager to d2app

- d2app now has a reference to an asset manager which it will use for loading
- added asset loader methods to the asset manager
- functions in d2asset are now wrappers for asset manager methods

* add asset manager reference to audio provider

- d2app asset manager reference is now passed to audio provider
- asset manager is created in main.go for now to pass into audio provider
- CreateSoundEffect is now a method, no longer exported, uses the asset manager reference

* d2app passes asset manager refence to map engine test

* in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile

* blizzard intro and credits screen

- d2app passes reference to the asset manager to these screens

* asset manager for d2map

- adding MapStampFactory, takes an asset manager reference
- embedded MapStampFactory into the MapEngine
- LoadStamp is now a method of the MapStampFactory

* d2asset: removed LoadFileStream, LoadFile, and FileExists

* d2gui changes

- singleton now has an asset manager reference
- calls to d2asset loader functions removed
- createButton is now a method of LayoutManager
- moved LayoutEntry to its own file

* map entity factory

- Map engine has an embedded map entity factory
- Map stamp factory gets a reference to the map engine's entity factory
- Stamps are given a reference to the map engine entity factory when created
- Character select gets a map entity factory
- Embedded the stamp factory into the MapEngine

* asset manager for d2ui

- d2ui is passed an asset manager reference when created
- all calls to d2asset loader functions in d2ui now refer to the asset manager
- d2gamescreen gets a ui manager when created
- help overlay is now passed a ui manager when created

* d2gamescreen + d2player: asset manager references

added an asset manager reference to
- inventory panel + inventory grid
- mini panel
- game controls
- help overlay
- character select
- main menu
- select hero class
- hero stats panel

* Removed d2asset.LoadAnimation

all references to this function have been replaced with calls to the asset manager method

* adding asset to help overlay, bugfix for 4d59c91

* Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect

all references to these have been replaced with calls to the asset manager methods

* MapRenderer now gets an asset manager reference

* removed d2asset.LoadPalette

all references have been replaced with calls to an asset manager instance

* merged d2object with d2mapentity

d2object was only being used to create objects in the map, so the provider
function is now a method of the map entity factory. calls to d2asset have
been removed.

* removed d2asset.LoadComposite

all calls are now made to the asset manager method

* removed d2asset singleton

all singleton references have been removed, a single instance of the
asset manager is passed around the entire app

* rename Initialize to NewAssetManager
2020-09-12 16:51:30 -04:00

234 lines
4.5 KiB
Go

package d2ui
import (
"strings"
"time"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
)
// TextBox represents a text input box
type TextBox struct {
manager *UIManager
textLabel *Label
lineBar *Label
text string
filter string
x int
y int
bgSprite *Sprite
visible bool
enabled bool
isFocused bool
}
// NewTextbox creates a new instance of a text box
func (ui *UIManager) NewTextbox() *TextBox {
animation, _ := ui.asset.LoadAnimation(d2resource.TextBox2, d2resource.PaletteUnits)
bgSprite, _ := ui.NewSprite(animation)
tb := &TextBox{
filter: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
bgSprite: bgSprite,
textLabel: ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
lineBar: ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
enabled: true,
visible: true,
}
tb.lineBar.SetText("_")
ui.addWidget(tb)
return tb
}
// SetFilter sets the text box filter
func (v *TextBox) SetFilter(filter string) {
v.filter = filter
}
// Render renders the text box
func (v *TextBox) Render(target d2interface.Surface) error {
if !v.visible {
return nil
}
if err := v.bgSprite.Render(target); err != nil {
return err
}
v.textLabel.Render(target)
if (time.Now().UnixNano()/1e6)&(1<<8) > 0 {
v.lineBar.Render(target)
}
return nil
}
// bindManager binds the textbox to the UI manager
func (v *TextBox) bindManager(manager *UIManager) {
v.manager = manager
}
// OnKeyChars handles key character events
func (v *TextBox) OnKeyChars(event d2interface.KeyCharsEvent) bool {
if !v.isFocused || !v.visible || !v.enabled {
return false
}
newText := string(event.Chars())
if len(newText) > 0 {
v.text += newText
v.SetText(v.text)
return true
}
return false
}
// OnKeyRepeat handles key repeat events
func (v *TextBox) OnKeyRepeat(event d2interface.KeyEvent) bool {
if event.Key() == d2enum.KeyBackspace && debounceEvents(event.Duration()) {
if len(v.text) >= 1 {
v.text = v.text[:len(v.text)-1]
}
v.SetText(v.text)
}
return false
}
func debounceEvents(numFrames int) bool {
const (
delay = 30
interval = 3
)
if numFrames == 1 {
return true
}
if numFrames >= delay && (numFrames-delay)%interval == 0 {
return true
}
return false
}
// Advance updates the text box
func (v *TextBox) Advance(_ float64) error {
return nil
}
// Update updates the textbox (not currently implemented)
func (v *TextBox) Update() {
}
// GetText returns the text box's text
func (v *TextBox) GetText() string {
return v.text
}
// SetText sets the text box's text
//nolint:gomnd // Built-in values
func (v *TextBox) SetText(newText string) {
result := ""
for _, c := range newText {
if !strings.Contains(v.filter, string(c)) {
continue
}
result += string(c)
}
if len(result) > 15 {
result = result[0:15]
}
v.text = result
for {
tw, _ := v.textLabel.GetTextMetrics(result)
if tw > 150 {
result = result[1:]
continue
}
v.lineBar.SetPosition(v.x+6+tw, v.y+3)
v.textLabel.SetText(result)
break
}
}
// GetSize returns the size of the text box
func (v *TextBox) GetSize() (width, height int) {
return v.bgSprite.GetCurrentFrameSize()
}
// SetPosition sets the position of the text box
//nolint:gomnd // Built-in values
func (v *TextBox) SetPosition(x, y int) {
lw, _ := v.textLabel.GetSize()
v.x = x
v.y = y
v.textLabel.SetPosition(v.x+6, v.y+3)
v.lineBar.SetPosition(v.x+6+lw, v.y+3)
v.bgSprite.SetPosition(v.x, v.y+26)
}
// GetPosition returns the position of the text box
func (v *TextBox) GetPosition() (x, y int) {
return v.x, v.y
}
// GetVisible returns the visibility of the text box
func (v *TextBox) GetVisible() bool {
return v.visible
}
// SetVisible sets the visibility of the text box
func (v *TextBox) SetVisible(visible bool) {
v.visible = visible
}
// GetEnabled returns the enabled state of the text box
func (v *TextBox) GetEnabled() bool {
return v.enabled
}
// SetEnabled sets the enabled state of the text box
func (v *TextBox) SetEnabled(enabled bool) {
v.enabled = enabled
}
// SetPressed does nothing for text boxes
func (v *TextBox) SetPressed(_ bool) {
// no op
}
// GetPressed does nothing for text boxes
func (v *TextBox) GetPressed() bool {
return false
}
// OnActivated handles activation events for the text box
func (v *TextBox) OnActivated(_ func()) {
// no op
}
// Activate activates the text box
func (v *TextBox) Activate() {
v.isFocused = true
}