1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-09 03:37:17 -05:00
OpenDiablo2/d2core/d2ui/widget_group.go
juander-ux 1f49df62d1
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
2020-11-21 02:35:32 -08:00

143 lines
3.1 KiB
Go

package d2ui
import (
"image/color"
"sort"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
)
const widgetGroupDebug = false // turns on debug rendering stuff for groups
// static check that WidgetGroup implements widget
var _ Widget = &WidgetGroup{}
// WidgetGroup allows the grouping of widgets to apply actions to all
// widgets at once.
type WidgetGroup struct {
*BaseWidget
entries []Widget
}
// NewWidgetGroup creates a new widget group
func (ui *UIManager) NewWidgetGroup(priority RenderPriority) *WidgetGroup {
base := NewBaseWidget(ui)
base.SetRenderPriority(priority)
group := &WidgetGroup{
BaseWidget: base,
}
ui.addWidget(group)
return group
}
// AddWidget adds a widget to the group
func (wg *WidgetGroup) AddWidget(w Widget) {
wg.adjustSize(w)
wg.entries = append(wg.entries, w)
sort.SliceStable(wg.entries, func(i, j int) bool {
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
func (wg *WidgetGroup) adjustSize(w Widget) {
x, y := w.GetPosition()
width, height := w.GetSize()
if x+width > wg.x+wg.width {
wg.width += (x + width) - (wg.x + wg.width)
}
if wg.x > x {
wg.width += wg.x - x
wg.x = x
}
if y+height > wg.y+wg.height {
wg.height += (y + height) - (wg.y + wg.height)
}
if wg.y > y {
wg.height += wg.y - y
wg.y = y
}
}
// Advance is a no-op here
func (wg *WidgetGroup) Advance(elapsed float64) error {
// No-op
return nil
}
// Render draw the widgets to the screen
func (wg *WidgetGroup) Render(target d2interface.Surface) {
for _, entry := range wg.entries {
if entry.GetVisible() {
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
func (wg *WidgetGroup) SetVisible(visible bool) {
wg.BaseWidget.SetVisible(visible)
for _, entry := range wg.entries {
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
func (wg *WidgetGroup) OnMouseMove(x, y int) {
for _, entry := range wg.entries {
if entry.Contains(x, y) && entry.GetVisible() {
if !entry.isHovered() {
entry.hoverStart()
}
} else if entry.isHovered() {
entry.hoverEnd()
}
}
}
// 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)
}
}
}