mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-05 08:07:51 -05:00
Ui hud polishing (#938)
* d2ui/tooltip: Make it invisible by default * d2ui/button: Add GetToggled() method * d2player/HUD: Add tooltip for minipanel button * d2ui/button: Add disabled frame to minipanel buttons * d2ui/widget_group: Add SetEnable method for clickable widgets * d2player/mini_panel: move menu button here from HUD * d2ui/button: toggled buttons take preference over disabled buttons * d2player/help_overlay: Make panel only use widgets * d2player/hud: Group most widgets into widget group * d2ui/custom_widget: Allow tooltip to be attached * d2player/hud: Attach staminaBar tooltip to staminaBar * d2player/hud: Attach experienceBar tooltip to experienceBar widget * d2ui/ui_manager: Always draw tooltips last * d2player/help_overlay: It should be drawn over the HUD * d2player/globeWidget: Move tooltip here from HUD * d2core/tooltip: Automatically add tooltips to the uiManager * d2core/ui_manager: Remove special handling of widgetGroups for rendering * d2player/help_overlay: Add button to widget group * d2player/hud: Attack runwalk tooltip to button * d2player/mini_panel: Add panelButton to its own widget group * d2core/widget_group: When a clickable is added, it's also added to uiManager * d2player/globeWidget: make tooltip un/lock on click * d2player/hud: Add runbutton to widget group * d2player/mini_panel: Add group for tooltips this allows us to move the tooltip with the panelbuttons. They can't be in the general panelGroup as they would all become visible when the panel is opened. * d2core/button: Remove debug log when a button with tooltip is hovered
This commit is contained in:
parent
e89450daf1
commit
1f49df62d1
@ -131,7 +131,6 @@ const (
|
|||||||
buttonSkillTreeTabFixedHeight = 107
|
buttonSkillTreeTabFixedHeight = 107
|
||||||
|
|
||||||
buttonMinipanelOpenCloseBaseFrame = 0
|
buttonMinipanelOpenCloseBaseFrame = 0
|
||||||
buttonMinipanelDisabledFrame = 2
|
|
||||||
buttonMinipanelXSegments = 1
|
buttonMinipanelXSegments = 1
|
||||||
buttonMinipanelYSegments = 1
|
buttonMinipanelYSegments = 1
|
||||||
|
|
||||||
@ -278,7 +277,7 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelOpenClose: {
|
ButtonTypeMinipanelOpenClose: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
DisabledFrame: buttonMinipanelDisabledFrame,
|
DisabledFrame: buttonMinipanelOpenCloseBaseFrame,
|
||||||
DisabledColor: whiteAlpha100,
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelOpenCloseBaseFrame,
|
BaseFrame: buttonMinipanelOpenCloseBaseFrame,
|
||||||
ResourceName: d2resource.MenuButton,
|
ResourceName: d2resource.MenuButton,
|
||||||
@ -294,6 +293,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelCharacter: {
|
ButtonTypeMinipanelCharacter: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelCharacterBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelCharacterBaseFrame,
|
BaseFrame: buttonMinipanelCharacterBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -308,6 +309,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelInventory: {
|
ButtonTypeMinipanelInventory: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelInventoryBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelInventoryBaseFrame,
|
BaseFrame: buttonMinipanelInventoryBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -322,6 +325,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelSkill: {
|
ButtonTypeMinipanelSkill: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelSkilltreeBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelSkilltreeBaseFrame,
|
BaseFrame: buttonMinipanelSkilltreeBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -336,6 +341,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelParty: {
|
ButtonTypeMinipanelParty: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelPartyBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelPartyBaseFrame,
|
BaseFrame: buttonMinipanelPartyBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -350,6 +357,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelAutomap: {
|
ButtonTypeMinipanelAutomap: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelAutomapBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelAutomapBaseFrame,
|
BaseFrame: buttonMinipanelAutomapBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -364,6 +373,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelMessage: {
|
ButtonTypeMinipanelMessage: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelMessageBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelMessageBaseFrame,
|
BaseFrame: buttonMinipanelMessageBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -378,6 +389,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelQuest: {
|
ButtonTypeMinipanelQuest: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelQuestBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelQuestBaseFrame,
|
BaseFrame: buttonMinipanelQuestBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -392,6 +405,8 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||||||
ButtonTypeMinipanelMen: {
|
ButtonTypeMinipanelMen: {
|
||||||
XSegments: buttonMinipanelXSegments,
|
XSegments: buttonMinipanelXSegments,
|
||||||
YSegments: buttonMinipanelYSegments,
|
YSegments: buttonMinipanelYSegments,
|
||||||
|
DisabledFrame: buttonMinipanelMenBaseFrame,
|
||||||
|
DisabledColor: whiteAlpha100,
|
||||||
BaseFrame: buttonMinipanelMenBaseFrame,
|
BaseFrame: buttonMinipanelMenBaseFrame,
|
||||||
ResourceName: d2resource.MinipanelButton,
|
ResourceName: d2resource.MinipanelButton,
|
||||||
PaletteName: d2resource.PaletteSky,
|
PaletteName: d2resource.PaletteSky,
|
||||||
@ -628,7 +643,12 @@ func (v *Button) Render(target d2interface.Surface) {
|
|||||||
case !v.enabled:
|
case !v.enabled:
|
||||||
target.PushColor(d2util.Color(v.buttonLayout.DisabledColor))
|
target.PushColor(d2util.Color(v.buttonLayout.DisabledColor))
|
||||||
defer target.Pop()
|
defer target.Pop()
|
||||||
|
|
||||||
|
if v.toggled {
|
||||||
|
target.Render(v.toggledSurface)
|
||||||
|
} else {
|
||||||
target.Render(v.disabledSurface)
|
target.Render(v.disabledSurface)
|
||||||
|
}
|
||||||
case v.toggled && v.pressed:
|
case v.toggled && v.pressed:
|
||||||
target.Render(v.pressedToggledSurface)
|
target.Render(v.pressedToggledSurface)
|
||||||
case v.pressed:
|
case v.pressed:
|
||||||
@ -649,6 +669,11 @@ func (v *Button) Toggle() {
|
|||||||
v.toggled = !v.toggled
|
v.toggled = !v.toggled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetToggled returns the toggled state of the button
|
||||||
|
func (v *Button) GetToggled() bool {
|
||||||
|
return v.toggled
|
||||||
|
}
|
||||||
|
|
||||||
// Advance advances the button state
|
// Advance advances the button state
|
||||||
func (v *Button) Advance(_ float64) error {
|
func (v *Button) Advance(_ float64) error {
|
||||||
return nil
|
return nil
|
||||||
@ -695,8 +720,7 @@ func (v *Button) SetPosition(x, y int) {
|
|||||||
// SetTooltip adds a tooltip to the button
|
// SetTooltip adds a tooltip to the button
|
||||||
func (v *Button) SetTooltip(t *Tooltip) {
|
func (v *Button) SetTooltip(t *Tooltip) {
|
||||||
v.tooltip = t
|
v.tooltip = t
|
||||||
v.manager.addWidget(t)
|
v.OnHoverStart(func() { v.tooltip.SetVisible(true) })
|
||||||
v.OnHoverStart(func() { log.Print("HoverStart"); v.tooltip.SetVisible(true) })
|
|
||||||
v.OnHoverEnd(func() { v.tooltip.SetVisible(false) })
|
v.OnHoverEnd(func() { v.tooltip.SetVisible(false) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ type CustomWidget struct {
|
|||||||
renderFunc func(target d2interface.Surface)
|
renderFunc func(target d2interface.Surface)
|
||||||
cached bool
|
cached bool
|
||||||
cachedImg *d2interface.Surface
|
cachedImg *d2interface.Surface
|
||||||
|
tooltip *Tooltip
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCustomWidgetCached creates a new widget and caches anything rendered via the
|
// NewCustomWidgetCached creates a new widget and caches anything rendered via the
|
||||||
@ -50,6 +51,13 @@ func (c *CustomWidget) Render(target d2interface.Surface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTooltip gives this widget a Tooltip that is displayed if the widget is hovered
|
||||||
|
func (c *CustomWidget) SetTooltip(t *Tooltip) {
|
||||||
|
c.tooltip = t
|
||||||
|
c.OnHoverStart(func() { c.tooltip.SetVisible(true) })
|
||||||
|
c.OnHoverEnd(func() { c.tooltip.SetVisible(false) })
|
||||||
|
}
|
||||||
|
|
||||||
// Advance is a no-op
|
// Advance is a no-op
|
||||||
func (c *CustomWidget) Advance(elapsed float64) error {
|
func (c *CustomWidget) Advance(elapsed float64) error {
|
||||||
return nil
|
return nil
|
||||||
|
@ -58,6 +58,7 @@ func (ui *UIManager) NewTooltip(font,
|
|||||||
label.Alignment = HorizontalAlignCenter
|
label.Alignment = HorizontalAlignCenter
|
||||||
|
|
||||||
base := NewBaseWidget(ui)
|
base := NewBaseWidget(ui)
|
||||||
|
base.SetVisible(false)
|
||||||
|
|
||||||
res := &Tooltip{
|
res := &Tooltip{
|
||||||
BaseWidget: base,
|
BaseWidget: base,
|
||||||
@ -68,6 +69,7 @@ func (ui *UIManager) NewTooltip(font,
|
|||||||
boxEnabled: true,
|
boxEnabled: true,
|
||||||
}
|
}
|
||||||
res.manager = ui
|
res.manager = ui
|
||||||
|
ui.addTooltip(res)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ type UIManager struct {
|
|||||||
inputManager d2interface.InputManager
|
inputManager d2interface.InputManager
|
||||||
audio d2interface.AudioProvider
|
audio d2interface.AudioProvider
|
||||||
widgets []Widget
|
widgets []Widget
|
||||||
|
tooltips []*Tooltip
|
||||||
widgetsGroups []*WidgetGroup
|
widgetsGroups []*WidgetGroup
|
||||||
clickableWidgets []ClickableWidget
|
clickableWidgets []ClickableWidget
|
||||||
cursorButtons CursorButton
|
cursorButtons CursorButton
|
||||||
@ -53,13 +54,8 @@ func (ui *UIManager) Reset() {
|
|||||||
ui.pressedWidget = nil
|
ui.pressedWidget = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addWidgetGroup adds a widgetGroup to the UI manager and sorts by priority
|
func (ui *UIManager) addClickable(widget ClickableWidget) {
|
||||||
func (ui *UIManager) addWidgetGroup(group *WidgetGroup) {
|
ui.clickableWidgets = append(ui.clickableWidgets, widget)
|
||||||
ui.widgetsGroups = append(ui.widgetsGroups, group)
|
|
||||||
|
|
||||||
sort.SliceStable(ui.widgetsGroups, func(i, j int) bool {
|
|
||||||
return ui.widgetsGroups[i].renderPriority < ui.widgetsGroups[j].renderPriority
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addWidget adds a widget to the UI manager
|
// addWidget adds a widget to the UI manager
|
||||||
@ -71,13 +67,27 @@ func (ui *UIManager) addWidget(widget Widget) {
|
|||||||
|
|
||||||
clickable, ok := widget.(ClickableWidget)
|
clickable, ok := widget.(ClickableWidget)
|
||||||
if ok {
|
if ok {
|
||||||
ui.clickableWidgets = append(ui.clickableWidgets, clickable)
|
ui.addClickable(clickable)
|
||||||
|
}
|
||||||
|
|
||||||
|
if widgetGroup, ok := widget.(*WidgetGroup); ok {
|
||||||
|
ui.widgetsGroups = append(ui.widgetsGroups, widgetGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.widgets = append(ui.widgets, widget)
|
ui.widgets = append(ui.widgets, widget)
|
||||||
|
|
||||||
|
sort.SliceStable(ui.widgets, func(i, j int) bool {
|
||||||
|
return ui.widgets[i].GetRenderPriority() < ui.widgets[j].GetRenderPriority()
|
||||||
|
})
|
||||||
|
|
||||||
widget.bindManager(ui)
|
widget.bindManager(ui)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addTooltip adds a widget to the UI manager
|
||||||
|
func (ui *UIManager) addTooltip(t *Tooltip) {
|
||||||
|
ui.tooltips = append(ui.tooltips, t)
|
||||||
|
}
|
||||||
|
|
||||||
// OnMouseButtonUp is an event handler for input
|
// OnMouseButtonUp is an event handler for input
|
||||||
func (ui *UIManager) OnMouseButtonUp(event d2interface.MouseEvent) bool {
|
func (ui *UIManager) OnMouseButtonUp(event d2interface.MouseEvent) bool {
|
||||||
ui.CursorX, ui.CursorY = event.X(), event.Y()
|
ui.CursorX, ui.CursorY = event.X(), event.Y()
|
||||||
@ -142,17 +152,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 _, widgetGroup := range ui.widgetsGroups {
|
|
||||||
if widgetGroup.GetVisible() {
|
|
||||||
widgetGroup.Render(target)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, widget := range ui.widgets {
|
for _, widget := range ui.widgets {
|
||||||
if widget.GetVisible() {
|
if widget.GetVisible() {
|
||||||
widget.Render(target)
|
widget.Render(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, tooltip := range ui.tooltips {
|
||||||
|
if tooltip.GetVisible() {
|
||||||
|
tooltip.Render(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance updates all of the UI elements
|
// Advance updates all of the UI elements
|
||||||
|
@ -4,18 +4,16 @@ package d2ui
|
|||||||
// The higher the number the later an element is drawn.
|
// The higher the number the later an element is drawn.
|
||||||
type RenderPriority int
|
type RenderPriority int
|
||||||
|
|
||||||
|
// Render priorities that determine the order in which widgets/widgetgroups are
|
||||||
|
// rendered. The higher the later it is rendered
|
||||||
const (
|
const (
|
||||||
// RenderPriorityBackground is the first element drawn
|
|
||||||
RenderPriorityBackground RenderPriority = iota
|
RenderPriorityBackground RenderPriority = iota
|
||||||
// RenderPrioritySkilltree is the priority for the skilltree
|
|
||||||
RenderPrioritySkilltree
|
RenderPrioritySkilltree
|
||||||
// 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
|
RenderPriorityHeroStatsPanel
|
||||||
// RenderPriorityForeground is the last element drawn
|
RenderPriorityHUDPanel
|
||||||
|
RenderPriorityMinipanel
|
||||||
|
RenderPriorityHelpPanel
|
||||||
RenderPriorityForeground
|
RenderPriorityForeground
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ func (ui *UIManager) NewWidgetGroup(priority RenderPriority) *WidgetGroup {
|
|||||||
BaseWidget: base,
|
BaseWidget: base,
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.addWidgetGroup(group)
|
ui.addWidget(group)
|
||||||
|
|
||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
@ -40,6 +40,10 @@ func (wg *WidgetGroup) AddWidget(w Widget) {
|
|||||||
sort.SliceStable(wg.entries, func(i, j int) bool {
|
sort.SliceStable(wg.entries, func(i, j int) bool {
|
||||||
return wg.entries[i].GetRenderPriority() < wg.entries[j].GetRenderPriority()
|
return wg.entries[i].GetRenderPriority() < wg.entries[j].GetRenderPriority()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if clickable, ok := w.(ClickableWidget); ok {
|
||||||
|
wg.manager.addClickable(clickable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjustSize recalculates the bounding box if a new widget is added
|
// adjustSize recalculates the bounding box if a new widget is added
|
||||||
@ -127,3 +131,12 @@ func (wg *WidgetGroup) OnMouseMove(x, y int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEnabled sets enable on all clickable widgets of this group
|
||||||
|
func (wg *WidgetGroup) SetEnabled(enabled bool) {
|
||||||
|
for _, entry := range wg.entries {
|
||||||
|
if v, ok := entry.(ClickableWidget); ok {
|
||||||
|
v.SetEnabled(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -219,8 +219,8 @@ func NewGameControls(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
helpOverlay := NewHelpOverlay(asset, renderer, ui, guiManager, l, keyMap)
|
helpOverlay := NewHelpOverlay(asset, ui, l, keyMap)
|
||||||
hud := NewHUD(asset, ui, hero, helpOverlay, miniPanel, actionableRegions, mapEngine, l, mapRenderer)
|
hud := NewHUD(asset, ui, hero, miniPanel, actionableRegions, mapEngine, l, mapRenderer)
|
||||||
|
|
||||||
const blackAlpha50percent = 0x0000007f
|
const blackAlpha50percent = 0x0000007f
|
||||||
|
|
||||||
@ -270,7 +270,8 @@ func NewGameControls(
|
|||||||
gc.inventory.SetOnCloseCb(gc.onCloseInventory)
|
gc.inventory.SetOnCloseCb(gc.onCloseInventory)
|
||||||
gc.skilltree.SetOnCloseCb(gc.onCloseSkilltree)
|
gc.skilltree.SetOnCloseCb(gc.onCloseSkilltree)
|
||||||
|
|
||||||
gc.escapeMenu.SetOnCloseCb(gc.hud.restoreMinipanelFromTempClose)
|
gc.escapeMenu.SetOnCloseCb(gc.hud.miniPanel.restoreDisabled)
|
||||||
|
gc.HelpOverlay.SetOnCloseCb(gc.hud.miniPanel.restoreDisabled)
|
||||||
|
|
||||||
err = gc.bindTerminalCommands(term)
|
err = gc.bindTerminalCommands(term)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -397,6 +398,8 @@ func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool {
|
|||||||
case d2enum.HoldRun:
|
case d2enum.HoldRun:
|
||||||
g.hud.onToggleRunButton(true)
|
g.hud.onToggleRunButton(true)
|
||||||
case d2enum.ToggleHelpScreen:
|
case d2enum.ToggleHelpScreen:
|
||||||
|
g.hud.miniPanel.openDisabled()
|
||||||
|
|
||||||
g.HelpOverlay.Toggle()
|
g.HelpOverlay.Toggle()
|
||||||
g.updateLayout()
|
g.updateLayout()
|
||||||
default:
|
default:
|
||||||
@ -646,7 +649,7 @@ func (g *GameControls) openEscMenu() {
|
|||||||
g.inventory.Close()
|
g.inventory.Close()
|
||||||
g.skilltree.Close()
|
g.skilltree.Close()
|
||||||
g.heroStatsPanel.Close()
|
g.heroStatsPanel.Close()
|
||||||
g.hud.closeMinipanelTemporary()
|
g.hud.miniPanel.closeDisabled()
|
||||||
g.escapeMenu.open()
|
g.escapeMenu.open()
|
||||||
g.updateLayout()
|
g.updateLayout()
|
||||||
}
|
}
|
||||||
@ -671,6 +674,7 @@ func (g *GameControls) Load() {
|
|||||||
// Advance advances the state of the GameControls
|
// Advance advances the state of the GameControls
|
||||||
func (g *GameControls) Advance(elapsed float64) error {
|
func (g *GameControls) Advance(elapsed float64) error {
|
||||||
g.mapRenderer.Advance(elapsed)
|
g.mapRenderer.Advance(elapsed)
|
||||||
|
g.hud.Advance(elapsed)
|
||||||
|
|
||||||
if err := g.escapeMenu.Advance(elapsed); err != nil {
|
if err := g.escapeMenu.Advance(elapsed); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package d2player
|
package d2player
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,11 +32,20 @@ const (
|
|||||||
manaStatusOffsetY = -12
|
manaStatusOffsetY = -12
|
||||||
|
|
||||||
manaGlobeScreenOffsetX = 117
|
manaGlobeScreenOffsetX = 117
|
||||||
|
|
||||||
|
hpLabelX = 15
|
||||||
|
hpLabelY = 487
|
||||||
|
|
||||||
|
manaLabelX = 785
|
||||||
|
manaLabelY = 487
|
||||||
)
|
)
|
||||||
|
|
||||||
// static check that globeWidget implements Widget
|
// static check that globeWidget implements Widget
|
||||||
var _ d2ui.Widget = &globeWidget{}
|
var _ d2ui.Widget = &globeWidget{}
|
||||||
|
|
||||||
|
// static check that globeWidget implements ClickableWidget
|
||||||
|
var _ d2ui.ClickableWidget = &globeWidget{}
|
||||||
|
|
||||||
type globeFrame struct {
|
type globeFrame struct {
|
||||||
sprite *d2ui.Sprite
|
sprite *d2ui.Sprite
|
||||||
offsetX int
|
offsetX int
|
||||||
@ -53,14 +64,18 @@ func (gf *globeFrame) setPosition(x, y int) {
|
|||||||
gf.sprite.SetPosition(x+gf.offsetX, y+gf.offsetY)
|
gf.sprite.SetPosition(x+gf.offsetX, y+gf.offsetY)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gf *globeFrame) getSize() (x, y int) {
|
func newGlobeWidget(ui *d2ui.UIManager,
|
||||||
w, h := gf.sprite.GetSize()
|
asset *d2asset.AssetManager,
|
||||||
return w + gf.offsetX, h + gf.offsetY
|
x, y int,
|
||||||
}
|
gtype globeType,
|
||||||
|
value *int, valueMax *int,
|
||||||
func newGlobeWidget(ui *d2ui.UIManager, x, y int, gtype globeType, value *int, l d2util.LogLevel, valueMax *int) *globeWidget {
|
l d2util.LogLevel) *globeWidget {
|
||||||
var globe, overlap *globeFrame
|
var globe, overlap *globeFrame
|
||||||
|
|
||||||
|
var tooltipX, tooltipY int
|
||||||
|
|
||||||
|
var tooltipTrans string
|
||||||
|
|
||||||
base := d2ui.NewBaseWidget(ui)
|
base := d2ui.NewBaseWidget(ui)
|
||||||
base.SetPosition(x, y)
|
base.SetPosition(x, y)
|
||||||
|
|
||||||
@ -75,6 +90,8 @@ func newGlobeWidget(ui *d2ui.UIManager, x, y int, gtype globeType, value *int, l
|
|||||||
offsetY: globeSpriteOffsetY,
|
offsetY: globeSpriteOffsetY,
|
||||||
idx: frameHealthStatus,
|
idx: frameHealthStatus,
|
||||||
}
|
}
|
||||||
|
tooltipX, tooltipY = hpLabelX, hpLabelY
|
||||||
|
tooltipTrans = "panelhealth"
|
||||||
} else if gtype == typeManaGlobe {
|
} else if gtype == typeManaGlobe {
|
||||||
globe = &globeFrame{
|
globe = &globeFrame{
|
||||||
offsetX: manaStatusOffsetX,
|
offsetX: manaStatusOffsetX,
|
||||||
@ -86,16 +103,35 @@ func newGlobeWidget(ui *d2ui.UIManager, x, y int, gtype globeType, value *int, l
|
|||||||
offsetY: rightGlobeOffsetY,
|
offsetY: rightGlobeOffsetY,
|
||||||
idx: frameRightGlobe,
|
idx: frameRightGlobe,
|
||||||
}
|
}
|
||||||
|
tooltipX, tooltipY = manaLabelX, manaLabelY
|
||||||
|
tooltipTrans = "panelmana"
|
||||||
}
|
}
|
||||||
|
|
||||||
gw := &globeWidget{
|
gw := &globeWidget{
|
||||||
BaseWidget: base,
|
BaseWidget: base,
|
||||||
|
asset: asset,
|
||||||
value: value,
|
value: value,
|
||||||
valueMax: valueMax,
|
valueMax: valueMax,
|
||||||
globe: globe,
|
globe: globe,
|
||||||
overlap: overlap,
|
overlap: overlap,
|
||||||
|
isTooltipLocked: false,
|
||||||
|
tooltipX: tooltipX,
|
||||||
|
tooltipY: tooltipY,
|
||||||
|
tooltipTrans: tooltipTrans,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gw.OnHoverStart(func() {
|
||||||
|
if !gw.isTooltipLocked {
|
||||||
|
gw.tooltip.SetVisible(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
gw.OnHoverEnd(func() {
|
||||||
|
if !gw.isTooltipLocked {
|
||||||
|
gw.tooltip.SetVisible(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
gw.logger = d2util.NewLogger()
|
gw.logger = d2util.NewLogger()
|
||||||
gw.logger.SetLevel(l)
|
gw.logger.SetLevel(l)
|
||||||
gw.logger.SetPrefix(logPrefix)
|
gw.logger.SetPrefix(logPrefix)
|
||||||
@ -105,11 +141,19 @@ func newGlobeWidget(ui *d2ui.UIManager, x, y int, gtype globeType, value *int, l
|
|||||||
|
|
||||||
type globeWidget struct {
|
type globeWidget struct {
|
||||||
*d2ui.BaseWidget
|
*d2ui.BaseWidget
|
||||||
|
asset *d2asset.AssetManager
|
||||||
value *int
|
value *int
|
||||||
valueMax *int
|
valueMax *int
|
||||||
globe *globeFrame
|
globe *globeFrame
|
||||||
overlap *globeFrame
|
overlap *globeFrame
|
||||||
logger *d2util.Logger
|
logger *d2util.Logger
|
||||||
|
|
||||||
|
pressed bool
|
||||||
|
isTooltipLocked bool
|
||||||
|
tooltip *d2ui.Tooltip
|
||||||
|
tooltipX int
|
||||||
|
tooltipY int
|
||||||
|
tooltipTrans string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *globeWidget) load() {
|
func (g *globeWidget) load() {
|
||||||
@ -128,6 +172,11 @@ func (g *globeWidget) load() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.overlap.setFrameIndex()
|
g.overlap.setFrameIndex()
|
||||||
|
|
||||||
|
// tooltip
|
||||||
|
g.tooltip = g.GetManager().NewTooltip(d2resource.Font16, d2resource.PaletteUnits, d2ui.TooltipXLeft, d2ui.TooltipYTop)
|
||||||
|
g.tooltip.SetPosition(g.tooltipX, g.tooltipY)
|
||||||
|
g.tooltip.SetBoxEnabled(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render draws the widget to the screen
|
// Render draws the widget to the screen
|
||||||
@ -144,10 +193,49 @@ func (g *globeWidget) Render(target d2interface.Surface) {
|
|||||||
g.overlap.sprite.Render(target)
|
g.overlap.sprite.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *globeWidget) GetSize() (x, y int) {
|
// Contains is special here as the point of origin is at the lower left corner
|
||||||
return g.overlap.getSize()
|
// in contrast to any other element which is top left.
|
||||||
|
func (g *globeWidget) Contains(px, py int) bool {
|
||||||
|
wx, wy := g.globe.sprite.GetPosition()
|
||||||
|
width, height := g.globe.sprite.GetSize()
|
||||||
|
|
||||||
|
return px >= wx && px <= wx+width && py <= wy && py >= wy-height
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) updateTooltip() {
|
||||||
|
// Create and format string from string lookup table.
|
||||||
|
fmtStr := g.asset.TranslateString(g.tooltipTrans)
|
||||||
|
strPanel := fmt.Sprintf(fmtStr, *g.value, *g.valueMax)
|
||||||
|
g.tooltip.SetText(strPanel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *globeWidget) Advance(elapsed float64) error {
|
func (g *globeWidget) Advance(elapsed float64) error {
|
||||||
|
g.updateTooltip()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) Activate() {
|
||||||
|
g.isTooltipLocked = !g.isTooltipLocked
|
||||||
|
g.tooltip.SetVisible(g.isTooltipLocked)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) GetEnabled() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) SetEnabled(enable bool) {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) GetPressed() bool {
|
||||||
|
return g.pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) SetPressed(pressed bool) {
|
||||||
|
g.pressed = pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *globeWidget) OnActivated(callback func()) {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -159,17 +158,13 @@ const (
|
|||||||
// NewHelpOverlay creates a new HelpOverlay instance
|
// NewHelpOverlay creates a new HelpOverlay instance
|
||||||
func NewHelpOverlay(
|
func NewHelpOverlay(
|
||||||
asset *d2asset.AssetManager,
|
asset *d2asset.AssetManager,
|
||||||
renderer d2interface.Renderer,
|
|
||||||
ui *d2ui.UIManager,
|
ui *d2ui.UIManager,
|
||||||
guiManager *d2gui.GuiManager,
|
|
||||||
l d2util.LogLevel,
|
l d2util.LogLevel,
|
||||||
keyMap *KeyMap,
|
keyMap *KeyMap,
|
||||||
) *HelpOverlay {
|
) *HelpOverlay {
|
||||||
h := &HelpOverlay{
|
h := &HelpOverlay{
|
||||||
asset: asset,
|
asset: asset,
|
||||||
renderer: renderer,
|
|
||||||
uiManager: ui,
|
uiManager: ui,
|
||||||
guiManager: guiManager,
|
|
||||||
keyMap: keyMap,
|
keyMap: keyMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,15 +179,15 @@ func NewHelpOverlay(
|
|||||||
type HelpOverlay struct {
|
type HelpOverlay struct {
|
||||||
asset *d2asset.AssetManager
|
asset *d2asset.AssetManager
|
||||||
isOpen bool
|
isOpen bool
|
||||||
renderer d2interface.Renderer
|
|
||||||
frames []*d2ui.Sprite
|
frames []*d2ui.Sprite
|
||||||
text []*d2ui.Label
|
text []*d2ui.Label
|
||||||
lines []line
|
lines []line
|
||||||
uiManager *d2ui.UIManager
|
uiManager *d2ui.UIManager
|
||||||
layout *d2gui.Layout
|
|
||||||
closeButton *d2ui.Button
|
closeButton *d2ui.Button
|
||||||
guiManager *d2gui.GuiManager
|
|
||||||
keyMap *KeyMap
|
keyMap *KeyMap
|
||||||
|
onCloseCb func()
|
||||||
|
panelGroup *d2ui.WidgetGroup
|
||||||
|
backgroundWidget *d2ui.CustomWidget
|
||||||
|
|
||||||
logger *d2util.Logger
|
logger *d2util.Logger
|
||||||
}
|
}
|
||||||
@ -211,20 +206,18 @@ func (h *HelpOverlay) Toggle() {
|
|||||||
// Close will hide the help overlay
|
// Close will hide the help overlay
|
||||||
func (h *HelpOverlay) Close() {
|
func (h *HelpOverlay) Close() {
|
||||||
h.isOpen = false
|
h.isOpen = false
|
||||||
h.closeButton.SetVisible(false)
|
h.panelGroup.SetVisible(false)
|
||||||
h.guiManager.SetLayout(nil)
|
h.onCloseCb()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOnCloseCb sets the callback run when Close() is called
|
||||||
|
func (h *HelpOverlay) SetOnCloseCb(cb func()) {
|
||||||
|
h.onCloseCb = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HelpOverlay) open() {
|
func (h *HelpOverlay) open() {
|
||||||
h.isOpen = true
|
h.isOpen = true
|
||||||
if h.layout == nil {
|
h.panelGroup.SetVisible(true)
|
||||||
h.layout = d2gui.CreateLayout(h.renderer, d2gui.PositionTypeHorizontal, h.asset)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.closeButton.SetVisible(true)
|
|
||||||
h.closeButton.SetPressed(false)
|
|
||||||
|
|
||||||
h.guiManager.SetLayout(h.layout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOpen returns whether or not the overlay is visible/open
|
// IsOpen returns whether or not the overlay is visible/open
|
||||||
@ -234,22 +227,21 @@ func (h *HelpOverlay) IsOpen() bool {
|
|||||||
|
|
||||||
// IsInRect checks if the given point is within the overlay layout rectangle
|
// IsInRect checks if the given point is within the overlay layout rectangle
|
||||||
func (h *HelpOverlay) IsInRect(px, py int) bool {
|
func (h *HelpOverlay) IsInRect(px, py int) bool {
|
||||||
ww, hh := h.layout.GetSize()
|
return h.panelGroup.Contains(px, py)
|
||||||
x, y := h.layout.GetPosition()
|
|
||||||
|
|
||||||
if px >= x && px <= x+ww && py >= y && py <= y+hh {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the overlay graphical assets
|
// Load the overlay graphical assets
|
||||||
func (h *HelpOverlay) Load() {
|
func (h *HelpOverlay) Load() {
|
||||||
|
h.panelGroup = h.uiManager.NewWidgetGroup(d2ui.RenderPriorityHelpPanel)
|
||||||
|
|
||||||
h.setupOverlayFrame()
|
h.setupOverlayFrame()
|
||||||
h.setupTitleAndButton()
|
h.setupTitleAndButton()
|
||||||
h.setupBulletedList()
|
h.setupBulletedList()
|
||||||
h.setupLabelsWithLines()
|
h.setupLabelsWithLines()
|
||||||
|
|
||||||
|
h.backgroundWidget = h.uiManager.NewCustomWidgetCached(h.Render, screenWidth, screenHeight)
|
||||||
|
h.panelGroup.AddWidget(h.backgroundWidget)
|
||||||
|
h.panelGroup.SetVisible(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HelpOverlay) setupOverlayFrame() {
|
func (h *HelpOverlay) setupOverlayFrame() {
|
||||||
@ -330,6 +322,8 @@ func (h *HelpOverlay) setupTitleAndButton() {
|
|||||||
h.closeButton.SetPosition(closeButtonX, closeButtonY)
|
h.closeButton.SetPosition(closeButtonX, closeButtonY)
|
||||||
h.closeButton.SetVisible(false)
|
h.closeButton.SetVisible(false)
|
||||||
h.closeButton.OnActivated(func() { h.Close() })
|
h.closeButton.OnActivated(func() { h.Close() })
|
||||||
|
h.closeButton.SetRenderPriority(d2ui.RenderPriorityForeground)
|
||||||
|
h.panelGroup.AddWidget(h.closeButton)
|
||||||
|
|
||||||
newLabel = h.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
newLabel = h.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||||
newLabel.SetText(h.asset.TranslateString("strClose")) // "Close"
|
newLabel.SetText(h.asset.TranslateString("strClose")) // "Close"
|
||||||
@ -621,11 +615,7 @@ func (h *HelpOverlay) createCallout(c callout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render the overlay to the given surface
|
// Render the overlay to the given surface
|
||||||
func (h *HelpOverlay) Render(target d2interface.Surface) error {
|
func (h *HelpOverlay) Render(target d2interface.Surface) {
|
||||||
if !h.isOpen {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range h.frames {
|
for _, f := range h.frames {
|
||||||
f.Render(target)
|
f.Render(target)
|
||||||
}
|
}
|
||||||
@ -639,6 +629,4 @@ func (h *HelpOverlay) Render(target d2interface.Surface) error {
|
|||||||
target.DrawLine(l.MoveX, l.MoveY, l.Color)
|
target.DrawLine(l.MoveX, l.MoveY, l.Color)
|
||||||
target.Pop()
|
target.Pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -35,16 +35,6 @@ const (
|
|||||||
percentStaminaBarLow = 0.25
|
percentStaminaBarLow = 0.25
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
hpLabelX = 15
|
|
||||||
hpLabelY = 487
|
|
||||||
|
|
||||||
manaLabelX = 785
|
|
||||||
manaLabelY = 487
|
|
||||||
|
|
||||||
staminaExperienceY = 535
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
frameHealthStatus = 0
|
frameHealthStatus = 0
|
||||||
frameManaStatus = 1
|
frameManaStatus = 1
|
||||||
@ -59,6 +49,7 @@ const (
|
|||||||
const (
|
const (
|
||||||
staminaBarOffsetX = 273
|
staminaBarOffsetX = 273
|
||||||
staminaBarOffsetY = 572
|
staminaBarOffsetY = 572
|
||||||
|
staminaExperienceY = 535
|
||||||
|
|
||||||
experienceBarOffsetX = 256
|
experienceBarOffsetX = 256
|
||||||
experienceBarOffsetY = 561
|
experienceBarOffsetY = 561
|
||||||
@ -68,6 +59,9 @@ const (
|
|||||||
|
|
||||||
miniPanelButtonOffsetX = -8
|
miniPanelButtonOffsetX = -8
|
||||||
miniPanelButtonOffsetY = -38
|
miniPanelButtonOffsetY = -38
|
||||||
|
|
||||||
|
miniPanelTooltipOffsetX = 7
|
||||||
|
miniPanelTooltipOffsetY = -14
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -81,7 +75,6 @@ type HUD struct {
|
|||||||
actionableRegions []actionableRegion
|
actionableRegions []actionableRegion
|
||||||
asset *d2asset.AssetManager
|
asset *d2asset.AssetManager
|
||||||
uiManager *d2ui.UIManager
|
uiManager *d2ui.UIManager
|
||||||
help *HelpOverlay
|
|
||||||
mapEngine *d2mapengine.MapEngine
|
mapEngine *d2mapengine.MapEngine
|
||||||
mapRenderer *d2maprenderer.MapRenderer
|
mapRenderer *d2maprenderer.MapRenderer
|
||||||
lastMouseX int
|
lastMouseX int
|
||||||
@ -89,14 +82,12 @@ type HUD struct {
|
|||||||
hero *d2mapentity.Player
|
hero *d2mapentity.Player
|
||||||
mainPanel *d2ui.Sprite
|
mainPanel *d2ui.Sprite
|
||||||
globeSprite *d2ui.Sprite
|
globeSprite *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
|
||||||
@ -104,9 +95,6 @@ type HUD struct {
|
|||||||
staminaTooltip *d2ui.Tooltip
|
staminaTooltip *d2ui.Tooltip
|
||||||
runWalkTooltip *d2ui.Tooltip
|
runWalkTooltip *d2ui.Tooltip
|
||||||
experienceTooltip *d2ui.Tooltip
|
experienceTooltip *d2ui.Tooltip
|
||||||
healthTooltip *d2ui.Tooltip
|
|
||||||
manaTooltip *d2ui.Tooltip
|
|
||||||
miniPanelTooltip *d2ui.Tooltip
|
|
||||||
nameLabel *d2ui.Label
|
nameLabel *d2ui.Label
|
||||||
healthGlobe *globeWidget
|
healthGlobe *globeWidget
|
||||||
manaGlobe *globeWidget
|
manaGlobe *globeWidget
|
||||||
@ -115,6 +103,7 @@ type HUD struct {
|
|||||||
widgetLeftSkill *d2ui.CustomWidget
|
widgetLeftSkill *d2ui.CustomWidget
|
||||||
widgetRightSkill *d2ui.CustomWidget
|
widgetRightSkill *d2ui.CustomWidget
|
||||||
panelBackground *d2ui.CustomWidget
|
panelBackground *d2ui.CustomWidget
|
||||||
|
panelGroup *d2ui.WidgetGroup
|
||||||
logger *d2util.Logger
|
logger *d2util.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +112,6 @@ func NewHUD(
|
|||||||
asset *d2asset.AssetManager,
|
asset *d2asset.AssetManager,
|
||||||
ui *d2ui.UIManager,
|
ui *d2ui.UIManager,
|
||||||
hero *d2mapentity.Player,
|
hero *d2mapentity.Player,
|
||||||
help *HelpOverlay,
|
|
||||||
miniPanel *miniPanel,
|
miniPanel *miniPanel,
|
||||||
actionableRegions []actionableRegion,
|
actionableRegions []actionableRegion,
|
||||||
mapEngine *d2mapengine.MapEngine,
|
mapEngine *d2mapengine.MapEngine,
|
||||||
@ -137,14 +125,21 @@ func NewHUD(
|
|||||||
zoneLabel := ui.NewLabel(d2resource.Font30, d2resource.PaletteUnits)
|
zoneLabel := ui.NewLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||||
zoneLabel.Alignment = d2ui.HorizontalAlignCenter
|
zoneLabel.Alignment = d2ui.HorizontalAlignCenter
|
||||||
|
|
||||||
healthGlobe := newGlobeWidget(ui, 0, screenHeight, typeHealthGlobe, &hero.Stats.Health, l, &hero.Stats.MaxHealth)
|
healthGlobe := newGlobeWidget(ui, asset,
|
||||||
manaGlobe := newGlobeWidget(ui, screenWidth-manaGlobeScreenOffsetX, screenHeight, typeManaGlobe, &hero.Stats.Mana, l, &hero.Stats.MaxMana)
|
0, screenHeight,
|
||||||
|
typeHealthGlobe,
|
||||||
|
&hero.Stats.Health, &hero.Stats.MaxHealth,
|
||||||
|
l)
|
||||||
|
manaGlobe := newGlobeWidget(ui, asset,
|
||||||
|
screenWidth-manaGlobeScreenOffsetX, screenHeight,
|
||||||
|
typeManaGlobe,
|
||||||
|
&hero.Stats.Mana, &hero.Stats.MaxMana,
|
||||||
|
l)
|
||||||
|
|
||||||
hud := &HUD{
|
hud := &HUD{
|
||||||
asset: asset,
|
asset: asset,
|
||||||
uiManager: ui,
|
uiManager: ui,
|
||||||
hero: hero,
|
hero: hero,
|
||||||
help: help,
|
|
||||||
mapEngine: mapEngine,
|
mapEngine: mapEngine,
|
||||||
mapRenderer: mapRenderer,
|
mapRenderer: mapRenderer,
|
||||||
miniPanel: miniPanel,
|
miniPanel: miniPanel,
|
||||||
@ -165,15 +160,24 @@ func NewHUD(
|
|||||||
|
|
||||||
// Load creates the ui elemets
|
// Load creates the ui elemets
|
||||||
func (h *HUD) Load() {
|
func (h *HUD) Load() {
|
||||||
|
h.panelGroup = h.uiManager.NewWidgetGroup(d2ui.RenderPriorityHUDPanel)
|
||||||
|
|
||||||
h.loadSprites()
|
h.loadSprites()
|
||||||
|
|
||||||
h.healthGlobe.load()
|
h.healthGlobe.load()
|
||||||
h.manaGlobe.load()
|
h.healthGlobe.SetRenderPriority(d2ui.RenderPriorityForeground)
|
||||||
|
h.panelGroup.AddWidget(h.healthGlobe)
|
||||||
|
|
||||||
|
h.manaGlobe.load()
|
||||||
|
h.manaGlobe.SetRenderPriority(d2ui.RenderPriorityForeground)
|
||||||
|
h.panelGroup.AddWidget(h.manaGlobe)
|
||||||
|
|
||||||
|
h.loadTooltips()
|
||||||
h.loadSkillResources()
|
h.loadSkillResources()
|
||||||
h.loadCustomWidgets()
|
h.loadCustomWidgets()
|
||||||
h.loadUIButtons()
|
h.loadUIButtons()
|
||||||
h.loadTooltips()
|
|
||||||
|
h.panelGroup.SetVisible(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) loadCustomWidgets() {
|
func (h *HUD) loadCustomWidgets() {
|
||||||
@ -186,13 +190,19 @@ func (h *HUD) loadCustomWidgets() {
|
|||||||
|
|
||||||
h.panelBackground = h.uiManager.NewCustomWidgetCached(h.renderPanelStatic, screenWidth, height)
|
h.panelBackground = h.uiManager.NewCustomWidgetCached(h.renderPanelStatic, screenWidth, height)
|
||||||
h.panelBackground.SetPosition(0, screenHeight-height)
|
h.panelBackground.SetPosition(0, screenHeight-height)
|
||||||
|
h.panelGroup.AddWidget(h.panelBackground)
|
||||||
|
|
||||||
// stamina bar
|
// stamina bar
|
||||||
h.widgetStamina = h.uiManager.NewCustomWidget(h.renderStaminaBar, staminaBarWidth, staminaBarHeight)
|
h.widgetStamina = h.uiManager.NewCustomWidget(h.renderStaminaBar, staminaBarWidth, staminaBarHeight)
|
||||||
h.widgetStamina.SetPosition(staminaBarOffsetX, staminaBarOffsetY)
|
h.widgetStamina.SetPosition(staminaBarOffsetX, staminaBarOffsetY)
|
||||||
|
h.widgetStamina.SetTooltip(h.staminaTooltip)
|
||||||
|
h.panelGroup.AddWidget(h.widgetStamina)
|
||||||
|
|
||||||
// experience bar
|
// experience bar
|
||||||
h.widgetExperience = h.uiManager.NewCustomWidget(h.renderExperienceBar, expBarWidth, expBarHeight)
|
h.widgetExperience = h.uiManager.NewCustomWidget(h.renderExperienceBar, expBarWidth, expBarHeight)
|
||||||
|
h.widgetExperience.SetPosition(experienceBarOffsetX, experienceBarOffsetY)
|
||||||
|
h.widgetExperience.SetTooltip(h.experienceTooltip)
|
||||||
|
h.panelGroup.AddWidget(h.widgetExperience)
|
||||||
|
|
||||||
// Left skill widget
|
// Left skill widget
|
||||||
leftRenderFunc := func(target d2interface.Surface) {
|
leftRenderFunc := func(target d2interface.Surface) {
|
||||||
@ -202,6 +212,7 @@ func (h *HUD) loadCustomWidgets() {
|
|||||||
|
|
||||||
h.widgetLeftSkill = h.uiManager.NewCustomWidget(leftRenderFunc, skillIconWidth, skillIconHeight)
|
h.widgetLeftSkill = h.uiManager.NewCustomWidget(leftRenderFunc, skillIconWidth, skillIconHeight)
|
||||||
h.widgetLeftSkill.SetPosition(leftSkillX, screenHeight)
|
h.widgetLeftSkill.SetPosition(leftSkillX, screenHeight)
|
||||||
|
h.panelGroup.AddWidget(h.widgetLeftSkill)
|
||||||
|
|
||||||
// Right skill widget
|
// Right skill widget
|
||||||
rightRenderFunc := func(target d2interface.Surface) {
|
rightRenderFunc := func(target d2interface.Surface) {
|
||||||
@ -211,6 +222,7 @@ func (h *HUD) loadCustomWidgets() {
|
|||||||
|
|
||||||
h.widgetRightSkill = h.uiManager.NewCustomWidget(rightRenderFunc, skillIconWidth, skillIconHeight)
|
h.widgetRightSkill = h.uiManager.NewCustomWidget(rightRenderFunc, skillIconWidth, skillIconHeight)
|
||||||
h.widgetRightSkill.SetPosition(rightSkillX, screenHeight)
|
h.widgetRightSkill.SetPosition(rightSkillX, screenHeight)
|
||||||
|
h.panelGroup.AddWidget(h.widgetRightSkill)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) loadSkillResources() {
|
func (h *HUD) loadSkillResources() {
|
||||||
@ -297,42 +309,31 @@ func (h *HUD) loadTooltips() {
|
|||||||
labelX = centerX
|
labelX = centerX
|
||||||
labelY = staminaExperienceY - halfLabelHeight
|
labelY = staminaExperienceY - halfLabelHeight
|
||||||
h.experienceTooltip.SetPosition(labelX, labelY)
|
h.experienceTooltip.SetPosition(labelX, labelY)
|
||||||
|
|
||||||
// Health tooltip
|
|
||||||
h.healthTooltip = h.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteUnits, d2ui.TooltipXLeft, d2ui.TooltipYTop)
|
|
||||||
h.healthTooltip.SetPosition(hpLabelX, hpLabelY)
|
|
||||||
h.healthTooltip.SetBoxEnabled(false)
|
|
||||||
|
|
||||||
// Health tooltip
|
|
||||||
h.manaTooltip = h.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteUnits, d2ui.TooltipXLeft, d2ui.TooltipYTop)
|
|
||||||
h.manaTooltip.SetPosition(manaLabelX, manaLabelY)
|
|
||||||
h.manaTooltip.SetBoxEnabled(false)
|
|
||||||
|
|
||||||
// minipanel tooltip
|
|
||||||
h.miniPanelTooltip = h.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteUnits, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) loadUIButtons() {
|
func (h *HUD) loadUIButtons() {
|
||||||
// Run button
|
// Run button
|
||||||
h.runButton = h.uiManager.NewButton(d2ui.ButtonTypeRun, "")
|
h.runButton = h.uiManager.NewButton(d2ui.ButtonTypeRun, "")
|
||||||
|
|
||||||
h.runButton.SetPosition(runButtonX, runButtonY)
|
h.runButton.SetPosition(runButtonX, runButtonY)
|
||||||
h.runButton.OnActivated(func() { h.onToggleRunButton(false) })
|
h.runButton.OnActivated(func() { h.onToggleRunButton(false) })
|
||||||
|
h.runButton.SetTooltip(h.runWalkTooltip)
|
||||||
|
h.updateRunTooltipText()
|
||||||
|
h.panelGroup.AddWidget(h.runButton)
|
||||||
|
|
||||||
if h.hero.IsRunToggled() {
|
if h.hero.IsRunToggled() {
|
||||||
h.runButton.Toggle()
|
h.runButton.Toggle()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// minipanel button
|
func (h *HUD) updateRunTooltipText() {
|
||||||
h.menuButton = h.uiManager.NewButton(d2ui.ButtonTypeMinipanelOpenClose, "")
|
var stringTableKey string
|
||||||
//nolint:golint,gomnd // 2 is not a magic number
|
if h.hero.IsRunToggled() {
|
||||||
x := screenWidth/2 + miniPanelButtonOffsetX
|
stringTableKey = "RunOff"
|
||||||
y := screenHeight + miniPanelButtonOffsetY
|
} else {
|
||||||
h.menuButton.SetPosition(x, y)
|
stringTableKey = "RunOn"
|
||||||
h.menuButton.OnActivated(func() {
|
}
|
||||||
h.menuButton.Toggle()
|
|
||||||
h.miniPanel.Toggle()
|
h.runWalkTooltip.SetText(h.asset.TranslateString(stringTableKey))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) onToggleRunButton(noButton bool) {
|
func (h *HUD) onToggleRunButton(noButton bool) {
|
||||||
@ -341,6 +342,7 @@ func (h *HUD) onToggleRunButton(noButton bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h.hero.ToggleRunWalk()
|
h.hero.ToggleRunWalk()
|
||||||
|
h.updateRunTooltipText()
|
||||||
|
|
||||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/800
|
// https://github.com/OpenDiablo2/OpenDiablo2/issues/800
|
||||||
h.hero.SetIsRunning(h.hero.IsRunToggled())
|
h.hero.SetIsRunning(h.hero.IsRunToggled())
|
||||||
@ -527,87 +529,16 @@ func (h *HUD) renderNewSkillsButton(x, _ int, target d2interface.Surface) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:golint,dupl // we clean this up later
|
func (h *HUD) setStaminaTooltipText() {
|
||||||
func (h *HUD) renderHealthTooltip(target d2interface.Surface) {
|
|
||||||
mx, my := h.lastMouseX, h.lastMouseY
|
|
||||||
|
|
||||||
// Create and format Health string from string lookup table.
|
|
||||||
fmtHealth := h.asset.TranslateString("panelhealth")
|
|
||||||
healthCurr, healthMax := h.hero.Stats.Health, h.hero.Stats.MaxHealth
|
|
||||||
strPanelHealth := fmt.Sprintf(fmtHealth, healthCurr, healthMax)
|
|
||||||
|
|
||||||
// Display current hp and mana stats hpGlobe or manaGlobe region is clicked
|
|
||||||
if !(h.actionableRegions[hpGlobe].rect.IsInRect(mx, my) || h.hpStatsIsVisible) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.healthTooltip.SetText(strPanelHealth)
|
|
||||||
h.healthTooltip.Render(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint:golint,dupl // we clean this up later
|
|
||||||
func (h *HUD) renderManaTooltip(target d2interface.Surface) {
|
|
||||||
mx, my := h.lastMouseX, h.lastMouseY
|
|
||||||
|
|
||||||
// Create and format Mana string from string lookup table.
|
|
||||||
fmtMana := h.asset.TranslateString("panelmana")
|
|
||||||
manaCurr, manaMax := h.hero.Stats.Mana, h.hero.Stats.MaxMana
|
|
||||||
strPanelMana := fmt.Sprintf(fmtMana, manaCurr, manaMax)
|
|
||||||
|
|
||||||
if !(h.actionableRegions[manaGlobe].rect.IsInRect(mx, my) || h.manaStatsIsVisible) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
h.manaTooltip.SetText(strPanelMana)
|
|
||||||
h.manaTooltip.Render(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HUD) renderRunWalkTooltip(target d2interface.Surface) {
|
|
||||||
mx, my := h.lastMouseX, h.lastMouseY
|
|
||||||
|
|
||||||
// Display run/walk tooltip when hovered.
|
|
||||||
// Note that whether the player is walking or running, the tooltip is the same in Diablo 2.
|
|
||||||
if !h.actionableRegions[walkRun].rect.IsInRect(mx, my) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var stringTableKey string
|
|
||||||
|
|
||||||
if h.hero.IsRunToggled() {
|
|
||||||
stringTableKey = "RunOff"
|
|
||||||
} else {
|
|
||||||
stringTableKey = "RunOn"
|
|
||||||
}
|
|
||||||
|
|
||||||
h.runWalkTooltip.SetText(h.asset.TranslateString(stringTableKey))
|
|
||||||
h.runWalkTooltip.Render(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *HUD) renderStaminaTooltip(target d2interface.Surface) {
|
|
||||||
mx, my := h.lastMouseX, h.lastMouseY
|
|
||||||
|
|
||||||
// Display stamina tooltip when hovered.
|
|
||||||
if !h.actionableRegions[stamina].rect.IsInRect(mx, my) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and format Stamina string from string lookup table.
|
// Create and format Stamina string from string lookup table.
|
||||||
fmtStamina := h.asset.TranslateString("panelstamina")
|
fmtStamina := h.asset.TranslateString("panelstamina")
|
||||||
staminaCurr, staminaMax := int(h.hero.Stats.Stamina), h.hero.Stats.MaxStamina
|
staminaCurr, staminaMax := int(h.hero.Stats.Stamina), h.hero.Stats.MaxStamina
|
||||||
strPanelStamina := fmt.Sprintf(fmtStamina, staminaCurr, staminaMax)
|
strPanelStamina := fmt.Sprintf(fmtStamina, staminaCurr, staminaMax)
|
||||||
|
|
||||||
h.staminaTooltip.SetText(strPanelStamina)
|
h.staminaTooltip.SetText(strPanelStamina)
|
||||||
h.staminaTooltip.Render(target)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) renderExperienceTooltip(target d2interface.Surface) {
|
func (h *HUD) setExperienceTooltipText() {
|
||||||
mx, my := h.lastMouseX, h.lastMouseY
|
|
||||||
|
|
||||||
// Display experience tooltip when hovered.
|
|
||||||
if !h.actionableRegions[xp].rect.IsInRect(mx, my) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and format Experience string from string lookup table.
|
// Create and format Experience string from string lookup table.
|
||||||
fmtExp := h.asset.TranslateString("panelexp")
|
fmtExp := h.asset.TranslateString("panelexp")
|
||||||
|
|
||||||
@ -621,7 +552,6 @@ func (h *HUD) renderExperienceTooltip(target d2interface.Surface) {
|
|||||||
strPanelExp := fmt.Sprintf(fmtExp, expCurr, expMax)
|
strPanelExp := fmt.Sprintf(fmtExp, expCurr, expMax)
|
||||||
|
|
||||||
h.experienceTooltip.SetText(strPanelExp)
|
h.experienceTooltip.SetText(strPanelExp)
|
||||||
h.experienceTooltip.Render(target)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HUD) renderForSelectableEntitiesHovered(target d2interface.Surface) {
|
func (h *HUD) renderForSelectableEntitiesHovered(target d2interface.Surface) {
|
||||||
@ -666,30 +596,11 @@ func (h *HUD) renderForSelectableEntitiesHovered(target d2interface.Surface) {
|
|||||||
func (h *HUD) Render(target d2interface.Surface) error {
|
func (h *HUD) Render(target d2interface.Surface) error {
|
||||||
h.renderForSelectableEntitiesHovered(target)
|
h.renderForSelectableEntitiesHovered(target)
|
||||||
|
|
||||||
h.panelBackground.Render(target)
|
|
||||||
|
|
||||||
h.healthGlobe.Render(target)
|
|
||||||
h.widgetLeftSkill.Render(target)
|
|
||||||
h.widgetRightSkill.Render(target)
|
|
||||||
h.manaGlobe.Render(target)
|
|
||||||
h.widgetStamina.Render(target)
|
|
||||||
h.widgetExperience.Render(target)
|
|
||||||
|
|
||||||
if err := h.help.Render(target); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if h.isZoneTextShown {
|
if h.isZoneTextShown {
|
||||||
h.zoneChangeText.SetPosition(zoneChangeTextX, zoneChangeTextY)
|
h.zoneChangeText.SetPosition(zoneChangeTextX, zoneChangeTextY)
|
||||||
h.zoneChangeText.Render(target)
|
h.zoneChangeText.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
h.renderHealthTooltip(target)
|
|
||||||
h.renderManaTooltip(target)
|
|
||||||
h.renderRunWalkTooltip(target)
|
|
||||||
h.renderStaminaTooltip(target)
|
|
||||||
h.renderExperienceTooltip(target)
|
|
||||||
|
|
||||||
if h.skillSelectMenu.IsOpen() {
|
if h.skillSelectMenu.IsOpen() {
|
||||||
h.skillSelectMenu.Render(target)
|
h.skillSelectMenu.Render(target)
|
||||||
}
|
}
|
||||||
@ -717,6 +628,21 @@ func (h *HUD) getSkillResourceByClass(class string) string {
|
|||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Advance updates syncs data on widgets that might have changed. I.e. the current stamina value
|
||||||
|
// in the stamina tooltip
|
||||||
|
func (h *HUD) Advance(elapsed float64) {
|
||||||
|
h.setStaminaTooltipText()
|
||||||
|
h.setExperienceTooltipText()
|
||||||
|
|
||||||
|
if err := h.healthGlobe.Advance(elapsed); err != nil {
|
||||||
|
h.logger.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.manaGlobe.Advance(elapsed); err != nil {
|
||||||
|
h.logger.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OnMouseMove handles mouse move events
|
// OnMouseMove handles mouse move events
|
||||||
func (h *HUD) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
func (h *HUD) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||||
mx, my := event.X(), event.Y()
|
mx, my := event.X(), event.Y()
|
||||||
@ -728,20 +654,3 @@ 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -63,11 +63,16 @@ type miniPanel struct {
|
|||||||
asset *d2asset.AssetManager
|
asset *d2asset.AssetManager
|
||||||
container *d2ui.Sprite
|
container *d2ui.Sprite
|
||||||
sprite *d2ui.Sprite
|
sprite *d2ui.Sprite
|
||||||
|
menuButton *d2ui.Button
|
||||||
|
miniPanelTooltip *d2ui.Tooltip
|
||||||
isOpen bool
|
isOpen bool
|
||||||
|
tempIsOpen bool
|
||||||
|
disabled bool
|
||||||
isSinglePlayer bool
|
isSinglePlayer bool
|
||||||
movedLeft bool
|
movedLeft bool
|
||||||
movedRight bool
|
movedRight bool
|
||||||
panelGroup *d2ui.WidgetGroup
|
panelGroup *d2ui.WidgetGroup
|
||||||
|
groupAlwaysVis *d2ui.WidgetGroup
|
||||||
tooltipGroup *d2ui.WidgetGroup
|
tooltipGroup *d2ui.WidgetGroup
|
||||||
|
|
||||||
logger *d2util.Logger
|
logger *d2util.Logger
|
||||||
@ -91,8 +96,11 @@ func (m *miniPanel) createWidgets(actions *miniPanelActions) {
|
|||||||
m.panelGroup = m.ui.NewWidgetGroup(d2ui.RenderPriorityMinipanel)
|
m.panelGroup = m.ui.NewWidgetGroup(d2ui.RenderPriorityMinipanel)
|
||||||
m.panelGroup.SetPosition(miniPanelX, miniPanelY)
|
m.panelGroup.SetPosition(miniPanelX, miniPanelY)
|
||||||
|
|
||||||
|
m.groupAlwaysVis = m.ui.NewWidgetGroup(d2ui.RenderPriorityMinipanel)
|
||||||
|
|
||||||
m.tooltipGroup = m.ui.NewWidgetGroup(d2ui.RenderPriorityForeground)
|
m.tooltipGroup = m.ui.NewWidgetGroup(d2ui.RenderPriorityForeground)
|
||||||
|
|
||||||
|
// container sprite
|
||||||
miniPanelContainerPath := d2resource.Minipanel
|
miniPanelContainerPath := d2resource.Minipanel
|
||||||
if m.isSinglePlayer {
|
if m.isSinglePlayer {
|
||||||
miniPanelContainerPath = d2resource.MinipanelSmall
|
miniPanelContainerPath = d2resource.MinipanelSmall
|
||||||
@ -114,6 +122,14 @@ func (m *miniPanel) createWidgets(actions *miniPanelActions) {
|
|||||||
m.container.SetPosition(x, y)
|
m.container.SetPosition(x, y)
|
||||||
m.panelGroup.AddWidget(m.container)
|
m.panelGroup.AddWidget(m.container)
|
||||||
|
|
||||||
|
m.createButtons(actions)
|
||||||
|
|
||||||
|
m.panelGroup.SetVisible(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) createButtons(actions *miniPanelActions) {
|
||||||
|
var x, y int
|
||||||
|
|
||||||
buttonWidth, buttonHeight, err := m.sprite.GetFrameSize(0)
|
buttonWidth, buttonHeight, err := m.sprite.GetFrameSize(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.logger.Error(err.Error())
|
m.logger.Error(err.Error())
|
||||||
@ -181,7 +197,21 @@ func (m *miniPanel) createWidgets(actions *miniPanelActions) {
|
|||||||
m.panelGroup.AddWidget(btn)
|
m.panelGroup.AddWidget(btn)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.panelGroup.SetVisible(false)
|
//nolint:gomnd // divide by 2 is not a magic number
|
||||||
|
x = screenWidth/2 + miniPanelButtonOffsetX
|
||||||
|
y = screenHeight + miniPanelButtonOffsetY
|
||||||
|
// minipanel open/close tooltip
|
||||||
|
m.miniPanelTooltip = m.ui.NewTooltip(d2resource.Font16, d2resource.PaletteUnits, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||||
|
m.miniPanelTooltip.SetPosition(x+miniPanelTooltipOffsetX, y+miniPanelTooltipOffsetY)
|
||||||
|
|
||||||
|
// minipanel button
|
||||||
|
m.menuButton = m.ui.NewButton(d2ui.ButtonTypeMinipanelOpenClose, "")
|
||||||
|
m.menuButton.SetPosition(x, y)
|
||||||
|
m.menuButton.OnActivated(m.onMenuButtonClicked)
|
||||||
|
|
||||||
|
m.menuButton.SetTooltip(m.miniPanelTooltip)
|
||||||
|
m.updateMinipanelTooltipText()
|
||||||
|
m.groupAlwaysVis.AddWidget(m.menuButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) createButton(content miniPanelContent, x, y, buttonHeight int) *d2ui.Button {
|
func (m *miniPanel) createButton(content miniPanelContent, x, y, buttonHeight int) *d2ui.Button {
|
||||||
@ -197,10 +227,28 @@ func (m *miniPanel) createButton(content miniPanelContent, x, y, buttonHeight in
|
|||||||
btn.SetPosition(x, y)
|
btn.SetPosition(x, y)
|
||||||
btn.OnActivated(content.onActivate)
|
btn.OnActivated(content.onActivate)
|
||||||
btn.SetTooltip(tt)
|
btn.SetTooltip(tt)
|
||||||
|
btn.SetRenderPriority(d2ui.RenderPriorityForeground)
|
||||||
|
|
||||||
return btn
|
return btn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) onMenuButtonClicked() {
|
||||||
|
m.menuButton.Toggle()
|
||||||
|
m.Toggle()
|
||||||
|
m.updateMinipanelTooltipText()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) updateMinipanelTooltipText() {
|
||||||
|
var stringTableKey string
|
||||||
|
if m.menuButton.GetToggled() {
|
||||||
|
stringTableKey = "panelcmini"
|
||||||
|
} else {
|
||||||
|
stringTableKey = "panelmini"
|
||||||
|
}
|
||||||
|
|
||||||
|
m.miniPanelTooltip.SetText(m.asset.TranslateString(stringTableKey))
|
||||||
|
}
|
||||||
|
|
||||||
func (m *miniPanel) IsOpen() bool {
|
func (m *miniPanel) IsOpen() bool {
|
||||||
return m.isOpen
|
return m.isOpen
|
||||||
}
|
}
|
||||||
@ -214,12 +262,24 @@ func (m *miniPanel) Toggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) Open() {
|
func (m *miniPanel) Open() {
|
||||||
|
if !m.movedLeft && !m.movedRight {
|
||||||
m.panelGroup.SetVisible(true)
|
m.panelGroup.SetVisible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !m.menuButton.GetToggled() {
|
||||||
|
m.menuButton.Toggle()
|
||||||
|
}
|
||||||
|
|
||||||
m.isOpen = true
|
m.isOpen = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) Close() {
|
func (m *miniPanel) Close() {
|
||||||
m.panelGroup.SetVisible(false)
|
m.panelGroup.SetVisible(false)
|
||||||
|
|
||||||
|
if m.menuButton.GetToggled() {
|
||||||
|
m.menuButton.Toggle()
|
||||||
|
}
|
||||||
|
|
||||||
m.isOpen = false
|
m.isOpen = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +294,6 @@ func (m *miniPanel) moveRight() {
|
|||||||
|
|
||||||
func (m *miniPanel) undoMoveRight() {
|
func (m *miniPanel) undoMoveRight() {
|
||||||
m.panelGroup.OffsetPosition(-panelOffsetRight, 0)
|
m.panelGroup.OffsetPosition(-panelOffsetRight, 0)
|
||||||
m.tooltipGroup.OffsetPosition(-panelOffsetRight, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *miniPanel) moveLeft() {
|
func (m *miniPanel) moveLeft() {
|
||||||
@ -258,7 +317,7 @@ func (m *miniPanel) SetMovedLeft(moveLeft bool) {
|
|||||||
m.panelGroup.SetVisible(false)
|
m.panelGroup.SetVisible(false)
|
||||||
} else {
|
} else {
|
||||||
m.moveRight()
|
m.moveRight()
|
||||||
m.panelGroup.SetVisible(true)
|
m.panelGroup.SetVisible(m.isOpen)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if moveLeft {
|
if moveLeft {
|
||||||
@ -282,7 +341,7 @@ func (m *miniPanel) SetMovedRight(moveRight bool) {
|
|||||||
m.panelGroup.SetVisible(false)
|
m.panelGroup.SetVisible(false)
|
||||||
} else {
|
} else {
|
||||||
m.moveLeft()
|
m.moveLeft()
|
||||||
m.panelGroup.SetVisible(true)
|
m.panelGroup.SetVisible(m.isOpen)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if moveRight {
|
if moveRight {
|
||||||
@ -294,3 +353,51 @@ func (m *miniPanel) SetMovedRight(moveRight bool) {
|
|||||||
|
|
||||||
m.movedRight = moveRight
|
m.movedRight = moveRight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) openDisabled() {
|
||||||
|
if m.disabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.tempIsOpen = m.isOpen
|
||||||
|
|
||||||
|
if !m.isOpen {
|
||||||
|
m.Open()
|
||||||
|
}
|
||||||
|
|
||||||
|
m.menuButton.SetEnabled(false)
|
||||||
|
m.panelGroup.SetEnabled(false)
|
||||||
|
m.disabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) closeDisabled() {
|
||||||
|
if m.disabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.tempIsOpen = m.isOpen
|
||||||
|
|
||||||
|
if m.isOpen {
|
||||||
|
m.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
m.menuButton.SetEnabled(false)
|
||||||
|
m.panelGroup.SetEnabled(false)
|
||||||
|
m.disabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *miniPanel) restoreDisabled() {
|
||||||
|
if !m.disabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.disabled = false
|
||||||
|
m.menuButton.SetEnabled(true)
|
||||||
|
m.panelGroup.SetEnabled(true)
|
||||||
|
|
||||||
|
if m.tempIsOpen {
|
||||||
|
m.Open()
|
||||||
|
} else {
|
||||||
|
m.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user