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.
 

bc1

Joined
Jan 12, 2004
Messages
1,281
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
 

Pazyryk

Deity
Joined
Jun 13, 2008
Messages
3,584
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.
 

Pazyryk

Deity
Joined
Jun 13, 2008
Messages
3,584
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