WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   ToggleGameMenu() not working after WorldMapFrame:Hide() (https://www.wowinterface.com/forums/showthread.php?t=58228)

LudiusMaximus 09-27-20 04:05 PM

ToggleGameMenu() not working after WorldMapFrame:Hide()
 
I want a button to hide the WorldMapFrame (even during combat).
The only way to do this seems to be WorldMapFrame:Hide(), because all other ways I could think of (HideUIPanel(WorldMapFrame), ToggleWorldMap(), WorldMapFrame:SetDisplayState(1)) are not allowed during combat.

The problem is: after I have hidden the map this way, the ESC key (Toggle Game Menu) is not working any more. I.e. ToggleGameMenu() is called but without any effect. Neither does my character leave combat nor is the game menu shown.

Any idea what is causing this and if there is a way around it?

Here is a minimal working example:

Code:

testButton = CreateFrame("Button", nil, WorldMapFrame, "UIPanelButtonTemplate")
testButton:SetPoint("CENTER", 0, 0)
testButton:SetFrameStrata("FULLSCREEN")
testButton:SetWidth(230)
testButton:SetHeight(80)

testButton:SetText("Click to hide world map!")

testButton:SetScript("OnClick", function()
    if InCombatLockdown() then
      WorldMapFrame:Hide()
    else
      HideUIPanel(WorldMapFrame)
    end
  end)

  • Open the map like you normally do.
  • Click the button while in combat.
  • Try the ESC key afterwards (or whatever key you have assigned to "Toggle Game Menu") and see that it is not working.


If you don't want to seek out a target dummy, you can also simplify the demonstration to get the same effect regardless of whether you are in combat or not.
But be aware that I need to hide the map during combat!

Code:

testButton = CreateFrame("Button", nil, WorldMapFrame, "UIPanelButtonTemplate")
testButton:SetPoint("CENTER", 0, 0)
testButton:SetFrameStrata("FULLSCREEN")
testButton:SetWidth(230)
testButton:SetHeight(80)

testButton:SetText("Click to hide world map!")

testButton:SetScript("OnClick", function()
    WorldMapFrame:Hide()
  end)


Fizzlemizz 09-27-20 04:19 PM

Works fine using WorldMapFrame:Hide() OR HideUIPanel(WorldMapFrame) while in combat and esc. after to open the game menu..

You've made testButton global, not sure what that might be doing.

This is in retail.

LudiusMaximus 09-27-20 04:53 PM

(Regarding the global button variable: you are of course right. I just did not pay that much attention when creating the example.)

But that it works for you is hard to believe. I have just checked again and made sure that all other addons except the minimal working example are disabled.
For both retail and ptr it is as I have described.

I added
Code:

hooksecurefunc("ToggleGameMenu", function(...)
    print("You pressed ESC", ...)
  end)

to my code and recorded this "proof" video:

https://youtu.be/Zz03Ttjjqvc

It also shows that once you have opened and closed the map "regularly" (here clicking the close button), ESC works again as expected, until you WorldMapFrame:Hide() it again with my button.

Fizzlemizz 09-27-20 05:02 PM

You're right, the HideUIPanel didn't work in combat but the game menu did.

Remember, the first Esc. is possibly being chewed clearing the target so you have to press it twice.

LudiusMaximus 09-27-20 05:07 PM

So you are saying that after opening the map and then hiding it with /run WorldMapFrame:Hide(), your ESC key is still working?

(In my video you can see how often I press ESC: "You pressed ESC" being printed to the console.)

Fizzlemizz 09-27-20 05:12 PM

Lua Code:
  1. local testButton = CreateFrame("Button", nil, WorldMapFrame, "UIPanelButtonTemplate")
  2. testButton:SetPoint("CENTER", 0, 0)
  3. testButton:SetFrameStrata("FULLSCREEN")
  4. testButton:SetWidth(230)
  5. testButton:SetHeight(80)
  6.  
  7. testButton:SetText("Click to hide world map!")
  8.  
  9. testButton:SetScript("OnClick", function()
  10.     if InCombatLockdown() then
  11.       WorldMapFrame:Hide()
  12.     else
  13.       HideUIPanel(WorldMapFrame)
  14.     end
  15.   end)

Open the map, enter combat with target dummy, press the button. press esc. twice (first clears the dummy), game menu opens.

LudiusMaximus 09-27-20 05:18 PM

What's going on here?? What class are you trying this with?

In my video I used a DemonHunter, where pressing ESC does neither cancel combat nor open the menu.

When I tried a warlock, pressing ESC did in fact cancel the auto-cast but did not open the menu upon any subsequent ESC presses.

Fizzlemizz 09-27-20 05:25 PM

HD, Mage, Hunter.. all work (happy to try anything else you like).

If esc. doesn't cancel combat/targeting, it sounds like a keybind or other addon problem.

LudiusMaximus 09-27-20 05:33 PM

I had all other addons disabled.

Have you tried it with all other addons disabled?

I just noticed that when I have "Mapster" activated at the same time, the issue is not there.

At least I could now go and see what mapster does to prevent it.

Fizzlemizz 09-27-20 06:35 PM

You are indeed correct. It does seem they've protected the closing for some reason.

Opening the map and pressing escape restores the game menu on escape, so some investigation as to what's going on would be needed.

LudiusMaximus 09-28-20 04:05 AM

OK, good to know that it is at least reproducible. :-)

