mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-10-01 15:46:17 -04:00
Continued work on GUI (#316)
* Configuration cleanup * Cleanup * Continued UI work
This commit is contained in:
parent
2285c31b53
commit
6f2c212417
@ -60,6 +60,10 @@ func loadFont(tablePath, spritePath, palettePath string) (*Font, error) {
|
|||||||
return font, nil
|
return font, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Font) SetColor(color color.Color) {
|
||||||
|
f.color = color
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Font) GetTextMetrics(text string) (int, int) {
|
func (f *Font) GetTextMetrics(text string) (int, int) {
|
||||||
var (
|
var (
|
||||||
lineWidth int
|
lineWidth int
|
||||||
|
131
d2core/d2gui/button.go
Normal file
131
d2core/d2gui/button.go
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
type buttonState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
buttonStateDefault buttonState = iota
|
||||||
|
buttonStatePressed
|
||||||
|
buttonStateToggled
|
||||||
|
buttonStatePressedToggled
|
||||||
|
)
|
||||||
|
|
||||||
|
type Button struct {
|
||||||
|
widgetBase
|
||||||
|
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
state buttonState
|
||||||
|
surfaces []d2render.Surface
|
||||||
|
}
|
||||||
|
|
||||||
|
func createButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||||
|
config, ok := buttonStyleConfigs[buttonStyle]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("invalid button style")
|
||||||
|
}
|
||||||
|
|
||||||
|
animation, err := d2asset.LoadAnimation(config.animationPath, config.palettePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonWidth int
|
||||||
|
for i := 0; i < config.segmentsX; i++ {
|
||||||
|
w, _, err := animation.GetFrameSize(i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonWidth += w
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonHeight int
|
||||||
|
for i := 0; i < config.segmentsY; i++ {
|
||||||
|
_, h, err := animation.GetFrameSize(i * config.segmentsY)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonHeight += h
|
||||||
|
}
|
||||||
|
|
||||||
|
font, err := loadFont(config.fontStyle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
textColor := color.RGBA{R: 0x64, G: 0x64, B: 0x64, A: 0xff}
|
||||||
|
textWidth, textHeight := font.GetTextMetrics(text)
|
||||||
|
textX := buttonWidth/2 - textWidth/2
|
||||||
|
textY := buttonHeight/2 - textHeight/2 + config.textOffset
|
||||||
|
|
||||||
|
surfaceCount := animation.GetFrameCount() / (config.segmentsX * config.segmentsY)
|
||||||
|
surfaces := make([]d2render.Surface, surfaceCount)
|
||||||
|
for i := 0; i < surfaceCount; i++ {
|
||||||
|
surface, err := d2render.NewSurface(buttonWidth, buttonHeight, d2render.FilterNearest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := renderSegmented(animation, config.segmentsX, config.segmentsY, i, surface); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
font.SetColor(textColor)
|
||||||
|
|
||||||
|
var textOffsetX, textOffsetY int
|
||||||
|
switch buttonState(i) {
|
||||||
|
case buttonStatePressed, buttonStatePressedToggled:
|
||||||
|
textOffsetX = -2
|
||||||
|
textOffsetY = 2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
surface.PushTranslation(textX+textOffsetX, textY+textOffsetY)
|
||||||
|
err = font.RenderText(text, surface)
|
||||||
|
surface.Pop()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaces[i] = surface
|
||||||
|
}
|
||||||
|
|
||||||
|
button := &Button{width: buttonWidth, height: buttonHeight, surfaces: surfaces}
|
||||||
|
button.SetVisible(true)
|
||||||
|
|
||||||
|
return button, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) onMouseButtonDown(event d2input.MouseEvent) bool {
|
||||||
|
b.state = buttonStatePressed
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) onMouseButtonUp(event d2input.MouseEvent) bool {
|
||||||
|
b.state = buttonStateDefault
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) onMouseLeave(event d2input.MouseMoveEvent) bool {
|
||||||
|
b.state = buttonStateDefault
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) render(target d2render.Surface) error {
|
||||||
|
return target.Render(b.surfaces[b.state])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) getSize() (int, int) {
|
||||||
|
return b.width, b.height
|
||||||
|
}
|
46
d2core/d2gui/common.go
Normal file
46
d2core/d2gui/common.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
func loadFont(fontStyle FontStyle) (*d2asset.Font, error) {
|
||||||
|
config, ok := fontStyleConfigs[fontStyle]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("invalid font style")
|
||||||
|
}
|
||||||
|
|
||||||
|
return d2asset.LoadFont(config.fontBasePath+".tbl", config.fontBasePath+".dc6", config.palettePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderSegmented(animation *d2asset.Animation, segmentsX, segmentsY, frameOffset int, target d2render.Surface) error {
|
||||||
|
var currentY int
|
||||||
|
for y := 0; y < segmentsY; y++ {
|
||||||
|
var currentX int
|
||||||
|
var maxHeight int
|
||||||
|
for x := 0; x < segmentsX; x++ {
|
||||||
|
if err := animation.SetCurrentFrame(x + y*segmentsX + frameOffset*segmentsX*segmentsY); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
target.PushTranslation(x+currentX, y+currentY)
|
||||||
|
err := animation.Render(target)
|
||||||
|
target.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
width, height := animation.GetCurrentFrameSize()
|
||||||
|
maxHeight = d2common.MaxInt(maxHeight, height)
|
||||||
|
currentX += width
|
||||||
|
}
|
||||||
|
|
||||||
|
currentY += maxHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -34,21 +34,14 @@ func Advance(elapsed float64) error {
|
|||||||
return singleton.advance(elapsed)
|
return singleton.advance(elapsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddLayout() *Layout {
|
func CreateLayout(positionType PositionType) *Layout {
|
||||||
return singleton.addLayout()
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddSprite(imagePath, palettePath string) *Sprite {
|
|
||||||
return singleton.addSprite(imagePath, palettePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddLabel(text string, fontStyle FontStyle) *Label {
|
|
||||||
return singleton.addLabel(text, fontStyle)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Clear() {
|
|
||||||
verifyWasInit()
|
verifyWasInit()
|
||||||
singleton.clear()
|
return createLayout(positionType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLayout(layout *Layout) {
|
||||||
|
verifyWasInit()
|
||||||
|
singleton.SetLayout(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowLoadScreen(progress float64) {
|
func ShowLoadScreen(progress float64) {
|
||||||
|
@ -1,60 +1,41 @@
|
|||||||
package d2gui
|
package d2gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Label struct {
|
type Label struct {
|
||||||
widgetBase
|
widgetBase
|
||||||
|
|
||||||
text string
|
|
||||||
font *d2asset.Font
|
|
||||||
surface d2render.Surface
|
surface d2render.Surface
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLabel(text string, fontStyle FontStyle) *Label {
|
func createLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||||
font, _ := loadFont(fontStyle)
|
font, err := loadFont(fontStyle)
|
||||||
label := &Label{font: font}
|
if err != nil {
|
||||||
label.SetText(text)
|
return nil, err
|
||||||
label.visible = true
|
}
|
||||||
return label
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Label) SetText(text string) *Label {
|
width, height := font.GetTextMetrics(text)
|
||||||
l.text = text
|
surface, err := d2render.NewSurface(width, height, d2render.FilterNearest)
|
||||||
l.cache()
|
if err != nil {
|
||||||
return l
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := font.RenderText(text, surface); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
label := &Label{surface: surface}
|
||||||
|
label.SetVisible(true)
|
||||||
|
|
||||||
|
return label, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Label) render(target d2render.Surface) error {
|
func (l *Label) render(target d2render.Surface) error {
|
||||||
if l.surface == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return target.Render(l.surface)
|
return target.Render(l.surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Label) cache() error {
|
|
||||||
l.surface = nil
|
|
||||||
if l.font == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
width, height := l.font.GetTextMetrics(l.text)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
if l.surface, err = d2render.NewSurface(width, height, d2render.FilterNearest); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return l.font.RenderText(l.text, l.surface)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Label) getSize() (int, int) {
|
func (l *Label) getSize() (int, int) {
|
||||||
if l.surface == nil {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return l.surface.GetSize()
|
return l.surface.GetSize()
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package d2gui
|
|||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
)
|
)
|
||||||
@ -10,26 +11,136 @@ import (
|
|||||||
type layoutEntry struct {
|
type layoutEntry struct {
|
||||||
widget widget
|
widget widget
|
||||||
|
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
|
||||||
mouseOver bool
|
mouseOver bool
|
||||||
mouseDown [3]bool
|
mouseDown [3]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VerticalAlign int
|
||||||
|
|
||||||
|
const (
|
||||||
|
VerticalAlignTop VerticalAlign = iota
|
||||||
|
VerticalAlignMiddle
|
||||||
|
VerticalAlignBottom
|
||||||
|
)
|
||||||
|
|
||||||
|
type HorizontalAlign int
|
||||||
|
|
||||||
|
const (
|
||||||
|
HorizontalAlignLeft HorizontalAlign = iota
|
||||||
|
HorizontalAlignCenter
|
||||||
|
HorizontalAlignRight
|
||||||
|
)
|
||||||
|
|
||||||
|
type PositionType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PositionTypeAbsolute PositionType = iota
|
||||||
|
PositionTypeVertical
|
||||||
|
PositionTypeHorizontal
|
||||||
|
)
|
||||||
|
|
||||||
type Layout struct {
|
type Layout struct {
|
||||||
widgetBase
|
widgetBase
|
||||||
entries []*layoutEntry
|
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
verticalAlign VerticalAlign
|
||||||
|
horizontalAlign HorizontalAlign
|
||||||
|
positionType PositionType
|
||||||
|
entries []*layoutEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLayout() *Layout {
|
func createLayout(positionType PositionType) *Layout {
|
||||||
layout := new(Layout)
|
layout := &Layout{positionType: positionType}
|
||||||
layout.visible = true
|
layout.SetVisible(true)
|
||||||
|
|
||||||
return layout
|
return layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Layout) SetSize(width, height int) {
|
||||||
|
l.width = width
|
||||||
|
l.height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) SetVerticalAlign(verticalAlign VerticalAlign) {
|
||||||
|
l.verticalAlign = verticalAlign
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) SetHorizontalAlign(horizontalAlign HorizontalAlign) {
|
||||||
|
l.horizontalAlign = horizontalAlign
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) AddLayout(positionType PositionType) *Layout {
|
||||||
|
layout := createLayout(positionType)
|
||||||
|
l.entries = append(l.entries, &layoutEntry{widget: layout})
|
||||||
|
return layout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) AddSpacerStatic(width, height int) *SpacerStatic {
|
||||||
|
spacer := createSpacerStatic(width, height)
|
||||||
|
l.entries = append(l.entries, &layoutEntry{widget: spacer})
|
||||||
|
return spacer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) AddSpacerDynamic() *SpacerDynamic {
|
||||||
|
spacer := createSpacerDynamic()
|
||||||
|
l.entries = append(l.entries, &layoutEntry{widget: spacer})
|
||||||
|
return spacer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) AddSprite(imagePath, palettePath string) (*Sprite, error) {
|
||||||
|
sprite, err := createSprite(imagePath, palettePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.entries = append(l.entries, &layoutEntry{widget: sprite})
|
||||||
|
return sprite, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) AddLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||||
|
label, err := createLabel(text, fontStyle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.entries = append(l.entries, &layoutEntry{widget: label})
|
||||||
|
return label, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) AddButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||||
|
button, err := createButton(text, buttonStyle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
l.entries = append(l.entries, &layoutEntry{widget: button})
|
||||||
|
return button, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) Clear() {
|
||||||
|
l.entries = nil
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Layout) render(target d2render.Surface) error {
|
func (l *Layout) render(target d2render.Surface) error {
|
||||||
|
l.adjustEntryPlacement()
|
||||||
|
|
||||||
for _, entry := range l.entries {
|
for _, entry := range l.entries {
|
||||||
if entry.widget.isVisible() {
|
if !entry.widget.isVisible() {
|
||||||
l.renderWidget(entry.widget, target)
|
continue
|
||||||
l.renderWidgetDebug(entry.widget, target)
|
}
|
||||||
|
|
||||||
|
if err := l.renderEntry(entry, target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := l.renderEntryDebug(entry, target); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,51 +149,88 @@ func (l *Layout) render(target d2render.Surface) error {
|
|||||||
|
|
||||||
func (l *Layout) advance(elapsed float64) error {
|
func (l *Layout) advance(elapsed float64) error {
|
||||||
for _, entry := range l.entries {
|
for _, entry := range l.entries {
|
||||||
if entry.widget.isVisible() {
|
if err := entry.widget.advance(elapsed); err != nil {
|
||||||
if err := entry.widget.advance(elapsed); err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) renderWidget(widget widget, target d2render.Surface) {
|
func (l *Layout) renderEntry(entry *layoutEntry, target d2render.Surface) error {
|
||||||
target.PushTranslation(widget.getPosition())
|
target.PushTranslation(entry.x, entry.y)
|
||||||
defer target.Pop()
|
defer target.Pop()
|
||||||
|
|
||||||
widget.render(target)
|
return entry.widget.render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) renderWidgetDebug(widget widget, target d2render.Surface) {
|
func (l *Layout) renderEntryDebug(entry *layoutEntry, target d2render.Surface) error {
|
||||||
target.PushTranslation(widget.getPosition())
|
target.PushTranslation(entry.x, entry.y)
|
||||||
defer target.Pop()
|
defer target.Pop()
|
||||||
|
|
||||||
drawColor := color.RGBA{R: 0x00, G: 0x00, B: 0xff, A: 0xb0}
|
drawColor := color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}
|
||||||
|
switch entry.widget.(type) {
|
||||||
|
case *Layout:
|
||||||
|
drawColor = color.RGBA{R: 0xff, G: 0x00, B: 0xff, A: 0xff}
|
||||||
|
case *SpacerStatic, *SpacerDynamic:
|
||||||
|
drawColor = color.RGBA{R: 0x80, G: 0x80, B: 0x80, A: 0xff}
|
||||||
|
case *Label:
|
||||||
|
drawColor = color.RGBA{R: 0x00, G: 0x00, B: 0xff, A: 0xff}
|
||||||
|
case *Button:
|
||||||
|
drawColor = color.RGBA{R: 0xff, G: 0xff, B: 0x00, A: 0xff}
|
||||||
|
}
|
||||||
|
|
||||||
width, height := widget.getSize()
|
target.DrawLine(entry.width, 0, drawColor)
|
||||||
target.DrawLine(width, 0, drawColor)
|
target.DrawLine(0, entry.height, drawColor)
|
||||||
target.DrawLine(0, height, drawColor)
|
|
||||||
|
|
||||||
target.PushTranslation(width, 0)
|
target.PushTranslation(entry.width, 0)
|
||||||
target.DrawLine(0, height, drawColor)
|
target.DrawLine(0, entry.height, drawColor)
|
||||||
target.Pop()
|
target.Pop()
|
||||||
|
|
||||||
target.PushTranslation(0, height)
|
target.PushTranslation(0, entry.height)
|
||||||
target.DrawLine(width, 0, drawColor)
|
target.DrawLine(entry.width, 0, drawColor)
|
||||||
target.Pop()
|
target.Pop()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Layout) getContentSize() (int, int) {
|
||||||
|
var width, height int
|
||||||
|
|
||||||
|
for _, entry := range l.entries {
|
||||||
|
x, y := entry.widget.getPosition()
|
||||||
|
w, h := entry.widget.getSize()
|
||||||
|
|
||||||
|
switch l.positionType {
|
||||||
|
case PositionTypeVertical:
|
||||||
|
width = d2common.MaxInt(width, w)
|
||||||
|
height += h
|
||||||
|
break
|
||||||
|
case PositionTypeHorizontal:
|
||||||
|
width += w
|
||||||
|
height = d2common.MaxInt(height, h)
|
||||||
|
break
|
||||||
|
case PositionTypeAbsolute:
|
||||||
|
width = d2common.MaxInt(width, x+w)
|
||||||
|
height = d2common.MaxInt(height, y+h)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return width, height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) getSize() (int, int) {
|
func (l *Layout) getSize() (int, int) {
|
||||||
return 0, 0
|
width, height := l.getContentSize()
|
||||||
|
return d2common.MaxInt(width, l.width), d2common.MaxInt(height, l.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) onMouseButtonDown(event d2input.MouseEvent) bool {
|
func (l *Layout) onMouseButtonDown(event d2input.MouseEvent) bool {
|
||||||
for _, entry := range l.entries {
|
for _, entry := range l.entries {
|
||||||
eventLocal := event
|
eventLocal := event
|
||||||
|
|
||||||
if l.adjustEventCoords(entry.widget, &eventLocal.X, &eventLocal.Y) {
|
if l.adjustEntryEvent(entry, &eventLocal.X, &eventLocal.Y) {
|
||||||
|
entry.widget.onMouseButtonDown(eventLocal)
|
||||||
entry.mouseDown[event.Button] = true
|
entry.mouseDown[event.Button] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,9 +242,10 @@ func (l *Layout) onMouseButtonUp(event d2input.MouseEvent) bool {
|
|||||||
for _, entry := range l.entries {
|
for _, entry := range l.entries {
|
||||||
eventLocal := event
|
eventLocal := event
|
||||||
|
|
||||||
if l.adjustEventCoords(entry.widget, &eventLocal.X, &eventLocal.Y) {
|
if l.adjustEntryEvent(entry, &eventLocal.X, &eventLocal.Y) {
|
||||||
if entry.mouseDown[event.Button] {
|
if entry.mouseDown[event.Button] {
|
||||||
entry.widget.onMouseClick(eventLocal)
|
entry.widget.onMouseButtonClick(eventLocal)
|
||||||
|
entry.widget.onMouseButtonUp(eventLocal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +259,8 @@ func (l *Layout) onMouseMove(event d2input.MouseMoveEvent) bool {
|
|||||||
for _, entry := range l.entries {
|
for _, entry := range l.entries {
|
||||||
eventLocal := event
|
eventLocal := event
|
||||||
|
|
||||||
if l.adjustEventCoords(entry.widget, &eventLocal.X, &eventLocal.Y) {
|
if l.adjustEntryEvent(entry, &eventLocal.X, &eventLocal.Y) {
|
||||||
|
entry.widget.onMouseMove(eventLocal)
|
||||||
if entry.mouseOver {
|
if entry.mouseOver {
|
||||||
entry.widget.onMouseOver(eventLocal)
|
entry.widget.onMouseOver(eventLocal)
|
||||||
} else {
|
} else {
|
||||||
@ -126,38 +276,90 @@ func (l *Layout) onMouseMove(event d2input.MouseMoveEvent) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) adjustEventCoords(widget widget, eventX, eventY *int) bool {
|
func (l *Layout) adjustEntryEvent(entry *layoutEntry, eventX, eventY *int) bool {
|
||||||
x, y := widget.getPosition()
|
*eventX -= entry.x
|
||||||
width, height := widget.getSize()
|
*eventY -= entry.y
|
||||||
|
|
||||||
*eventX -= x
|
if *eventX < 0 || *eventY < 0 || *eventX >= entry.width || *eventY >= entry.height {
|
||||||
*eventY -= y
|
|
||||||
|
|
||||||
if *eventX < 0 || *eventY < 0 || *eventX >= width || *eventY >= height {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) addLayout() *Layout {
|
func (l *Layout) adjustEntryPlacement() {
|
||||||
layout := createLayout()
|
width, height := l.getSize()
|
||||||
l.entries = append(l.entries, &layoutEntry{widget: layout})
|
|
||||||
return layout
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Layout) addSprite(imagePath, palettePath string) *Sprite {
|
var expanderCount int
|
||||||
sprite := createSprite(imagePath, palettePath)
|
for _, entry := range l.entries {
|
||||||
l.entries = append(l.entries, &layoutEntry{widget: sprite})
|
if entry.widget.isVisible() && entry.widget.isExpanding() {
|
||||||
return sprite
|
expanderCount++
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Layout) addLabel(text string, fontStyle FontStyle) *Label {
|
var expanderWidth, expanderHeight int
|
||||||
label := createLabel(text, fontStyle)
|
if expanderCount > 0 {
|
||||||
l.entries = append(l.entries, &layoutEntry{widget: label})
|
contentWidth, contentHeight := l.getContentSize()
|
||||||
return label
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Layout) clear() {
|
switch l.positionType {
|
||||||
l.entries = nil
|
case PositionTypeVertical:
|
||||||
|
expanderHeight = (height - contentHeight) / expanderCount
|
||||||
|
break
|
||||||
|
case PositionTypeHorizontal:
|
||||||
|
expanderWidth = (width - contentWidth) / expanderCount
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
expanderWidth = d2common.MaxInt(0, expanderWidth)
|
||||||
|
expanderHeight = d2common.MaxInt(0, expanderHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
var offsetX, offsetY int
|
||||||
|
for _, entry := range l.entries {
|
||||||
|
if !entry.widget.isVisible() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.widget.isExpanding() {
|
||||||
|
entry.width, entry.height = expanderWidth, expanderHeight
|
||||||
|
} else {
|
||||||
|
entry.width, entry.height = entry.widget.getSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch l.positionType {
|
||||||
|
case PositionTypeVertical:
|
||||||
|
entry.y = offsetY
|
||||||
|
offsetY += entry.height
|
||||||
|
switch l.horizontalAlign {
|
||||||
|
case HorizontalAlignLeft:
|
||||||
|
entry.x = 0
|
||||||
|
break
|
||||||
|
case HorizontalAlignCenter:
|
||||||
|
entry.x = width/2 - entry.width/2
|
||||||
|
break
|
||||||
|
case HorizontalAlignRight:
|
||||||
|
entry.x = width - entry.width
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case PositionTypeHorizontal:
|
||||||
|
entry.x = offsetX
|
||||||
|
offsetX += entry.width
|
||||||
|
switch l.verticalAlign {
|
||||||
|
case VerticalAlignTop:
|
||||||
|
entry.y = 0
|
||||||
|
break
|
||||||
|
case VerticalAlignMiddle:
|
||||||
|
entry.y = height/2 - entry.height/2
|
||||||
|
break
|
||||||
|
case VerticalAlignBottom:
|
||||||
|
entry.y = height - entry.height
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case PositionTypeAbsolute:
|
||||||
|
entry.x, entry.y = entry.widget.getPosition()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type manager struct {
|
type manager struct {
|
||||||
Layout
|
layout *Layout
|
||||||
|
|
||||||
cursorAnim *d2asset.Animation
|
cursorAnim *d2asset.Animation
|
||||||
cursorX int
|
cursorX int
|
||||||
@ -46,19 +46,35 @@ func createGuiManager() (*manager, error) {
|
|||||||
return manager, nil
|
return manager, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *manager) SetLayout(layout *Layout) {
|
||||||
|
m.layout = layout
|
||||||
|
}
|
||||||
|
|
||||||
func (m *manager) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
func (m *manager) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
||||||
return m.Layout.onMouseButtonDown(event)
|
if m.layout == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.layout.onMouseButtonDown(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) OnMouseButtonUp(event d2input.MouseEvent) bool {
|
func (m *manager) OnMouseButtonUp(event d2input.MouseEvent) bool {
|
||||||
return m.Layout.onMouseButtonUp(event)
|
if m.layout == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.layout.onMouseButtonUp(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) OnMouseMove(event d2input.MouseMoveEvent) bool {
|
func (m *manager) OnMouseMove(event d2input.MouseMoveEvent) bool {
|
||||||
m.cursorX = event.X
|
m.cursorX = event.X
|
||||||
m.cursorY = event.Y
|
m.cursorY = event.Y
|
||||||
|
|
||||||
return m.Layout.onMouseMove(event)
|
if m.layout == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.layout.onMouseMove(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) render(target d2render.Surface) error {
|
func (m *manager) render(target d2render.Surface) error {
|
||||||
@ -66,8 +82,9 @@ func (m *manager) render(target d2render.Surface) error {
|
|||||||
if err := m.renderLoadScreen(target); err != nil {
|
if err := m.renderLoadScreen(target); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else if m.layout != nil {
|
||||||
if err := m.Layout.render(target); err != nil {
|
m.layout.SetSize(target.GetSize())
|
||||||
|
if err := m.layout.render(target); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,8 +120,8 @@ func (m *manager) renderCursor(target d2render.Surface) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) advance(elapsed float64) error {
|
func (m *manager) advance(elapsed float64) error {
|
||||||
if !m.loading {
|
if !m.loading && m.layout != nil {
|
||||||
if err := m.Layout.advance(elapsed); err != nil {
|
if err := m.layout.advance(elapsed); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,6 +153,6 @@ func (m *manager) hideCursor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) clear() {
|
func (m *manager) clear() {
|
||||||
m.Layout.clear()
|
m.SetLayout(nil)
|
||||||
m.hideLoadScreen()
|
m.hideLoadScreen()
|
||||||
}
|
}
|
||||||
|
31
d2core/d2gui/spacer.go
Normal file
31
d2core/d2gui/spacer.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
type SpacerStatic struct {
|
||||||
|
widgetBase
|
||||||
|
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSpacerStatic(width, height int) *SpacerStatic {
|
||||||
|
spacer := &SpacerStatic{width: width, height: height}
|
||||||
|
spacer.SetVisible(true)
|
||||||
|
|
||||||
|
return spacer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SpacerStatic) getSize() (int, int) {
|
||||||
|
return s.width, s.height
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpacerDynamic struct {
|
||||||
|
widgetBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func createSpacerDynamic() *SpacerDynamic {
|
||||||
|
spacer := &SpacerDynamic{}
|
||||||
|
spacer.SetVisible(true)
|
||||||
|
spacer.SetExpanding(true)
|
||||||
|
|
||||||
|
return spacer
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package d2gui
|
package d2gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
)
|
)
|
||||||
@ -16,11 +15,17 @@ type Sprite struct {
|
|||||||
animation *d2asset.Animation
|
animation *d2asset.Animation
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSprite(imagePath, palettePath string) *Sprite {
|
func createSprite(imagePath, palettePath string) (*Sprite, error) {
|
||||||
sprite := new(Sprite)
|
animation, err := d2asset.LoadAnimation(imagePath, palettePath)
|
||||||
sprite.animation, _ = d2asset.LoadAnimation(imagePath, palettePath)
|
if err != nil {
|
||||||
sprite.visible = true
|
return nil, err
|
||||||
return sprite
|
}
|
||||||
|
|
||||||
|
sprite := &Sprite{}
|
||||||
|
sprite.animation = animation
|
||||||
|
sprite.SetVisible(true)
|
||||||
|
|
||||||
|
return sprite, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) SetSegmented(segmentsX, segmentsY, frameOffset int) {
|
func (s *Sprite) SetSegmented(segmentsX, segmentsY, frameOffset int) {
|
||||||
@ -30,57 +35,13 @@ func (s *Sprite) SetSegmented(segmentsX, segmentsY, frameOffset int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) render(target d2render.Surface) error {
|
func (s *Sprite) render(target d2render.Surface) error {
|
||||||
if s.animation == nil {
|
return renderSegmented(s.animation, s.segmentsX, s.segmentsY, s.frameOffset, target)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
_, height := s.animation.GetCurrentFrameSize()
|
|
||||||
target.PushTranslation(0, -height)
|
|
||||||
defer target.Pop()
|
|
||||||
|
|
||||||
if s.segmentsX == 0 && s.segmentsY == 0 {
|
|
||||||
return s.animation.Render(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentY int
|
|
||||||
for y := 0; y < s.segmentsY; y++ {
|
|
||||||
var currentX int
|
|
||||||
var maxHeight int
|
|
||||||
for x := 0; x < s.segmentsX; x++ {
|
|
||||||
if err := s.animation.SetCurrentFrame(x + y*s.segmentsX + s.frameOffset*s.segmentsX*s.segmentsY); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
target.PushTranslation(s.x+currentX, s.y+currentY)
|
|
||||||
err := s.animation.Render(target)
|
|
||||||
target.Pop()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
width, height := s.animation.GetCurrentFrameSize()
|
|
||||||
maxHeight = d2common.MaxInt(maxHeight, height)
|
|
||||||
currentX += width
|
|
||||||
}
|
|
||||||
|
|
||||||
currentY += maxHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) advance(elapsed float64) error {
|
func (s *Sprite) advance(elapsed float64) error {
|
||||||
if s.animation == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.animation.Advance(elapsed)
|
return s.animation.Advance(elapsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) getSize() (int, int) {
|
func (s *Sprite) getSize() (int, int) {
|
||||||
if s.animation == nil {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.animation.GetCurrentFrameSize()
|
return s.animation.GetCurrentFrameSize()
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package d2gui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type FontStyle int
|
type FontStyle int
|
||||||
@ -11,9 +10,11 @@ const (
|
|||||||
FontStyle16Units FontStyle = iota
|
FontStyle16Units FontStyle = iota
|
||||||
FontStyle30Units
|
FontStyle30Units
|
||||||
FontStyle42Units
|
FontStyle42Units
|
||||||
|
FontStyleExocet10
|
||||||
FontStyleFormal10Static
|
FontStyleFormal10Static
|
||||||
FontStyleFormal11Units
|
FontStyleFormal11Units
|
||||||
FontStyleFormal12Static
|
FontStyleFormal12Static
|
||||||
|
FontStyleRediculous
|
||||||
)
|
)
|
||||||
|
|
||||||
type fontStyleConfig struct {
|
type fontStyleConfig struct {
|
||||||
@ -25,12 +26,37 @@ var fontStyleConfigs = map[FontStyle]fontStyleConfig{
|
|||||||
FontStyle16Units: {d2resource.Font16, d2resource.PaletteUnits},
|
FontStyle16Units: {d2resource.Font16, d2resource.PaletteUnits},
|
||||||
FontStyle30Units: {d2resource.Font30, d2resource.PaletteUnits},
|
FontStyle30Units: {d2resource.Font30, d2resource.PaletteUnits},
|
||||||
FontStyle42Units: {d2resource.Font42, d2resource.PaletteUnits},
|
FontStyle42Units: {d2resource.Font42, d2resource.PaletteUnits},
|
||||||
|
FontStyleExocet10: {d2resource.FontExocet10, d2resource.PaletteUnits},
|
||||||
FontStyleFormal10Static: {d2resource.FontFormal10, d2resource.PaletteStatic},
|
FontStyleFormal10Static: {d2resource.FontFormal10, d2resource.PaletteStatic},
|
||||||
FontStyleFormal11Units: {d2resource.FontFormal11, d2resource.PaletteUnits},
|
FontStyleFormal11Units: {d2resource.FontFormal11, d2resource.PaletteUnits},
|
||||||
FontStyleFormal12Static: {d2resource.FontFormal12, d2resource.PaletteStatic},
|
FontStyleFormal12Static: {d2resource.FontFormal12, d2resource.PaletteStatic},
|
||||||
|
FontStyleRediculous: {d2resource.FontRediculous, d2resource.PaletteUnits},
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFont(fontStyle FontStyle) (*d2asset.Font, error) {
|
type ButtonStyle int
|
||||||
config := fontStyleConfigs[fontStyle]
|
|
||||||
return d2asset.LoadFont(config.fontBasePath+".tbl", config.fontBasePath+".dc6", config.palettePath)
|
type buttonStyleConfig struct {
|
||||||
|
segmentsX int
|
||||||
|
segmentsY int
|
||||||
|
animationPath string
|
||||||
|
palettePath string
|
||||||
|
fontStyle FontStyle
|
||||||
|
textOffset int
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ButtonStyleMedium ButtonStyle = iota
|
||||||
|
ButtonStyleNarrow
|
||||||
|
ButtonStyleOkCancel
|
||||||
|
ButtonStyleShort
|
||||||
|
ButtonStyleTall
|
||||||
|
ButtonStyleWide
|
||||||
|
)
|
||||||
|
|
||||||
|
var buttonStyleConfigs = map[ButtonStyle]buttonStyleConfig{
|
||||||
|
ButtonStyleMedium: {1, 1, d2resource.MediumButtonBlank, d2resource.PaletteUnits, FontStyleExocet10, 0},
|
||||||
|
ButtonStyleOkCancel: {1, 1, d2resource.CancelButton, d2resource.PaletteUnits, FontStyleRediculous, 0},
|
||||||
|
ButtonStyleShort: {1, 1, d2resource.ShortButtonBlank, d2resource.PaletteUnits, FontStyleRediculous, -1},
|
||||||
|
ButtonStyleTall: {1, 1, d2resource.TallButtonBlank, d2resource.PaletteUnits, FontStyleExocet10, 5},
|
||||||
|
ButtonStyleWide: {2, 1, d2resource.WideButtonBlank, d2resource.PaletteUnits, FontStyleExocet10, 1},
|
||||||
}
|
}
|
||||||
|
@ -12,26 +12,30 @@ type widget interface {
|
|||||||
render(target d2render.Surface) error
|
render(target d2render.Surface) error
|
||||||
advance(elapsed float64) error
|
advance(elapsed float64) error
|
||||||
|
|
||||||
onMouseEnter(event d2input.MouseMoveEvent)
|
onMouseMove(event d2input.MouseMoveEvent) bool
|
||||||
onMouseLeave(event d2input.MouseMoveEvent)
|
onMouseEnter(event d2input.MouseMoveEvent) bool
|
||||||
onMouseOver(event d2input.MouseMoveEvent)
|
onMouseLeave(event d2input.MouseMoveEvent) bool
|
||||||
onMouseClick(event d2input.MouseEvent)
|
onMouseOver(event d2input.MouseMoveEvent) bool
|
||||||
|
onMouseButtonDown(event d2input.MouseEvent) bool
|
||||||
|
onMouseButtonUp(event d2input.MouseEvent) bool
|
||||||
|
onMouseButtonClick(event d2input.MouseEvent) bool
|
||||||
|
|
||||||
getPosition() (int, int)
|
getPosition() (int, int)
|
||||||
getSize() (int, int)
|
getSize() (int, int)
|
||||||
getLayer() int
|
getLayer() int
|
||||||
isVisible() bool
|
isVisible() bool
|
||||||
|
isExpanding() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type widgetBase struct {
|
type widgetBase struct {
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
layer int
|
layer int
|
||||||
visible bool
|
visible bool
|
||||||
|
expanding bool
|
||||||
|
|
||||||
mouseEnterHandler MouseMoveHandler
|
mouseEnterHandler MouseMoveHandler
|
||||||
mouseLeaveHandler MouseMoveHandler
|
mouseLeaveHandler MouseMoveHandler
|
||||||
mouseMoveHandler MouseMoveHandler
|
|
||||||
mouseClickHandler MouseHandler
|
mouseClickHandler MouseHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +52,10 @@ func (w *widgetBase) SetVisible(visible bool) {
|
|||||||
w.visible = visible
|
w.visible = visible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) SetExpanding(expanding bool) {
|
||||||
|
w.expanding = expanding
|
||||||
|
}
|
||||||
|
|
||||||
func (w *widgetBase) SetMouseEnterHandler(handler MouseMoveHandler) {
|
func (w *widgetBase) SetMouseEnterHandler(handler MouseMoveHandler) {
|
||||||
w.mouseEnterHandler = handler
|
w.mouseEnterHandler = handler
|
||||||
}
|
}
|
||||||
@ -56,10 +64,6 @@ func (w *widgetBase) SetMouseLeaveHandler(handler MouseMoveHandler) {
|
|||||||
w.mouseLeaveHandler = handler
|
w.mouseLeaveHandler = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *widgetBase) SetMouseMoveHandler(handler MouseMoveHandler) {
|
|
||||||
w.mouseMoveHandler = handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *widgetBase) SetMouseClickHandler(handler MouseHandler) {
|
func (w *widgetBase) SetMouseClickHandler(handler MouseHandler) {
|
||||||
w.mouseClickHandler = handler
|
w.mouseClickHandler = handler
|
||||||
}
|
}
|
||||||
@ -68,6 +72,10 @@ func (w *widgetBase) getPosition() (int, int) {
|
|||||||
return w.x, w.y
|
return w.x, w.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) getSize() (int, int) {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
func (w *widgetBase) getLayer() int {
|
func (w *widgetBase) getLayer() int {
|
||||||
return w.layer
|
return w.layer
|
||||||
}
|
}
|
||||||
@ -76,30 +84,54 @@ func (w *widgetBase) isVisible() bool {
|
|||||||
return w.visible
|
return w.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) isExpanding() bool {
|
||||||
|
return w.expanding
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) render(target d2render.Surface) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *widgetBase) advance(elapsed float64) error {
|
func (w *widgetBase) advance(elapsed float64) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *widgetBase) onMouseEnter(event d2input.MouseMoveEvent) {
|
func (w *widgetBase) onMouseEnter(event d2input.MouseMoveEvent) bool {
|
||||||
if w.mouseEnterHandler != nil {
|
if w.mouseEnterHandler != nil {
|
||||||
w.mouseEnterHandler(event)
|
w.mouseEnterHandler(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *widgetBase) onMouseLeave(event d2input.MouseMoveEvent) {
|
func (w *widgetBase) onMouseLeave(event d2input.MouseMoveEvent) bool {
|
||||||
if w.mouseLeaveHandler != nil {
|
if w.mouseLeaveHandler != nil {
|
||||||
w.mouseLeaveHandler(event)
|
w.mouseLeaveHandler(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *widgetBase) onMouseOver(event d2input.MouseMoveEvent) {
|
func (w *widgetBase) onMouseButtonClick(event d2input.MouseEvent) bool {
|
||||||
if w.mouseMoveHandler != nil {
|
|
||||||
w.mouseMoveHandler(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *widgetBase) onMouseClick(event d2input.MouseEvent) {
|
|
||||||
if w.mouseClickHandler != nil {
|
if w.mouseClickHandler != nil {
|
||||||
w.mouseClickHandler(event)
|
w.mouseClickHandler(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) onMouseMove(event d2input.MouseMoveEvent) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) onMouseOver(event d2input.MouseMoveEvent) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) onMouseButtonDown(event d2input.MouseEvent) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *widgetBase) onMouseButtonUp(event d2input.MouseEvent) bool {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ func Advance(elapsed float64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d2ui.Reset()
|
d2ui.Reset()
|
||||||
d2gui.Clear()
|
d2gui.SetLayout(nil)
|
||||||
|
|
||||||
if _, ok := singleton.nextScene.(SceneLoadHandler); ok {
|
if _, ok := singleton.nextScene.(SceneLoadHandler); ok {
|
||||||
d2gui.ShowLoadScreen(0)
|
d2gui.ShowLoadScreen(0)
|
||||||
|
49
d2game/d2gamescene/gui_testing.go
Normal file
49
d2game/d2gamescene/gui_testing.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package d2gamescene
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GuiTestMain struct{}
|
||||||
|
|
||||||
|
func CreateGuiTestMain() *GuiTestMain {
|
||||||
|
return &GuiTestMain{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GuiTestMain) OnLoad() error {
|
||||||
|
layout := d2gui.CreateLayout(d2gui.PositionTypeHorizontal)
|
||||||
|
//
|
||||||
|
layoutLeft := layout.AddLayout(d2gui.PositionTypeVertical)
|
||||||
|
layoutLeft.SetHorizontalAlign(d2gui.HorizontalAlignCenter)
|
||||||
|
layoutLeft.AddLabel("FontStyle16Units", d2gui.FontStyle16Units)
|
||||||
|
layoutLeft.AddSpacerStatic(0, 100)
|
||||||
|
layoutLeft.AddLabel("FontStyle30Units", d2gui.FontStyle30Units)
|
||||||
|
layoutLeft.AddLabel("FontStyle42Units", d2gui.FontStyle42Units)
|
||||||
|
layoutLeft.AddLabel("FontStyleFormal10Static", d2gui.FontStyleFormal10Static)
|
||||||
|
layoutLeft.AddLabel("FontStyleFormal11Units", d2gui.FontStyleFormal11Units)
|
||||||
|
layoutLeft.AddLabel("FontStyleFormal12Static", d2gui.FontStyleFormal12Static)
|
||||||
|
|
||||||
|
layout.AddSpacerDynamic()
|
||||||
|
|
||||||
|
layoutRight := layout.AddLayout(d2gui.PositionTypeVertical)
|
||||||
|
layoutRight.SetHorizontalAlign(d2gui.HorizontalAlignRight)
|
||||||
|
layoutRight.AddButton("Medium", d2gui.ButtonStyleMedium)
|
||||||
|
layoutRight.AddButton("Narrow", d2gui.ButtonStyleNarrow)
|
||||||
|
layoutRight.AddButton("OkCancel", d2gui.ButtonStyleOkCancel)
|
||||||
|
layoutRight.AddButton("Short", d2gui.ButtonStyleShort)
|
||||||
|
layoutRight.AddButton("Wide", d2gui.ButtonStyleWide)
|
||||||
|
|
||||||
|
layout.SetVerticalAlign(d2gui.VerticalAlignMiddle)
|
||||||
|
d2gui.SetLayout(layout)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GuiTestMain) Render(screen d2render.Surface) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GuiTestMain) Advance(tickTime float64) error {
|
||||||
|
return nil
|
||||||
|
}
|
3
main.go
3
main.go
@ -153,6 +153,9 @@ func initialize() error {
|
|||||||
d2term.BindAction("quit", "exits the game", func() {
|
d2term.BindAction("quit", "exits the game", func() {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
})
|
})
|
||||||
|
d2term.BindAction("scene-gui", "enters the gui playground scene", func() {
|
||||||
|
d2scene.SetNextScene(d2gamescene.CreateGuiTestMain())
|
||||||
|
})
|
||||||
|
|
||||||
if err := d2asset.Initialize(); err != nil {
|
if err := d2asset.Initialize(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user