I wanted to override how the DButtons are setup in the DMenuBarand thought I could add a PANEL:OnChildAdded(panel) to the menubar and modify it there. I was getting odd errors about methods not existing when I knew for a fact they should have and realized the engine was calling PANEL:OnChildAdded(panel) before Lua applied the metatable and called PANEL:Prepare() which is done in lua\includes\extensions\client\panel\scriptedpanels.lua. I discovered that the panel reference I had was the one I indeed wanted by calling timer.Simple(...) and printing it a second time which revealed it was the DButton I thought it was from the start.
I assume that PANEL:OnChildAdded(panel) is being called from the engine to make sure PANEL:SetParent(parent) calls work since that seems to not be overwritten in Lua but the engine sets the parent early when creating the C base class Label since vgui.Create(...) recursively creates each base until it hits the engine VGUI class.
Steps to reproduce
tl;dr(List of steps at bottom), Execute this script and let the game run the timers. You'll see the label change to red:
-- OnChildAdded issue
-- Frame to hold hook
local frame = vgui.Create('DFrame')
-- Cleanup
timer.Simple(10, function()
if IsValid(frame) then frame:Remove() end
end)
-- Frame setup
frame:SetSize(400, 300)
frame:Center()
function frame:OnChildAdded(panel)
-- Timer for proof later
timer.Simple(5, function()
if IsValid(panel) then
print('timer.Simple - DLabel added to DFrame: ', panel)
panel:SetTextColor(Color(255, 0, 0, 255))
end
end)
-- Print VGUI Label
print('OnChildAdded - DLabel added to DFrame: ', panel)
-- Call DLabel method
-- Will explode since the metatable isn't setup yet
panel:SetTextColor(Color(255, 0, 0, 255))
end
-- Victim DLabel
local label = vgui.Create('DLabel', frame)
label:Dock(FILL)
label:SetContentAlignment(5)
-- Lets go
frame:MakePopup()
Actual steps if needed:
Grab script from above
Execute in console
Hook error should have already triggered
Close console and let the timers run
After 5 seconds the same method is called on the upvalue reference from the hook and the DLabel changes to red (you will also see the references printed in the console)After 10 seconds the frame is removed
GMod Version: 2016.07.06
Details
I wanted to override how the
DButtons
are setup in theDMenuBar
and thought I could add aPANEL:OnChildAdded(panel)
to the menubar and modify it there. I was getting odd errors about methods not existing when I knew for a fact they should have and realized the engine was callingPANEL:OnChildAdded(panel)
before Lua applied the metatable and calledPANEL:Prepare()
which is done inlua\includes\extensions\client\panel\scriptedpanels.lua
. I discovered that the panel reference I had was the one I indeed wanted by callingtimer.Simple(...)
and printing it a second time which revealed it was the DButton I thought it was from the start.I assume that
PANEL:OnChildAdded(panel)
is being called from the engine to make surePANEL:SetParent(parent)
calls work since that seems to not be overwritten in Lua but the engine sets the parent early when creating the C base classLabel
sincevgui.Create(...)
recursively creates each base until it hits the engine VGUI class.Steps to reproduce
tl;dr (List of steps at bottom), Execute this script and let the game run the timers. You'll see the label change to red:
Actual steps if needed: