How can I trigger on UI opening, without modding the UI file?

Pazyryk

Deity
Joined
Jun 13, 2008
Messages
3,584
To be specific, I need to run some Lua whenever a player opens the in-game menu (the one you get when you press esc or the MENU link in top panel). And I want to do it without modding GameMenu.lua itself.

Does anyone know how to do this? I think I'm supposed to be able to do this with ContextPtr, but I'm not very clear how to do that from outside a Lua state.

(I could do it by intercepting ESC and modding top panel, but I'd prefer a cleaner solution.)


Edit: well, I'm playing with LookUpControl but can't seem to get it for GameMenu. It's certainly loaded because I'm in Fire Tuner.

> print(ContextPtr:LookUpControl("/InGame/WorldView/MiniMapPanel"))
EaMain: LuaContext: 1A4849A0
> print(ContextPtr:LookUpControl("/InGame/Menus/GameMenu"))
EaMain: nil

Even if I get that working, I'm not sure what to do with it. I could SetShowHideHandler(MyFunction), but then I will have removed its own OnShowHide function.



Edit2: Darn, I thought the menu might be a kind of popup. But it isn't. Added this in Fire Tuner and it prints for other popups like social policies, but not the Game Menu:
Code:
Events.SerialEventGameMessagePopup.Add(function(popupInfo) print(popupInfo.Type) end)


Edit3: OK, I got a context pointer:

> ContextPtr:LookUpControl("/InGame/GameMenu")
LuaContext: 1A2F26A0

I'm not sure what to do with it though...


Edit4: I got it!

ContextPtr:LookUpControl("/InGame/GameMenu"):SetShowHideHandler(function(isHide, isInit) print(isHide, isInit) end)

Prints false nil whenever I enter the menu.
 
There is only one ShowHideHandler for each context, if you change it the GameMenu's original handler will no longer work.
Workaround idea (untested): attach your own Lua Context to GameMenu using LookUpControl("/InGame/GameMenu"):LoadNewContext( path ), and do what you want with that context (which should show / hide in synch with its parent GameMenu context)

Cheers
 
Yeah, you're right.

I'm not too happy about attaching the code I'm working with. I guess I could attach some little piece of code that sends a LuaEvents back to my function.

I don't suppose there is any way to GetShowHideHandler? If I could do that then I could wrap up the original function in my own. (Or get the registered callback on a button. That would get me even closer to what I want...)

To be more specific, what I really want to do is hook on the Save Game button. I don't want to block it. I just want to run a function when it is pressed. On the other hand, I wonder if it would be possible to a) "steal" the button by registering to it; and b) do what the button was supposed to do anyway.

...actually that looks very doable. The function registered to that button only has a single line of code that I can easily duplicate even from another state. OK... I think I've got something now.
 
I never quite figured out how to do this (as posted in the thread title) although I found some workarounds for my specific needs.

It's easy to intercept a UI's ShowHideHandler:
Code:
ContextPtr:LookUpControl("/InGame/GameMenu"):SetShowHideHandler(MyFunction)
...or a button's function in a UI:
Code:
ContextPtr:LookUpControl("/InGame/GameMenu/SaveGameButton"):RegisterCallback(Mouse.eLClick, MyFunction)
The problem with those is that they replace the original functions. I wish there were a way to hook to them instead, but maybe there isn't... (Could be done if there were GetShowHideHandler and GetRegisteredCallback methods, but these don't exist.)
 
Top Bottom