mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-26 19:27:31 -05:00
Ui minipanel refactor (#926)
* d2player/hud: Make minipanel button a real ui/button * d2ui/button: Add implicit tooltips for now it is only for close buttons. * d2ui/frame: Add size caluclation now frame.GetSize() returns meaningful values. * d2ui/button: Add minipanel button types * d2ui/hero_stats_panel: Fix cached image being way to big * d2ui/widget_group: Fix widget groups size calculation * d2ui/widget_group: Add debug rendering * d2ui/widget_group: SetVisible() now sets the visibility of the group object * d2player: Refactor mini_panel we converted all elements to widgets. Thus rendering from game_controls is no longer neccessary. * d2ui/button: Add disabled color to layouts * d2player/gamecontrols: temp hide minipanel when in esc menu * d2ui/widget_group: Add OffsetPosition() method * d2player/mini_panel: Implement moving of minipanel this only occours when other panels are opened. * d2player/minipanel: Fix inv/skilltree/char closebuttons these would screw up the moving of the mini panel. * Fix linter * d2player/minipanel: Add tooltips to buttons * d2player/skilltree: Fix icon rendering
This commit is contained in:
parent
12821147ce
commit
ba5ea334cc
@ -40,6 +40,8 @@ const (
|
|||||||
ButtonTypeMinipanelMen ButtonType = 19
|
ButtonTypeMinipanelMen ButtonType = 19
|
||||||
ButtonTypeSquareClose ButtonType = 20
|
ButtonTypeSquareClose ButtonType = 20
|
||||||
ButtonTypeSkillTreeTab ButtonType = 21
|
ButtonTypeSkillTreeTab ButtonType = 21
|
||||||
|
ButtonTypeMinipanelOpenClose ButtonType = 22
|
||||||
|
ButtonTypeMinipanelParty ButtonType = 23
|
||||||
|
|
||||||
ButtonNoFixedWidth int = -1
|
ButtonNoFixedWidth int = -1
|
||||||
ButtonNoFixedHeight int = -1
|
ButtonNoFixedHeight int = -1
|
||||||
@ -71,6 +73,7 @@ type ButtonLayout struct {
|
|||||||
YSegments int
|
YSegments int
|
||||||
BaseFrame int
|
BaseFrame int
|
||||||
DisabledFrame int
|
DisabledFrame int
|
||||||
|
DisabledColor uint32
|
||||||
TextOffset int
|
TextOffset int
|
||||||
FixedWidth int
|
FixedWidth int
|
||||||
FixedHeight int
|
FixedHeight int
|
||||||
@ -78,8 +81,21 @@ type ButtonLayout struct {
|
|||||||
Toggleable bool
|
Toggleable bool
|
||||||
AllowFrameChange bool
|
AllowFrameChange bool
|
||||||
HasImage bool
|
HasImage bool
|
||||||
|
Tooltip int
|
||||||
|
TooltipXOffset int
|
||||||
|
TooltipYOffset int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
buttonTooltipNone int = iota
|
||||||
|
buttonTooltipClose
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
buttonCloseTooltipXOffset = 15
|
||||||
|
buttonCloseTooltipYOffset = -2
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
buttonWideSegmentsX = 2
|
buttonWideSegmentsX = 2
|
||||||
buttonWideSegmentsY = 1
|
buttonWideSegmentsY = 1
|
||||||
@ -106,13 +122,28 @@ const (
|
|||||||
buttonBuySellSegmentsY = 1
|
buttonBuySellSegmentsY = 1
|
||||||
buttonBuySellDisabledFrame = 1
|
buttonBuySellDisabledFrame = 1
|
||||||
|
|
||||||
buttonSkillTreeTabXSegments = 1
|
buttonSkillTreeTabXSegments = 1
|
||||||
buttonSkillTreeTabYSegments = 1
|
buttonSkillTreeTabYSegments = 1
|
||||||
|
|
||||||
buttonSkillTreeTabDisabledFrame = 7
|
buttonSkillTreeTabDisabledFrame = 7
|
||||||
buttonSkillTreeTabBaseFrame = 7
|
buttonSkillTreeTabBaseFrame = 7
|
||||||
buttonSkillTreeTabFixedWidth = 93
|
buttonSkillTreeTabFixedWidth = 93
|
||||||
buttonSkillTreeTabFixedHeight = 107
|
buttonSkillTreeTabFixedHeight = 107
|
||||||
|
|
||||||
|
buttonMinipanelOpenCloseBaseFrame = 0
|
||||||
|
buttonMinipanelDisabledFrame = 2
|
||||||
|
buttonMinipanelXSegments = 1
|
||||||
|
buttonMinipanelYSegments = 1
|
||||||
|
|
||||||
|
buttonMinipanelCharacterBaseFrame = 0
|
||||||
|
buttonMinipanelInventoryBaseFrame = 2
|
||||||
|
buttonMinipanelSkilltreeBaseFrame = 4
|
||||||
|
buttonMinipanelPartyBaseFrame = 6
|
||||||
|
buttonMinipanelAutomapBaseFrame = 8
|
||||||
|
buttonMinipanelMessageBaseFrame = 10
|
||||||
|
buttonMinipanelQuestBaseFrame = 12
|
||||||
|
buttonMinipanelMenBaseFrame = 14
|
||||||
|
|
||||||
buttonRunSegmentsX = 1
|
buttonRunSegmentsX = 1
|
||||||
buttonRunSegmentsY = 1
|
buttonRunSegmentsY = 1
|
||||||
buttonRunDisabledFrame = -1
|
buttonRunDisabledFrame = -1
|
||||||
@ -127,6 +158,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
XSegments: buttonWideSegmentsX,
|
XSegments: buttonWideSegmentsX,
|
||||||
YSegments: buttonWideSegmentsY,
|
YSegments: buttonWideSegmentsY,
|
||||||
DisabledFrame: buttonWideDisabledFrame,
|
DisabledFrame: buttonWideDisabledFrame,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
TextOffset: buttonWideTextOffset,
|
TextOffset: buttonWideTextOffset,
|
||||||
ResourceName: d2resource.WideButtonBlank,
|
ResourceName: d2resource.WideButtonBlank,
|
||||||
PaletteName: d2resource.PaletteUnits,
|
PaletteName: d2resource.PaletteUnits,
|
||||||
@ -141,6 +173,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
XSegments: buttonShortSegmentsX,
|
XSegments: buttonShortSegmentsX,
|
||||||
YSegments: buttonShortSegmentsY,
|
YSegments: buttonShortSegmentsY,
|
||||||
DisabledFrame: buttonShortDisabledFrame,
|
DisabledFrame: buttonShortDisabledFrame,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
TextOffset: buttonShortTextOffset,
|
TextOffset: buttonShortTextOffset,
|
||||||
ResourceName: d2resource.ShortButtonBlank,
|
ResourceName: d2resource.ShortButtonBlank,
|
||||||
PaletteName: d2resource.PaletteUnits,
|
PaletteName: d2resource.PaletteUnits,
|
||||||
@ -154,6 +187,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMedium: {
|
ButtonTypeMedium: {
|
||||||
XSegments: buttonMediumSegmentsX,
|
XSegments: buttonMediumSegmentsX,
|
||||||
YSegments: buttonMediumSegmentsY,
|
YSegments: buttonMediumSegmentsY,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
ResourceName: d2resource.MediumButtonBlank,
|
ResourceName: d2resource.MediumButtonBlank,
|
||||||
PaletteName: d2resource.PaletteUnits,
|
PaletteName: d2resource.PaletteUnits,
|
||||||
FontPath: d2resource.FontExocet10,
|
FontPath: d2resource.FontExocet10,
|
||||||
@ -167,6 +201,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
XSegments: buttonTallSegmentsX,
|
XSegments: buttonTallSegmentsX,
|
||||||
YSegments: buttonTallSegmentsY,
|
YSegments: buttonTallSegmentsY,
|
||||||
TextOffset: buttonTallTextOffset,
|
TextOffset: buttonTallTextOffset,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
ResourceName: d2resource.TallButtonBlank,
|
ResourceName: d2resource.TallButtonBlank,
|
||||||
PaletteName: d2resource.PaletteUnits,
|
PaletteName: d2resource.PaletteUnits,
|
||||||
FontPath: d2resource.FontExocet10,
|
FontPath: d2resource.FontExocet10,
|
||||||
@ -180,6 +215,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
XSegments: buttonOkCancelSegmentsX,
|
XSegments: buttonOkCancelSegmentsX,
|
||||||
YSegments: buttonOkCancelSegmentsY,
|
YSegments: buttonOkCancelSegmentsY,
|
||||||
DisabledFrame: buttonOkCancelDisabledFrame,
|
DisabledFrame: buttonOkCancelDisabledFrame,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
ResourceName: d2resource.CancelButton,
|
ResourceName: d2resource.CancelButton,
|
||||||
PaletteName: d2resource.PaletteUnits,
|
PaletteName: d2resource.PaletteUnits,
|
||||||
FontPath: d2resource.FontRediculous,
|
FontPath: d2resource.FontRediculous,
|
||||||
@ -193,6 +229,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
XSegments: buttonRunSegmentsX,
|
XSegments: buttonRunSegmentsX,
|
||||||
YSegments: buttonRunSegmentsY,
|
YSegments: buttonRunSegmentsY,
|
||||||
DisabledFrame: buttonRunDisabledFrame,
|
DisabledFrame: buttonRunDisabledFrame,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
ResourceName: d2resource.RunButton,
|
ResourceName: d2resource.RunButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
Toggleable: true,
|
Toggleable: true,
|
||||||
@ -207,6 +244,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
XSegments: buttonBuySellSegmentsX,
|
XSegments: buttonBuySellSegmentsX,
|
||||||
YSegments: buttonBuySellSegmentsY,
|
YSegments: buttonBuySellSegmentsY,
|
||||||
DisabledFrame: buttonBuySellDisabledFrame,
|
DisabledFrame: buttonBuySellDisabledFrame,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
ResourceName: d2resource.BuySellButton,
|
ResourceName: d2resource.BuySellButton,
|
||||||
PaletteName: d2resource.PaletteUnits,
|
PaletteName: d2resource.PaletteUnits,
|
||||||
Toggleable: true,
|
Toggleable: true,
|
||||||
@ -217,11 +255,15 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
FixedWidth: ButtonNoFixedWidth,
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
FixedHeight: ButtonNoFixedHeight,
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
LabelColor: greyAlpha100,
|
LabelColor: greyAlpha100,
|
||||||
|
Tooltip: buttonTooltipClose,
|
||||||
|
TooltipXOffset: buttonCloseTooltipXOffset,
|
||||||
|
TooltipYOffset: buttonCloseTooltipYOffset,
|
||||||
},
|
},
|
||||||
ButtonTypeSkillTreeTab: {
|
ButtonTypeSkillTreeTab: {
|
||||||
XSegments: buttonSkillTreeTabXSegments,
|
XSegments: buttonSkillTreeTabXSegments,
|
||||||
YSegments: buttonSkillTreeTabYSegments,
|
YSegments: buttonSkillTreeTabYSegments,
|
||||||
DisabledFrame: buttonSkillTreeTabDisabledFrame,
|
DisabledFrame: buttonSkillTreeTabDisabledFrame,
|
||||||
|
DisabledColor: lightGreyAlpha75,
|
||||||
BaseFrame: buttonSkillTreeTabBaseFrame,
|
BaseFrame: buttonSkillTreeTabBaseFrame,
|
||||||
ResourceName: d2resource.SkillsPanelAmazon,
|
ResourceName: d2resource.SkillsPanelAmazon,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -233,6 +275,134 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
FixedHeight: buttonSkillTreeTabFixedHeight,
|
FixedHeight: buttonSkillTreeTabFixedHeight,
|
||||||
LabelColor: whiteAlpha100,
|
LabelColor: whiteAlpha100,
|
||||||
},
|
},
|
||||||
|
ButtonTypeMinipanelOpenClose: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelDisabledFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
|
BaseFrame: buttonMinipanelOpenCloseBaseFrame,
|
||||||
|
ResourceName: d2resource.MenuButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: true,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelCharacter: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelCharacterBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelInventory: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelInventoryBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelSkill: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelSkilltreeBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelParty: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelPartyBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelAutomap: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelAutomapBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelMessage: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelMessageBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelQuest: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelQuestBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
|
ButtonTypeMinipanelMen: {
|
||||||
|
XSegments: buttonMinipanelXSegments,
|
||||||
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
BaseFrame: buttonMinipanelMenBaseFrame,
|
||||||
|
ResourceName: d2resource.MinipanelButton,
|
||||||
|
PaletteName: d2resource.PaletteSky,
|
||||||
|
Toggleable: false,
|
||||||
|
FontPath: d2resource.Font16,
|
||||||
|
AllowFrameChange: true,
|
||||||
|
HasImage: true,
|
||||||
|
FixedWidth: ButtonNoFixedWidth,
|
||||||
|
FixedHeight: ButtonNoFixedHeight,
|
||||||
|
LabelColor: whiteAlpha100,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +421,7 @@ type Button struct {
|
|||||||
enabled bool
|
enabled bool
|
||||||
pressed bool
|
pressed bool
|
||||||
toggled bool
|
toggled bool
|
||||||
|
tooltip *Tooltip
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewButton creates an instance of Button
|
// NewButton creates an instance of Button
|
||||||
@ -311,6 +482,8 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
|||||||
buttonSprite.SetPosition(0, 0)
|
buttonSprite.SetPosition(0, 0)
|
||||||
buttonSprite.SetEffect(d2enum.DrawEffectModulate)
|
buttonSprite.SetEffect(d2enum.DrawEffectModulate)
|
||||||
|
|
||||||
|
btn.createTooltip()
|
||||||
|
|
||||||
ui.addWidget(btn) // important that this comes before prerenderStates!
|
ui.addWidget(btn) // important that this comes before prerenderStates!
|
||||||
|
|
||||||
btn.prerenderStates(buttonSprite, &buttonLayout, lbl)
|
btn.prerenderStates(buttonSprite, &buttonLayout, lbl)
|
||||||
@ -325,6 +498,21 @@ type buttonStateDescriptor struct {
|
|||||||
fmtErr string
|
fmtErr string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Button) createTooltip() {
|
||||||
|
var t *Tooltip
|
||||||
|
|
||||||
|
switch v.buttonLayout.Tooltip {
|
||||||
|
case buttonTooltipNone:
|
||||||
|
return
|
||||||
|
case buttonTooltipClose:
|
||||||
|
t = v.manager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, TooltipXCenter, TooltipYBottom)
|
||||||
|
t.SetText(v.manager.asset.TranslateString("strClose"))
|
||||||
|
}
|
||||||
|
|
||||||
|
t.SetVisible(false)
|
||||||
|
v.SetTooltip(t)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, label *Label) {
|
func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, label *Label) {
|
||||||
numButtonStates := btnSprite.GetFrameCount() / (btnLayout.XSegments * btnLayout.YSegments)
|
numButtonStates := btnSprite.GetFrameCount() / (btnLayout.XSegments * btnLayout.YSegments)
|
||||||
|
|
||||||
@ -438,7 +626,7 @@ func (v *Button) Render(target d2interface.Surface) {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case !v.enabled:
|
case !v.enabled:
|
||||||
target.PushColor(d2util.Color(lightGreyAlpha75))
|
target.PushColor(d2util.Color(v.buttonLayout.DisabledColor))
|
||||||
defer target.Pop()
|
defer target.Pop()
|
||||||
target.Render(v.disabledSurface)
|
target.Render(v.disabledSurface)
|
||||||
case v.toggled && v.pressed:
|
case v.toggled && v.pressed:
|
||||||
@ -486,6 +674,32 @@ func (v *Button) SetPressed(pressed bool) {
|
|||||||
v.pressed = pressed
|
v.pressed = pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetVisible sets the pressed state of the button
|
||||||
|
func (v *Button) SetVisible(visible bool) {
|
||||||
|
v.BaseWidget.SetVisible(visible)
|
||||||
|
|
||||||
|
if v.isHovered() && !visible {
|
||||||
|
v.hoverEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPosition sets the position of the widget
|
||||||
|
func (v *Button) SetPosition(x, y int) {
|
||||||
|
v.BaseWidget.SetPosition(x, y)
|
||||||
|
|
||||||
|
if v.buttonLayout.Tooltip != buttonTooltipNone {
|
||||||
|
v.tooltip.SetPosition(x+v.buttonLayout.TooltipXOffset, y+v.buttonLayout.TooltipYOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTooltip adds a tooltip to the button
|
||||||
|
func (v *Button) SetTooltip(t *Tooltip) {
|
||||||
|
v.tooltip = t
|
||||||
|
v.manager.addWidget(t)
|
||||||
|
v.OnHoverStart(func() { log.Print("HoverStart"); v.tooltip.SetVisible(true) })
|
||||||
|
v.OnHoverEnd(func() { v.tooltip.SetVisible(false) })
|
||||||
|
}
|
||||||
|
|
||||||
func half(n int) int {
|
func half(n int) int {
|
||||||
return n / 2
|
return n / 2
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ type UIFrame struct {
|
|||||||
const (
|
const (
|
||||||
leftFrameTopLeft = iota
|
leftFrameTopLeft = iota
|
||||||
leftFrameTopRight
|
leftFrameTopRight
|
||||||
leftFrameMiddleRight
|
leftFrameMiddleLeft
|
||||||
leftFrameBottomLeft
|
leftFrameBottomLeft
|
||||||
leftFrameBottomRight
|
leftFrameBottomRight
|
||||||
rightFrameTopLeft
|
rightFrameTopLeft
|
||||||
@ -80,6 +80,51 @@ func (u *UIFrame) Load() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u.frame = sprite
|
u.frame = sprite
|
||||||
|
u.calculateSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.width += w
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range framesHeight {
|
||||||
|
_, h, err := u.frame.GetFrameSize(framesHeight[i])
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u.height += h
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the frame to the target surface
|
// Render the frame to the target surface
|
||||||
@ -101,7 +146,7 @@ func (u *UIFrame) renderLeft(target d2interface.Surface) error {
|
|||||||
framePieces := []int{
|
framePieces := []int{
|
||||||
leftFrameTopLeft,
|
leftFrameTopLeft,
|
||||||
leftFrameTopRight,
|
leftFrameTopRight,
|
||||||
leftFrameMiddleRight,
|
leftFrameMiddleLeft,
|
||||||
leftFrameBottomLeft,
|
leftFrameBottomLeft,
|
||||||
leftFrameBottomRight,
|
leftFrameBottomRight,
|
||||||
}
|
}
|
||||||
@ -129,7 +174,7 @@ func (u *UIFrame) renderLeft(target d2interface.Surface) error {
|
|||||||
case leftFrameTopRight:
|
case leftFrameTopRight:
|
||||||
c.x, c.y = currentX, startY+height
|
c.x, c.y = currentX, startY+height
|
||||||
currentX = startX
|
currentX = startX
|
||||||
case leftFrameMiddleRight:
|
case leftFrameMiddleLeft:
|
||||||
c.x, c.y = currentX, currentY+height
|
c.x, c.y = currentX, currentY+height
|
||||||
currentY += height
|
currentY += height
|
||||||
case leftFrameBottomLeft:
|
case leftFrameBottomLeft:
|
||||||
|
@ -105,6 +105,12 @@ func (ui *UIManager) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, w := range ui.widgets {
|
||||||
|
if w.GetVisible() {
|
||||||
|
w.OnMouseMove(event.X(), event.Y())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,17 +140,17 @@ func (ui *UIManager) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
|||||||
|
|
||||||
// Render renders all of the UI elements
|
// Render renders all of the UI elements
|
||||||
func (ui *UIManager) Render(target d2interface.Surface) {
|
func (ui *UIManager) Render(target d2interface.Surface) {
|
||||||
for _, widget := range ui.widgets {
|
|
||||||
if widget.GetVisible() {
|
|
||||||
widget.Render(target)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, widgetGroup := range ui.widgetsGroups {
|
for _, widgetGroup := range ui.widgetsGroups {
|
||||||
if widgetGroup.GetVisible() {
|
if widgetGroup.GetVisible() {
|
||||||
widgetGroup.Render(target)
|
widgetGroup.Render(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, widget := range ui.widgets {
|
||||||
|
if widget.GetVisible() {
|
||||||
|
widget.Render(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance updates all of the UI elements
|
// Advance updates all of the UI elements
|
||||||
|
@ -11,6 +11,8 @@ const (
|
|||||||
RenderPrioritySkilltree
|
RenderPrioritySkilltree
|
||||||
// RenderPrioritySkilltreeIcon is the priority for the skilltree icons
|
// RenderPrioritySkilltreeIcon is the priority for the skilltree icons
|
||||||
RenderPrioritySkilltreeIcon
|
RenderPrioritySkilltreeIcon
|
||||||
|
// RenderPriorityMinipanel is the priority for the minipanel icons
|
||||||
|
RenderPriorityMinipanel
|
||||||
// RenderPriorityHeroStatsPanel is the priority for the hero_stats_panel
|
// RenderPriorityHeroStatsPanel is the priority for the hero_stats_panel
|
||||||
RenderPriorityHeroStatsPanel
|
RenderPriorityHeroStatsPanel
|
||||||
// RenderPriorityForeground is the last element drawn
|
// RenderPriorityForeground is the last element drawn
|
||||||
@ -22,6 +24,7 @@ type Widget interface {
|
|||||||
Drawable
|
Drawable
|
||||||
bindManager(ui *UIManager)
|
bindManager(ui *UIManager)
|
||||||
GetManager() (ui *UIManager)
|
GetManager() (ui *UIManager)
|
||||||
|
OnMouseMove(x int, y int)
|
||||||
OnHoverStart(callback func())
|
OnHoverStart(callback func())
|
||||||
OnHoverEnd(callback func())
|
OnHoverEnd(callback func())
|
||||||
isHovered() bool
|
isHovered() bool
|
||||||
@ -156,3 +159,14 @@ func (b *BaseWidget) Contains(x, y int) bool {
|
|||||||
func (b *BaseWidget) GetManager() (ui *UIManager) {
|
func (b *BaseWidget) GetManager() (ui *UIManager) {
|
||||||
return b.manager
|
return b.manager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnMouseMove is called when the mouse is moved
|
||||||
|
func (b *BaseWidget) OnMouseMove(x, y int) {
|
||||||
|
if b.Contains(x, y) {
|
||||||
|
if !b.isHovered() {
|
||||||
|
b.hoverStart()
|
||||||
|
}
|
||||||
|
} else if b.isHovered() {
|
||||||
|
b.hoverEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package d2ui
|
package d2ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image/color"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const widgetGroupDebug = false // turns on debug rendering stuff for groups
|
||||||
|
|
||||||
// static check that WidgetGroup implements widget
|
// static check that WidgetGroup implements widget
|
||||||
var _ Widget = &WidgetGroup{}
|
var _ Widget = &WidgetGroup{}
|
||||||
|
|
||||||
@ -44,8 +47,8 @@ func (wg *WidgetGroup) adjustSize(w Widget) {
|
|||||||
x, y := w.GetPosition()
|
x, y := w.GetPosition()
|
||||||
width, height := w.GetSize()
|
width, height := w.GetSize()
|
||||||
|
|
||||||
if x+width > wg.width {
|
if x+width > wg.x+wg.width {
|
||||||
wg.width = x + width
|
wg.width += (x + width) - (wg.x + wg.width)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wg.x > x {
|
if wg.x > x {
|
||||||
@ -53,8 +56,8 @@ func (wg *WidgetGroup) adjustSize(w Widget) {
|
|||||||
wg.x = x
|
wg.x = x
|
||||||
}
|
}
|
||||||
|
|
||||||
if y+height > wg.height {
|
if y+height > wg.y+wg.height {
|
||||||
wg.height = x + height
|
wg.height += (y + height) - (wg.y + wg.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wg.y > y {
|
if wg.y > y {
|
||||||
@ -76,15 +79,42 @@ func (wg *WidgetGroup) Render(target d2interface.Surface) {
|
|||||||
entry.Render(target)
|
entry.Render(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if widgetGroupDebug && wg.GetVisible() {
|
||||||
|
wg.renderDebug(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wg *WidgetGroup) renderDebug(target d2interface.Surface) {
|
||||||
|
target.PushTranslation(wg.GetPosition())
|
||||||
|
defer target.Pop()
|
||||||
|
target.DrawLine(wg.width, 0, color.White)
|
||||||
|
target.DrawLine(0, wg.height, color.White)
|
||||||
|
|
||||||
|
target.PushTranslation(wg.width, wg.height)
|
||||||
|
target.DrawLine(-wg.width, 0, color.White)
|
||||||
|
target.DrawLine(0, -wg.height, color.White)
|
||||||
|
target.Pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVisible sets the visibility of all widgets in the group
|
// SetVisible sets the visibility of all widgets in the group
|
||||||
func (wg *WidgetGroup) SetVisible(visible bool) {
|
func (wg *WidgetGroup) SetVisible(visible bool) {
|
||||||
|
wg.BaseWidget.SetVisible(visible)
|
||||||
|
|
||||||
for _, entry := range wg.entries {
|
for _, entry := range wg.entries {
|
||||||
entry.SetVisible(visible)
|
entry.SetVisible(visible)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OffsetPosition moves all widgets by x and y
|
||||||
|
func (wg *WidgetGroup) OffsetPosition(x, y int) {
|
||||||
|
wg.BaseWidget.OffsetPosition(x, y)
|
||||||
|
|
||||||
|
for _, entry := range wg.entries {
|
||||||
|
entry.OffsetPosition(x, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OnMouseMove handles mouse move events
|
// OnMouseMove handles mouse move events
|
||||||
func (wg *WidgetGroup) OnMouseMove(x, y int) {
|
func (wg *WidgetGroup) OnMouseMove(x, y int) {
|
||||||
for _, entry := range wg.entries {
|
for _, entry := range wg.entries {
|
||||||
|
@ -80,6 +80,8 @@ type EscapeMenu struct {
|
|||||||
assetManager *d2asset.AssetManager
|
assetManager *d2asset.AssetManager
|
||||||
keyMap *KeyMap
|
keyMap *KeyMap
|
||||||
keyBindingMenu *KeyBindingMenu
|
keyBindingMenu *KeyBindingMenu
|
||||||
|
|
||||||
|
onCloseCb func()
|
||||||
}
|
}
|
||||||
|
|
||||||
type layout struct {
|
type layout struct {
|
||||||
@ -410,10 +412,16 @@ func (m *EscapeMenu) OnEscKey() {
|
|||||||
m.close()
|
m.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetOnCloseCb sets the callback that is run when close() is called
|
||||||
|
func (m *EscapeMenu) SetOnCloseCb(cb func()) {
|
||||||
|
m.onCloseCb = cb
|
||||||
|
}
|
||||||
|
|
||||||
func (m *EscapeMenu) close() {
|
func (m *EscapeMenu) close() {
|
||||||
m.isOpen = false
|
m.isOpen = false
|
||||||
|
|
||||||
m.guiManager.SetLayout(nil)
|
m.guiManager.SetLayout(nil)
|
||||||
|
m.onCloseCb()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *EscapeMenu) open() {
|
func (m *EscapeMenu) open() {
|
||||||
|
@ -39,18 +39,10 @@ const (
|
|||||||
xp
|
xp
|
||||||
walkRun
|
walkRun
|
||||||
stamina
|
stamina
|
||||||
miniPnl
|
|
||||||
newSkills
|
newSkills
|
||||||
rightSkill
|
rightSkill
|
||||||
hpGlobe
|
hpGlobe
|
||||||
manaGlobe
|
manaGlobe
|
||||||
miniPanelCharacter
|
|
||||||
miniPanelInventory
|
|
||||||
miniPanelSkillTree
|
|
||||||
miniPanelAutomap
|
|
||||||
miniPanelMessageLog
|
|
||||||
miniPanelQuestLog
|
|
||||||
miniPanelGameMenu
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -79,11 +71,6 @@ const (
|
|||||||
staminaWidth,
|
staminaWidth,
|
||||||
staminaHeight = 273, 573, 105, 20
|
staminaHeight = 273, 573, 105, 20
|
||||||
|
|
||||||
miniPnlX,
|
|
||||||
miniPnlY,
|
|
||||||
miniPnlWidth,
|
|
||||||
miniPnlHeight = 393, 563, 12, 23
|
|
||||||
|
|
||||||
newSkillsX,
|
newSkillsX,
|
||||||
newSkillsY,
|
newSkillsY,
|
||||||
newSkillsWidth,
|
newSkillsWidth,
|
||||||
@ -103,41 +90,6 @@ const (
|
|||||||
manaGlobeY,
|
manaGlobeY,
|
||||||
manaGlobeWidth,
|
manaGlobeWidth,
|
||||||
manaGlobeHeight = 695, 525, 80, 60
|
manaGlobeHeight = 695, 525, 80, 60
|
||||||
|
|
||||||
miniPanelCharacterX,
|
|
||||||
miniPanelCharacterY,
|
|
||||||
miniPanelCharacterWidth,
|
|
||||||
miniPanelCharacterHeight = 324, 528, 22, 26
|
|
||||||
|
|
||||||
miniPanelInventoryX,
|
|
||||||
miniPanelInventoryY,
|
|
||||||
miniPanelInventoryWidth,
|
|
||||||
miniPanelInventoryHeight = 346, 528, 22, 26
|
|
||||||
|
|
||||||
miniPanelSkillTreeX,
|
|
||||||
miniPanelSkillTreeY,
|
|
||||||
miniPanelSkillTreeWidth,
|
|
||||||
miniPanelSkillTreeHeight = 368, 528, 22, 26
|
|
||||||
|
|
||||||
miniPanelAutomapX,
|
|
||||||
miniPanelAutomapY,
|
|
||||||
miniPanelAutomapWidth,
|
|
||||||
miniPanelAutomapHeight = 390, 528, 22, 26
|
|
||||||
|
|
||||||
miniPanelMessageLogX,
|
|
||||||
miniPanelMessageLogY,
|
|
||||||
miniPanelMessageLogWidth,
|
|
||||||
miniPanelMessageLogHeight = 412, 528, 22, 26
|
|
||||||
|
|
||||||
miniPanelQuestLogX,
|
|
||||||
miniPanelQuestLogY,
|
|
||||||
miniPanelQuestLogWidth,
|
|
||||||
miniPanelQuestLogHeight = 434, 528, 22, 26
|
|
||||||
|
|
||||||
miniPanelGameMenuX,
|
|
||||||
miniPanelGameMenuY,
|
|
||||||
miniPanelGameMenuWidth,
|
|
||||||
miniPanelGameMenuHeight = 456, 528, 22, 26
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -269,12 +221,6 @@ func NewGameControls(
|
|||||||
Width: staminaWidth,
|
Width: staminaWidth,
|
||||||
Height: staminaHeight,
|
Height: staminaHeight,
|
||||||
}},
|
}},
|
||||||
{miniPnl, d2geom.Rectangle{
|
|
||||||
Left: miniPnlX,
|
|
||||||
Top: miniPnlY,
|
|
||||||
Width: miniPnlWidth,
|
|
||||||
Height: miniPnlHeight,
|
|
||||||
}},
|
|
||||||
{newSkills, d2geom.Rectangle{
|
{newSkills, d2geom.Rectangle{
|
||||||
Left: newSkillsX,
|
Left: newSkillsX,
|
||||||
Top: newSkillsY,
|
Top: newSkillsY,
|
||||||
@ -299,59 +245,22 @@ func NewGameControls(
|
|||||||
Width: manaGlobeWidth,
|
Width: manaGlobeWidth,
|
||||||
Height: manaGlobeHeight,
|
Height: manaGlobeHeight,
|
||||||
}},
|
}},
|
||||||
{miniPanelCharacter, d2geom.Rectangle{
|
|
||||||
Left: miniPanelCharacterX,
|
|
||||||
Top: miniPanelCharacterY,
|
|
||||||
Width: miniPanelCharacterWidth,
|
|
||||||
Height: miniPanelCharacterHeight,
|
|
||||||
}},
|
|
||||||
{miniPanelInventory, d2geom.Rectangle{
|
|
||||||
Left: miniPanelInventoryX,
|
|
||||||
Top: miniPanelInventoryY,
|
|
||||||
Width: miniPanelInventoryWidth,
|
|
||||||
Height: miniPanelInventoryHeight,
|
|
||||||
}},
|
|
||||||
{miniPanelSkillTree, d2geom.Rectangle{
|
|
||||||
Left: miniPanelSkillTreeX,
|
|
||||||
Top: miniPanelSkillTreeY,
|
|
||||||
Width: miniPanelSkillTreeWidth,
|
|
||||||
Height: miniPanelSkillTreeHeight,
|
|
||||||
}},
|
|
||||||
{miniPanelAutomap, d2geom.Rectangle{
|
|
||||||
Left: miniPanelAutomapX,
|
|
||||||
Top: miniPanelAutomapY,
|
|
||||||
Width: miniPanelAutomapWidth,
|
|
||||||
Height: miniPanelAutomapHeight,
|
|
||||||
}},
|
|
||||||
{miniPanelMessageLog, d2geom.Rectangle{
|
|
||||||
Left: miniPanelMessageLogX,
|
|
||||||
Top: miniPanelMessageLogY,
|
|
||||||
Width: miniPanelMessageLogWidth,
|
|
||||||
Height: miniPanelMessageLogHeight,
|
|
||||||
}},
|
|
||||||
{miniPanelQuestLog, d2geom.Rectangle{
|
|
||||||
Left: miniPanelQuestLogX,
|
|
||||||
Top: miniPanelQuestLogY,
|
|
||||||
Width: miniPanelQuestLogWidth,
|
|
||||||
Height: miniPanelQuestLogHeight,
|
|
||||||
}},
|
|
||||||
{miniPanelGameMenu, d2geom.Rectangle{
|
|
||||||
Left: miniPanelGameMenuX,
|
|
||||||
Top: miniPanelGameMenuY,
|
|
||||||
Width: miniPanelGameMenuWidth,
|
|
||||||
Height: miniPanelGameMenuHeight,
|
|
||||||
}},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inventoryRecord := asset.Records.Layout.Inventory[inventoryRecordKey]
|
inventoryRecord := asset.Records.Layout.Inventory[inventoryRecordKey]
|
||||||
|
|
||||||
|
heroStatsPanel := NewHeroStatsPanel(asset, ui, hero.Name(), hero.Class, hero.Stats)
|
||||||
|
inventory := NewInventory(asset, ui, inventoryRecord)
|
||||||
|
skilltree := newSkillTree(hero.Skills, hero.Class, asset, ui)
|
||||||
|
|
||||||
|
miniPanel := newMiniPanel(asset, ui, isSinglePlayer)
|
||||||
|
|
||||||
heroState, err := d2hero.NewHeroStateFactory(asset)
|
heroState, err := d2hero.NewHeroStateFactory(asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
helpOverlay := NewHelpOverlay(asset, renderer, ui, guiManager, keyMap)
|
helpOverlay := NewHelpOverlay(asset, renderer, ui, guiManager, keyMap)
|
||||||
hud := NewHUD(asset, ui, hero, helpOverlay, newMiniPanel(asset, ui, isSinglePlayer), actionableRegions, mapEngine, mapRenderer)
|
hud := NewHUD(asset, ui, hero, helpOverlay, miniPanel, actionableRegions, mapEngine, mapRenderer)
|
||||||
|
|
||||||
const blackAlpha50percent = 0x0000007f
|
const blackAlpha50percent = 0x0000007f
|
||||||
|
|
||||||
@ -367,9 +276,9 @@ func NewGameControls(
|
|||||||
escapeMenu: escapeMenu,
|
escapeMenu: escapeMenu,
|
||||||
inputListener: inputListener,
|
inputListener: inputListener,
|
||||||
mapRenderer: mapRenderer,
|
mapRenderer: mapRenderer,
|
||||||
inventory: NewInventory(asset, ui, inventoryRecord),
|
inventory: inventory,
|
||||||
skilltree: newSkillTree(hero.Skills, hero.Class, asset, ui),
|
skilltree: skilltree,
|
||||||
heroStatsPanel: NewHeroStatsPanel(asset, ui, hero.Name(), hero.Class, hero.Stats),
|
heroStatsPanel: heroStatsPanel,
|
||||||
HelpOverlay: helpOverlay,
|
HelpOverlay: helpOverlay,
|
||||||
keyMap: keyMap,
|
keyMap: keyMap,
|
||||||
hud: hud,
|
hud: hud,
|
||||||
@ -397,10 +306,11 @@ func NewGameControls(
|
|||||||
isSinglePlayer: isSinglePlayer,
|
isSinglePlayer: isSinglePlayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
closeCb := func() { gc.updateLayout() }
|
gc.heroStatsPanel.SetOnCloseCb(gc.onCloseHeroStatsPanel)
|
||||||
gc.heroStatsPanel.SetOnCloseCb(closeCb)
|
gc.inventory.SetOnCloseCb(gc.onCloseInventory)
|
||||||
gc.inventory.SetOnCloseCb(closeCb)
|
gc.skilltree.SetOnCloseCb(gc.onCloseSkilltree)
|
||||||
gc.skilltree.SetOnCloseCb(closeCb)
|
|
||||||
|
gc.escapeMenu.SetOnCloseCb(gc.hud.restoreMinipanelFromTempClose)
|
||||||
|
|
||||||
err = gc.bindTerminalCommands(term)
|
err = gc.bindTerminalCommands(term)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -467,14 +377,11 @@ func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool {
|
|||||||
g.HelpOverlay.Close()
|
g.HelpOverlay.Close()
|
||||||
g.updateLayout()
|
g.updateLayout()
|
||||||
case d2enum.ToggleInventoryPanel:
|
case d2enum.ToggleInventoryPanel:
|
||||||
g.inventory.Toggle()
|
g.toggleInventoryPanel()
|
||||||
g.updateLayout()
|
|
||||||
case d2enum.ToggleSkillTreePanel:
|
case d2enum.ToggleSkillTreePanel:
|
||||||
g.skilltree.Toggle()
|
g.toggleInventoryPanel()
|
||||||
g.updateLayout()
|
|
||||||
case d2enum.ToggleCharacterPanel:
|
case d2enum.ToggleCharacterPanel:
|
||||||
g.heroStatsPanel.Toggle()
|
g.toggleHeroStatsPanel()
|
||||||
g.updateLayout()
|
|
||||||
case d2enum.ToggleRunWalk:
|
case d2enum.ToggleRunWalk:
|
||||||
g.hud.onToggleRunButton(false)
|
g.hud.onToggleRunButton(false)
|
||||||
case d2enum.HoldRun:
|
case d2enum.HoldRun:
|
||||||
@ -547,7 +454,7 @@ func (g *GameControls) onEscKey() {
|
|||||||
if g.escapeMenu.IsOpen() {
|
if g.escapeMenu.IsOpen() {
|
||||||
g.escapeMenu.OnEscKey()
|
g.escapeMenu.OnEscKey()
|
||||||
} else {
|
} else {
|
||||||
g.escapeMenu.open()
|
g.openEscMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,6 +597,50 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) toggleHeroStatsPanel() {
|
||||||
|
g.heroStatsPanel.Toggle()
|
||||||
|
g.hud.miniPanel.SetMovedRight(g.heroStatsPanel.IsOpen())
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) onCloseHeroStatsPanel() {
|
||||||
|
g.hud.miniPanel.SetMovedRight(g.heroStatsPanel.IsOpen())
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) toggleInventoryPanel() {
|
||||||
|
g.skilltree.Close()
|
||||||
|
g.inventory.Toggle()
|
||||||
|
g.hud.miniPanel.SetMovedLeft(g.inventory.IsOpen())
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) onCloseInventory() {
|
||||||
|
g.hud.miniPanel.SetMovedLeft(g.inventory.IsOpen())
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) toggleSkilltreePanel() {
|
||||||
|
g.inventory.Close()
|
||||||
|
g.skilltree.Toggle()
|
||||||
|
g.hud.miniPanel.SetMovedLeft(g.skilltree.IsOpen())
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) onCloseSkilltree() {
|
||||||
|
g.hud.miniPanel.SetMovedLeft(g.skilltree.IsOpen())
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) openEscMenu() {
|
||||||
|
g.inventory.Close()
|
||||||
|
g.skilltree.Close()
|
||||||
|
g.heroStatsPanel.Close()
|
||||||
|
g.hud.closeMinipanelTemporary()
|
||||||
|
g.escapeMenu.open()
|
||||||
|
g.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
// Load the resources required for the GameControls
|
// Load the resources required for the GameControls
|
||||||
func (g *GameControls) Load() {
|
func (g *GameControls) Load() {
|
||||||
g.hud.Load()
|
g.hud.Load()
|
||||||
@ -697,6 +648,14 @@ func (g *GameControls) Load() {
|
|||||||
g.skilltree.load()
|
g.skilltree.load()
|
||||||
g.heroStatsPanel.Load()
|
g.heroStatsPanel.Load()
|
||||||
g.HelpOverlay.Load()
|
g.HelpOverlay.Load()
|
||||||
|
|
||||||
|
miniPanelActions := &miniPanelActions{
|
||||||
|
characterToggle: g.toggleHeroStatsPanel,
|
||||||
|
inventoryToggle: g.toggleInventoryPanel,
|
||||||
|
skilltreeToggle: g.toggleSkilltreePanel,
|
||||||
|
menuToggle: g.openEscMenu,
|
||||||
|
}
|
||||||
|
g.hud.miniPanel.load(miniPanelActions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance advances the state of the GameControls
|
// Advance advances the state of the GameControls
|
||||||
@ -746,7 +705,7 @@ func (g *GameControls) isInActiveMenusRect(px, py int) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.hud.miniPanel.IsOpen() && g.hud.miniPanel.isInRect(px, py) {
|
if g.hud.miniPanel.IsOpen() && g.hud.miniPanel.IsInRect(px, py) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,23 +787,15 @@ func (g *GameControls) ToggleManaStats() {
|
|||||||
// Handles what to do when an actionable is hovered
|
// Handles what to do when an actionable is hovered
|
||||||
func (g *GameControls) onHoverActionable(item actionableType) {
|
func (g *GameControls) onHoverActionable(item actionableType) {
|
||||||
hoverMap := map[actionableType]func(){
|
hoverMap := map[actionableType]func(){
|
||||||
leftSkill: func() {},
|
leftSkill: func() {},
|
||||||
newStats: func() {},
|
newStats: func() {},
|
||||||
xp: func() {},
|
xp: func() {},
|
||||||
walkRun: func() {},
|
walkRun: func() {},
|
||||||
stamina: func() {},
|
stamina: func() {},
|
||||||
miniPnl: func() {},
|
newSkills: func() {},
|
||||||
newSkills: func() {},
|
rightSkill: func() {},
|
||||||
rightSkill: func() {},
|
hpGlobe: func() {},
|
||||||
hpGlobe: func() {},
|
manaGlobe: func() {},
|
||||||
manaGlobe: func() {},
|
|
||||||
miniPanelCharacter: func() {},
|
|
||||||
miniPanelInventory: func() {},
|
|
||||||
miniPanelSkillTree: func() {},
|
|
||||||
miniPanelAutomap: func() {},
|
|
||||||
miniPanelMessageLog: func() {},
|
|
||||||
miniPanelQuestLog: func() {},
|
|
||||||
miniPanelGameMenu: func() {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onHover, found := hoverMap[item]
|
onHover, found := hoverMap[item]
|
||||||
@ -879,12 +830,6 @@ func (g *GameControls) onClickActionable(item actionableType) {
|
|||||||
log.Println("Stamina Action Pressed")
|
log.Println("Stamina Action Pressed")
|
||||||
},
|
},
|
||||||
|
|
||||||
miniPnl: func() {
|
|
||||||
log.Println("Mini Panel Action Pressed")
|
|
||||||
|
|
||||||
g.hud.miniPanel.Toggle()
|
|
||||||
},
|
|
||||||
|
|
||||||
newSkills: func() {
|
newSkills: func() {
|
||||||
log.Println("New Skills Selector Action Pressed")
|
log.Println("New Skills Selector Action Pressed")
|
||||||
},
|
},
|
||||||
@ -902,32 +847,6 @@ func (g *GameControls) onClickActionable(item actionableType) {
|
|||||||
g.ToggleManaStats()
|
g.ToggleManaStats()
|
||||||
log.Println("Mana Globe Pressed")
|
log.Println("Mana Globe Pressed")
|
||||||
},
|
},
|
||||||
|
|
||||||
miniPanelCharacter: func() {
|
|
||||||
log.Println("Character button on mini panel is pressed")
|
|
||||||
|
|
||||||
g.heroStatsPanel.Toggle()
|
|
||||||
g.updateLayout()
|
|
||||||
},
|
|
||||||
|
|
||||||
miniPanelInventory: func() {
|
|
||||||
log.Println("Inventory button on mini panel is pressed")
|
|
||||||
|
|
||||||
g.inventory.Toggle()
|
|
||||||
g.updateLayout()
|
|
||||||
},
|
|
||||||
|
|
||||||
miniPanelSkillTree: func() {
|
|
||||||
log.Println("Skilltree button on mini panel is pressed")
|
|
||||||
|
|
||||||
g.skilltree.Toggle()
|
|
||||||
g.updateLayout()
|
|
||||||
},
|
|
||||||
|
|
||||||
miniPanelGameMenu: func() {
|
|
||||||
g.hud.miniPanel.Close()
|
|
||||||
g.escapeMenu.open()
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action, found := actionMap[item]
|
action, found := actionMap[item]
|
||||||
|
@ -131,9 +131,7 @@ func (s *HeroStatsPanel) Load() {
|
|||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fw, fh := frame.GetFrameBounds()
|
w, h := frame.GetSize()
|
||||||
fc := frame.GetFrameCount()
|
|
||||||
w, h := fw*fc, fh*fc
|
|
||||||
staticPanel := s.uiManager.NewCustomWidgetCached(s.renderStaticMenu, w, h)
|
staticPanel := s.uiManager.NewCustomWidgetCached(s.renderStaticMenu, w, h)
|
||||||
s.panelGroup.AddWidget(staticPanel)
|
s.panelGroup.AddWidget(staticPanel)
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
frameMenuButton = 2
|
|
||||||
frameHealthStatus = 0
|
frameHealthStatus = 0
|
||||||
frameManaStatus = 1
|
frameManaStatus = 1
|
||||||
frameNewStatsSelector = 1
|
frameNewStatsSelector = 1
|
||||||
@ -69,7 +68,7 @@ const (
|
|||||||
rightGlobeOffsetY = -8
|
rightGlobeOffsetY = -8
|
||||||
|
|
||||||
miniPanelButtonOffsetX = -8
|
miniPanelButtonOffsetX = -8
|
||||||
miniPanelButtonOffsetY = -16
|
miniPanelButtonOffsetY = -38
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -91,13 +90,14 @@ type HUD struct {
|
|||||||
hero *d2mapentity.Player
|
hero *d2mapentity.Player
|
||||||
mainPanel *d2ui.Sprite
|
mainPanel *d2ui.Sprite
|
||||||
globeSprite *d2ui.Sprite
|
globeSprite *d2ui.Sprite
|
||||||
menuButton *d2ui.Sprite
|
menuButton *d2ui.Button
|
||||||
hpManaStatusSprite *d2ui.Sprite
|
hpManaStatusSprite *d2ui.Sprite
|
||||||
leftSkillResource *SkillResource
|
leftSkillResource *SkillResource
|
||||||
rightSkillResource *SkillResource
|
rightSkillResource *SkillResource
|
||||||
runButton *d2ui.Button
|
runButton *d2ui.Button
|
||||||
zoneChangeText *d2ui.Label
|
zoneChangeText *d2ui.Label
|
||||||
miniPanel *miniPanel
|
miniPanel *miniPanel
|
||||||
|
isMiniPanelOpen bool
|
||||||
isZoneTextShown bool
|
isZoneTextShown bool
|
||||||
hpStatsIsVisible bool
|
hpStatsIsVisible bool
|
||||||
manaStatsIsVisible bool
|
manaStatsIsVisible bool
|
||||||
@ -241,16 +241,6 @@ func (h *HUD) loadSprites() {
|
|||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.menuButton, err = h.uiManager.NewSprite(d2resource.MenuButton, d2resource.PaletteSky)
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = h.menuButton.SetCurrentFrame(frameMenuButton)
|
|
||||||
if err != nil {
|
|
||||||
log.Print(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.mainPanel, err = h.uiManager.NewSprite(d2resource.GamePanels, d2resource.PaletteSky)
|
h.mainPanel, err = h.uiManager.NewSprite(d2resource.GamePanels, d2resource.PaletteSky)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
@ -325,6 +315,17 @@ func (h *HUD) loadUIButtons() {
|
|||||||
if h.hero.IsRunToggled() {
|
if h.hero.IsRunToggled() {
|
||||||
h.runButton.Toggle()
|
h.runButton.Toggle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// minipanel button
|
||||||
|
h.menuButton = h.uiManager.NewButton(d2ui.ButtonTypeMinipanelOpenClose, "")
|
||||||
|
//nolint:golint,gomnd // 2 is not a magic number
|
||||||
|
x := screenWidth/2 + miniPanelButtonOffsetX
|
||||||
|
y := screenHeight + miniPanelButtonOffsetY
|
||||||
|
h.menuButton.SetPosition(x, y)
|
||||||
|
h.menuButton.OnActivated(func() {
|
||||||
|
h.menuButton.Toggle()
|
||||||
|
h.miniPanel.Toggle()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) onToggleRunButton(noButton bool) {
|
func (h *HUD) onToggleRunButton(noButton bool) {
|
||||||
@ -493,65 +494,6 @@ func (h *HUD) renderExperienceBar(target d2interface.Surface) {
|
|||||||
target.DrawRect(int(expPercent*expBarWidth), 2, d2util.Color(whiteAlpha100))
|
target.DrawRect(int(expPercent*expBarWidth), 2, d2util.Color(whiteAlpha100))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) renderMiniPanel(target d2interface.Surface) error {
|
|
||||||
width, height := target.GetSize()
|
|
||||||
mx, my := h.lastMouseX, h.lastMouseY
|
|
||||||
|
|
||||||
menuButtonFrameIndex := 0
|
|
||||||
if h.miniPanel.isOpen {
|
|
||||||
menuButtonFrameIndex = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := h.menuButton.SetCurrentFrame(menuButtonFrameIndex); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
buttonX, buttonY := (width>>1)+miniPanelButtonOffsetX, height+miniPanelButtonOffsetY
|
|
||||||
|
|
||||||
h.menuButton.SetPosition(buttonX, buttonY)
|
|
||||||
h.menuButton.Render(target)
|
|
||||||
h.miniPanel.Render(target)
|
|
||||||
|
|
||||||
miniPanelButtons := map[actionableType]string{
|
|
||||||
miniPanelCharacter: "minipanelchar",
|
|
||||||
miniPanelInventory: "minipanelinv",
|
|
||||||
miniPanelSkillTree: "minipaneltree",
|
|
||||||
miniPanelAutomap: "minipanelautomap",
|
|
||||||
miniPanelMessageLog: "minipanelmessage",
|
|
||||||
miniPanelQuestLog: "minipanelquest",
|
|
||||||
miniPanelGameMenu: "minipanelmenubtn",
|
|
||||||
}
|
|
||||||
|
|
||||||
if !h.miniPanel.IsOpen() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for miniPanelButton, stringTableKey := range miniPanelButtons {
|
|
||||||
if !h.actionableRegions[miniPanelButton].rect.IsInRect(mx, my) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
rect := &h.actionableRegions[miniPanelButton].rect
|
|
||||||
h.miniPanelTooltip.SetText(h.asset.TranslateString(stringTableKey))
|
|
||||||
|
|
||||||
halfButtonWidth := rect.Width >> 1
|
|
||||||
halfButtonHeight := rect.Height >> 1
|
|
||||||
|
|
||||||
centerX := rect.Left + halfButtonWidth
|
|
||||||
centerY := rect.Top + halfButtonHeight
|
|
||||||
|
|
||||||
_, labelHeight := h.miniPanelTooltip.GetSize()
|
|
||||||
|
|
||||||
labelX := centerX
|
|
||||||
labelY := centerY - halfButtonHeight - labelHeight
|
|
||||||
|
|
||||||
h.miniPanelTooltip.SetPosition(labelX, labelY)
|
|
||||||
h.miniPanelTooltip.Render(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HUD) renderPotions(x, _ int, target d2interface.Surface) error {
|
func (h *HUD) renderPotions(x, _ int, target d2interface.Surface) error {
|
||||||
_, height := target.GetSize()
|
_, height := target.GetSize()
|
||||||
|
|
||||||
@ -726,11 +668,6 @@ func (h *HUD) Render(target d2interface.Surface) error {
|
|||||||
h.widgetStamina.Render(target)
|
h.widgetStamina.Render(target)
|
||||||
h.widgetExperience.Render(target)
|
h.widgetExperience.Render(target)
|
||||||
|
|
||||||
// Mini Panel and button
|
|
||||||
if err := h.renderMiniPanel(target); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := h.help.Render(target); err != nil {
|
if err := h.help.Render(target); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -784,3 +721,20 @@ func (h *HUD) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *HUD) closeMinipanelTemporary() {
|
||||||
|
h.isMiniPanelOpen = h.miniPanel.IsOpen()
|
||||||
|
if h.isMiniPanelOpen {
|
||||||
|
h.menuButton.SetEnabled(false)
|
||||||
|
h.menuButton.Toggle()
|
||||||
|
h.miniPanel.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HUD) restoreMinipanelFromTempClose() {
|
||||||
|
if h.isMiniPanelOpen {
|
||||||
|
h.menuButton.SetEnabled(true)
|
||||||
|
h.menuButton.Toggle()
|
||||||
|
h.miniPanel.Open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,74 +3,192 @@ package d2player
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
miniPanelX = 325
|
miniPanelX = 325
|
||||||
miniPanelY = 526
|
miniPanelY = 526
|
||||||
miniPanelWidth = 156
|
|
||||||
miniPanelHeight = 26
|
panelOffsetLeft = 130
|
||||||
|
panelOffsetRight = 130
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
containerOffsetX = -75
|
containerOffsetX = -75
|
||||||
containerOffsetY = -48
|
containerOffsetY = -49
|
||||||
|
|
||||||
buttonOffsetX = -72
|
buttonOffsetX = -72
|
||||||
buttonOffsetY = -51
|
buttonOffsetY = -52
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type miniPanelContent struct {
|
||||||
|
buttonType d2ui.ButtonType
|
||||||
|
onActivate func()
|
||||||
|
tooltip string
|
||||||
|
}
|
||||||
|
|
||||||
|
type miniPanelActions struct {
|
||||||
|
characterToggle func()
|
||||||
|
inventoryToggle func()
|
||||||
|
skilltreeToggle func()
|
||||||
|
partyToggle func()
|
||||||
|
automapToggle func()
|
||||||
|
messageToggle func()
|
||||||
|
questToggle func()
|
||||||
|
menuToggle func()
|
||||||
|
}
|
||||||
|
|
||||||
type miniPanel struct {
|
type miniPanel struct {
|
||||||
|
ui *d2ui.UIManager
|
||||||
asset *d2asset.AssetManager
|
asset *d2asset.AssetManager
|
||||||
container *d2ui.Sprite
|
container *d2ui.Sprite
|
||||||
button *d2ui.Sprite
|
sprite *d2ui.Sprite
|
||||||
isOpen bool
|
isOpen bool
|
||||||
isSinglePlayer bool
|
isSinglePlayer bool
|
||||||
rectangle d2geom.Rectangle
|
movedLeft bool
|
||||||
|
movedRight bool
|
||||||
|
panelGroup *d2ui.WidgetGroup
|
||||||
|
tooltipGroup *d2ui.WidgetGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMiniPanel(asset *d2asset.AssetManager, uiManager *d2ui.UIManager, isSinglePlayer bool) *miniPanel {
|
func newMiniPanel(asset *d2asset.AssetManager, uiManager *d2ui.UIManager, isSinglePlayer bool) *miniPanel {
|
||||||
|
return &miniPanel{
|
||||||
|
ui: uiManager,
|
||||||
|
asset: asset,
|
||||||
|
isOpen: false,
|
||||||
|
isSinglePlayer: isSinglePlayer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) load(actions *miniPanelActions) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
m.sprite, err = m.ui.NewSprite(d2resource.MinipanelButton, d2resource.PaletteSky)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.createWidgets(actions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) createWidgets(actions *miniPanelActions) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
m.panelGroup = m.ui.NewWidgetGroup(d2ui.RenderPriorityMinipanel)
|
||||||
|
m.panelGroup.SetPosition(miniPanelX, miniPanelY)
|
||||||
|
|
||||||
|
m.tooltipGroup = m.ui.NewWidgetGroup(d2ui.RenderPriorityForeground)
|
||||||
|
|
||||||
miniPanelContainerPath := d2resource.Minipanel
|
miniPanelContainerPath := d2resource.Minipanel
|
||||||
if isSinglePlayer {
|
if m.isSinglePlayer {
|
||||||
miniPanelContainerPath = d2resource.MinipanelSmall
|
miniPanelContainerPath = d2resource.MinipanelSmall
|
||||||
}
|
}
|
||||||
|
|
||||||
containerSprite, err := uiManager.NewSprite(miniPanelContainerPath, d2resource.PaletteSky)
|
m.container, err = m.ui.NewSprite(miniPanelContainerPath, d2resource.PaletteSky)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonSprite, err := uiManager.NewSprite(d2resource.MinipanelButton, d2resource.PaletteSky)
|
if err = m.container.SetCurrentFrame(0); err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// nolint:golint,gomnd // divide by 2 does not need a magic number
|
||||||
|
x, y := screenWidth/2+containerOffsetX, screenHeight+containerOffsetY
|
||||||
|
m.container.SetPosition(x, y)
|
||||||
|
m.panelGroup.AddWidget(m.container)
|
||||||
|
|
||||||
|
buttonWidth, buttonHeight, err := m.sprite.GetFrameSize(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rectangle := d2geom.Rectangle{
|
buttonWidth++
|
||||||
Left: miniPanelX,
|
|
||||||
Top: miniPanelY,
|
// nolint:golint,gomnd // divide by 2 does not need a magic number
|
||||||
Width: miniPanelWidth,
|
x, y = screenWidth/2+buttonOffsetX, screenHeight+buttonOffsetY-buttonHeight
|
||||||
Height: miniPanelHeight,
|
buttonsFirst := []miniPanelContent{
|
||||||
|
{d2ui.ButtonTypeMinipanelCharacter,
|
||||||
|
actions.characterToggle,
|
||||||
|
m.asset.TranslateString("minipanelchar"),
|
||||||
|
},
|
||||||
|
{d2ui.ButtonTypeMinipanelInventory,
|
||||||
|
actions.inventoryToggle,
|
||||||
|
m.asset.TranslateString("minipanelinv"),
|
||||||
|
},
|
||||||
|
{d2ui.ButtonTypeMinipanelSkill,
|
||||||
|
actions.skilltreeToggle,
|
||||||
|
m.asset.TranslateString("minipaneltree"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isSinglePlayer {
|
for i := range buttonsFirst {
|
||||||
rectangle.Width = 182
|
btn := m.createButton(buttonsFirst[i], x+(i*buttonWidth), y, buttonHeight)
|
||||||
|
m.panelGroup.AddWidget(btn)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &miniPanel{
|
idxOffset := len(buttonsFirst)
|
||||||
asset: asset,
|
|
||||||
container: containerSprite,
|
if !m.isSinglePlayer {
|
||||||
button: buttonSprite,
|
partyContent := miniPanelContent{d2ui.ButtonTypeMinipanelParty,
|
||||||
isOpen: false,
|
actions.partyToggle,
|
||||||
isSinglePlayer: isSinglePlayer,
|
m.asset.TranslateString("minipanelparty"),
|
||||||
rectangle: rectangle,
|
}
|
||||||
|
btn := m.createButton(partyContent, x+(3*buttonWidth), y, buttonHeight)
|
||||||
|
m.panelGroup.AddWidget(btn)
|
||||||
|
idxOffset++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buttonsLast := []miniPanelContent{
|
||||||
|
{d2ui.ButtonTypeMinipanelAutomap,
|
||||||
|
actions.automapToggle,
|
||||||
|
m.asset.TranslateString("minipanelautomap"),
|
||||||
|
},
|
||||||
|
{d2ui.ButtonTypeMinipanelMessage,
|
||||||
|
actions.messageToggle,
|
||||||
|
m.asset.TranslateString("minipanelmessage"),
|
||||||
|
},
|
||||||
|
{d2ui.ButtonTypeMinipanelQuest,
|
||||||
|
actions.questToggle,
|
||||||
|
m.asset.TranslateString("minipanelquest"),
|
||||||
|
},
|
||||||
|
{d2ui.ButtonTypeMinipanelMen,
|
||||||
|
actions.menuToggle,
|
||||||
|
m.asset.TranslateString("minipanelmenubtn"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range buttonsLast {
|
||||||
|
idx := i + idxOffset
|
||||||
|
btn := m.createButton(buttonsLast[i], x+(idx*buttonWidth), y, buttonHeight)
|
||||||
|
m.panelGroup.AddWidget(btn)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.panelGroup.SetVisible(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) createButton(content miniPanelContent, x, y, buttonHeight int) *d2ui.Button {
|
||||||
|
// Tooltip
|
||||||
|
tt := m.ui.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||||
|
tt.SetPosition(x, y-buttonHeight)
|
||||||
|
tt.SetText(content.tooltip)
|
||||||
|
tt.SetVisible(false)
|
||||||
|
m.tooltipGroup.AddWidget(tt)
|
||||||
|
|
||||||
|
// Button
|
||||||
|
btn := m.ui.NewButton(content.buttonType, "")
|
||||||
|
btn.SetPosition(x, y)
|
||||||
|
btn.OnActivated(content.onActivate)
|
||||||
|
btn.SetTooltip(tt)
|
||||||
|
|
||||||
|
return btn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) IsOpen() bool {
|
func (m *miniPanel) IsOpen() bool {
|
||||||
@ -78,56 +196,91 @@ func (m *miniPanel) IsOpen() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) Toggle() {
|
func (m *miniPanel) Toggle() {
|
||||||
m.isOpen = !m.isOpen
|
if m.isOpen {
|
||||||
|
m.Close()
|
||||||
|
} else {
|
||||||
|
m.Open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) Open() {
|
func (m *miniPanel) Open() {
|
||||||
|
m.panelGroup.SetVisible(true)
|
||||||
m.isOpen = true
|
m.isOpen = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) Close() {
|
func (m *miniPanel) Close() {
|
||||||
|
m.panelGroup.SetVisible(false)
|
||||||
m.isOpen = false
|
m.isOpen = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) Render(target d2interface.Surface) {
|
func (m *miniPanel) IsInRect(px, py int) bool {
|
||||||
if !m.isOpen {
|
return m.panelGroup.Contains(px, py)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) moveRight() {
|
||||||
|
m.panelGroup.OffsetPosition(panelOffsetRight, 0)
|
||||||
|
m.tooltipGroup.OffsetPosition(panelOffsetRight, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) undoMoveRight() {
|
||||||
|
m.panelGroup.OffsetPosition(-panelOffsetRight, 0)
|
||||||
|
m.tooltipGroup.OffsetPosition(-panelOffsetRight, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) moveLeft() {
|
||||||
|
m.panelGroup.OffsetPosition(-panelOffsetLeft, 0)
|
||||||
|
m.tooltipGroup.OffsetPosition(-panelOffsetLeft, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) undoMoveLeft() {
|
||||||
|
m.panelGroup.OffsetPosition(panelOffsetLeft, 0)
|
||||||
|
m.tooltipGroup.OffsetPosition(panelOffsetLeft, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) SetMovedLeft(moveLeft bool) {
|
||||||
|
if m.movedLeft == moveLeft {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.container.SetCurrentFrame(0); err != nil {
|
if m.movedRight {
|
||||||
|
if moveLeft {
|
||||||
|
m.undoMoveRight()
|
||||||
|
m.panelGroup.SetVisible(false)
|
||||||
|
} else {
|
||||||
|
m.moveRight()
|
||||||
|
m.panelGroup.SetVisible(true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if moveLeft {
|
||||||
|
m.moveLeft()
|
||||||
|
} else {
|
||||||
|
m.undoMoveLeft()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.movedLeft = moveLeft
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) SetMovedRight(moveRight bool) {
|
||||||
|
if m.movedRight == moveRight {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
width, height := target.GetSize()
|
if m.movedLeft {
|
||||||
halfW := width >> 1
|
if moveRight {
|
||||||
x, y := halfW+containerOffsetX, height+containerOffsetY
|
m.undoMoveLeft()
|
||||||
|
m.panelGroup.SetVisible(false)
|
||||||
m.container.SetPosition(x, y)
|
} else {
|
||||||
|
m.moveLeft()
|
||||||
m.container.Render(target)
|
m.panelGroup.SetVisible(true)
|
||||||
|
|
||||||
buttonWidth, _ := m.button.GetCurrentFrameSize()
|
|
||||||
buttonWidth++
|
|
||||||
|
|
||||||
for i, j := 0, 0; j < 16; i++ {
|
|
||||||
if m.isSinglePlayer && j == 6 { // skip Party Screen button if the game is single player
|
|
||||||
j += 2
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if err := m.button.SetCurrentFrame(j); err != nil {
|
if moveRight {
|
||||||
return
|
m.moveRight()
|
||||||
|
} else {
|
||||||
|
m.undoMoveRight()
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetX := buttonOffsetX + (buttonWidth * i)
|
|
||||||
x, y := halfW+offsetX, height+buttonOffsetY
|
|
||||||
|
|
||||||
m.button.SetPosition(x, y)
|
|
||||||
m.button.Render(target)
|
|
||||||
|
|
||||||
j += 2
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (m *miniPanel) isInRect(x, y int) bool {
|
m.movedRight = moveRight
|
||||||
return m.rectangle.IsInRect(x, y)
|
|
||||||
}
|
}
|
||||||
|
@ -357,6 +357,7 @@ func (s *skillTree) Open() {
|
|||||||
s.isOpen = true
|
s.isOpen = true
|
||||||
|
|
||||||
s.panelGroup.SetVisible(true)
|
s.panelGroup.SetVisible(true)
|
||||||
|
s.iconGroup.SetVisible(true)
|
||||||
|
|
||||||
// we only want to enable the icons of our current tab again
|
// we only want to enable the icons of our current tab again
|
||||||
s.setTab(s.selectedTab)
|
s.setTab(s.selectedTab)
|
||||||
|
Loading…
Reference in New Issue
Block a user