The manager that holds widgets is the WidgetManager
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
UIManager named the category, not the contents. Every other manager is named after what it registers — ItemManager holds Items, SceneManager holds Scenes — so the one that registers Widgets is the WidgetManager. The alias, the Game field and both manual pages move together. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -180,7 +180,7 @@ type DialogueManager = Manager[Dialogue]
|
|||||||
type ScriptManager = Manager[Script]
|
type ScriptManager = Manager[Script]
|
||||||
type AssetManager = Manager[Asset]
|
type AssetManager = Manager[Asset]
|
||||||
type VerbManager = Manager[Verb]
|
type VerbManager = Manager[Verb]
|
||||||
type UIManager = Manager[Widget]
|
type WidgetManager = Manager[Widget]
|
||||||
type ThemeManager = Manager[Theme]
|
type ThemeManager = Manager[Theme]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ type Game struct {
|
|||||||
ScriptManager *ScriptManager
|
ScriptManager *ScriptManager
|
||||||
AssetManager *AssetManager
|
AssetManager *AssetManager
|
||||||
VerbManager *VerbManager
|
VerbManager *VerbManager
|
||||||
UIManager *UIManager
|
WidgetManager *WidgetManager
|
||||||
ThemeManager *ThemeManager
|
ThemeManager *ThemeManager
|
||||||
|
|
||||||
// exits
|
// exits
|
||||||
@@ -273,7 +273,7 @@ Initialises every manager (empty), registers the default SCUMM verb set
|
|||||||
(`look`, `use`, `talk`, `take`), installs all four preset themes, and
|
(`look`, `use`, `talk`, `take`), installs all four preset themes, and
|
||||||
selects `classic-scumm` as the active theme. Widgets are **not**
|
selects `classic-scumm` as the active theme. Widgets are **not**
|
||||||
auto-registered — call `RegisterDefaultUI(g)` (or one of its siblings)
|
auto-registered — call `RegisterDefaultUI(g)` (or one of its siblings)
|
||||||
explicitly, or let `Run` install the default set if `UIManager` is empty.
|
explicitly, or let `Run` install the default set if `WidgetManager` is empty.
|
||||||
|
|
||||||
The manager fields are ordinary `*Manager` values, so a domain that keeps its
|
The manager fields are ordinary `*Manager` values, so a domain that keeps its
|
||||||
own registries can **assign them onto the Game** instead of copying every entry
|
own registries can **assign them onto the Game** instead of copying every entry
|
||||||
@@ -1002,7 +1002,7 @@ could be used by triggers once those land.
|
|||||||
|
|
||||||
## 10. The widget system
|
## 10. The widget system
|
||||||
|
|
||||||
The HUD is a tree of `Widget`s, each registered into `g.UIManager`. The
|
The HUD is a tree of `Widget`s, each registered into `g.WidgetManager`. The
|
||||||
library ships built-in widgets for every classic adventure UI piece;
|
library ships built-in widgets for every classic adventure UI piece;
|
||||||
domain code can register arbitrary new ones — chat panels, minimaps,
|
domain code can register arbitrary new ones — chat panels, minimaps,
|
||||||
hotbars — without touching the library.
|
hotbars — without touching the library.
|
||||||
@@ -1352,7 +1352,7 @@ func (m *Minimap) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
|
|||||||
// ... render scene thumbnail, mark NPCs, etc.
|
// ... render scene thumbnail, mark NPCs, etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
g.UIManager.Register(&Minimap{
|
g.WidgetManager.Register(&Minimap{
|
||||||
Name: "minimap",
|
Name: "minimap",
|
||||||
Bounds: inkwell.Rect(220, 4, 96, 56),
|
Bounds: inkwell.Rect(220, 4, 96, 56),
|
||||||
})
|
})
|
||||||
@@ -1554,7 +1554,7 @@ func Run(g *Game) error // toplevel — same as g.Run()
|
|||||||
1. `g.Audio.attach(g.AssetManager)` — wire the audio player to whichever
|
1. `g.Audio.attach(g.AssetManager)` — wire the audio player to whichever
|
||||||
asset registry the game is carrying by now.
|
asset registry the game is carrying by now.
|
||||||
2. `g.Validate()` — cross-check name references between managers.
|
2. `g.Validate()` — cross-check name references between managers.
|
||||||
3. If `UIManager` is empty, call `RegisterDefaultUI(g)`.
|
3. If `WidgetManager` is empty, call `RegisterDefaultUI(g)`.
|
||||||
4. Place the start scene directly (no transition), bump
|
4. Place the start scene directly (no transition), bump
|
||||||
`State.NoteVisit`, position registered actors, kick off music.
|
`State.NoteVisit`, position registered actors, kick off music.
|
||||||
5. Compose `Seq(scene.OnEnter, OnStart script, OnFinale script)` and queue
|
5. Compose `Seq(scene.OnEnter, OnStart script, OnFinale script)` and queue
|
||||||
@@ -1575,7 +1575,7 @@ if scriptRunner != nil:
|
|||||||
return
|
return
|
||||||
|
|
||||||
clear hoverLabel
|
clear hoverLabel
|
||||||
for w in reversed(UIManager):
|
for w in reversed(WidgetManager):
|
||||||
w.Tick(uictx) // widgets consume input top-down
|
w.Tick(uictx) // widgets consume input top-down
|
||||||
|
|
||||||
handleSceneInput() // hotspot resolution + right-click reset
|
handleSceneInput() // hotspot resolution + right-click reset
|
||||||
@@ -1589,7 +1589,7 @@ fill Theme.SceneBackdrop (if any)
|
|||||||
draw scene background image
|
draw scene background image
|
||||||
for c in characters sorted by Y:
|
for c in characters sorted by Y:
|
||||||
drawCharacter(c)
|
drawCharacter(c)
|
||||||
for w in UIManager (registration order):
|
for w in WidgetManager (registration order):
|
||||||
w.Draw(screen, uictx)
|
w.Draw(screen, uictx)
|
||||||
draw transition overlay
|
draw transition overlay
|
||||||
```
|
```
|
||||||
@@ -1845,7 +1845,7 @@ inkwell/ # module git.teletypegames.org/games/inkwell
|
|||||||
├── input.def.go # Input (consume-on-use)
|
├── input.def.go # Input (consume-on-use)
|
||||||
│
|
│
|
||||||
├── ui.widget.go # Widget interface, UICtx, Size, Align
|
├── ui.widget.go # Widget interface, UICtx, Size, Align
|
||||||
├── ui.manager.go # UIManager alias + reversed/ordered iterators
|
├── ui.manager.go # WidgetManager alias + reversed/ordered iterators
|
||||||
├── ui.theme.go # Theme + ThemeManager
|
├── ui.theme.go # Theme + ThemeManager
|
||||||
├── ui.theme_presets.go # 4 preset themes
|
├── ui.theme_presets.go # 4 preset themes
|
||||||
├── ui.defaults.go # RegisterDefaultUI/RadialVerbUI/RichUI
|
├── ui.defaults.go # RegisterDefaultUI/RadialVerbUI/RichUI
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ func Run(g *Game) error {
|
|||||||
}
|
}
|
||||||
// If the domain didn't register any widgets, fall back to the SCUMM
|
// If the domain didn't register any widgets, fall back to the SCUMM
|
||||||
// preset so the game is still playable.
|
// preset so the game is still playable.
|
||||||
if g.UIManager.Len() == 0 {
|
if g.WidgetManager.Len() == 0 {
|
||||||
RegisterDefaultUI(g)
|
RegisterDefaultUI(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -61,7 +61,7 @@ func (e *engine) Update() error {
|
|||||||
// Top-down input: the widget drawn last (= registered last) gets the
|
// Top-down input: the widget drawn last (= registered last) gets the
|
||||||
// click first, then the next-to-last, etc. A widget signals "I took it"
|
// click first, then the next-to-last, etc. A widget signals "I took it"
|
||||||
// via g.Input.ConsumeLeft / ConsumeRight.
|
// via g.Input.ConsumeLeft / ConsumeRight.
|
||||||
for _, w := range reversedWidgets(g.UIManager) {
|
for _, w := range reversedWidgets(g.WidgetManager) {
|
||||||
w.Tick(uictx)
|
w.Tick(uictx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ func (e *engine) Draw(screen *ebiten.Image) {
|
|||||||
|
|
||||||
// widgets in registration order
|
// widgets in registration order
|
||||||
uictx := &UICtx{Game: g, DT: 1.0 / 60.0}
|
uictx := &UICtx{Game: g, DT: 1.0 / 60.0}
|
||||||
for _, w := range orderedWidgets(g.UIManager) {
|
for _, w := range orderedWidgets(g.WidgetManager) {
|
||||||
w.Draw(screen, uictx)
|
w.Draw(screen, uictx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -21,7 +21,7 @@ type Game struct {
|
|||||||
ScriptManager *ScriptManager
|
ScriptManager *ScriptManager
|
||||||
AssetManager *AssetManager
|
AssetManager *AssetManager
|
||||||
VerbManager *VerbManager
|
VerbManager *VerbManager
|
||||||
UIManager *UIManager
|
WidgetManager *WidgetManager
|
||||||
ThemeManager *ThemeManager
|
ThemeManager *ThemeManager
|
||||||
|
|
||||||
// SceneRect is the part of the window the picture occupies. Zero means
|
// SceneRect is the part of the window the picture occupies. Zero means
|
||||||
@@ -131,7 +131,7 @@ func NewGame(title string, w, h int) *Game {
|
|||||||
ScriptManager: NewManager[Script](),
|
ScriptManager: NewManager[Script](),
|
||||||
AssetManager: NewManager[Asset](),
|
AssetManager: NewManager[Asset](),
|
||||||
VerbManager: NewManager[Verb](),
|
VerbManager: NewManager[Verb](),
|
||||||
UIManager: NewManager[Widget](),
|
WidgetManager: NewManager[Widget](),
|
||||||
ThemeManager: NewManager[Theme](),
|
ThemeManager: NewManager[Theme](),
|
||||||
State: NewState(),
|
State: NewState(),
|
||||||
Inventory: NewInventory(),
|
Inventory: NewInventory(),
|
||||||
|
|||||||
+28
-28
@@ -1,20 +1,20 @@
|
|||||||
package inkwell
|
package inkwell
|
||||||
|
|
||||||
// RegisterDefaultUI installs the SCUMM-style HUD widgets into g.UIManager
|
// RegisterDefaultUI installs the SCUMM-style HUD widgets into g.WidgetManager
|
||||||
// in the conventional Z-order (HotspotDebug at the back, Cursor on top).
|
// in the conventional Z-order (HotspotDebug at the back, Cursor on top).
|
||||||
// Domains that want a different layout call this and then either tweak
|
// Domains that want a different layout call this and then either tweak
|
||||||
// the registered widgets in place or replace them entirely.
|
// the registered widgets in place or replace them entirely.
|
||||||
//
|
//
|
||||||
// Layout assumes the default 320×200 internal resolution.
|
// Layout assumes the default 320×200 internal resolution.
|
||||||
func RegisterDefaultUI(g *Game) {
|
func RegisterDefaultUI(g *Game) {
|
||||||
g.UIManager.Register(&HotspotDebug{Name: "hotspot_debug"})
|
g.WidgetManager.Register(&HotspotDebug{Name: "hotspot_debug"})
|
||||||
g.UIManager.Register(&VerbBar{
|
g.WidgetManager.Register(&VerbBar{
|
||||||
Name: "verbs",
|
Name: "verbs",
|
||||||
Origin: Point{X: 4, Y: 152},
|
Origin: Point{X: 4, Y: 152},
|
||||||
Cols: 2,
|
Cols: 2,
|
||||||
Button: Size{W: 60, H: 14},
|
Button: Size{W: 60, H: 14},
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&InventoryBar{
|
g.WidgetManager.Register(&InventoryBar{
|
||||||
Name: "inventory",
|
Name: "inventory",
|
||||||
Origin: Point{X: 132, Y: 152},
|
Origin: Point{X: 132, Y: 152},
|
||||||
Slots: 8,
|
Slots: 8,
|
||||||
@@ -22,11 +22,11 @@ func RegisterDefaultUI(g *Game) {
|
|||||||
SlotSize: 22,
|
SlotSize: 22,
|
||||||
Gap: 2,
|
Gap: 2,
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&StatusLine{Name: "status", Y: 142, Align: AlignCenter})
|
g.WidgetManager.Register(&StatusLine{Name: "status", Y: 142, Align: AlignCenter})
|
||||||
g.UIManager.Register(&SpeechBubble{Name: "speech", MaxWidth: 200, Padding: 3, OffsetY: 4, FallbackY: 14})
|
g.WidgetManager.Register(&SpeechBubble{Name: "speech", MaxWidth: 200, Padding: 3, OffsetY: 4, FallbackY: 14})
|
||||||
g.UIManager.Register(&DialogBox{Name: "dialog", Bounds: Rect(0, 140, float64(g.Width), 60), LineHeight: 14, Padding: 6})
|
g.WidgetManager.Register(&DialogBox{Name: "dialog", Bounds: Rect(0, 140, float64(g.Width), 60), LineHeight: 14, Padding: 6})
|
||||||
g.UIManager.Register(&EndCard{Name: "endcard"})
|
g.WidgetManager.Register(&EndCard{Name: "endcard"})
|
||||||
g.UIManager.Register(&Cursor{Name: "cursor"})
|
g.WidgetManager.Register(&Cursor{Name: "cursor"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterRichUI installs a "story-rich" HUD that matches the layout of
|
// RegisterRichUI installs a "story-rich" HUD that matches the layout of
|
||||||
@@ -39,15 +39,15 @@ func RegisterDefaultUI(g *Game) {
|
|||||||
// PlayerName / NPCName correspond to registered characters. Pass "" for
|
// PlayerName / NPCName correspond to registered characters. Pass "" for
|
||||||
// NPCName to skip the NPC panel.
|
// NPCName to skip the NPC panel.
|
||||||
func RegisterRichUI(g *Game, playerName, npcName string) {
|
func RegisterRichUI(g *Game, playerName, npcName string) {
|
||||||
g.UIManager.Register(&TopBar{
|
g.WidgetManager.Register(&TopBar{
|
||||||
Name: "topbar",
|
Name: "topbar",
|
||||||
Height: 12,
|
Height: 12,
|
||||||
ScoreVar: "score", ScoreMax: 100,
|
ScoreVar: "score", ScoreMax: 100,
|
||||||
TimeVar: "time",
|
TimeVar: "time",
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&HotspotDebug{Name: "hotspot_debug"})
|
g.WidgetManager.Register(&HotspotDebug{Name: "hotspot_debug"})
|
||||||
if playerName != "" {
|
if playerName != "" {
|
||||||
g.UIManager.Register(&CharacterPanel{
|
g.WidgetManager.Register(&CharacterPanel{
|
||||||
Name: "panel_player",
|
Name: "panel_player",
|
||||||
Bounds: Rect(2, 14, 92, 36),
|
Bounds: Rect(2, 14, 92, 36),
|
||||||
Character: playerName,
|
Character: playerName,
|
||||||
@@ -59,7 +59,7 @@ func RegisterRichUI(g *Game, playerName, npcName string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if npcName != "" {
|
if npcName != "" {
|
||||||
g.UIManager.Register(&CharacterPanel{
|
g.WidgetManager.Register(&CharacterPanel{
|
||||||
Name: "panel_npc",
|
Name: "panel_npc",
|
||||||
Bounds: Rect(180, 14, 92, 36),
|
Bounds: Rect(180, 14, 92, 36),
|
||||||
Character: npcName,
|
Character: npcName,
|
||||||
@@ -70,7 +70,7 @@ func RegisterRichUI(g *Game, playerName, npcName string) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
g.UIManager.Register(&InventoryBar{
|
g.WidgetManager.Register(&InventoryBar{
|
||||||
Name: "inventory",
|
Name: "inventory",
|
||||||
Origin: Point{X: 4, Y: 188},
|
Origin: Point{X: 4, Y: 188},
|
||||||
Slots: 8,
|
Slots: 8,
|
||||||
@@ -78,14 +78,14 @@ func RegisterRichUI(g *Game, playerName, npcName string) {
|
|||||||
SlotSize: 10,
|
SlotSize: 10,
|
||||||
Gap: 1,
|
Gap: 1,
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&ChatLog{
|
g.WidgetManager.Register(&ChatLog{
|
||||||
Name: "chat",
|
Name: "chat",
|
||||||
Bounds: Rect(2, 148, 280, 38),
|
Bounds: Rect(2, 148, 280, 38),
|
||||||
LineHeight: 9,
|
LineHeight: 9,
|
||||||
Padding: 3,
|
Padding: 3,
|
||||||
ShowBorder: true,
|
ShowBorder: true,
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&RadialVerbs{
|
g.WidgetManager.Register(&RadialVerbs{
|
||||||
Name: "verbs",
|
Name: "verbs",
|
||||||
AlwaysVisible: true,
|
AlwaysVisible: true,
|
||||||
Center: Point{X: 282, Y: 90},
|
Center: Point{X: 282, Y: 90},
|
||||||
@@ -97,18 +97,18 @@ func RegisterRichUI(g *Game, playerName, npcName string) {
|
|||||||
"take": "Vedd",
|
"take": "Vedd",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&SpeechBubble{Name: "speech", MaxWidth: 200, Padding: 3, OffsetY: 4, FallbackY: 18})
|
g.WidgetManager.Register(&SpeechBubble{Name: "speech", MaxWidth: 200, Padding: 3, OffsetY: 4, FallbackY: 18})
|
||||||
g.UIManager.Register(&DialogBox{Name: "dialog", Bounds: Rect(0, 90, float64(g.Width), 56), LineHeight: 12, Padding: 6})
|
g.WidgetManager.Register(&DialogBox{Name: "dialog", Bounds: Rect(0, 90, float64(g.Width), 56), LineHeight: 12, Padding: 6})
|
||||||
g.UIManager.Register(&EndCard{Name: "endcard"})
|
g.WidgetManager.Register(&EndCard{Name: "endcard"})
|
||||||
g.UIManager.Register(&Cursor{Name: "cursor"})
|
g.WidgetManager.Register(&Cursor{Name: "cursor"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterRadialVerbUI installs an alternative HUD that swaps the
|
// RegisterRadialVerbUI installs an alternative HUD that swaps the
|
||||||
// permanent verb-bar for a verb-coin (right-click radial menu). Inventory,
|
// permanent verb-bar for a verb-coin (right-click radial menu). Inventory,
|
||||||
// dialog, speech and cursor stay the same.
|
// dialog, speech and cursor stay the same.
|
||||||
func RegisterRadialVerbUI(g *Game) {
|
func RegisterRadialVerbUI(g *Game) {
|
||||||
g.UIManager.Register(&HotspotDebug{Name: "hotspot_debug"})
|
g.WidgetManager.Register(&HotspotDebug{Name: "hotspot_debug"})
|
||||||
g.UIManager.Register(&InventoryBar{
|
g.WidgetManager.Register(&InventoryBar{
|
||||||
Name: "inventory",
|
Name: "inventory",
|
||||||
Origin: Point{X: 4, Y: 178},
|
Origin: Point{X: 4, Y: 178},
|
||||||
Slots: 14,
|
Slots: 14,
|
||||||
@@ -116,10 +116,10 @@ func RegisterRadialVerbUI(g *Game) {
|
|||||||
SlotSize: 22,
|
SlotSize: 22,
|
||||||
Gap: 0,
|
Gap: 0,
|
||||||
})
|
})
|
||||||
g.UIManager.Register(&StatusLine{Name: "status", Y: 168, Align: AlignCenter})
|
g.WidgetManager.Register(&StatusLine{Name: "status", Y: 168, Align: AlignCenter})
|
||||||
g.UIManager.Register(&SpeechBubble{Name: "speech", MaxWidth: 200, Padding: 3, OffsetY: 4, FallbackY: 14})
|
g.WidgetManager.Register(&SpeechBubble{Name: "speech", MaxWidth: 200, Padding: 3, OffsetY: 4, FallbackY: 14})
|
||||||
g.UIManager.Register(&DialogBox{Name: "dialog", Bounds: Rect(0, 140, float64(g.Width), 60), LineHeight: 14, Padding: 6})
|
g.WidgetManager.Register(&DialogBox{Name: "dialog", Bounds: Rect(0, 140, float64(g.Width), 60), LineHeight: 14, Padding: 6})
|
||||||
g.UIManager.Register(&RadialVerbs{Name: "verbs", Trigger: MouseButtonRight, Radius: 40})
|
g.WidgetManager.Register(&RadialVerbs{Name: "verbs", Trigger: MouseButtonRight, Radius: 40})
|
||||||
g.UIManager.Register(&EndCard{Name: "endcard"})
|
g.WidgetManager.Register(&EndCard{Name: "endcard"})
|
||||||
g.UIManager.Register(&Cursor{Name: "cursor"})
|
g.WidgetManager.Register(&Cursor{Name: "cursor"})
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
package inkwell
|
package inkwell
|
||||||
|
|
||||||
// UIManager registers Widget instances. Same shape as every other manager.
|
// WidgetManager registers Widget instances. Same shape as every other manager.
|
||||||
type UIManager = Manager[Widget]
|
type WidgetManager = Manager[Widget]
|
||||||
|
|
||||||
// reversedWidgets iterates a manager's contents in reverse registration
|
// reversedWidgets iterates a manager's contents in reverse registration
|
||||||
// order — used by the engine for top-down input dispatch (the widget
|
// order — used by the engine for top-down input dispatch (the widget
|
||||||
// drawn on top gets the click first).
|
// drawn on top gets the click first).
|
||||||
func reversedWidgets(m *UIManager) []Widget {
|
func reversedWidgets(m *WidgetManager) []Widget {
|
||||||
all := m.All()
|
all := m.All()
|
||||||
out := make([]Widget, len(all))
|
out := make([]Widget, len(all))
|
||||||
for i, w := range all {
|
for i, w := range all {
|
||||||
@@ -16,4 +16,4 @@ func reversedWidgets(m *UIManager) []Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// orderedWidgets iterates in registration order — bottom-up draw.
|
// orderedWidgets iterates in registration order — bottom-up draw.
|
||||||
func orderedWidgets(m *UIManager) []Widget { return m.All() }
|
func orderedWidgets(m *WidgetManager) []Widget { return m.All() }
|
||||||
|
|||||||
+2
-2
@@ -140,11 +140,11 @@ func (r *RadialVerbs) consumeTrigger(g *Game) {
|
|||||||
// whether its area covers the cursor — so the radial menu doesn't open
|
// whether its area covers the cursor — so the radial menu doesn't open
|
||||||
// over an InventoryBar that would also want this click.
|
// over an InventoryBar that would also want this click.
|
||||||
func (r *RadialVerbs) blockedAt(ctx *UICtx, p Point) bool {
|
func (r *RadialVerbs) blockedAt(ctx *UICtx, p Point) bool {
|
||||||
for _, name := range ctx.Game.UIManager.Names() {
|
for _, name := range ctx.Game.WidgetManager.Names() {
|
||||||
if name == r.Name {
|
if name == r.Name {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
w := ctx.Game.UIManager.MustGet(name)
|
w := ctx.Game.WidgetManager.MustGet(name)
|
||||||
// DialogBox advertises its bounds via clickBlocker even when no
|
// DialogBox advertises its bounds via clickBlocker even when no
|
||||||
// dialog is open, so the verb-coin would refuse to pop up over
|
// dialog is open, so the verb-coin would refuse to pop up over
|
||||||
// scenery that happens to sit under the dialog rect. Skip the
|
// scenery that happens to sit under the dialog rect. Skip the
|
||||||
|
|||||||
Reference in New Issue
Block a user