mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-05 09:47:18 -05:00
5cd404e4a5
* d2ui.Frame refactor * removed unneccessery d2asset.AssetManager argument from d2ui.NewUIFrame * d2ui.Frame refactor * removed unneccessery d2asset.AssetManager argument from d2ui.NewUIFrame Co-authored-by: M. Sz <mszeptuch@protonmail.com> Co-authored-by: Tim Sarbin <tim.sarbin@gmail.com> Co-authored-by: gravestench <dknuth0101@gmail.com>
279 lines
5.9 KiB
Go
279 lines
5.9 KiB
Go
package d2ui
|
|
|
|
import (
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
|
)
|
|
|
|
// static check that UIFrame implements Widget
|
|
var _ Widget = &UIFrame{}
|
|
|
|
type frameOrientation = int
|
|
|
|
// Frame orientations
|
|
const (
|
|
FrameLeft frameOrientation = iota
|
|
FrameRight
|
|
)
|
|
|
|
// UIFrame is a representation of a ui panel that occupies the left or right half of the screen
|
|
// when it is visible.
|
|
type UIFrame struct {
|
|
*BaseWidget
|
|
frame *Sprite
|
|
frameOrientation frameOrientation
|
|
*d2util.Logger
|
|
}
|
|
|
|
// frame indices into dc6 images for panels
|
|
const (
|
|
leftFrameTopLeft = iota
|
|
leftFrameTopRight
|
|
leftFrameMiddleLeft
|
|
leftFrameBottomLeft
|
|
leftFrameBottomRight
|
|
rightFrameTopLeft
|
|
rightFrameTopRight
|
|
rightFrameMiddleRight
|
|
rightFrameBottomRight
|
|
rightFrameBottomLeft
|
|
)
|
|
|
|
// NewUIFrame creates a new Frame instance
|
|
func (ui *UIManager) NewUIFrame(frameOrientation frameOrientation) *UIFrame {
|
|
var originX, originY = 0, 0
|
|
|
|
switch frameOrientation {
|
|
case FrameLeft:
|
|
originX = 0
|
|
originY = 0
|
|
case FrameRight:
|
|
originX = 400
|
|
originY = 0
|
|
}
|
|
|
|
base := NewBaseWidget(ui)
|
|
base.SetVisible(false)
|
|
base.SetPosition(originX, originY)
|
|
|
|
frame := &UIFrame{
|
|
BaseWidget: base,
|
|
frameOrientation: frameOrientation,
|
|
Logger: ui.Logger,
|
|
}
|
|
|
|
sprite, err := ui.NewSprite(d2resource.Frame, d2resource.PaletteSky)
|
|
if err != nil {
|
|
frame.Error(err.Error())
|
|
}
|
|
|
|
frame.frame = sprite
|
|
frame.calculateSize()
|
|
|
|
ui.addWidget(frame)
|
|
|
|
return frame
|
|
}
|
|
|
|
func (u *UIFrame) calculateSize() {
|
|
var framesWidth, framesHeight []int
|
|
|
|
if u.frameOrientation == FrameLeft {
|
|
framesWidth = []int{
|
|
leftFrameTopLeft,
|
|
leftFrameTopRight,
|
|
}
|
|
framesHeight = []int{
|
|
leftFrameTopLeft,
|
|
leftFrameMiddleLeft,
|
|
leftFrameBottomLeft,
|
|
}
|
|
} else if u.frameOrientation == FrameRight {
|
|
framesWidth = []int{
|
|
rightFrameTopLeft,
|
|
rightFrameTopRight,
|
|
}
|
|
framesHeight = []int{
|
|
rightFrameTopRight,
|
|
rightFrameMiddleRight,
|
|
rightFrameBottomRight,
|
|
}
|
|
}
|
|
|
|
for i := range framesWidth {
|
|
w, _, err := u.frame.GetFrameSize(framesWidth[i])
|
|
if err != nil {
|
|
u.Error(err.Error())
|
|
}
|
|
|
|
u.width += w
|
|
}
|
|
|
|
for i := range framesHeight {
|
|
_, h, err := u.frame.GetFrameSize(framesHeight[i])
|
|
if err != nil {
|
|
u.Error(err.Error())
|
|
}
|
|
|
|
u.height += h
|
|
}
|
|
}
|
|
|
|
// Render the frame to the target surface
|
|
func (u *UIFrame) Render(target d2interface.Surface) {
|
|
switch u.frameOrientation {
|
|
case FrameLeft:
|
|
if err := u.renderLeft(target); err != nil {
|
|
u.Error("Render error" + err.Error())
|
|
}
|
|
case FrameRight:
|
|
if err := u.renderRight(target); err != nil {
|
|
u.Error("Render error" + err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
func (u *UIFrame) renderLeft(target d2interface.Surface) error {
|
|
// the frame pieces we are interested in.
|
|
framePieces := []int{
|
|
leftFrameTopLeft,
|
|
leftFrameTopRight,
|
|
leftFrameMiddleLeft,
|
|
leftFrameBottomLeft,
|
|
leftFrameBottomRight,
|
|
}
|
|
|
|
// the frame coordinates
|
|
coord := make(map[int]*struct{ x, y int })
|
|
|
|
startX, startY := u.GetPosition()
|
|
currentX, currentY := startX, startY
|
|
|
|
// first determine the coordinates for each frame
|
|
// the order that we check is important
|
|
for _, piece := range framePieces {
|
|
width, height, err := u.frame.GetFrameSize(piece)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
c := &struct{ x, y int }{}
|
|
|
|
switch piece {
|
|
case leftFrameTopLeft:
|
|
c.x, c.y = currentX, currentY+height
|
|
currentX, currentY = currentX+width, currentY+height
|
|
case leftFrameTopRight:
|
|
c.x, c.y = currentX, startY+height
|
|
currentX = startX
|
|
case leftFrameMiddleLeft:
|
|
c.x, c.y = currentX, currentY+height
|
|
currentY += height
|
|
case leftFrameBottomLeft:
|
|
c.x, c.y = currentX, currentY+height
|
|
currentX += width
|
|
case leftFrameBottomRight:
|
|
c.x, c.y = currentX, currentY+height
|
|
}
|
|
|
|
coord[piece] = c
|
|
}
|
|
|
|
// now render the pieces with the coordinates
|
|
for idx, c := range coord {
|
|
err := u.renderFramePiece(target, c.x, c.y, idx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (u *UIFrame) renderRight(target d2interface.Surface) error {
|
|
// the frame pieces we are interested in.
|
|
framePieces := []int{
|
|
rightFrameTopLeft,
|
|
rightFrameTopRight,
|
|
rightFrameMiddleRight,
|
|
rightFrameBottomRight,
|
|
rightFrameBottomLeft,
|
|
}
|
|
|
|
// the frame coordinates
|
|
coord := make(map[int]*struct{ x, y int })
|
|
|
|
startX, startY := u.GetPosition()
|
|
currentX, currentY := startX, startY
|
|
|
|
// first determine the coordinates for each frame
|
|
// the order that we check is important
|
|
for _, piece := range framePieces {
|
|
width, height, err := u.frame.GetFrameSize(piece)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
c := &struct{ x, y int }{}
|
|
|
|
switch piece {
|
|
case rightFrameTopLeft:
|
|
c.x, c.y = currentX, currentY+height
|
|
currentX += width
|
|
case rightFrameTopRight:
|
|
c.x, c.y = currentX, currentY+height
|
|
currentX += width
|
|
currentY += height
|
|
case rightFrameMiddleRight:
|
|
c.x, c.y = currentX-width, currentY+height
|
|
currentY += height
|
|
case rightFrameBottomRight:
|
|
c.x, c.y = currentX-width, currentY+height
|
|
currentX -= width
|
|
case rightFrameBottomLeft:
|
|
c.x, c.y = currentX-width, currentY+height
|
|
currentX += width
|
|
}
|
|
|
|
coord[piece] = c
|
|
}
|
|
|
|
// now render the pieces with the coordinates
|
|
for idx, c := range coord {
|
|
err := u.renderFramePiece(target, c.x, c.y, idx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetFrameBounds returns the maximum width and height of all frames in sprite.
|
|
func (u *UIFrame) GetFrameBounds() (width, height int) {
|
|
return u.frame.GetFrameBounds()
|
|
}
|
|
|
|
// GetFrameCount returns the number of frames in the sprite
|
|
func (u *UIFrame) GetFrameCount() int {
|
|
return u.frame.GetFrameCount()
|
|
}
|
|
|
|
func (u *UIFrame) renderFramePiece(sfc d2interface.Surface, x, y, idx int) error {
|
|
if err := u.frame.SetCurrentFrame(idx); err != nil {
|
|
return err
|
|
}
|
|
|
|
u.frame.SetPosition(x, y)
|
|
|
|
u.frame.Render(sfc)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Advance is a no-op
|
|
func (u *UIFrame) Advance(elapsed float64) error {
|
|
return nil
|
|
}
|