1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 06:05:23 +00:00

d2ui: Create default base widget

this encapsulates all the repeating functions defined for all widgets in
the same way, like Set/GetPosition().
This commit is contained in:
juander 2020-11-06 12:38:20 +01:00
parent aa1fca84d5
commit 881d5f1f71
12 changed files with 121 additions and 198 deletions

View File

@ -242,32 +242,28 @@ var _ Widget = &Button{} // static check to ensure button implements widget
// Button defines a standard wide UI button
type Button struct {
manager *UIManager
*BaseWidget
buttonLayout ButtonLayout
normalSurface d2interface.Surface
pressedSurface d2interface.Surface
toggledSurface d2interface.Surface
pressedToggledSurface d2interface.Surface
disabledSurface d2interface.Surface
x int
y int
width int
height int
onClick func()
enabled bool
visible bool
pressed bool
toggled bool
}
// NewButton creates an instance of Button
func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
base := NewBaseWidget(ui)
base.SetVisible(true)
btn := &Button{
width: 0,
height: 0,
visible: true,
enabled: true,
pressed: false,
BaseWidget: base,
enabled: true,
pressed: false,
}
buttonLayout := getButtonLayouts()[buttonType]
@ -426,11 +422,6 @@ func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, lab
}
}
// bindManager binds the button to the UI manager
func (v *Button) bindManager(manager *UIManager) {
v.manager = manager
}
// OnActivated defines the callback handler for the activate event
func (v *Button) OnActivated(callback func()) {
v.onClick = callback
@ -495,32 +486,6 @@ func (v *Button) SetEnabled(enabled bool) {
v.enabled = enabled
}
// GetSize returns the size of the button
func (v *Button) GetSize() (width, height int) {
return v.width, v.height
}
// SetPosition moves the button
func (v *Button) SetPosition(x, y int) {
v.x = x
v.y = y
}
// GetPosition returns the location of the button
func (v *Button) GetPosition() (x, y int) {
return v.x, v.y
}
// GetVisible returns the visibility of the button
func (v *Button) GetVisible() bool {
return v.visible
}
// SetVisible sets the visibility of the button
func (v *Button) SetVisible(visible bool) {
v.visible = visible
}
// GetPressed returns the pressed state of the button
func (v *Button) GetPressed() bool {
return v.pressed

View File

@ -10,16 +10,11 @@ import (
// Checkbox represents a checkbox UI element
type Checkbox struct {
manager *UIManager
*BaseWidget
Image d2interface.Surface
checkedImage d2interface.Surface
x int
y int
width int
height int
onClick func()
checkState bool
visible bool
enabled bool
}
@ -27,11 +22,11 @@ type Checkbox struct {
func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
var err error
base := NewBaseWidget(ui)
result := &Checkbox{
BaseWidget: base,
checkState: checkState,
visible: true,
width: 0,
height: 0,
enabled: true,
}
@ -70,11 +65,6 @@ func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
return result
}
// bindManager binds the checkbox to the UI manager
func (v *Checkbox) bindManager(manager *UIManager) {
v.manager = manager
}
// Render renders the checkbox
func (v *Checkbox) Render(target d2interface.Surface) error {
target.PushTranslation(v.x, v.y)
@ -140,29 +130,3 @@ func (v *Checkbox) Activate() {
v.onClick()
}
// GetPosition returns the position of the checkbox
func (v *Checkbox) GetPosition() (x, y int) {
return v.x, v.y
}
// GetSize returns the size of the checkbox
func (v *Checkbox) GetSize() (width, height int) {
return v.width, v.height
}
// GetVisible returns the visibility state of the checkbox
func (v *Checkbox) GetVisible() bool {
return v.visible
}
// SetPosition sets the position of the checkbox
func (v *Checkbox) SetPosition(x, y int) {
v.x = x
v.y = y
}
// SetVisible sets the visibility of the checkbox
func (v *Checkbox) SetVisible(visible bool) {
v.visible = visible
}

View File

@ -11,6 +11,7 @@ type Drawable interface {
GetSize() (width, height int)
SetPosition(x, y int)
GetPosition() (x, y int)
OffsetPosition(xo, yo int)
GetVisible() bool
SetVisible(visible bool)
}

View File

@ -19,11 +19,9 @@ const (
// 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
asset *d2asset.AssetManager
uiManager *UIManager
frame *Sprite
originX int
originY int
frameOrientation frameOrientation
}
@ -58,12 +56,13 @@ func NewUIFrame(
originY = 0
}
base := NewBaseWidget(uiManager)
base.SetPosition(originX, originY)
frame := &UIFrame{
BaseWidget: base,
asset: asset,
uiManager: uiManager,
frameOrientation: frameOrientation,
originX: originX,
originY: originY,
}
frame.Load()
@ -72,7 +71,7 @@ func NewUIFrame(
// Load the necessary frame resources
func (u *UIFrame) Load() {
sprite, err := u.uiManager.NewSprite(d2resource.Frame, d2resource.PaletteSky)
sprite, err := u.manager.NewSprite(d2resource.Frame, d2resource.PaletteSky)
if err != nil {
log.Print(err)
}
@ -105,7 +104,7 @@ func (u *UIFrame) renderLeft(target d2interface.Surface) error {
// the frame coordinates
coord := make(map[int]*struct{ x, y int })
startX, startY := u.originX, u.originY
startX, startY := u.GetPosition()
currentX, currentY := startX, startY
// first determine the coordinates for each frame
@ -162,7 +161,7 @@ func (u *UIFrame) renderRight(target d2interface.Surface) error {
// the frame coordinates
coord := make(map[int]*struct{ x, y int })
startX, startY := u.originX, u.originY
startX, startY := u.GetPosition()
currentX, currentY := startX, startY
// first determine the coordinates for each frame

View File

@ -15,10 +15,8 @@ import (
// Label represents a user interface label
type Label struct {
manager *UIManager
*BaseWidget
text string
X int
Y int
Alignment d2gui.HorizontalAlign
font *d2asset.Font
Color map[int]color.Color
@ -33,10 +31,13 @@ func (ui *UIManager) NewLabel(fontPath, palettePath string) *Label {
return nil
}
base := NewBaseWidget(ui)
result := &Label{
Alignment: d2gui.HorizontalAlignLeft,
Color: map[int]color.Color{0: color.White},
font: font,
BaseWidget: base,
Alignment: d2gui.HorizontalAlignLeft,
Color: map[int]color.Color{0: color.White},
font: font,
}
result.bindManager(ui)
@ -46,7 +47,7 @@ func (ui *UIManager) NewLabel(fontPath, palettePath string) *Label {
// Render draws the label on the screen, respliting the lines to allow for other alignments.
func (v *Label) Render(target d2interface.Surface) {
target.PushTranslation(v.X, v.Y)
target.PushTranslation(v.GetPosition())
lines := strings.Split(v.text, "\n")
yOffset := 0
@ -91,17 +92,6 @@ func (v *Label) Render(target d2interface.Surface) {
target.Pop()
}
// bindManager binds the label to the UI manager
func (v *Label) bindManager(manager *UIManager) {
v.manager = manager
}
// SetPosition moves the label to the specified location
func (v *Label) SetPosition(x, y int) {
v.X = x
v.Y = y
}
// GetSize returns the size of the label
func (v *Label) GetSize() (width, height int) {
return v.font.GetTextMetrics(v.text)

View File

@ -17,9 +17,7 @@ const (
// Scrollbar is a vertical slider ui element
type Scrollbar struct {
manager *UIManager
x, y, height int
visible bool
*BaseWidget
enabled bool
currentOffset int
maxOffset int
@ -36,12 +34,13 @@ func (ui *UIManager) NewScrollbar(x, y, height int) *Scrollbar {
return nil
}
base := NewBaseWidget(ui)
base.SetPosition(x, y)
base.height = height
result := &Scrollbar{
visible: true,
BaseWidget: base,
enabled: true,
x: x,
y: y,
height: height,
scrollbarSprite: scrollbarSprite,
}
@ -146,11 +145,6 @@ func (v *Scrollbar) Render(target d2interface.Surface) error {
return nil
}
// bindManager binds the scrollbar to the UI manager
func (v *Scrollbar) bindManager(manager *UIManager) {
v.manager = manager
}
// Advance advances the scrollbar sprite
func (v *Scrollbar) Advance(elapsed float64) error {
return v.scrollbarSprite.Advance(elapsed)
@ -161,27 +155,6 @@ func (v *Scrollbar) GetSize() (width, height int) {
return scrollbarWidth, v.height
}
// SetPosition sets the scrollbar x,y position
func (v *Scrollbar) SetPosition(x, y int) {
v.x = x
v.y = y
}
// GetPosition returns the scrollbar x,y position
func (v *Scrollbar) GetPosition() (x, y int) {
return v.x, v.y
}
// GetVisible returns whether or not the scrollbar is visible
func (v *Scrollbar) GetVisible() bool {
return v.visible
}
// SetVisible sets the scrollbar visibility state
func (v *Scrollbar) SetVisible(visible bool) {
v.visible = visible
}
// SetMaxOffset sets the maximum offset of the scrollbar
func (v *Scrollbar) SetMaxOffset(maxOffset int) {
v.maxOffset = maxOffset

View File

@ -13,8 +13,7 @@ import (
// Sprite is a positioned visual object.
type Sprite struct {
x int
y int
*BaseWidget
animation d2interface.Animation
}
@ -31,7 +30,11 @@ func (ui *UIManager) NewSprite(animationPath, palettePath string) (*Sprite, erro
animation.BindRenderer(ui.renderer)
return &Sprite{animation: animation}, nil
base := NewBaseWidget(ui)
return &Sprite{
BaseWidget: base,
animation: animation}, nil
}
// Render renders the sprite on the given surface
@ -80,15 +83,9 @@ func (s *Sprite) RenderSegmented(target d2interface.Surface, segmentsX, segments
return nil
}
// SetPosition places the sprite in 2D
func (s *Sprite) SetPosition(x, y int) {
s.x = x
s.y = y
}
// GetPosition retrieves the 2D position of the sprite
func (s *Sprite) GetPosition() (x, y int) {
return s.x, s.y
// GetSize returns the size of the current frame
func (s *Sprite) GetSize() (width, height int) {
return s.GetCurrentFrameSize()
}
// GetFrameSize gets the Size(width, height) of a indexed frame.

View File

@ -12,15 +12,12 @@ import (
// TextBox represents a text input box
type TextBox struct {
manager *UIManager
*BaseWidget
textLabel *Label
lineBar *Label
text string
filter string
x int
y int
bgSprite *Sprite
visible bool
enabled bool
isFocused bool
}
@ -33,13 +30,15 @@ func (ui *UIManager) NewTextbox() *TextBox {
return nil
}
base := NewBaseWidget(ui)
tb := &TextBox{
filter: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
bgSprite: bgSprite,
textLabel: ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
lineBar: ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
enabled: true,
visible: true,
BaseWidget: base,
filter: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
bgSprite: bgSprite,
textLabel: ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
lineBar: ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
enabled: true,
}
tb.lineBar.SetText("_")
@ -69,11 +68,6 @@ func (v *TextBox) Render(target d2interface.Surface) error {
return nil
}
// bindManager binds the textbox to the UI manager
func (v *TextBox) bindManager(manager *UIManager) {
v.manager = manager
}
// OnKeyChars handles key character events
func (v *TextBox) OnKeyChars(event d2interface.KeyCharsEvent) bool {
if !v.isFocused || !v.visible || !v.enabled {
@ -189,21 +183,6 @@ func (v *TextBox) SetPosition(x, y int) {
v.bgSprite.SetPosition(v.x, v.y+26)
}
// GetPosition returns the position of the text box
func (v *TextBox) GetPosition() (x, y int) {
return v.x, v.y
}
// GetVisible returns the visibility of the text box
func (v *TextBox) GetVisible() bool {
return v.visible
}
// SetVisible sets the visibility of the text box
func (v *TextBox) SetVisible(visible bool) {
v.visible = visible
}
// GetEnabled returns the enabled state of the text box
func (v *TextBox) GetEnabled() bool {
return v.enabled

View File

@ -16,11 +16,10 @@ const (
// Tooltip contains a label containing text with a transparent, black background
type Tooltip struct {
manager *UIManager
*BaseWidget
lines []string
label *Label
backgroundColor int
x, y int
originX tooltipXOrigin
originY tooltipYOrigin
boxEnabled bool
@ -56,11 +55,12 @@ func (ui *UIManager) NewTooltip(font,
label := ui.NewLabel(font, palette)
label.Alignment = d2gui.HorizontalAlignCenter
base := NewBaseWidget(ui)
res := &Tooltip{
BaseWidget: base,
backgroundColor: blackAlpha70,
label: label,
x: 0,
y: 0,
originX: originX,
originY: originY,
boxEnabled: true,
@ -70,12 +70,6 @@ func (ui *UIManager) NewTooltip(font,
return res
}
// SetPosition sets the position of the origin point of the tooltip
func (t *Tooltip) SetPosition(x, y int) {
t.x = x
t.y = y
}
// SetTextLines sets the tooltip text in the form of an array of strings
func (t *Tooltip) SetTextLines(lines []string) {
t.lines = lines

View File

@ -16,3 +16,60 @@ type ClickableWidget interface {
OnActivated(callback func())
Activate()
}
// BaseWidget contains default functionality that all widgets share
type BaseWidget struct {
manager *UIManager
x int
y int
width int
height int
visible bool
}
// NewBaseWidget creates a new BaseWidget with defaults
func NewBaseWidget(manager *UIManager) *BaseWidget {
return &BaseWidget{
manager: manager,
x: 0,
y: 0,
width: 0,
height: 0,
visible: true,
}
}
func (b *BaseWidget) bindManager(manager *UIManager) {
b.manager = manager
}
// GetSize returns the size of the widget
func (b *BaseWidget) GetSize() (width, height int) {
return b.width, b.height
}
// SetPosition sets the position of the widget
func (b *BaseWidget) SetPosition(x, y int) {
b.x, b.y = x, y
}
// OffsetPosition moves the widget by x and y
func (b *BaseWidget) OffsetPosition(x, y int) {
b.x += x
b.y += y
}
// GetPosition returns the position of the widget
func (b *BaseWidget) GetPosition() (x, y int) {
return b.x, b.y
}
// GetVisible returns whether the widget is visible
func (b *BaseWidget) GetVisible() (visible bool) {
return b.visible
}
// SetVisible make the widget visible, not visible
func (b *BaseWidget) SetVisible(visible bool) {
b.visible = visible
}

View File

@ -392,8 +392,9 @@ func (v *CharacterSelect) Render(screen d2interface.Surface) {
v.characterStatsLabel[i].Render(screen)
v.characterExpLabel[i].Render(screen)
charImgX := v.characterNameLabel[i].X - selectionBoxImageOffsetX
charImgY := v.characterNameLabel[i].Y + selectionBoxImageOffsetY
x, y := v.characterNameLabel[i].GetPosition()
charImgX := x - selectionBoxImageOffsetX
charImgY := y + selectionBoxImageOffsetY
screen.PushTranslation(charImgX, charImgY)
v.characterImage[i].Render(screen)
screen.Pop()

View File

@ -159,11 +159,14 @@ func (v *Credits) Advance(tickTime float64) error {
continue
}
if label.Label.Y-1 < -15 {
_, y := label.Label.GetPosition()
if y-1 < -15 {
label.Available = true
continue
}
label.Label.Y--
label.Label.OffsetPosition(0, -1)
}
}