The log doesn't show anything.
I've added the "mod" I was using to test this out.
To reproduce:
- Click the "1" button in the top UI to spawn the tabbed list
- Save the game
- Reload the game
- Click on any of the tabs
Edit: Adding source from control.lua here.
Code: Select all
GUI = {}
GUI.TabFunc =
function(caption)
return function(frame)
frame.add{type="label", caption=caption}
end
end
GUI.TabData =
{
name = "Tabbed_Frame",
active = "Option_2",
navButtons =
{
{
name="Option_1",
caption="Option 1"
},
{
name="Option_2",
caption="Really Long Name"
},
{
name="Option_3",
caption="Op3"
}
},
tabs =
{
Option_1 = GUI.TabFunc("This is Option 1's tab"),
Option_2 = GUI.TabFunc("This is Option 2's tab"),
Option_3 = GUI.TabFunc("This is Option 3's tab")
}
--player = game.players[event.player_index]
--parent = game.players[1].gui.top
}
script.on_event(defines.events.on_player_joined_game, function (event)
local player = game.players[event.player_index]
if not player.gui.top["Test"] then
local test = player.gui.top.add{type="flow", name="Test", direction="horizontal"}
test.add{type="button", name="Test1", caption="1"}
test.add{type="button", name="Test2", caption="2"}
GUI.Events.Add("Test1", GUI.Events.CreateTab)
GUI.Events.Add("Test2", GUI.Events.DestroyTab)
end
end)
GUI.Events = {}
GUI.Events.DestroyTab = function(event)
GUI.TabData.player = game.players[event.player_index]
Utils.TabLib.Destroy(GUI.TabData)
end
GUI.Events.CreateTab = function (event)
GUI.TabData.player = game.players[event.player_index]
Utils.TabLib.Create(GUI.TabData)
end
--Add a new GUI clicked event to the GUI event
-- @param name name of the element
-- @param func function to be called for it
GUI.Events.Add = function(name, func)
global.GuiEvents = global.GuiEvents or {} --[name] = callback_function
global.GuiEvents[name] = func
--GUI.Events.Register()
end
--Remove a GUI clicked event from the GUI event
-- @param name name of the element
-- @param func function to be called for it
GUI.Events.Remove = function(name, func)
--TODO
--GUI.Events.Register()
end
script.on_event(defines.events.on_gui_click, function(event)
game.players[1].print("Clicked"..event.element.name) --DEBUG
local element = event.element
for name, func in pairs(global.GuiEvents) do
if name == element.name then
global.GuiEvents[name](event)
return nil
end
end
end)
----------------------------- UTILS ----------------------------------
Utils = {}
Utils.TabLib = {}
Utils.TabLib.Create = function(d)
global.TabLibData = global.TabLibData or {} -- TODO on_init
local data = Utils.TabLib.VerifyData(d)
if data then
if not Utils.TabLib.Verify(data) then
Utils.TabLib.Draw(data)
Utils.TabLib.RegisterEvents(data)
end
end
end
Utils.TabLib.Switch = function(d)
local data = Utils.TabLib.VerifyData(d)
if data then
if Utils.TabLib.Verify(data) then
Utils.TabLib.Destroy(data)
Utils.TabLib.Draw(data)
end
end
end
Utils.TabLib.Destroy = function(d)
local data = Utils.TabLib.VerifyData(d)
if data then
game.players[1].print("Destroying name: "..data.name) --DEBUG
if Utils.TabLib.Verify(data) then
data.parent[data.name].destroy()
global.TabLibData[data.name][data.player.name] = nil
game.players[1].print("Parent name: "..data.parent.name) --DEBUG
end
end
end
Utils.TabLib.Draw = function(data)
local mainFrame = data.parent.add{type="frame", name=data.name, direction="vertical"}
local navFlow = mainFrame.add{type="flow", name=data.name.."_nav", direction="horizontal"}
for _, navButton in pairs(data.navButtons) do
if data.active == navButton.name then
navFlow.add{type="label", name=navButton.name, caption=navButton.caption, style="Proxy_Wars_tab_nav_active"}
else
navFlow.add{type="button", name=navButton.name, caption=navButton.caption, style="Proxy_Wars_tab_nav_inactive"}
end
end
local tabFrame = mainFrame.add{type="frame", name=data.name.."_tab_frame", direction="vertical"}
data.tabs[data.active](tabFrame)
global.TabLibData[data.name] = global.TabLibData[data.name] or {}
global.TabLibData[data.name][data.player.name] = data
end
Utils.TabLib.RegisterEvents = function(data)
local navButtons = data.navButtons
local func = function(event)
local element = event.element
--local elementName = element.name
--local navFlow = element.parent
--Only if a different tab was selected
if string.find(element.style.name, "inactive") then
data.active = element.name
Utils.TabLib.Switch(data)
end
end
for _, navButton in pairs(navButtons) do
GUI.Events.Add(navButton.name, Utils.TabLib.OnGuiEvent)
end
end
Utils.TabLib.OnGuiEvent = function(event)
local element = event.element
local player = game.players[event.player_index]
--Only if a different tab was selected
if string.find(element.style.name, "inactive") then
local data = global.TabLibData[element.parent.parent.name][player.name]
data.active = element.name
Utils.TabLib.Switch(data)
end
end
Utils.TabLib.Verify = function(data)
if data.parent[data.name] then
return true
end
return false
end
Utils.TabLib.VerifyData = function(d)
local data = deepcopy(d)
if data and data.name and data.navButtons and data.tabs then
--Either player or parent is required
--Make sure we have somewhere to draw the tab
if data.parent then
if not data.parent.valid then return nil end
if not data.player then
data.player = data.parent.player
end
else
if not data.player then return nil end
data.parent = data.player.gui.center
end
--Verify that each nav button has a tab
for _, navButton in pairs(data.navButtons) do
if navButton.name and navButton.caption then
if not data.tabs[navButton.name] then return nil end
if type(data.tabs[navButton.name]) ~= "function" then return nil end
else
return nil
end
end
--Verify the active tab or set it
if not data.active then
data.active = navButtons[1].name
end
game.players[1].print("Valid data"..game.tick) --DEBUG
return data
end
return nil
end
--From base game's util
function deepcopy(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
-- don't copy factorio rich objects
elseif object.__self then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end