mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-05 16:17:45 -05:00
Added text entry. Fixed performance issue. Added error checking. (#132)
This commit is contained in:
parent
e8292e9c42
commit
f156475731
@ -19,11 +19,11 @@ type CharacterSelect struct {
|
||||
fileProvider d2interface.FileProvider
|
||||
sceneProvider d2interface.SceneProvider
|
||||
background d2render.Sprite
|
||||
newCharButton *d2ui.Button
|
||||
convertCharButton *d2ui.Button
|
||||
deleteCharButton *d2ui.Button
|
||||
exitButton *d2ui.Button
|
||||
okButton *d2ui.Button
|
||||
newCharButton d2ui.Button
|
||||
convertCharButton d2ui.Button
|
||||
deleteCharButton d2ui.Button
|
||||
exitButton d2ui.Button
|
||||
okButton d2ui.Button
|
||||
}
|
||||
|
||||
func CreateCharacterSelect(
|
||||
@ -52,31 +52,31 @@ func (v *CharacterSelect) Load() []func() {
|
||||
v.newCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#831"), 15)))
|
||||
v.newCharButton.MoveTo(33, 468)
|
||||
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
||||
v.uiManager.AddWidget(v.newCharButton)
|
||||
v.uiManager.AddWidget(&v.newCharButton)
|
||||
},
|
||||
func() {
|
||||
v.convertCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#825"), 15)))
|
||||
v.convertCharButton.MoveTo(233, 468)
|
||||
v.convertCharButton.SetEnabled(false)
|
||||
v.uiManager.AddWidget(v.convertCharButton)
|
||||
v.uiManager.AddWidget(&v.convertCharButton)
|
||||
},
|
||||
func() {
|
||||
v.deleteCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#832"), 15)))
|
||||
v.deleteCharButton.MoveTo(433, 468)
|
||||
v.deleteCharButton.SetEnabled(false)
|
||||
v.uiManager.AddWidget(v.deleteCharButton)
|
||||
v.uiManager.AddWidget(&v.deleteCharButton)
|
||||
},
|
||||
func() {
|
||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
||||
v.exitButton.MoveTo(33, 537)
|
||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
v.uiManager.AddWidget(v.exitButton)
|
||||
v.uiManager.AddWidget(&v.exitButton)
|
||||
},
|
||||
func() {
|
||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#971"))
|
||||
v.okButton.MoveTo(625, 537)
|
||||
v.okButton.SetEnabled(false)
|
||||
v.uiManager.AddWidget(v.okButton)
|
||||
v.uiManager.AddWidget(&v.okButton)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
type labelItem struct {
|
||||
Label *d2ui.Label
|
||||
Label d2ui.Label
|
||||
IsHeading bool
|
||||
Available bool
|
||||
}
|
||||
@ -34,7 +34,7 @@ type Credits struct {
|
||||
fileProvider d2interface.FileProvider
|
||||
sceneProvider d2interface.SceneProvider
|
||||
creditsBackground d2render.Sprite
|
||||
exitButton *d2ui.Button
|
||||
exitButton d2ui.Button
|
||||
creditsText []string
|
||||
labels []*labelItem
|
||||
cycleTime float64
|
||||
@ -68,7 +68,7 @@ func (v *Credits) Load() []func() {
|
||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
||||
v.exitButton.MoveTo(30, 550)
|
||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
v.uiManager.AddWidget(v.exitButton)
|
||||
v.uiManager.AddWidget(&v.exitButton)
|
||||
},
|
||||
func() {
|
||||
fileData, _ := dh.Utf16BytesToString(v.fileProvider.LoadFile(d2resource.CreditsText)[2:])
|
||||
@ -192,7 +192,7 @@ func (v *Credits) getNewFontLabel(isHeading bool) *d2ui.Label {
|
||||
} else {
|
||||
label.Label.Color = color.RGBA{198, 178, 150, 255}
|
||||
}
|
||||
return label.Label
|
||||
return &label.Label
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,5 +210,5 @@ func (v *Credits) getNewFontLabel(isHeading bool) *d2ui.Label {
|
||||
}
|
||||
|
||||
v.labels = append(v.labels, newLabelItem)
|
||||
return newLabelItem.Label
|
||||
return &newLabelItem.Label
|
||||
}
|
||||
|
@ -37,17 +37,17 @@ type MainMenu struct {
|
||||
diabloLogoRight d2render.Sprite
|
||||
diabloLogoLeftBack d2render.Sprite
|
||||
diabloLogoRightBack d2render.Sprite
|
||||
singlePlayerButton *d2ui.Button
|
||||
githubButton *d2ui.Button
|
||||
exitDiabloButton *d2ui.Button
|
||||
creditsButton *d2ui.Button
|
||||
cinematicsButton *d2ui.Button
|
||||
mapTestButton *d2ui.Button
|
||||
copyrightLabel *d2ui.Label
|
||||
copyrightLabel2 *d2ui.Label
|
||||
openDiabloLabel *d2ui.Label
|
||||
versionLabel *d2ui.Label
|
||||
commitLabel *d2ui.Label
|
||||
singlePlayerButton d2ui.Button
|
||||
githubButton d2ui.Button
|
||||
exitDiabloButton d2ui.Button
|
||||
creditsButton d2ui.Button
|
||||
cinematicsButton d2ui.Button
|
||||
mapTestButton d2ui.Button
|
||||
copyrightLabel d2ui.Label
|
||||
copyrightLabel2 d2ui.Label
|
||||
openDiabloLabel d2ui.Label
|
||||
versionLabel d2ui.Label
|
||||
commitLabel d2ui.Label
|
||||
|
||||
ShowTrademarkScreen bool
|
||||
leftButtonHeld bool
|
||||
@ -138,41 +138,41 @@ func (v *MainMenu) Load() []func() {
|
||||
v.exitDiabloButton.MoveTo(264, 535)
|
||||
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
||||
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
v.uiManager.AddWidget(v.exitDiabloButton)
|
||||
v.uiManager.AddWidget(&v.exitDiabloButton)
|
||||
},
|
||||
func() {
|
||||
v.creditsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, v.fileProvider, d2common.TranslateString("#1627"))
|
||||
v.creditsButton.MoveTo(264, 505)
|
||||
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
||||
v.uiManager.AddWidget(v.creditsButton)
|
||||
v.uiManager.AddWidget(&v.creditsButton)
|
||||
},
|
||||
func() {
|
||||
v.cinematicsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, v.fileProvider, d2common.TranslateString("#1639"))
|
||||
v.cinematicsButton.MoveTo(401, 505)
|
||||
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||
v.uiManager.AddWidget(v.cinematicsButton)
|
||||
v.uiManager.AddWidget(&v.cinematicsButton)
|
||||
},
|
||||
func() {
|
||||
v.singlePlayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, d2common.TranslateString("#1620"))
|
||||
v.singlePlayerButton.MoveTo(264, 290)
|
||||
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
||||
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
||||
v.uiManager.AddWidget(v.singlePlayerButton)
|
||||
v.uiManager.AddWidget(&v.singlePlayerButton)
|
||||
},
|
||||
func() {
|
||||
v.githubButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, "PROJECT WEBSITE")
|
||||
v.githubButton.MoveTo(264, 330)
|
||||
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
||||
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
||||
v.uiManager.AddWidget(v.githubButton)
|
||||
v.uiManager.AddWidget(&v.githubButton)
|
||||
},
|
||||
func() {
|
||||
v.mapTestButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, "MAP ENGINE TEST")
|
||||
v.mapTestButton.MoveTo(264, 450)
|
||||
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
||||
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
||||
v.uiManager.AddWidget(v.mapTestButton)
|
||||
v.uiManager.AddWidget(&v.mapTestButton)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package d2scene
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
|
||||
@ -35,20 +36,23 @@ type HeroRenderInfo struct {
|
||||
}
|
||||
|
||||
type SelectHeroClass struct {
|
||||
uiManager *d2ui.Manager
|
||||
soundManager *d2audio.Manager
|
||||
fileProvider d2interface.FileProvider
|
||||
sceneProvider d2interface.SceneProvider
|
||||
bgImage d2render.Sprite
|
||||
campfire d2render.Sprite
|
||||
headingLabel *d2ui.Label
|
||||
heroClassLabel *d2ui.Label
|
||||
heroDesc1Label *d2ui.Label
|
||||
heroDesc2Label *d2ui.Label
|
||||
heroDesc3Label *d2ui.Label
|
||||
heroRenderInfo map[d2enum.Hero]*HeroRenderInfo
|
||||
selectedHero d2enum.Hero
|
||||
exitButton *d2ui.Button
|
||||
uiManager *d2ui.Manager
|
||||
soundManager *d2audio.Manager
|
||||
fileProvider d2interface.FileProvider
|
||||
sceneProvider d2interface.SceneProvider
|
||||
bgImage d2render.Sprite
|
||||
campfire d2render.Sprite
|
||||
headingLabel d2ui.Label
|
||||
heroClassLabel d2ui.Label
|
||||
heroDesc1Label d2ui.Label
|
||||
heroDesc2Label d2ui.Label
|
||||
heroDesc3Label d2ui.Label
|
||||
heroNameTextbox d2ui.TextBox
|
||||
heroNameLabel d2ui.Label
|
||||
heroRenderInfo map[d2enum.Hero]*HeroRenderInfo
|
||||
selectedHero d2enum.Hero
|
||||
exitButton d2ui.Button
|
||||
okButton d2ui.Button
|
||||
}
|
||||
|
||||
func CreateSelectHeroClass(
|
||||
@ -115,7 +119,28 @@ func (v *SelectHeroClass) Load() []func() {
|
||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
||||
v.exitButton.MoveTo(33, 537)
|
||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
v.uiManager.AddWidget(v.exitButton)
|
||||
v.uiManager.AddWidget(&v.exitButton)
|
||||
},
|
||||
func() {
|
||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#971"))
|
||||
v.okButton.MoveTo(630, 537)
|
||||
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
||||
v.okButton.SetVisible(false)
|
||||
v.okButton.SetEnabled(false)
|
||||
v.uiManager.AddWidget(&v.okButton)
|
||||
},
|
||||
func() {
|
||||
v.heroNameLabel = d2ui.CreateLabel(v.fileProvider, d2resource.Font16, d2enum.Units)
|
||||
v.heroNameLabel.Alignment = d2ui.LabelAlignLeft
|
||||
v.heroNameLabel.Color = color.RGBA{216, 196, 128, 255}
|
||||
v.heroNameLabel.SetText(d2common.TranslateString("#1694"))
|
||||
v.heroNameLabel.MoveTo(321, 475)
|
||||
},
|
||||
func() {
|
||||
v.heroNameTextbox = d2ui.CreateTextbox(v.fileProvider)
|
||||
v.heroNameTextbox.MoveTo(318, 493)
|
||||
v.heroNameTextbox.SetVisible(false)
|
||||
v.uiManager.AddWidget(&v.heroNameTextbox)
|
||||
},
|
||||
func() {
|
||||
v.heroRenderInfo[d2enum.HeroBarbarian] = &HeroRenderInfo{
|
||||
@ -368,10 +393,14 @@ func (v *SelectHeroClass) Unload() {
|
||||
v.heroRenderInfo = nil
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) onExitButtonClicked() {
|
||||
func (v SelectHeroClass) onExitButtonClicked() {
|
||||
v.sceneProvider.SetNextScene(CreateCharacterSelect(v.fileProvider, v.sceneProvider, v.uiManager, v.soundManager))
|
||||
}
|
||||
|
||||
func (v SelectHeroClass) onOkButtonClicked() {
|
||||
// TODO: Start the game
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) Render(screen *ebiten.Image) {
|
||||
v.bgImage.DrawSegments(screen, 4, 3, 0)
|
||||
v.headingLabel.Draw(screen)
|
||||
@ -392,6 +421,9 @@ func (v *SelectHeroClass) Render(screen *ebiten.Image) {
|
||||
}
|
||||
}
|
||||
v.campfire.Draw(screen)
|
||||
if v.heroNameTextbox.GetVisible() {
|
||||
v.heroNameLabel.Draw(screen)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) Update(tickTime float64) {
|
||||
@ -412,6 +444,8 @@ func (v *SelectHeroClass) Update(tickTime float64) {
|
||||
if v.selectedHero != d2enum.HeroNone && allIdle {
|
||||
v.selectedHero = d2enum.HeroNone
|
||||
}
|
||||
v.heroNameTextbox.Update()
|
||||
v.okButton.SetEnabled(len(v.heroNameTextbox.GetText()) >= 2)
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) updateHeroSelectionHover(hero d2enum.Hero, canSelect bool) {
|
||||
@ -444,7 +478,8 @@ func (v *SelectHeroClass) updateHeroSelectionHover(hero d2enum.Hero, canSelect b
|
||||
b := renderInfo.SelectionBounds
|
||||
mouseHover := (mouseX >= b.Min.X) && (mouseX <= b.Min.X+b.Max.X) && (mouseY >= b.Min.Y) && (mouseY <= b.Min.Y+b.Max.Y)
|
||||
if mouseHover && v.uiManager.CursorButtonPressed(d2ui.CursorButtonLeft) {
|
||||
// showEntryUi = true;
|
||||
v.heroNameTextbox.SetVisible(true)
|
||||
v.okButton.SetVisible(true)
|
||||
renderInfo.Stance = d2enum.HeroStanceApproaching
|
||||
renderInfo.ForwardWalkSprite.ResetAnimation()
|
||||
if renderInfo.ForwardWalkSpriteOverlay.IsValid() {
|
||||
|
@ -3,6 +3,7 @@ package d2render
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -156,7 +157,9 @@ func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) {
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
opts.GeoM.Translate(float64(v.frameLocations[frameName][v.currentFrame].Left+offsetX),
|
||||
float64(v.frameLocations[frameName][v.currentFrame].Top+offsetY+40))
|
||||
target.DrawImage(v.frames[frameName][v.currentFrame], opts)
|
||||
if err := target.DrawImage(v.frames[frameName][v.currentFrame], opts); err != nil {
|
||||
log.Panic(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
"image"
|
||||
"image/color"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -29,7 +30,6 @@ type Sprite struct {
|
||||
LastFrameTime time.Time
|
||||
Animate bool
|
||||
ColorMod color.Color
|
||||
visible bool
|
||||
valid bool
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ func CreateSprite(data []byte, palette d2datadict.PaletteRec) Sprite {
|
||||
|
||||
x := uint32(0)
|
||||
y := result.Frames[i].Height - 1
|
||||
for true {
|
||||
for {
|
||||
b := data[dataPointer]
|
||||
dataPointer++
|
||||
if b == 0x80 {
|
||||
@ -197,7 +197,9 @@ func (v *Sprite) cacheFrame(frame int) {
|
||||
v.atlasBytes[idx+3] = v.Frames[frame].FrameData[pix+3]
|
||||
}
|
||||
}
|
||||
v.atlas.ReplacePixels(v.atlasBytes)
|
||||
if err := v.atlas.ReplacePixels(v.atlasBytes); err != nil {
|
||||
log.Panic(err.Error())
|
||||
}
|
||||
v.Frames[frame].cached = true
|
||||
}
|
||||
|
||||
@ -218,7 +220,7 @@ func (v *Sprite) updateAnimation() {
|
||||
} else {
|
||||
timePerFrame = time.Duration(float64(time.Second) * (1.0 / float64(len(v.Frames))))
|
||||
}
|
||||
for time.Now().Sub(v.LastFrameTime) >= timePerFrame {
|
||||
for time.Since(v.LastFrameTime) >= timePerFrame {
|
||||
v.LastFrameTime = v.LastFrameTime.Add(timePerFrame)
|
||||
v.Frame++
|
||||
if v.Frame >= uint8(v.FramesPerDirection) {
|
||||
@ -272,7 +274,9 @@ func (v *Sprite) Draw(target *ebiten.Image) {
|
||||
if v.ColorMod != nil {
|
||||
opts.ColorM = d2helper.ColorToColorM(v.ColorMod)
|
||||
}
|
||||
target.DrawImage(frame.Image, opts)
|
||||
if err := target.DrawImage(frame.Image, opts); err != nil {
|
||||
log.Panic(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// DrawSegments draws the sprite via a grid of segments
|
||||
@ -300,7 +304,9 @@ func (v *Sprite) DrawSegments(target *ebiten.Image, xSegments, ySegments, offset
|
||||
if v.ColorMod != nil {
|
||||
opts.ColorM = d2helper.ColorToColorM(v.ColorMod)
|
||||
}
|
||||
target.DrawImage(frame.Image, opts)
|
||||
if err := target.DrawImage(frame.Image, opts); err != nil {
|
||||
log.Panic(err.Error())
|
||||
}
|
||||
xOffset += int32(frame.Width)
|
||||
biggestYOffset = d2helper.MaxInt32(biggestYOffset, int32(frame.Height))
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ type Button struct {
|
||||
}
|
||||
|
||||
// CreateButton creates an instance of Button
|
||||
func CreateButton(buttonType ButtonType, fileProvider d2interface.FileProvider, text string) *Button {
|
||||
result := &Button{
|
||||
func CreateButton(buttonType ButtonType, fileProvider d2interface.FileProvider, text string) Button {
|
||||
result := Button{
|
||||
fileProvider: fileProvider,
|
||||
width: 0,
|
||||
height: 0,
|
||||
@ -159,7 +159,7 @@ func CreateButton(buttonType ButtonType, fileProvider d2interface.FileProvider,
|
||||
if buttonLayout.DisabledFrame != -1 {
|
||||
result.disabledImage, _ = ebiten.NewImage(int(result.width), int(result.height), ebiten.FilterNearest)
|
||||
buttonSprite.DrawSegments(result.disabledImage, buttonLayout.XSegments, buttonLayout.YSegments, buttonLayout.DisabledFrame)
|
||||
font.Draw(0, textY-1, text, color.RGBA{100, 100, 100, 255}, result.disabledImage)
|
||||
font.Draw(0, textY, text, color.RGBA{100, 100, 100, 255}, result.disabledImage)
|
||||
}
|
||||
}
|
||||
return result
|
||||
@ -171,7 +171,7 @@ func (v *Button) OnActivated(callback func()) {
|
||||
}
|
||||
|
||||
// Activate calls the on activated callback handler, if any
|
||||
func (v *Button) Activate() {
|
||||
func (v Button) Activate() {
|
||||
if v.onClick == nil {
|
||||
return
|
||||
}
|
||||
@ -179,7 +179,7 @@ func (v *Button) Activate() {
|
||||
}
|
||||
|
||||
// Draw renders the button
|
||||
func (v *Button) Draw(target *ebiten.Image) {
|
||||
func (v Button) Draw(target *ebiten.Image) {
|
||||
opts := &ebiten.DrawImageOptions{
|
||||
CompositeMode: ebiten.CompositeModeSourceAtop,
|
||||
Filter: ebiten.FilterNearest,
|
||||
@ -202,7 +202,7 @@ func (v *Button) Draw(target *ebiten.Image) {
|
||||
}
|
||||
|
||||
// GetEnabled returns the enabled state
|
||||
func (v *Button) GetEnabled() bool {
|
||||
func (v Button) GetEnabled() bool {
|
||||
return v.enabled
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ func (v *Button) SetEnabled(enabled bool) {
|
||||
}
|
||||
|
||||
// GetSize returns the size of the button
|
||||
func (v *Button) GetSize() (uint32, uint32) {
|
||||
func (v Button) GetSize() (uint32, uint32) {
|
||||
return v.width, v.height
|
||||
}
|
||||
|
||||
@ -223,12 +223,12 @@ func (v *Button) MoveTo(x, y int) {
|
||||
}
|
||||
|
||||
// GetLocation returns the location of the button
|
||||
func (v *Button) GetLocation() (x, y int) {
|
||||
func (v Button) GetLocation() (x, y int) {
|
||||
return v.x, v.y
|
||||
}
|
||||
|
||||
// GetVisible returns the visibility of the button
|
||||
func (v *Button) GetVisible() bool {
|
||||
func (v Button) GetVisible() bool {
|
||||
return v.visible
|
||||
}
|
||||
|
||||
@ -238,7 +238,7 @@ func (v *Button) SetVisible(visible bool) {
|
||||
}
|
||||
|
||||
// GetPressed returns the pressed state of the button
|
||||
func (v *Button) GetPressed() bool {
|
||||
func (v Button) GetPressed() bool {
|
||||
return v.pressed
|
||||
}
|
||||
|
||||
|
@ -36,13 +36,12 @@ type Label struct {
|
||||
}
|
||||
|
||||
// CreateLabel creates a new instance of a UI label
|
||||
func CreateLabel(provider d2interface.FileProvider, font string, palette d2enum.PaletteType) *Label {
|
||||
result := &Label{
|
||||
func CreateLabel(provider d2interface.FileProvider, font string, palette d2enum.PaletteType) Label {
|
||||
result := Label{
|
||||
Alignment: LabelAlignLeft,
|
||||
Color: color.White,
|
||||
font: GetFont(font, palette, provider),
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -72,6 +71,10 @@ func (v *Label) MoveTo(x, y int) {
|
||||
v.Y = y
|
||||
}
|
||||
|
||||
func (v *Label) GetTextMetrics(text string) (width, height uint32) {
|
||||
return v.font.GetTextMetrics(text)
|
||||
}
|
||||
|
||||
func (v *Label) cacheImage() {
|
||||
if v.imageData != nil {
|
||||
return
|
||||
@ -93,7 +96,7 @@ func (v *Label) SetText(newText string) {
|
||||
}
|
||||
|
||||
// GetSize returns the size of the label
|
||||
func (v *Label) GetSize() (width, height uint32) {
|
||||
func (v Label) GetSize() (width, height uint32) {
|
||||
v.cacheImage()
|
||||
width = v.Width
|
||||
height = v.Height
|
||||
|
158
d2render/d2ui/TextBox.go
Normal file
158
d2render/d2ui/TextBox.go
Normal file
@ -0,0 +1,158 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2data/d2datadict"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
)
|
||||
|
||||
// TextBox represents a text input box
|
||||
type TextBox struct {
|
||||
text string
|
||||
x int
|
||||
y int
|
||||
visible bool
|
||||
enabled bool
|
||||
bgSprite d2render.Sprite
|
||||
textLabel Label
|
||||
lineBar Label
|
||||
}
|
||||
|
||||
func CreateTextbox(fileProvider d2interface.FileProvider) TextBox {
|
||||
result := TextBox{
|
||||
bgSprite: d2render.CreateSprite(fileProvider.LoadFile(d2resource.TextBox2), d2datadict.Palettes[d2enum.Units]),
|
||||
textLabel: CreateLabel(fileProvider, d2resource.FontFormal11, d2enum.Units),
|
||||
lineBar: CreateLabel(fileProvider, d2resource.FontFormal11, d2enum.Units),
|
||||
enabled: true,
|
||||
visible: true,
|
||||
}
|
||||
result.lineBar.SetText("_")
|
||||
return result
|
||||
}
|
||||
|
||||
func repeatingKeyPressed(key ebiten.Key) bool {
|
||||
const (
|
||||
delay = 30
|
||||
interval = 3
|
||||
)
|
||||
d := inpututil.KeyPressDuration(key)
|
||||
if d == 1 {
|
||||
return true
|
||||
}
|
||||
if d >= delay && (d-delay)%interval == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (v TextBox) Draw(target *ebiten.Image) {
|
||||
if !v.visible {
|
||||
return
|
||||
}
|
||||
v.bgSprite.Draw(target)
|
||||
v.textLabel.Draw(target)
|
||||
if (time.Now().UnixNano()/1e6)&(1<<8) > 0 {
|
||||
v.lineBar.Draw(target)
|
||||
}
|
||||
}
|
||||
|
||||
func (v *TextBox) Update() {
|
||||
if !v.visible || !v.enabled {
|
||||
return
|
||||
}
|
||||
newText := string(ebiten.InputChars())
|
||||
if len(newText) > 0 {
|
||||
v.text += newText
|
||||
v.SetText(v.text)
|
||||
}
|
||||
if repeatingKeyPressed(ebiten.KeyBackspace) {
|
||||
if len(v.text) >= 1 {
|
||||
v.text = v.text[:len(v.text)-1]
|
||||
}
|
||||
v.SetText(v.text)
|
||||
}
|
||||
}
|
||||
|
||||
func (v TextBox) GetText() string {
|
||||
return v.text
|
||||
}
|
||||
|
||||
func (v *TextBox) SetText(newText string) {
|
||||
result := ""
|
||||
for _, c := range newText {
|
||||
if !strings.Contains("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 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.MoveTo(v.x+6+int(tw), v.y+3)
|
||||
v.textLabel.SetText(result)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func (v TextBox) GetSize() (width, height uint32) {
|
||||
return v.bgSprite.GetSize()
|
||||
}
|
||||
|
||||
func (v *TextBox) MoveTo(x, y int) {
|
||||
v.x = x
|
||||
v.y = y
|
||||
v.textLabel.MoveTo(v.x+6, v.y+3)
|
||||
v.lineBar.MoveTo(v.x+6+int(v.textLabel.Width), v.y+3)
|
||||
v.bgSprite.MoveTo(v.x, v.y+26)
|
||||
}
|
||||
|
||||
func (v TextBox) GetLocation() (x, y int) {
|
||||
return v.x, v.y
|
||||
}
|
||||
|
||||
func (v TextBox) GetVisible() bool {
|
||||
return v.visible
|
||||
}
|
||||
|
||||
func (v *TextBox) SetVisible(visible bool) {
|
||||
v.visible = visible
|
||||
}
|
||||
|
||||
func (v TextBox) GetEnabled() bool {
|
||||
return v.enabled
|
||||
}
|
||||
|
||||
func (v *TextBox) SetEnabled(enabled bool) {
|
||||
v.enabled = enabled
|
||||
}
|
||||
|
||||
func (v *TextBox) SetPressed(pressed bool) {
|
||||
// no op
|
||||
}
|
||||
|
||||
func (v TextBox) GetPressed() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (v *TextBox) OnActivated(callback func()) {
|
||||
// no op
|
||||
}
|
||||
|
||||
func (v TextBox) Activate() {
|
||||
//no op
|
||||
}
|
Loading…
Reference in New Issue
Block a user