From bbc716f682a73522b88103820dc5ccabecae99ef Mon Sep 17 00:00:00 2001 From: juander-ux <73304484+juander-ux@users.noreply.github.com> Date: Sun, 25 Oct 2020 15:54:39 +0100 Subject: [PATCH] Add close buttons to all panels (#808) * d2player/panels: Add close button to hero/inventory/skilltree panel we require a OnClose callback here, as we need to update the perspective of the view which is handled by gamecontrols.updateLayout(). * d2player/skilltree: Fix using the same tab label for all tabs * d2player/game_controls: Fix wrong position of left/right menu the character would not detect that a click was in a menu and start walking. --- d2game/d2player/game_controls.go | 9 +++- d2game/d2player/hero_stats_panel.go | 25 ++++++++++- d2game/d2player/inventory.go | 39 +++++++++++++---- d2game/d2player/skilltree.go | 67 ++++++++++++++++++++++++++--- 4 files changed, 124 insertions(+), 16 deletions(-) diff --git a/d2game/d2player/game_controls.go b/d2game/d2player/game_controls.go index ef621fa9..1f427949 100644 --- a/d2game/d2player/game_controls.go +++ b/d2game/d2player/game_controls.go @@ -221,12 +221,12 @@ const ( menuLeftRectX, menuLeftRectY, menuLeftRectW, - menuLeftRectH = 0, 550, 800, 50 + menuLeftRectH = 0, 0, 400, 600 menuRightRectX, menuRightRectY, menuRightRectW, - menuRightRectH = 0, 550, 800, 50 + menuRightRectH = 400, 0, 400, 600 ) // GameControls represents the game's controls on the screen @@ -494,6 +494,11 @@ func NewGameControls( isSinglePlayer: isSinglePlayer, } + closeCb := func() { gc.updateLayout() } + gc.heroStatsPanel.SetOnCloseCb(closeCb) + gc.inventory.SetOnCloseCb(closeCb) + gc.skilltree.SetOnCloseCb(closeCb) + err = gc.bindTerminalCommands(term) if err != nil { return nil, err diff --git a/d2game/d2player/hero_stats_panel.go b/d2game/d2player/hero_stats_panel.go index 8b66e2c0..51ee226a 100644 --- a/d2game/d2player/hero_stats_panel.go +++ b/d2game/d2player/hero_stats_panel.go @@ -53,6 +53,10 @@ const ( labelResPoisLine2X, labelResPoisLine2Y = 310, 477 ) +const ( + heroStatsCloseButtonX, heroStatsCloseButtonY = 208, 453 +) + // PanelText represents text on the panel type PanelText struct { X int @@ -91,6 +95,8 @@ type HeroStatsPanel struct { renderer d2interface.Renderer staticMenuImageCache *d2interface.Surface labels *StatsPanelLabels + closeButton *d2ui.Button + onCloseCb func() originX int originY int @@ -122,6 +128,11 @@ func (s *HeroStatsPanel) Load() { s.frame = d2ui.NewUIFrame(s.asset, s.uiManager, d2ui.FrameLeft) + s.closeButton = s.uiManager.NewButton(d2ui.ButtonTypeSquareClose, "") + s.closeButton.SetVisible(false) + s.closeButton.SetPosition(heroStatsCloseButtonX, heroStatsCloseButtonY) + s.closeButton.OnActivated(func() { s.Close() }) + s.panel, err = s.uiManager.NewSprite(d2resource.InventoryCharacterPanel, d2resource.PaletteSky) if err != nil { log.Print(err) @@ -137,17 +148,29 @@ func (s *HeroStatsPanel) IsOpen() bool { // Toggle toggles the visibility of the hero status panel func (s *HeroStatsPanel) Toggle() { - s.isOpen = !s.isOpen + if s.isOpen { + s.Close() + } else { + s.Open() + } } // Open opens the hero status panel func (s *HeroStatsPanel) Open() { s.isOpen = true + s.closeButton.SetVisible(true) } // Close closed the hero status panel func (s *HeroStatsPanel) Close() { s.isOpen = false + s.closeButton.SetVisible(false) + s.onCloseCb() +} + +// Set the callback run on closing the HeroStatsPanel +func (s *HeroStatsPanel) SetOnCloseCb(cb func()) { + s.onCloseCb = cb } // Render renders the hero status panel diff --git a/d2game/d2player/inventory.go b/d2game/d2player/inventory.go index 8155fdea..d2235ff9 100644 --- a/d2game/d2player/inventory.go +++ b/d2game/d2player/inventory.go @@ -26,15 +26,20 @@ const ( blackAlpha70 = 0x000000C8 ) +const ( + invCloseButtonX, invCloseButtonY = 419, 449 +) + // Inventory represents the inventory type Inventory struct { - asset *d2asset.AssetManager - item *diablo2item.ItemFactory - uiManager *d2ui.UIManager - frame *d2ui.UIFrame - panel *d2ui.Sprite - grid *ItemGrid - hoverLabel *d2ui.Label + asset *d2asset.AssetManager + item *diablo2item.ItemFactory + uiManager *d2ui.UIManager + frame *d2ui.UIFrame + panel *d2ui.Sprite + grid *ItemGrid + hoverLabel *d2ui.Label + closeButton *d2ui.Button hoverX int hoverY int originX int @@ -43,6 +48,7 @@ type Inventory struct { lastMouseY int hovering bool isOpen bool + onCloseCb func() } // NewInventory creates an inventory instance and returns a pointer to it @@ -73,23 +79,40 @@ func (g *Inventory) IsOpen() bool { // Toggle negates the open state of the inventory func (g *Inventory) Toggle() { - g.isOpen = !g.isOpen + if g.isOpen { + g.Close() + } else { + g.Open() + } } // Open opens the inventory func (g *Inventory) Open() { g.isOpen = true + g.closeButton.SetVisible(true) } // Close closes the inventory func (g *Inventory) Close() { g.isOpen = false + g.closeButton.SetVisible(false) + g.onCloseCb() +} + +// Set the callback run on closing the inventory +func (g *Inventory) SetOnCloseCb(cb func()) { + g.onCloseCb = cb } // Load the resources required by the inventory func (g *Inventory) Load() { g.frame = d2ui.NewUIFrame(g.asset, g.uiManager, d2ui.FrameRight) + g.closeButton = g.uiManager.NewButton(d2ui.ButtonTypeSquareClose, "") + g.closeButton.SetVisible(false) + g.closeButton.SetPosition(invCloseButtonX, invCloseButtonY) + g.closeButton.OnActivated(func() { g.Close() }) + g.panel, _ = g.uiManager.NewSprite(d2resource.InventoryCharacterPanel, d2resource.PaletteSky) // https://github.com/OpenDiablo2/OpenDiablo2/issues/795 diff --git a/d2game/d2player/skilltree.go b/d2game/d2player/skilltree.go index f19b1919..772bf1e4 100644 --- a/d2game/d2player/skilltree.go +++ b/d2game/d2player/skilltree.go @@ -27,6 +27,11 @@ const ( skillIconYOff = 59 skillIconDistX = 69 skillIconDistY = 68 + + skillCloseButtonXLeft = 416 + skillCloseButtonXMiddle = 501 + skillCloseButtonXRight = 572 + skillCloseButtonY = 449 ) const ( @@ -62,8 +67,9 @@ const ( ) type skillTreeTab struct { - buttonText string - button *d2ui.Button + buttonText string + button *d2ui.Button + closeButtonPosX int } func (st *skillTreeTab) createButton(uiManager *d2ui.UIManager, x, y int) { @@ -90,11 +96,13 @@ type skillTree struct { heroClass d2enum.Hero frame *d2ui.UIFrame availSPLabel *d2ui.Label + closeButton *d2ui.Button tab [3]*skillTreeTab isOpen bool originX int originY int selectedTab int + onCloseCb func() } func newSkillTree( @@ -126,6 +134,9 @@ func newSkillTree( func (s *skillTree) load() { s.frame = d2ui.NewUIFrame(s.asset, s.uiManager, d2ui.FrameRight) + s.closeButton = s.uiManager.NewButton(d2ui.ButtonTypeSquareClose, "") + s.closeButton.SetVisible(false) + s.closeButton.OnActivated(func() { s.Close() }) s.setHeroTypeResourcePath() s.loadForHeroType() @@ -165,6 +176,7 @@ func (s *skillTree) loadForHeroType() { type heroTabData struct { resources *skillTreeHeroTypeResources str1, str2, str3 string + closeButtonPos [3]int } func makeTabString(keys ...interface{}) string { @@ -184,6 +196,10 @@ func makeTabString(keys ...interface{}) string { return fmt.Sprintf(format, translations...) } +func makeCloseButtonPos(close1 int , close2 int, close3 int) [3]int { + return [3]int{ close1, close2, close3 } +} + func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { tabMap := map[d2enum.Hero]heroTabData{ d2enum.HeroBarbarian: { @@ -194,6 +210,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree21", "StrSklTree4"), makeTabString("StrSklTree21", "StrSklTree22"), makeTabString("StrSklTree20"), + makeCloseButtonPos( + skillCloseButtonXRight, + skillCloseButtonXLeft, + skillCloseButtonXRight), }, d2enum.HeroNecromancer: { &skillTreeHeroTypeResources{ @@ -203,6 +223,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree19"), makeTabString("StrSklTree17", "StrSklTree18", "StrSklTree5"), makeTabString("StrSklTree16", "StrSklTree5"), + makeCloseButtonPos( + skillCloseButtonXLeft, + skillCloseButtonXRight, + skillCloseButtonXLeft), }, d2enum.HeroPaladin: { &skillTreeHeroTypeResources{ @@ -212,6 +236,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree15", "StrSklTree4"), makeTabString("StrSklTree14", "StrSklTree13"), makeTabString("StrSklTree12", "StrSklTree13"), + makeCloseButtonPos( + skillCloseButtonXLeft, + skillCloseButtonXMiddle, + skillCloseButtonXLeft), }, d2enum.HeroAssassin: { @@ -223,6 +251,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree30"), makeTabString("StrSklTree31", "StrSklTree32"), makeTabString("StrSklTree33", "StrSklTree34"), + makeCloseButtonPos( + skillCloseButtonXMiddle, + skillCloseButtonXRight, + skillCloseButtonXLeft), }, d2enum.HeroSorceress: { &skillTreeHeroTypeResources{ @@ -232,6 +264,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree25", "StrSklTree5"), makeTabString("StrSklTree24", "StrSklTree5"), makeTabString("StrSklTree23", "StrSklTree5"), + makeCloseButtonPos( + skillCloseButtonXLeft, + skillCloseButtonXLeft, + skillCloseButtonXRight), }, d2enum.HeroAmazon: { @@ -242,6 +278,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree10", "StrSklTree11", "StrSklTree4"), makeTabString("StrSklTree8", "StrSklTree9", "StrSklTree4"), makeTabString("StrSklTree6", "StrSklTree7", "StrSklTree4"), + makeCloseButtonPos( + skillCloseButtonXRight, + skillCloseButtonXMiddle, + skillCloseButtonXLeft), }, d2enum.HeroDruid: { @@ -252,6 +292,10 @@ func (s *skillTree) getTab(class d2enum.Hero) (heroTabData, bool) { makeTabString("StrSklTree26"), makeTabString("StrSklTree27", "StrSklTree28"), makeTabString("StrSklTree29"), + makeCloseButtonPos( + skillCloseButtonXRight, + skillCloseButtonXRight, + skillCloseButtonXRight), }, } @@ -268,8 +312,12 @@ func (s *skillTree) setHeroTypeResourcePath() { s.resources = entry.resources s.tab[firstTab].buttonText = entry.str1 - s.tab[secondTab].buttonText = entry.str1 - s.tab[thirdTab].buttonText = entry.str1 + s.tab[secondTab].buttonText = entry.str2 + s.tab[thirdTab].buttonText = entry.str3 + + for i:= 0; i < 3; i++ { + s.tab[i].closeButtonPosX = entry.closeButtonPos[i] + } } // Toggle the skill tree visibility @@ -287,10 +335,11 @@ func (s *skillTree) Toggle() { func (s *skillTree) Close() { s.isOpen = false s.guiManager.SetLayout(nil) - + s.closeButton.SetVisible(false) for i := 0; i < 3; i++ { s.tab[i].button.SetVisible(false) } + s.onCloseCb() } // Open the skill tree @@ -300,6 +349,7 @@ func (s *skillTree) Open() { s.layout = d2gui.CreateLayout(s.renderer, d2gui.PositionTypeHorizontal, s.asset) } + s.closeButton.SetVisible(true) for i := 0; i < 3; i++ { s.tab[i].button.SetVisible(true) } @@ -311,8 +361,15 @@ func (s *skillTree) IsOpen() bool { return s.isOpen } +// Set the callback run on closing the skilltree +func (s *skillTree) SetOnCloseCb(cb func()) { + s.onCloseCb = cb +} + + func (s *skillTree) setTab(tab int) { s.selectedTab = tab + s.closeButton.SetPosition(s.tab[tab].closeButtonPosX, skillCloseButtonY) } func (s *skillTree) renderPanelSegment(