mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 07:27:19 -05:00
d2ui: Add WidgetGroup
this allows us to groups screens together, such that they can be de-/activated by de-/activating the group instead of every ui element by hand. Before we were deactivating buttons and stopped rendering to deactivate ui elements. This tied the renderer to these elements.
This commit is contained in:
parent
881d5f1f71
commit
627bc8ec65
@ -14,4 +14,6 @@ type Drawable interface {
|
||||
OffsetPosition(xo, yo int)
|
||||
GetVisible() bool
|
||||
SetVisible(visible bool)
|
||||
SetRenderPriority(priority RenderPriority)
|
||||
GetRenderPriority() (priority RenderPriority)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package d2ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
|
||||
@ -17,6 +18,7 @@ type UIManager struct {
|
||||
inputManager d2interface.InputManager
|
||||
audio d2interface.AudioProvider
|
||||
widgets []Widget
|
||||
widgetsGroups []*WidgetGroup
|
||||
clickableWidgets []ClickableWidget
|
||||
cursorButtons CursorButton
|
||||
CursorX int
|
||||
@ -49,6 +51,14 @@ func (ui *UIManager) Reset() {
|
||||
ui.pressedWidget = nil
|
||||
}
|
||||
|
||||
// addWidgetGroup adds a widgetGroup to the UI manager and sorts by priority
|
||||
func (ui *UIManager) addWidgetGroup(group *WidgetGroup) {
|
||||
ui.widgetsGroups = append(ui.widgetsGroups, group)
|
||||
sort.SliceStable(ui.widgetsGroups, func(i, j int) bool {
|
||||
return ui.widgetsGroups[i].priority < ui.widgetsGroups[j].priority
|
||||
})
|
||||
}
|
||||
|
||||
// addWidget adds a widget to the UI manager
|
||||
func (ui *UIManager) addWidget(widget Widget) {
|
||||
err := ui.inputManager.BindHandler(widget)
|
||||
@ -120,6 +130,15 @@ func (ui *UIManager) Render(target d2interface.Surface) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, widgetGroup := range ui.widgetsGroups {
|
||||
if widgetGroup.GetVisible() {
|
||||
err := widgetGroup.Render(target)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// contains determines whether a given x,y coordinate lands within a Widget
|
||||
|
@ -1,5 +1,16 @@
|
||||
package d2ui
|
||||
|
||||
// RenderPriority determines in which order ui elements are drawn.
|
||||
// The higher the number the later an element is drawn.
|
||||
type RenderPriority int
|
||||
|
||||
const (
|
||||
// RenderPriorityBackground is the first element drawn
|
||||
RenderPriorityBackground RenderPriority = iota
|
||||
// RenderPriorityForeground is the last element drawn
|
||||
RenderPriorityForeground
|
||||
)
|
||||
|
||||
// Widget defines an object that is a UI widget
|
||||
type Widget interface {
|
||||
Drawable
|
||||
@ -19,23 +30,25 @@ type ClickableWidget interface {
|
||||
|
||||
// BaseWidget contains default functionality that all widgets share
|
||||
type BaseWidget struct {
|
||||
manager *UIManager
|
||||
x int
|
||||
y int
|
||||
width int
|
||||
height int
|
||||
visible bool
|
||||
manager *UIManager
|
||||
x int
|
||||
y int
|
||||
width int
|
||||
height int
|
||||
renderPriority RenderPriority
|
||||
visible bool
|
||||
}
|
||||
|
||||
// NewBaseWidget creates a new BaseWidget with defaults
|
||||
func NewBaseWidget(manager *UIManager) *BaseWidget {
|
||||
return &BaseWidget{
|
||||
manager: manager,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
visible: true,
|
||||
manager: manager,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
visible: true,
|
||||
renderPriority: RenderPriorityBackground,
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,3 +86,13 @@ func (b *BaseWidget) GetVisible() (visible bool) {
|
||||
func (b *BaseWidget) SetVisible(visible bool) {
|
||||
b.visible = visible
|
||||
}
|
||||
|
||||
// GetRenderPriority returns the order in which this widget is rendered
|
||||
func (b *BaseWidget) GetRenderPriority() (prio RenderPriority) {
|
||||
return b.renderPriority
|
||||
}
|
||||
|
||||
// SetRenderPriority sets the order in which this widget is rendered
|
||||
func (b *BaseWidget) SetRenderPriority(prio RenderPriority) {
|
||||
b.renderPriority = prio
|
||||
}
|
||||
|
92
d2core/d2ui/widget_group.go
Normal file
92
d2core/d2ui/widget_group.go
Normal file
@ -0,0 +1,92 @@
|
||||
package d2ui
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
// 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
|
||||
priority RenderPriority
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
if x+width > wg.width {
|
||||
wg.width = x + width
|
||||
}
|
||||
|
||||
if wg.x > x {
|
||||
wg.width += wg.x - x
|
||||
wg.x = x
|
||||
}
|
||||
|
||||
if y+height > wg.height {
|
||||
wg.height = x + 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) error {
|
||||
for _, entry := range wg.entries {
|
||||
if entry.GetVisible() {
|
||||
err := entry.Render(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetVisible sets the visibility of all widgets in the group
|
||||
func (wg *WidgetGroup) SetVisible(visible bool) {
|
||||
for _, entry := range wg.entries {
|
||||
entry.SetVisible(visible)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user