I think I will break down Mapster to find and then copy whatever it does to prevent this effect from happening.

sezz 09-28-20 04:20 PM

Excuse me for asking, but why do you want an extra button for this?

If you used a keybinding to open the map you can just press it again (or press esc) and if you're a clicker you can just click the close button?

Nevertheless I quickly tested it on beta and securecall("CloseAllWindows") (called by ToggleGameMenu()) still returns the WorldMapFrame after hiding the frame, that's why it stops there and doesnt open the menu.

Just hiding the map frame isn't the same as closing it - open your character frame after hiding the map, it will not be correctly anchored to the left side of the screen, instead it's next to the invisible map and fixing that requires calling secure code which we can't do.

LudiusMaximus 09-28-20 04:33 PM

Quote:

Originally Posted by sezz (Post 336940)
Excuse me for asking, but why do you want an extra button for this?

What I really want to achieve is that the AdventureJournal opens when clicking on a dungeon(-boss) pin on the map during combat while the map closes itself. So I basically want to imitate the standard behaviour of the map during combat although it is "tainted" by my addon.

I am able to do all this, except that ToggleGameMenu() does not work any more afterwards.

LudiusMaximus 09-29-20 06:42 AM

It turns out you can get this to work if you do.

Code:

UIPanelWindows["WorldMapFrame"] = nil
WorldMapFrame:SetAttribute("UIPanelLayout-area", nil)
WorldMapFrame:SetAttribute("UIPanelLayout-enabled", false)
tinsert(UISpecialFrames, "WorldMapFrame")

But then you sacrifice the effect of the map automatically pushing other frames (like CharacterFrame as pointed out by sezz) to the right. Mapster does not mind this as it makes the map frame moveable anyway.

LudiusMaximus 09-29-20 07:01 AM

I think this is the best way to go:

Code:

testButton:SetScript("OnClick", function()
   
    if InCombatLockdown() then
   
      -- If you are using an addon that has removed WorldMapFrame from UIPanelWindows,
      -- we are able to hide WorldMapFrame for you here.
      -- If not, hiding the map will result in ToggleGameMenu() not working any more,
      -- because WorldMapFrame will still be listed in UIParent's FramePositionDelegate.
      if not UIPanelWindows["WorldMapFrame"] then
        WorldMapFrame:Hide()
      end
     
    else
      HideUIPanel(WorldMapFrame)
    end
  end)


sezz 09-29-20 05:11 PM

Quote:

Originally Posted by LudiusMaximus (Post 336941)
What I really want to achieve is that the AdventureJournal opens when clicking on a dungeon(-boss) pin on the map during combat while the map closes itself. So I basically want to imitate the standard behaviour of the map during combat although it is "tainted" by my addon.

I am able to do all this, except that ToggleGameMenu() does not work any more afterwards.

I see, sounds like something that should be in the UI by default :) but ToggleEncounterJournal() doesn't work in combat anymore or did you find a way around it?

LudiusMaximus 09-29-20 05:19 PM

Quote:

Originally Posted by sezz (Post 336952)
I see, sounds like something that should be in the UI by default :) but ToggleEncounterJournal() doesn't work in combat anymore or did you find a way around it?

Yeah, I do it like this now:

Code:

hooksecurefunc(WorldMapFrame, "SetMapID",
  function(self, mapID)
    -- During combat, the OnClick functions of the dungeon/boss pins do not manage
    -- to bring up EncounterJournal and hide WorldMapFrame.
    if WorldMapFrame.ScrollContainer.Child then
      local kids = { WorldMapFrame.ScrollContainer.Child:GetChildren() };
      for _, v in ipairs(kids) do

        if v.pinTemplate and (v.pinTemplate == "EncounterJournalPinTemplate" or v.pinTemplate == "DungeonEntrancePinTemplate") then
       
          local OriginalOnClick = v.OnClick
          v.OnClick = function(...)
            if InCombatLockdown() then

              if not EncounterJournal:IsShown() then
                EncounterJournal:Show()
              end
                           
              -- WorldMapFrame:Hide() will lead to ToggleGameMenu() not working any more
              -- because WorldMapFrame will still be listed in UIParent's FramePositionDelegate.
              -- So we only hide it, if WorldMapFrame is not in UIPanelWindows (e.g. Mapster).
              if WorldMapFrame:IsShown() and not UIPanelWindows["WorldMapFrame"] then
                WorldMapFrame:Hide()
              end
             
            end
           
            OriginalOnClick(...)

          end
        end
      end
    end
  end
)


local startupFrame = CreateFrame("Frame")
startupFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
startupFrame:SetScript("OnEvent", function()

  -- Needed for the boss pins to work in combat lockdown.
  if not IsAddOnLoaded("Blizzard_EncounterJournal") then
    EncounterJournal_LoadUI()
  end

  -- Got to call this once to bring the frames into the right position.
  -- Otherwise it will be misplaced when Show() is the first called function.
  ShowUIPanel(EncounterJournal)
  HideUIPanel(EncounterJournal)
 
  ShowUIPanel(WorldMapFrame)
  HideUIPanel(WorldMapFrame)

  -- Otherwise closing with ESC may not work during combat.
  tinsert(UISpecialFrames, "EncounterJournal")
  tinsert(UISpecialFrames, "WorldMapFrame")

end)



All times are GMT -6. The time now is 03:51 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI