mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-05 17:57:17 -05:00
1f49df62d1
* 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
194 lines
4.8 KiB
Go
194 lines
4.8 KiB
Go
package d2ui
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
|
)
|
|
|
|
// UIManager manages a collection of UI elements (buttons, textboxes, labels)
|
|
type UIManager struct {
|
|
asset *d2asset.AssetManager
|
|
renderer d2interface.Renderer
|
|
inputManager d2interface.InputManager
|
|
audio d2interface.AudioProvider
|
|
widgets []Widget
|
|
tooltips []*Tooltip
|
|
widgetsGroups []*WidgetGroup
|
|
clickableWidgets []ClickableWidget
|
|
cursorButtons CursorButton
|
|
CursorX int
|
|
CursorY int
|
|
pressedWidget ClickableWidget
|
|
clickSfx d2interface.SoundEffect
|
|
|
|
*d2util.Logger
|
|
}
|
|
|
|
// Note: methods for creating buttons and stuff are in their respective files
|
|
|
|
// Initialize is meant to be called after the game loads all of the necessary files
|
|
// for sprites and audio
|
|
func (ui *UIManager) Initialize() {
|
|
sfx, err := ui.audio.LoadSound(d2resource.SFXButtonClick, false, false)
|
|
if err != nil {
|
|
ui.Fatalf("failed to initialize ui: %v", err)
|
|
}
|
|
|
|
ui.clickSfx = sfx
|
|
|
|
if err := ui.inputManager.BindHandler(ui); err != nil {
|
|
ui.Fatalf("failed to initialize ui: %v", err)
|
|
}
|
|
}
|
|
|
|
// Reset resets the state of the UI manager. Typically called for new screens
|
|
func (ui *UIManager) Reset() {
|
|
ui.widgets = nil
|
|
ui.clickableWidgets = nil
|
|
ui.pressedWidget = nil
|
|
}
|
|
|
|
func (ui *UIManager) addClickable(widget ClickableWidget) {
|
|
ui.clickableWidgets = append(ui.clickableWidgets, widget)
|
|
}
|
|
|
|
// addWidget adds a widget to the UI manager
|
|
func (ui *UIManager) addWidget(widget Widget) {
|
|
err := ui.inputManager.BindHandler(widget)
|
|
if err != nil {
|
|
ui.Error(err.Error())
|
|
}
|
|
|
|
clickable, ok := widget.(ClickableWidget)
|
|
if ok {
|
|
ui.addClickable(clickable)
|
|
}
|
|
|
|
if widgetGroup, ok := widget.(*WidgetGroup); ok {
|
|
ui.widgetsGroups = append(ui.widgetsGroups, widgetGroup)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
// 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
|
|
func (ui *UIManager) OnMouseButtonUp(event d2interface.MouseEvent) bool {
|
|
ui.CursorX, ui.CursorY = event.X(), event.Y()
|
|
if event.Button() == d2enum.MouseButtonLeft {
|
|
ui.cursorButtons |= CursorButtonLeft
|
|
// activate previously pressed widget if cursor is still hovering
|
|
w := ui.pressedWidget
|
|
|
|
if w != nil && w.Contains(ui.CursorX, ui.CursorY) && w.GetVisible() && w.GetEnabled() {
|
|
w.Activate()
|
|
}
|
|
|
|
// unpress all widgets that are pressed
|
|
for _, w := range ui.clickableWidgets {
|
|
w.SetPressed(false)
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// OnMouseMove is the mouse move event handler
|
|
func (ui *UIManager) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
|
for _, w := range ui.widgetsGroups {
|
|
if w.GetVisible() {
|
|
w.OnMouseMove(event.X(), event.Y())
|
|
}
|
|
}
|
|
|
|
for _, w := range ui.widgets {
|
|
if w.GetVisible() {
|
|
w.OnMouseMove(event.X(), event.Y())
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// OnMouseButtonDown is the mouse button down event handler
|
|
func (ui *UIManager) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
|
ui.CursorX, ui.CursorY = event.X(), event.Y()
|
|
if event.Button() == d2enum.MouseButtonLeft {
|
|
// find and press a widget on screen
|
|
ui.pressedWidget = nil
|
|
for _, w := range ui.clickableWidgets {
|
|
if w.Contains(ui.CursorX, ui.CursorY) && w.GetVisible() && w.GetEnabled() {
|
|
w.SetPressed(true)
|
|
ui.pressedWidget = w
|
|
ui.clickSfx.Play()
|
|
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if event.Button() == d2enum.MouseButtonRight {
|
|
ui.cursorButtons |= CursorButtonRight
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// Render renders all of the UI elements
|
|
func (ui *UIManager) Render(target d2interface.Surface) {
|
|
for _, widget := range ui.widgets {
|
|
if widget.GetVisible() {
|
|
widget.Render(target)
|
|
}
|
|
}
|
|
|
|
for _, tooltip := range ui.tooltips {
|
|
if tooltip.GetVisible() {
|
|
tooltip.Render(target)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Advance updates all of the UI elements
|
|
func (ui *UIManager) Advance(elapsed float64) {
|
|
for _, widget := range ui.widgets {
|
|
if widget.GetVisible() {
|
|
err := widget.Advance(elapsed)
|
|
if err != nil {
|
|
ui.Error(err.Error())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// CursorButtonPressed determines if the specified button has been pressed
|
|
func (ui *UIManager) CursorButtonPressed(button CursorButton) bool {
|
|
return ui.cursorButtons&button > 0
|
|
}
|
|
|
|
// CursorPosition returns the current cursor position
|
|
func (ui *UIManager) CursorPosition() (x, y int) {
|
|
return ui.CursorX, ui.CursorY
|
|
}
|
|
|
|
// Renderer returns the renderer for this ui manager
|
|
func (ui *UIManager) Renderer() d2interface.Renderer {
|
|
return ui.renderer
|
|
}
|