2020-11-06 07:28:24 -05:00
|
|
|
package d2ui
|
|
|
|
|
|
|
|
import (
|
2020-11-16 04:41:01 -05:00
|
|
|
"image/color"
|
2020-11-06 07:28:24 -05:00
|
|
|
"sort"
|
|
|
|
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
|
|
)
|
|
|
|
|
2020-11-16 04:41:01 -05:00
|
|
|
const widgetGroupDebug = false // turns on debug rendering stuff for groups
|
|
|
|
|
2020-11-06 07:28:24 -05:00
|
|
|
// 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
|
2020-11-13 15:08:43 -05:00
|
|
|
entries []Widget
|
2020-11-06 07:28:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewWidgetGroup creates a new widget group
|
|
|
|
func (ui *UIManager) NewWidgetGroup(priority RenderPriority) *WidgetGroup {
|
|
|
|
base := NewBaseWidget(ui)
|
|
|
|
base.SetRenderPriority(priority)
|
|
|
|
|
|
|
|
group := &WidgetGroup{
|
|
|
|
BaseWidget: base,
|
|
|
|
}
|
|
|
|
|
|
|
|
ui.addWidgetGroup(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()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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()
|
|
|
|
|
2020-11-16 04:41:01 -05:00
|
|
|
if x+width > wg.x+wg.width {
|
|
|
|
wg.width += (x + width) - (wg.x + wg.width)
|
2020-11-06 07:28:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if wg.x > x {
|
|
|
|
wg.width += wg.x - x
|
|
|
|
wg.x = x
|
|
|
|
}
|
|
|
|
|
2020-11-16 04:41:01 -05:00
|
|
|
if y+height > wg.y+wg.height {
|
|
|
|
wg.height += (y + height) - (wg.y + wg.height)
|
2020-11-06 07:28:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2020-11-11 08:55:59 -05:00
|
|
|
func (wg *WidgetGroup) Render(target d2interface.Surface) {
|
2020-11-06 07:28:24 -05:00
|
|
|
for _, entry := range wg.entries {
|
|
|
|
if entry.GetVisible() {
|
2020-11-11 08:55:59 -05:00
|
|
|
entry.Render(target)
|
2020-11-06 07:28:24 -05:00
|
|
|
}
|
|
|
|
}
|
2020-11-16 04:41:01 -05:00
|
|
|
|
|
|
|
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()
|
2020-11-06 07:28:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetVisible sets the visibility of all widgets in the group
|
|
|
|
func (wg *WidgetGroup) SetVisible(visible bool) {
|
2020-11-16 04:41:01 -05:00
|
|
|
wg.BaseWidget.SetVisible(visible)
|
|
|
|
|
2020-11-06 07:28:24 -05:00
|
|
|
for _, entry := range wg.entries {
|
|
|
|
entry.SetVisible(visible)
|
|
|
|
}
|
|
|
|
}
|
2020-11-13 15:08:43 -05:00
|
|
|
|
2020-11-16 04:41:01 -05:00
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-13 15:08:43 -05:00
|
|
|
// 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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|