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
|
fileProvider d2interface.FileProvider
|
||||||
sceneProvider d2interface.SceneProvider
|
sceneProvider d2interface.SceneProvider
|
||||||
background d2render.Sprite
|
background d2render.Sprite
|
||||||
newCharButton *d2ui.Button
|
newCharButton d2ui.Button
|
||||||
convertCharButton *d2ui.Button
|
convertCharButton d2ui.Button
|
||||||
deleteCharButton *d2ui.Button
|
deleteCharButton d2ui.Button
|
||||||
exitButton *d2ui.Button
|
exitButton d2ui.Button
|
||||||
okButton *d2ui.Button
|
okButton d2ui.Button
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateCharacterSelect(
|
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 = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#831"), 15)))
|
||||||
v.newCharButton.MoveTo(33, 468)
|
v.newCharButton.MoveTo(33, 468)
|
||||||
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.newCharButton)
|
v.uiManager.AddWidget(&v.newCharButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.convertCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#825"), 15)))
|
v.convertCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#825"), 15)))
|
||||||
v.convertCharButton.MoveTo(233, 468)
|
v.convertCharButton.MoveTo(233, 468)
|
||||||
v.convertCharButton.SetEnabled(false)
|
v.convertCharButton.SetEnabled(false)
|
||||||
v.uiManager.AddWidget(v.convertCharButton)
|
v.uiManager.AddWidget(&v.convertCharButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.deleteCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#832"), 15)))
|
v.deleteCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, v.fileProvider, dh.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#832"), 15)))
|
||||||
v.deleteCharButton.MoveTo(433, 468)
|
v.deleteCharButton.MoveTo(433, 468)
|
||||||
v.deleteCharButton.SetEnabled(false)
|
v.deleteCharButton.SetEnabled(false)
|
||||||
v.uiManager.AddWidget(v.deleteCharButton)
|
v.uiManager.AddWidget(&v.deleteCharButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
||||||
v.exitButton.MoveTo(33, 537)
|
v.exitButton.MoveTo(33, 537)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.exitButton)
|
v.uiManager.AddWidget(&v.exitButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#971"))
|
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#971"))
|
||||||
v.okButton.MoveTo(625, 537)
|
v.okButton.MoveTo(625, 537)
|
||||||
v.okButton.SetEnabled(false)
|
v.okButton.SetEnabled(false)
|
||||||
v.uiManager.AddWidget(v.okButton)
|
v.uiManager.AddWidget(&v.okButton)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type labelItem struct {
|
type labelItem struct {
|
||||||
Label *d2ui.Label
|
Label d2ui.Label
|
||||||
IsHeading bool
|
IsHeading bool
|
||||||
Available bool
|
Available bool
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ type Credits struct {
|
|||||||
fileProvider d2interface.FileProvider
|
fileProvider d2interface.FileProvider
|
||||||
sceneProvider d2interface.SceneProvider
|
sceneProvider d2interface.SceneProvider
|
||||||
creditsBackground d2render.Sprite
|
creditsBackground d2render.Sprite
|
||||||
exitButton *d2ui.Button
|
exitButton d2ui.Button
|
||||||
creditsText []string
|
creditsText []string
|
||||||
labels []*labelItem
|
labels []*labelItem
|
||||||
cycleTime float64
|
cycleTime float64
|
||||||
@ -68,7 +68,7 @@ func (v *Credits) Load() []func() {
|
|||||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
||||||
v.exitButton.MoveTo(30, 550)
|
v.exitButton.MoveTo(30, 550)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.exitButton)
|
v.uiManager.AddWidget(&v.exitButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
fileData, _ := dh.Utf16BytesToString(v.fileProvider.LoadFile(d2resource.CreditsText)[2:])
|
fileData, _ := dh.Utf16BytesToString(v.fileProvider.LoadFile(d2resource.CreditsText)[2:])
|
||||||
@ -192,7 +192,7 @@ func (v *Credits) getNewFontLabel(isHeading bool) *d2ui.Label {
|
|||||||
} else {
|
} else {
|
||||||
label.Label.Color = color.RGBA{198, 178, 150, 255}
|
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)
|
v.labels = append(v.labels, newLabelItem)
|
||||||
return newLabelItem.Label
|
return &newLabelItem.Label
|
||||||
}
|
}
|
||||||
|
@ -37,17 +37,17 @@ type MainMenu struct {
|
|||||||
diabloLogoRight d2render.Sprite
|
diabloLogoRight d2render.Sprite
|
||||||
diabloLogoLeftBack d2render.Sprite
|
diabloLogoLeftBack d2render.Sprite
|
||||||
diabloLogoRightBack d2render.Sprite
|
diabloLogoRightBack d2render.Sprite
|
||||||
singlePlayerButton *d2ui.Button
|
singlePlayerButton d2ui.Button
|
||||||
githubButton *d2ui.Button
|
githubButton d2ui.Button
|
||||||
exitDiabloButton *d2ui.Button
|
exitDiabloButton d2ui.Button
|
||||||
creditsButton *d2ui.Button
|
creditsButton d2ui.Button
|
||||||
cinematicsButton *d2ui.Button
|
cinematicsButton d2ui.Button
|
||||||
mapTestButton *d2ui.Button
|
mapTestButton d2ui.Button
|
||||||
copyrightLabel *d2ui.Label
|
copyrightLabel d2ui.Label
|
||||||
copyrightLabel2 *d2ui.Label
|
copyrightLabel2 d2ui.Label
|
||||||
openDiabloLabel *d2ui.Label
|
openDiabloLabel d2ui.Label
|
||||||
versionLabel *d2ui.Label
|
versionLabel d2ui.Label
|
||||||
commitLabel *d2ui.Label
|
commitLabel d2ui.Label
|
||||||
|
|
||||||
ShowTrademarkScreen bool
|
ShowTrademarkScreen bool
|
||||||
leftButtonHeld bool
|
leftButtonHeld bool
|
||||||
@ -138,41 +138,41 @@ func (v *MainMenu) Load() []func() {
|
|||||||
v.exitDiabloButton.MoveTo(264, 535)
|
v.exitDiabloButton.MoveTo(264, 535)
|
||||||
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.exitDiabloButton)
|
v.uiManager.AddWidget(&v.exitDiabloButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.creditsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, v.fileProvider, d2common.TranslateString("#1627"))
|
v.creditsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, v.fileProvider, d2common.TranslateString("#1627"))
|
||||||
v.creditsButton.MoveTo(264, 505)
|
v.creditsButton.MoveTo(264, 505)
|
||||||
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.creditsButton)
|
v.uiManager.AddWidget(&v.creditsButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.cinematicsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, v.fileProvider, d2common.TranslateString("#1639"))
|
v.cinematicsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, v.fileProvider, d2common.TranslateString("#1639"))
|
||||||
v.cinematicsButton.MoveTo(401, 505)
|
v.cinematicsButton.MoveTo(401, 505)
|
||||||
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.uiManager.AddWidget(v.cinematicsButton)
|
v.uiManager.AddWidget(&v.cinematicsButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.singlePlayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, d2common.TranslateString("#1620"))
|
v.singlePlayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, d2common.TranslateString("#1620"))
|
||||||
v.singlePlayerButton.MoveTo(264, 290)
|
v.singlePlayerButton.MoveTo(264, 290)
|
||||||
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
||||||
v.uiManager.AddWidget(v.singlePlayerButton)
|
v.uiManager.AddWidget(&v.singlePlayerButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.githubButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, "PROJECT WEBSITE")
|
v.githubButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, "PROJECT WEBSITE")
|
||||||
v.githubButton.MoveTo(264, 330)
|
v.githubButton.MoveTo(264, 330)
|
||||||
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
||||||
v.uiManager.AddWidget(v.githubButton)
|
v.uiManager.AddWidget(&v.githubButton)
|
||||||
},
|
},
|
||||||
func() {
|
func() {
|
||||||
v.mapTestButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, "MAP ENGINE TEST")
|
v.mapTestButton = d2ui.CreateButton(d2ui.ButtonTypeWide, v.fileProvider, "MAP ENGINE TEST")
|
||||||
v.mapTestButton.MoveTo(264, 450)
|
v.mapTestButton.MoveTo(264, 450)
|
||||||
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
||||||
v.uiManager.AddWidget(v.mapTestButton)
|
v.uiManager.AddWidget(&v.mapTestButton)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package d2scene
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
|
|
||||||
@ -35,20 +36,23 @@ type HeroRenderInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SelectHeroClass struct {
|
type SelectHeroClass struct {
|
||||||
uiManager *d2ui.Manager
|
uiManager *d2ui.Manager
|
||||||
soundManager *d2audio.Manager
|
soundManager *d2audio.Manager
|
||||||
fileProvider d2interface.FileProvider
|
fileProvider d2interface.FileProvider
|
||||||
sceneProvider d2interface.SceneProvider
|
sceneProvider d2interface.SceneProvider
|
||||||
bgImage d2render.Sprite
|
bgImage d2render.Sprite
|
||||||
campfire d2render.Sprite
|
campfire d2render.Sprite
|
||||||
headingLabel *d2ui.Label
|
headingLabel d2ui.Label
|
||||||
heroClassLabel *d2ui.Label
|
heroClassLabel d2ui.Label
|
||||||
heroDesc1Label *d2ui.Label
|
heroDesc1Label d2ui.Label
|
||||||
heroDesc2Label *d2ui.Label
|
heroDesc2Label d2ui.Label
|
||||||
heroDesc3Label *d2ui.Label
|
heroDesc3Label d2ui.Label
|
||||||
heroRenderInfo map[d2enum.Hero]*HeroRenderInfo
|
heroNameTextbox d2ui.TextBox
|
||||||
selectedHero d2enum.Hero
|
heroNameLabel d2ui.Label
|
||||||
exitButton *d2ui.Button
|
heroRenderInfo map[d2enum.Hero]*HeroRenderInfo
|
||||||
|
selectedHero d2enum.Hero
|
||||||
|
exitButton d2ui.Button
|
||||||
|
okButton d2ui.Button
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateSelectHeroClass(
|
func CreateSelectHeroClass(
|
||||||
@ -115,7 +119,28 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, v.fileProvider, d2common.TranslateString("#970"))
|
||||||
v.exitButton.MoveTo(33, 537)
|
v.exitButton.MoveTo(33, 537)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
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() {
|
func() {
|
||||||
v.heroRenderInfo[d2enum.HeroBarbarian] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroBarbarian] = &HeroRenderInfo{
|
||||||
@ -368,10 +393,14 @@ func (v *SelectHeroClass) Unload() {
|
|||||||
v.heroRenderInfo = nil
|
v.heroRenderInfo = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) onExitButtonClicked() {
|
func (v SelectHeroClass) onExitButtonClicked() {
|
||||||
v.sceneProvider.SetNextScene(CreateCharacterSelect(v.fileProvider, v.sceneProvider, v.uiManager, v.soundManager))
|
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) {
|
func (v *SelectHeroClass) Render(screen *ebiten.Image) {
|
||||||
v.bgImage.DrawSegments(screen, 4, 3, 0)
|
v.bgImage.DrawSegments(screen, 4, 3, 0)
|
||||||
v.headingLabel.Draw(screen)
|
v.headingLabel.Draw(screen)
|
||||||
@ -392,6 +421,9 @@ func (v *SelectHeroClass) Render(screen *ebiten.Image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
v.campfire.Draw(screen)
|
v.campfire.Draw(screen)
|
||||||
|
if v.heroNameTextbox.GetVisible() {
|
||||||
|
v.heroNameLabel.Draw(screen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) Update(tickTime float64) {
|
func (v *SelectHeroClass) Update(tickTime float64) {
|
||||||
@ -412,6 +444,8 @@ func (v *SelectHeroClass) Update(tickTime float64) {
|
|||||||
if v.selectedHero != d2enum.HeroNone && allIdle {
|
if v.selectedHero != d2enum.HeroNone && allIdle {
|
||||||
v.selectedHero = d2enum.HeroNone
|
v.selectedHero = d2enum.HeroNone
|
||||||
}
|
}
|
||||||
|
v.heroNameTextbox.Update()
|
||||||
|
v.okButton.SetEnabled(len(v.heroNameTextbox.GetText()) >= 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) updateHeroSelectionHover(hero d2enum.Hero, canSelect bool) {
|
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
|
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)
|
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) {
|
if mouseHover && v.uiManager.CursorButtonPressed(d2ui.CursorButtonLeft) {
|
||||||
// showEntryUi = true;
|
v.heroNameTextbox.SetVisible(true)
|
||||||
|
v.okButton.SetVisible(true)
|
||||||
renderInfo.Stance = d2enum.HeroStanceApproaching
|
renderInfo.Stance = d2enum.HeroStanceApproaching
|
||||||
renderInfo.ForwardWalkSprite.ResetAnimation()
|
renderInfo.ForwardWalkSprite.ResetAnimation()
|
||||||
if renderInfo.ForwardWalkSpriteOverlay.IsValid() {
|
if renderInfo.ForwardWalkSpriteOverlay.IsValid() {
|
||||||
|
@ -3,6 +3,7 @@ package d2render
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -156,7 +157,9 @@ func (v *AnimatedEntity) Render(target *ebiten.Image, offsetX, offsetY int) {
|
|||||||
opts := &ebiten.DrawImageOptions{}
|
opts := &ebiten.DrawImageOptions{}
|
||||||
opts.GeoM.Translate(float64(v.frameLocations[frameName][v.currentFrame].Left+offsetX),
|
opts.GeoM.Translate(float64(v.frameLocations[frameName][v.currentFrame].Left+offsetX),
|
||||||
float64(v.frameLocations[frameName][v.currentFrame].Top+offsetY+40))
|
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"
|
"encoding/binary"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -29,7 +30,6 @@ type Sprite struct {
|
|||||||
LastFrameTime time.Time
|
LastFrameTime time.Time
|
||||||
Animate bool
|
Animate bool
|
||||||
ColorMod color.Color
|
ColorMod color.Color
|
||||||
visible bool
|
|
||||||
valid bool
|
valid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ func CreateSprite(data []byte, palette d2datadict.PaletteRec) Sprite {
|
|||||||
|
|
||||||
x := uint32(0)
|
x := uint32(0)
|
||||||
y := result.Frames[i].Height - 1
|
y := result.Frames[i].Height - 1
|
||||||
for true {
|
for {
|
||||||
b := data[dataPointer]
|
b := data[dataPointer]
|
||||||
dataPointer++
|
dataPointer++
|
||||||
if b == 0x80 {
|
if b == 0x80 {
|
||||||
@ -197,7 +197,9 @@ func (v *Sprite) cacheFrame(frame int) {
|
|||||||
v.atlasBytes[idx+3] = v.Frames[frame].FrameData[pix+3]
|
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
|
v.Frames[frame].cached = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +220,7 @@ func (v *Sprite) updateAnimation() {
|
|||||||
} else {
|
} else {
|
||||||
timePerFrame = time.Duration(float64(time.Second) * (1.0 / float64(len(v.Frames))))
|
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.LastFrameTime = v.LastFrameTime.Add(timePerFrame)
|
||||||
v.Frame++
|
v.Frame++
|
||||||
if v.Frame >= uint8(v.FramesPerDirection) {
|
if v.Frame >= uint8(v.FramesPerDirection) {
|
||||||
@ -272,7 +274,9 @@ func (v *Sprite) Draw(target *ebiten.Image) {
|
|||||||
if v.ColorMod != nil {
|
if v.ColorMod != nil {
|
||||||
opts.ColorM = d2helper.ColorToColorM(v.ColorMod)
|
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
|
// 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 {
|
if v.ColorMod != nil {
|
||||||
opts.ColorM = d2helper.ColorToColorM(v.ColorMod)
|
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)
|
xOffset += int32(frame.Width)
|
||||||
biggestYOffset = d2helper.MaxInt32(biggestYOffset, int32(frame.Height))
|
biggestYOffset = d2helper.MaxInt32(biggestYOffset, int32(frame.Height))
|
||||||
}
|
}
|
||||||
|
@ -108,8 +108,8 @@ type Button struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateButton creates an instance of Button
|
// CreateButton creates an instance of Button
|
||||||
func CreateButton(buttonType ButtonType, fileProvider d2interface.FileProvider, text string) *Button {
|
func CreateButton(buttonType ButtonType, fileProvider d2interface.FileProvider, text string) Button {
|
||||||
result := &Button{
|
result := Button{
|
||||||
fileProvider: fileProvider,
|
fileProvider: fileProvider,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
@ -159,7 +159,7 @@ func CreateButton(buttonType ButtonType, fileProvider d2interface.FileProvider,
|
|||||||
if buttonLayout.DisabledFrame != -1 {
|
if buttonLayout.DisabledFrame != -1 {
|
||||||
result.disabledImage, _ = ebiten.NewImage(int(result.width), int(result.height), ebiten.FilterNearest)
|
result.disabledImage, _ = ebiten.NewImage(int(result.width), int(result.height), ebiten.FilterNearest)
|
||||||
buttonSprite.DrawSegments(result.disabledImage, buttonLayout.XSegments, buttonLayout.YSegments, buttonLayout.DisabledFrame)
|
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
|
return result
|
||||||
@ -171,7 +171,7 @@ func (v *Button) OnActivated(callback func()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Activate calls the on activated callback handler, if any
|
// Activate calls the on activated callback handler, if any
|
||||||
func (v *Button) Activate() {
|
func (v Button) Activate() {
|
||||||
if v.onClick == nil {
|
if v.onClick == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ func (v *Button) Activate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw renders the button
|
// Draw renders the button
|
||||||
func (v *Button) Draw(target *ebiten.Image) {
|
func (v Button) Draw(target *ebiten.Image) {
|
||||||
opts := &ebiten.DrawImageOptions{
|
opts := &ebiten.DrawImageOptions{
|
||||||
CompositeMode: ebiten.CompositeModeSourceAtop,
|
CompositeMode: ebiten.CompositeModeSourceAtop,
|
||||||
Filter: ebiten.FilterNearest,
|
Filter: ebiten.FilterNearest,
|
||||||
@ -202,7 +202,7 @@ func (v *Button) Draw(target *ebiten.Image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetEnabled returns the enabled state
|
// GetEnabled returns the enabled state
|
||||||
func (v *Button) GetEnabled() bool {
|
func (v Button) GetEnabled() bool {
|
||||||
return v.enabled
|
return v.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ func (v *Button) SetEnabled(enabled bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the size of the button
|
// GetSize returns the size of the button
|
||||||
func (v *Button) GetSize() (uint32, uint32) {
|
func (v Button) GetSize() (uint32, uint32) {
|
||||||
return v.width, v.height
|
return v.width, v.height
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,12 +223,12 @@ func (v *Button) MoveTo(x, y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLocation returns the location of the button
|
// 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
|
return v.x, v.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVisible returns the visibility of the button
|
// GetVisible returns the visibility of the button
|
||||||
func (v *Button) GetVisible() bool {
|
func (v Button) GetVisible() bool {
|
||||||
return v.visible
|
return v.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ func (v *Button) SetVisible(visible bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPressed returns the pressed state of the button
|
// GetPressed returns the pressed state of the button
|
||||||
func (v *Button) GetPressed() bool {
|
func (v Button) GetPressed() bool {
|
||||||
return v.pressed
|
return v.pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +36,12 @@ type Label struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateLabel creates a new instance of a UI label
|
// CreateLabel creates a new instance of a UI label
|
||||||
func CreateLabel(provider d2interface.FileProvider, font string, palette d2enum.PaletteType) *Label {
|
func CreateLabel(provider d2interface.FileProvider, font string, palette d2enum.PaletteType) Label {
|
||||||
result := &Label{
|
result := Label{
|
||||||
Alignment: LabelAlignLeft,
|
Alignment: LabelAlignLeft,
|
||||||
Color: color.White,
|
Color: color.White,
|
||||||
font: GetFont(font, palette, provider),
|
font: GetFont(font, palette, provider),
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +71,10 @@ func (v *Label) MoveTo(x, y int) {
|
|||||||
v.Y = y
|
v.Y = y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Label) GetTextMetrics(text string) (width, height uint32) {
|
||||||
|
return v.font.GetTextMetrics(text)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Label) cacheImage() {
|
func (v *Label) cacheImage() {
|
||||||
if v.imageData != nil {
|
if v.imageData != nil {
|
||||||
return
|
return
|
||||||
@ -93,7 +96,7 @@ func (v *Label) SetText(newText string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the size of the label
|
// GetSize returns the size of the label
|
||||||
func (v *Label) GetSize() (width, height uint32) {
|
func (v Label) GetSize() (width, height uint32) {
|
||||||
v.cacheImage()
|
v.cacheImage()
|
||||||
width = v.Width
|
width = v.Width
|
||||||
height = v.Height
|
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