mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-12-25 19:46:50 -05:00
removed most lint errors in d2gui (#604)
This commit is contained in:
parent
c92ad67eaa
commit
dbc07e2ce8
@ -2,11 +2,9 @@ package d2gui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
|
||||
@ -15,10 +13,13 @@ type buttonState int
|
||||
const (
|
||||
buttonStateDefault buttonState = iota
|
||||
buttonStatePressed
|
||||
buttonStateToggled
|
||||
buttonStatePressedToggled
|
||||
)
|
||||
|
||||
const (
|
||||
grey = 0x404040ff
|
||||
)
|
||||
|
||||
// Button is a user actionable drawable toggle switch
|
||||
type Button struct {
|
||||
widgetBase
|
||||
@ -35,12 +36,13 @@ func createButton(renderer d2interface.Renderer, text string, buttonStyle Button
|
||||
return nil, errors.New("invalid button style")
|
||||
}
|
||||
|
||||
animation, err := d2asset.LoadAnimation(config.animationPath, config.palettePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
animation, loadErr := d2asset.LoadAnimation(config.animationPath, config.palettePath)
|
||||
if loadErr != nil {
|
||||
return nil, loadErr
|
||||
}
|
||||
|
||||
var buttonWidth int
|
||||
|
||||
for i := 0; i < config.segmentsX; i++ {
|
||||
w, _, err := animation.GetFrameSize(i)
|
||||
if err != nil {
|
||||
@ -51,6 +53,7 @@ func createButton(renderer d2interface.Renderer, text string, buttonStyle Button
|
||||
}
|
||||
|
||||
var buttonHeight int
|
||||
|
||||
for i := 0; i < config.segmentsY; i++ {
|
||||
_, h, err := animation.GetFrameSize(i * config.segmentsY)
|
||||
if err != nil {
|
||||
@ -60,31 +63,34 @@ func createButton(renderer d2interface.Renderer, text string, buttonStyle Button
|
||||
buttonHeight += h
|
||||
}
|
||||
|
||||
font, err := loadFont(config.fontStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
font, loadErr := loadFont(config.fontStyle)
|
||||
if loadErr != nil {
|
||||
return nil, loadErr
|
||||
}
|
||||
|
||||
textColor := color.RGBA{R: 0x64, G: 0x64, B: 0x64, A: 0xff}
|
||||
textColor := rgbaColor(grey)
|
||||
textWidth, textHeight := font.GetTextMetrics(text)
|
||||
textX := buttonWidth/2 - textWidth/2
|
||||
textY := buttonHeight/2 - textHeight/2 + config.textOffset
|
||||
textX := half(buttonWidth) - half(textWidth)
|
||||
textY := half(buttonHeight) - half(textHeight) + config.textOffset
|
||||
|
||||
surfaceCount := animation.GetFrameCount() / (config.segmentsX * config.segmentsY)
|
||||
surfaces := make([]d2interface.Surface, surfaceCount)
|
||||
|
||||
for i := 0; i < surfaceCount; i++ {
|
||||
surface, err := renderer.NewSurface(buttonWidth, buttonHeight, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
surface, surfaceErr := renderer.NewSurface(buttonWidth, buttonHeight, d2enum.FilterNearest)
|
||||
if surfaceErr != nil {
|
||||
return nil, surfaceErr
|
||||
}
|
||||
|
||||
if err := renderSegmented(animation, config.segmentsX, config.segmentsY, i, surface); err != nil {
|
||||
return nil, err
|
||||
segX, segY, frame := config.segmentsX, config.segmentsY, i
|
||||
if segErr := renderSegmented(animation, segX, segY, frame, surface); segErr != nil {
|
||||
return nil, segErr
|
||||
}
|
||||
|
||||
font.SetColor(textColor)
|
||||
|
||||
var textOffsetX, textOffsetY int
|
||||
|
||||
switch buttonState(i) {
|
||||
case buttonStatePressed, buttonStatePressedToggled:
|
||||
textOffsetX = -2
|
||||
@ -92,11 +98,11 @@ func createButton(renderer d2interface.Renderer, text string, buttonStyle Button
|
||||
}
|
||||
|
||||
surface.PushTranslation(textX+textOffsetX, textY+textOffsetY)
|
||||
err = font.RenderText(text, surface)
|
||||
surfaceErr = font.RenderText(text, surface)
|
||||
surface.Pop()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if surfaceErr != nil {
|
||||
return nil, surfaceErr
|
||||
}
|
||||
|
||||
surfaces[i] = surface
|
||||
@ -108,17 +114,17 @@ func createButton(renderer d2interface.Renderer, text string, buttonStyle Button
|
||||
return button, nil
|
||||
}
|
||||
|
||||
func (b *Button) onMouseButtonDown(event d2interface.MouseEvent) bool {
|
||||
func (b *Button) onMouseButtonDown(_ d2interface.MouseEvent) bool {
|
||||
b.state = buttonStatePressed
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Button) onMouseButtonUp(event d2interface.MouseEvent) bool {
|
||||
func (b *Button) onMouseButtonUp(_ d2interface.MouseEvent) bool {
|
||||
b.state = buttonStateDefault
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Button) onMouseLeave(event d2interface.MouseMoveEvent) bool {
|
||||
func (b *Button) onMouseLeave(_ d2interface.MouseMoveEvent) bool {
|
||||
b.state = buttonStateDefault
|
||||
return false
|
||||
}
|
||||
@ -127,6 +133,6 @@ func (b *Button) render(target d2interface.Surface) error {
|
||||
return target.Render(b.surfaces[b.state])
|
||||
}
|
||||
|
||||
func (b *Button) getSize() (int, int) {
|
||||
func (b *Button) getSize() (width, height int) {
|
||||
return b.width, b.height
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package d2gui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
@ -21,9 +22,10 @@ func loadFont(fontStyle FontStyle) (d2interface.Font, error) {
|
||||
func renderSegmented(animation d2interface.Animation, segmentsX, segmentsY, frameOffset int,
|
||||
target d2interface.Surface) error {
|
||||
var currentY int
|
||||
|
||||
for y := 0; y < segmentsY; y++ {
|
||||
var currentX int
|
||||
var maxHeight int
|
||||
var currentX, maxHeight int
|
||||
|
||||
for x := 0; x < segmentsX; x++ {
|
||||
if err := animation.SetCurrentFrame(x + y*segmentsX + frameOffset*segmentsX*segmentsY); err != nil {
|
||||
return err
|
||||
@ -32,6 +34,7 @@ func renderSegmented(animation d2interface.Animation, segmentsX, segmentsY, fram
|
||||
target.PushTranslation(x+currentX, y+currentY)
|
||||
err := animation.Render(target)
|
||||
target.Pop()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -46,3 +49,32 @@ func renderSegmented(animation d2interface.Animation, segmentsX, segmentsY, fram
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func half(n int) int {
|
||||
return n / 2
|
||||
}
|
||||
|
||||
func rgbaColor(rgba uint32) color.RGBA {
|
||||
result := color.RGBA{}
|
||||
a, b, g, r := 0, 1, 2, 3
|
||||
byteWidth := 8
|
||||
byteMask := 0xff
|
||||
|
||||
for idx := 0; idx < 4; idx++ {
|
||||
shift := idx * byteWidth
|
||||
component := uint8(rgba>>shift) & uint8(byteMask)
|
||||
|
||||
switch idx {
|
||||
case a:
|
||||
result.A = component
|
||||
case b:
|
||||
result.B = component
|
||||
case g:
|
||||
result.G = component
|
||||
case r:
|
||||
result.R = component
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -7,12 +7,13 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrWasInit = errors.New("gui system is already initialized")
|
||||
ErrNotInit = errors.New("gui system is not initialized")
|
||||
errWasInit = errors.New("gui system is already initialized")
|
||||
errNotInit = errors.New("gui system is not initialized")
|
||||
)
|
||||
|
||||
var singleton *manager
|
||||
|
||||
// Initialize creates a singleton gui manager
|
||||
func Initialize(inputManager d2interface.InputManager) error {
|
||||
verifyNotInit()
|
||||
|
||||
@ -24,42 +25,51 @@ func Initialize(inputManager d2interface.InputManager) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Render all of the gui elements
|
||||
func Render(target d2interface.Surface) error {
|
||||
verifyWasInit()
|
||||
return singleton.render(target)
|
||||
}
|
||||
|
||||
// Advance all of the gui elements
|
||||
func Advance(elapsed float64) error {
|
||||
verifyWasInit()
|
||||
return singleton.advance(elapsed)
|
||||
}
|
||||
|
||||
// CreateLayout creates a dynamic layout
|
||||
func CreateLayout(renderer d2interface.Renderer, positionType PositionType) *Layout {
|
||||
verifyWasInit()
|
||||
return createLayout(renderer, positionType)
|
||||
}
|
||||
|
||||
// SetLayout sets the gui manager's layout
|
||||
func SetLayout(layout *Layout) {
|
||||
verifyWasInit()
|
||||
singleton.SetLayout(layout)
|
||||
}
|
||||
|
||||
// ShowLoadScreen renders the loading progress screen. The provided progress argument defines the loading animation's state in the range `[0, 1]`, where `0` is initial frame and `1` is the final frame
|
||||
// ShowLoadScreen renders the loading progress screen.
|
||||
// The provided progress argument defines the loading animation's state in the range `[0, 1]`,
|
||||
// where `0` is initial frame and `1` is the final frame
|
||||
func ShowLoadScreen(progress float64) {
|
||||
verifyWasInit()
|
||||
singleton.showLoadScreen(progress)
|
||||
}
|
||||
|
||||
// HideLoadScreen hides the loading screen
|
||||
func HideLoadScreen() {
|
||||
verifyWasInit()
|
||||
singleton.hideLoadScreen()
|
||||
}
|
||||
|
||||
// ShowCursor shows the in-game mouse cursor
|
||||
func ShowCursor() {
|
||||
verifyWasInit()
|
||||
singleton.showCursor()
|
||||
}
|
||||
|
||||
// HideCursor hides the in-game mouse cursor
|
||||
func HideCursor() {
|
||||
verifyWasInit()
|
||||
singleton.hideCursor()
|
||||
@ -67,12 +77,12 @@ func HideCursor() {
|
||||
|
||||
func verifyWasInit() {
|
||||
if singleton == nil {
|
||||
panic(ErrNotInit)
|
||||
panic(errNotInit)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyNotInit() {
|
||||
if singleton != nil {
|
||||
panic(ErrWasInit)
|
||||
panic(errWasInit)
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
// Label is renderable text
|
||||
type Label struct {
|
||||
widgetBase
|
||||
|
||||
@ -35,31 +36,38 @@ func (l *Label) render(target d2interface.Surface) error {
|
||||
return target.Render(l.surface)
|
||||
}
|
||||
|
||||
func (l *Label) getSize() (int, int) {
|
||||
func (l *Label) getSize() (width, height int) {
|
||||
return l.surface.GetSize()
|
||||
}
|
||||
|
||||
// GetText returns the label text
|
||||
func (l *Label) GetText() string {
|
||||
return l.text
|
||||
}
|
||||
|
||||
// SetText sets the label text
|
||||
func (l *Label) SetText(text string) error {
|
||||
if text == l.text {
|
||||
return nil
|
||||
}
|
||||
|
||||
return l.setText(text)
|
||||
}
|
||||
|
||||
func (l *Label) setText(text string) error {
|
||||
width, height := l.font.GetTextMetrics(text)
|
||||
|
||||
surface, err := l.renderer.NewSurface(width, height, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := l.font.RenderText(text, surface); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.surface = surface
|
||||
l.text = text
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
package d2gui
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
type layoutEntry struct {
|
||||
@ -20,30 +17,48 @@ type layoutEntry struct {
|
||||
mouseDown [3]bool
|
||||
}
|
||||
|
||||
const layoutDebug = false // turns on debug rendering stuff for layouts
|
||||
|
||||
const (
|
||||
white = 0xffffff_ff
|
||||
magenta = 0xff00ff_ff
|
||||
grey2 = 0x808080_ff
|
||||
green = 0x0000ff_ff
|
||||
yellow = 0xffff00_ff
|
||||
)
|
||||
|
||||
// VerticalAlign type, determines alignment along y-axis within a layout
|
||||
type VerticalAlign int
|
||||
|
||||
// VerticalAlign types
|
||||
const (
|
||||
VerticalAlignTop VerticalAlign = iota
|
||||
VerticalAlignMiddle
|
||||
VerticalAlignBottom
|
||||
)
|
||||
|
||||
// HorizontalAlign type, determines alignment along x-axis within a layout
|
||||
type HorizontalAlign int
|
||||
|
||||
// Horizontal alignment types
|
||||
const (
|
||||
HorizontalAlignLeft HorizontalAlign = iota
|
||||
HorizontalAlignCenter
|
||||
HorizontalAlignRight
|
||||
)
|
||||
|
||||
// PositionType determines layout positioning
|
||||
type PositionType int
|
||||
|
||||
// Positioning types
|
||||
const (
|
||||
PositionTypeAbsolute PositionType = iota
|
||||
PositionTypeVertical
|
||||
PositionTypeHorizontal
|
||||
)
|
||||
|
||||
// Layout is a gui element container which will automatically position/align gui elements.
|
||||
// Layouts are gui elements as well, so they can be nested in other layouts.
|
||||
type Layout struct {
|
||||
widgetBase
|
||||
|
||||
@ -68,37 +83,52 @@ func createLayout(renderer d2interface.Renderer, positionType PositionType) *Lay
|
||||
return layout
|
||||
}
|
||||
|
||||
// SetSize sets the size of the layout
|
||||
func (l *Layout) SetSize(width, height int) {
|
||||
l.width = width
|
||||
l.height = height
|
||||
}
|
||||
|
||||
// SetVerticalAlign sets the vertical alignment type of the layout
|
||||
func (l *Layout) SetVerticalAlign(verticalAlign VerticalAlign) {
|
||||
l.verticalAlign = verticalAlign
|
||||
}
|
||||
|
||||
// SetHorizontalAlign sets the horizontal alignment type of the layout
|
||||
func (l *Layout) SetHorizontalAlign(horizontalAlign HorizontalAlign) {
|
||||
l.horizontalAlign = horizontalAlign
|
||||
}
|
||||
|
||||
// AddLayout adds a nested layout to this layout, given a position type.
|
||||
// Returns a pointer to the nested layout
|
||||
func (l *Layout) AddLayout(positionType PositionType) *Layout {
|
||||
layout := createLayout(l.renderer, positionType)
|
||||
l.entries = append(l.entries, &layoutEntry{widget: layout})
|
||||
|
||||
return layout
|
||||
}
|
||||
|
||||
// AddSpacerStatic adds a spacer with explicitly defined height and width
|
||||
func (l *Layout) AddSpacerStatic(width, height int) *SpacerStatic {
|
||||
spacer := createSpacerStatic(width, height)
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: spacer})
|
||||
|
||||
return spacer
|
||||
}
|
||||
|
||||
// AddSpacerDynamic adds a spacer which has dynamic width and height. The width
|
||||
// and height are computed based off of the position/alignment type of the layout
|
||||
// and the dimensions/positions of the layout entries.
|
||||
func (l *Layout) AddSpacerDynamic() *SpacerDynamic {
|
||||
spacer := createSpacerDynamic()
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: spacer})
|
||||
|
||||
return spacer
|
||||
}
|
||||
|
||||
// AddSprite given a path and palette, adds a Sprite as a layout entry
|
||||
func (l *Layout) AddSprite(imagePath, palettePath string) (*Sprite, error) {
|
||||
sprite, err := createSprite(imagePath, palettePath)
|
||||
if err != nil {
|
||||
@ -106,9 +136,12 @@ func (l *Layout) AddSprite(imagePath, palettePath string) (*Sprite, error) {
|
||||
}
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: sprite})
|
||||
|
||||
return sprite, nil
|
||||
}
|
||||
|
||||
// AddAnimatedSprite given a path, palette, and direction will add an animated
|
||||
// sprite as a layout entry
|
||||
func (l *Layout) AddAnimatedSprite(imagePath, palettePath string, direction AnimationDirection) (*AnimatedSprite, error) {
|
||||
sprite, err := createAnimatedSprite(imagePath, palettePath, direction)
|
||||
if err != nil {
|
||||
@ -116,9 +149,11 @@ func (l *Layout) AddAnimatedSprite(imagePath, palettePath string, direction Anim
|
||||
}
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: sprite})
|
||||
|
||||
return sprite, nil
|
||||
}
|
||||
|
||||
// AddLabel given a string and a FontStyle, adds a text label as a layout entry
|
||||
func (l *Layout) AddLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||
label, err := createLabel(l.renderer, text, fontStyle)
|
||||
if err != nil {
|
||||
@ -126,9 +161,11 @@ func (l *Layout) AddLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||
}
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: label})
|
||||
|
||||
return label, nil
|
||||
}
|
||||
|
||||
// AddButton given a string and ButtonStyle, adds a button as a layout entry
|
||||
func (l *Layout) AddButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||
button, err := createButton(l.renderer, text, buttonStyle)
|
||||
if err != nil {
|
||||
@ -136,9 +173,11 @@ func (l *Layout) AddButton(text string, buttonStyle ButtonStyle) (*Button, error
|
||||
}
|
||||
|
||||
l.entries = append(l.entries, &layoutEntry{widget: button})
|
||||
|
||||
return button, nil
|
||||
}
|
||||
|
||||
// Clear removes all layout entries
|
||||
func (l *Layout) Clear() {
|
||||
l.entries = nil
|
||||
}
|
||||
@ -155,10 +194,11 @@ func (l *Layout) render(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// uncomment to see debug boxes
|
||||
//if err := l.renderEntryDebug(entry, target); err != nil {
|
||||
// return err
|
||||
//}
|
||||
if layoutDebug {
|
||||
if err := l.renderEntryDebug(entry, target); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -185,16 +225,16 @@ func (l *Layout) renderEntryDebug(entry *layoutEntry, target d2interface.Surface
|
||||
target.PushTranslation(entry.x, entry.y)
|
||||
defer target.Pop()
|
||||
|
||||
drawColor := color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}
|
||||
drawColor := rgbaColor(white)
|
||||
switch entry.widget.(type) {
|
||||
case *Layout:
|
||||
drawColor = color.RGBA{R: 0xff, G: 0x00, B: 0xff, A: 0xff}
|
||||
drawColor = rgbaColor(magenta)
|
||||
case *SpacerStatic, *SpacerDynamic:
|
||||
drawColor = color.RGBA{R: 0x80, G: 0x80, B: 0x80, A: 0xff}
|
||||
drawColor = rgbaColor(grey2)
|
||||
case *Label:
|
||||
drawColor = color.RGBA{R: 0x00, G: 0x00, B: 0xff, A: 0xff}
|
||||
drawColor = rgbaColor(green)
|
||||
case *Button:
|
||||
drawColor = color.RGBA{R: 0xff, G: 0xff, B: 0x00, A: 0xff}
|
||||
drawColor = rgbaColor(yellow)
|
||||
}
|
||||
|
||||
target.DrawLine(entry.width, 0, drawColor)
|
||||
@ -211,9 +251,7 @@ func (l *Layout) renderEntryDebug(entry *layoutEntry, target d2interface.Surface
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Layout) getContentSize() (int, int) {
|
||||
var width, height int
|
||||
|
||||
func (l *Layout) getContentSize() (width, height int) {
|
||||
for _, entry := range l.entries {
|
||||
x, y := entry.widget.getPosition()
|
||||
w, h := entry.widget.getSize()
|
||||
@ -234,8 +272,8 @@ func (l *Layout) getContentSize() (int, int) {
|
||||
return width, height
|
||||
}
|
||||
|
||||
func (l *Layout) getSize() (int, int) {
|
||||
width, height := l.getContentSize()
|
||||
func (l *Layout) getSize() (width, height int) {
|
||||
width, height = l.getContentSize()
|
||||
return d2common.MaxInt(width, l.width), d2common.MaxInt(height, l.height)
|
||||
}
|
||||
|
||||
@ -286,17 +324,20 @@ func (l *Layout) onMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// AdjustEntryPlacement calculates and sets the position for all layout entries.
|
||||
// This is based on the position/horizontal/vertical alignment type set, as well as the
|
||||
// expansion types of spacers.
|
||||
func (l *Layout) AdjustEntryPlacement() {
|
||||
width, height := l.getSize()
|
||||
|
||||
var expanderCount int
|
||||
var expanderCount, expanderWidth, expanderHeight int
|
||||
|
||||
for _, entry := range l.entries {
|
||||
if entry.widget.isVisible() && entry.widget.isExpanding() {
|
||||
expanderCount++
|
||||
}
|
||||
}
|
||||
|
||||
var expanderWidth, expanderHeight int
|
||||
if expanderCount > 0 {
|
||||
contentWidth, contentHeight := l.getContentSize()
|
||||
|
||||
@ -312,7 +353,9 @@ func (l *Layout) AdjustEntryPlacement() {
|
||||
}
|
||||
|
||||
var offsetX, offsetY int
|
||||
for _, entry := range l.entries {
|
||||
|
||||
for idx := range l.entries {
|
||||
entry := l.entries[idx]
|
||||
if !entry.widget.isVisible() {
|
||||
continue
|
||||
}
|
||||
@ -323,31 +366,13 @@ func (l *Layout) AdjustEntryPlacement() {
|
||||
entry.width, entry.height = entry.widget.getSize()
|
||||
}
|
||||
|
||||
l.handleEntryPosition(offsetX, offsetY, entry)
|
||||
|
||||
switch l.positionType {
|
||||
case PositionTypeVertical:
|
||||
entry.y = offsetY
|
||||
offsetY += entry.height
|
||||
switch l.horizontalAlign {
|
||||
case HorizontalAlignLeft:
|
||||
entry.x = 0
|
||||
case HorizontalAlignCenter:
|
||||
entry.x = width/2 - entry.width/2
|
||||
case HorizontalAlignRight:
|
||||
entry.x = width - entry.width
|
||||
}
|
||||
case PositionTypeHorizontal:
|
||||
entry.x = offsetX
|
||||
offsetX += entry.width
|
||||
switch l.verticalAlign {
|
||||
case VerticalAlignTop:
|
||||
entry.y = 0
|
||||
case VerticalAlignMiddle:
|
||||
entry.y = height/2 - entry.height/2
|
||||
case VerticalAlignBottom:
|
||||
entry.y = height - entry.height
|
||||
}
|
||||
case PositionTypeAbsolute:
|
||||
entry.x, entry.y = entry.widget.getPosition()
|
||||
}
|
||||
|
||||
sx, sy := l.ScreenPos()
|
||||
@ -356,9 +381,49 @@ func (l *Layout) AdjustEntryPlacement() {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Layout) handleEntryPosition(offsetX, offsetY int, entry *layoutEntry) {
|
||||
width, height := l.getSize()
|
||||
|
||||
switch l.positionType {
|
||||
case PositionTypeVertical:
|
||||
entry.y = offsetY
|
||||
l.handleEntryVerticalAlign(width, entry)
|
||||
|
||||
case PositionTypeHorizontal:
|
||||
entry.x = offsetX
|
||||
l.handleEntryHorizontalAlign(height, entry)
|
||||
|
||||
case PositionTypeAbsolute:
|
||||
entry.x, entry.y = entry.widget.getPosition()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Layout) handleEntryHorizontalAlign(height int, entry *layoutEntry) {
|
||||
switch l.verticalAlign {
|
||||
case VerticalAlignTop:
|
||||
entry.y = 0
|
||||
case VerticalAlignMiddle:
|
||||
entry.y = half(height) - half(entry.height)
|
||||
case VerticalAlignBottom:
|
||||
entry.y = height - entry.height
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Layout) handleEntryVerticalAlign(width int, entry *layoutEntry) {
|
||||
switch l.horizontalAlign {
|
||||
case HorizontalAlignLeft:
|
||||
entry.x = 0
|
||||
case HorizontalAlignCenter:
|
||||
entry.x = half(width) - half(entry.width)
|
||||
case HorizontalAlignRight:
|
||||
entry.x = width - entry.width
|
||||
}
|
||||
}
|
||||
|
||||
// IsIn layout entry, spc. of an event.
|
||||
func (l *layoutEntry) IsIn(event d2interface.HandlerEvent) bool {
|
||||
sx, sy := l.widget.ScreenPos()
|
||||
rect := d2common.Rectangle{Left: sx, Top: sy, Width: l.width, Height: l.height}
|
||||
|
||||
return rect.IsInRect(event.X(), event.Y())
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ func createGuiManager(inputManager d2interface.InputManager) (*manager, error) {
|
||||
cursorVisible: true,
|
||||
}
|
||||
|
||||
manager.clear()
|
||||
|
||||
if err := inputManager.BindHandler(manager); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -100,22 +102,37 @@ func (m *manager) render(target d2interface.Surface) error {
|
||||
}
|
||||
|
||||
func (m *manager) renderLoadScreen(target d2interface.Surface) error {
|
||||
target.Clear(color.Black)
|
||||
if clearErr := target.Clear(color.Black); clearErr != nil {
|
||||
return clearErr
|
||||
}
|
||||
|
||||
pushCount := 0
|
||||
|
||||
screenWidth, screenHeight := target.GetSize()
|
||||
animWidth, animHeight := m.loadingAnim.GetCurrentFrameSize()
|
||||
|
||||
target.PushTranslation(screenWidth/2-animWidth/2, screenHeight/2+animHeight/2)
|
||||
pushCount++
|
||||
|
||||
target.PushTranslation(0, -animHeight)
|
||||
defer target.PopN(2)
|
||||
pushCount++
|
||||
|
||||
defer target.PopN(pushCount)
|
||||
|
||||
return m.loadingAnim.Render(target)
|
||||
}
|
||||
|
||||
func (m *manager) renderCursor(target d2interface.Surface) error {
|
||||
_, height := m.cursorAnim.GetCurrentFrameSize()
|
||||
pushCount := 0
|
||||
|
||||
target.PushTranslation(m.cursorX, m.cursorY)
|
||||
pushCount++
|
||||
|
||||
target.PushTranslation(0, -height)
|
||||
defer target.PopN(2)
|
||||
pushCount++
|
||||
|
||||
defer target.PopN(pushCount)
|
||||
|
||||
return m.cursorAnim.Render(target)
|
||||
}
|
||||
@ -136,7 +153,8 @@ func (m *manager) showLoadScreen(progress float64) {
|
||||
|
||||
animation := m.loadingAnim
|
||||
frameCount := animation.GetFrameCount()
|
||||
animation.SetCurrentFrame(int(float64(frameCount-1.0) * progress))
|
||||
|
||||
_ = animation.SetCurrentFrame(int(float64(frameCount-1) * progress))
|
||||
|
||||
m.loading = true
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package d2gui
|
||||
|
||||
// SpacerStatic is a spacer with explicit width and height, meaning
|
||||
// that it wont dynamically expand within a layout
|
||||
type SpacerStatic struct {
|
||||
widgetBase
|
||||
|
||||
@ -14,10 +16,12 @@ func createSpacerStatic(width, height int) *SpacerStatic {
|
||||
return spacer
|
||||
}
|
||||
|
||||
func (s *SpacerStatic) getSize() (int, int) {
|
||||
func (s *SpacerStatic) getSize() (width, height int) {
|
||||
return s.width, s.height
|
||||
}
|
||||
|
||||
// SpacerDynamic is a spacer that will expand within a layout,
|
||||
// depending on the layout position and alignment types
|
||||
type SpacerDynamic struct {
|
||||
widgetBase
|
||||
}
|
||||
|
@ -6,13 +6,16 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
|
||||
// AnimationDirection is a the animation play direction
|
||||
type AnimationDirection int
|
||||
|
||||
// AnimationDirection types
|
||||
const (
|
||||
DirectionForward AnimationDirection = 0
|
||||
DirectionBackward = 1
|
||||
DirectionForward AnimationDirection = iota
|
||||
DirectionBackward
|
||||
)
|
||||
|
||||
// Sprite is an image
|
||||
type Sprite struct {
|
||||
widgetBase
|
||||
|
||||
@ -23,6 +26,7 @@ type Sprite struct {
|
||||
animation d2interface.Animation
|
||||
}
|
||||
|
||||
// AnimatedSprite is a sprite that has animation
|
||||
type AnimatedSprite struct {
|
||||
*Sprite
|
||||
}
|
||||
@ -45,15 +49,19 @@ func createAnimatedSprite(imagePath, palettePath string, direction AnimationDire
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sprite := &AnimatedSprite{
|
||||
&Sprite{},
|
||||
}
|
||||
|
||||
sprite.animation = animation
|
||||
|
||||
if direction == DirectionForward {
|
||||
sprite.animation.PlayForward()
|
||||
} else {
|
||||
sprite.animation.PlayBackward()
|
||||
}
|
||||
|
||||
sprite.SetVisible(true)
|
||||
|
||||
return sprite, nil
|
||||
@ -64,9 +72,11 @@ func (s *AnimatedSprite) render(target d2interface.Surface) error {
|
||||
|
||||
target.PushTranslation(s.x, s.y-frameHeight)
|
||||
defer target.Pop()
|
||||
|
||||
return s.animation.Render(target)
|
||||
}
|
||||
|
||||
// SetSegmented sets the segment properties of the sprite
|
||||
func (s *Sprite) SetSegmented(segmentsX, segmentsY, frameOffset int) {
|
||||
s.segmentsX = segmentsX
|
||||
s.segmentsY = segmentsY
|
||||
@ -81,10 +91,11 @@ func (s *Sprite) advance(elapsed float64) error {
|
||||
return s.animation.Advance(elapsed)
|
||||
}
|
||||
|
||||
func (s *Sprite) getSize() (int, int) {
|
||||
func (s *Sprite) getSize() (width, height int) {
|
||||
return s.animation.GetCurrentFrameSize()
|
||||
}
|
||||
|
||||
// SetEffect sets the draw effect for the sprite
|
||||
func (s *Sprite) SetEffect(e d2enum.DrawEffect) {
|
||||
s.animation.SetEffect(e)
|
||||
}
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
)
|
||||
|
||||
// FontStyle is a representation of a font with a palette
|
||||
type FontStyle int
|
||||
|
||||
// Font styles
|
||||
const (
|
||||
FontStyle16Units FontStyle = iota
|
||||
FontStyle30Units
|
||||
@ -33,8 +35,20 @@ var fontStyleConfigs = map[FontStyle]fontStyleConfig{
|
||||
FontStyleRediculous: {d2resource.FontRediculous, d2resource.PaletteUnits},
|
||||
}
|
||||
|
||||
// ButtonStyle is a representation of a button style. Button styles have
|
||||
// x and y sebment counts, an image, a palette, a font, and a text offset
|
||||
type ButtonStyle int
|
||||
|
||||
// Button styles
|
||||
const (
|
||||
ButtonStyleMedium ButtonStyle = iota
|
||||
ButtonStyleNarrow
|
||||
ButtonStyleOkCancel
|
||||
ButtonStyleShort
|
||||
ButtonStyleTall
|
||||
ButtonStyleWide
|
||||
)
|
||||
|
||||
type buttonStyleConfig struct {
|
||||
segmentsX int
|
||||
segmentsY int
|
||||
@ -44,15 +58,6 @@ type buttonStyleConfig struct {
|
||||
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},
|
||||
|
@ -4,7 +4,10 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
// MouseHandler is a handler function for mouse events
|
||||
type MouseHandler func(d2interface.MouseEvent)
|
||||
|
||||
// MouseMoveHandler is a handler function for mouse movement events
|
||||
type MouseMoveHandler func(d2interface.MouseMoveEvent)
|
||||
|
||||
type widget interface {
|
||||
@ -46,16 +49,19 @@ type widgetBase struct {
|
||||
mouseClickHandler MouseHandler
|
||||
}
|
||||
|
||||
// SetPosition sets the widget position
|
||||
func (w *widgetBase) SetPosition(x, y int) {
|
||||
w.x = x
|
||||
w.y = y
|
||||
}
|
||||
|
||||
func (w *widgetBase) GetPosition() (int, int) {
|
||||
// GetPosition returns the widget position
|
||||
func (w *widgetBase) GetPosition() (x, y int) {
|
||||
return w.x, w.y
|
||||
}
|
||||
|
||||
func (w *widgetBase) GetOffset() (int, int) {
|
||||
// GetOffset gets the widget offset
|
||||
func (w *widgetBase) GetOffset() (x, y int) {
|
||||
return w.offsetX, w.offsetY
|
||||
}
|
||||
|
||||
@ -74,26 +80,32 @@ func (w *widgetBase) setOffset(x, y int) {
|
||||
w.offsetY = y
|
||||
}
|
||||
|
||||
// SetLayer sets the widget layer (for rendering order)
|
||||
func (w *widgetBase) SetLayer(layer int) {
|
||||
w.layer = layer
|
||||
}
|
||||
|
||||
// SetVisible sets the widget's visibility
|
||||
func (w *widgetBase) SetVisible(visible bool) {
|
||||
w.visible = visible
|
||||
}
|
||||
|
||||
// SetExpanding tells the widget to expand (or not) when inside of a layout
|
||||
func (w *widgetBase) SetExpanding(expanding bool) {
|
||||
w.expanding = expanding
|
||||
}
|
||||
|
||||
// SetMouseEnterHandler sets the handler function for mouse-enter events
|
||||
func (w *widgetBase) SetMouseEnterHandler(handler MouseMoveHandler) {
|
||||
w.mouseEnterHandler = handler
|
||||
}
|
||||
|
||||
// SetMouseLeaveHandler sets the handler function for mouse-leave events
|
||||
func (w *widgetBase) SetMouseLeaveHandler(handler MouseMoveHandler) {
|
||||
w.mouseLeaveHandler = handler
|
||||
}
|
||||
|
||||
// SetMouseClickHandler sets the handler function for mouse-click events
|
||||
func (w *widgetBase) SetMouseClickHandler(handler MouseHandler) {
|
||||
w.mouseClickHandler = handler
|
||||
}
|
||||
@ -118,11 +130,11 @@ func (w *widgetBase) isExpanding() bool {
|
||||
return w.expanding
|
||||
}
|
||||
|
||||
func (w *widgetBase) render(target d2interface.Surface) error {
|
||||
func (w *widgetBase) render(_ d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *widgetBase) advance(elapsed float64) error {
|
||||
func (w *widgetBase) advance(_ float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -150,18 +162,18 @@ func (w *widgetBase) onMouseButtonClick(event d2interface.MouseEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *widgetBase) onMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||
func (w *widgetBase) onMouseMove(_ d2interface.MouseMoveEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *widgetBase) onMouseOver(event d2interface.MouseMoveEvent) bool {
|
||||
func (w *widgetBase) onMouseOver(_ d2interface.MouseMoveEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *widgetBase) onMouseButtonDown(event d2interface.MouseEvent) bool {
|
||||
func (w *widgetBase) onMouseButtonDown(_ d2interface.MouseEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (w *widgetBase) onMouseButtonUp(event d2interface.MouseEvent) bool {
|
||||
func (w *widgetBase) onMouseButtonUp(_ d2interface.MouseEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user