134 lines
5.0 KiB
Lua
134 lines
5.0 KiB
Lua
|
--- Gui module
|
||
|
-- @module Gui
|
||
|
|
||
|
require 'stdlib/event/event'
|
||
|
|
||
|
Gui = {}
|
||
|
-- Factorio's gui events are so monolithic we need a special event system for it.
|
||
|
Gui.Event = {
|
||
|
_registry = {},
|
||
|
_dispatch = {}
|
||
|
}
|
||
|
|
||
|
--- Registers a function for a given event and matching gui element pattern
|
||
|
-- @param event Valid values are defines.event.on_gui_*
|
||
|
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||
|
-- @param handler Function to call when event is triggered
|
||
|
-- @return #Gui.Event
|
||
|
function Gui.Event.register(event, gui_element_pattern, handler)
|
||
|
fail_if_missing(event, "missing event name argument")
|
||
|
fail_if_missing(gui_element_pattern, "missing gui name or pattern argument")
|
||
|
|
||
|
if type(gui_element_pattern) ~= "string" then
|
||
|
error("gui_element_pattern argument must be a string")
|
||
|
end
|
||
|
|
||
|
if handler == nil then
|
||
|
Gui.Event.remove(event, gui_element_pattern)
|
||
|
return Gui.Event
|
||
|
end
|
||
|
|
||
|
if not Gui.Event._registry[event] then
|
||
|
Gui.Event._registry[event] = {}
|
||
|
end
|
||
|
Gui.Event._registry[event][gui_element_pattern] = handler
|
||
|
|
||
|
-- Use custom Gui event dispatcher to pass off the event to the correct sub-handler
|
||
|
if not Gui.Event._dispatch[event] then
|
||
|
Event.register(event, Gui.Event.dispatch)
|
||
|
Gui.Event._dispatch[event] = true
|
||
|
end
|
||
|
|
||
|
return Gui.Event
|
||
|
end
|
||
|
|
||
|
--- Calls the registered handlers
|
||
|
-- @param event LuaEvent as created by game.raise_event
|
||
|
function Gui.Event.dispatch(event)
|
||
|
fail_if_missing(event, "missing event argument")
|
||
|
|
||
|
local gui_element = event.element
|
||
|
if gui_element and gui_element.valid then
|
||
|
local gui_element_name = gui_element.name;
|
||
|
local gui_element_state = nil;
|
||
|
local gui_element_text = nil;
|
||
|
|
||
|
if event.name == defines.events.on_gui_checked_state_changed then
|
||
|
gui_element_state = gui_element.state
|
||
|
end
|
||
|
|
||
|
if event.name == defines.events.on_gui_text_changed then
|
||
|
gui_element_text = gui_element.text
|
||
|
end
|
||
|
|
||
|
for gui_element_pattern, handler in pairs(Gui.Event._registry[event.name]) do
|
||
|
local match_str = string.match(gui_element_name, gui_element_pattern)
|
||
|
if match_str ~= nil then
|
||
|
local new_event = { tick = event.tick, name = event.name, _handler = handler, match = match_str, element = gui_element, state=gui_element_state, text=gui_element_text, player_index = event.player_index , _event = event}
|
||
|
local success, err = pcall(handler, new_event)
|
||
|
if not success then
|
||
|
Game.print_all(err)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- Removes the handler with matching gui element pattern from the event
|
||
|
-- @param event Valid values are defines.event.on_gui_*
|
||
|
-- @param gui_element_pattern the name or string regular expression to remove the handler for
|
||
|
-- @return #Gui.Event
|
||
|
function Gui.Event.remove(event, gui_element_pattern)
|
||
|
fail_if_missing(event, "missing event argument")
|
||
|
fail_if_missing(gui_element_pattern, "missing gui_element_pattern argument")
|
||
|
|
||
|
if type(gui_element_pattern) ~= "string" then
|
||
|
error("gui_element_pattern argument must be a string")
|
||
|
end
|
||
|
|
||
|
local function tablelength(T)
|
||
|
local count = 0
|
||
|
for _ in pairs(T) do count = count + 1 end
|
||
|
return count
|
||
|
end
|
||
|
|
||
|
if Gui.Event._registry[event] then
|
||
|
if Gui.Event._registry[event][gui_element_pattern] then
|
||
|
Gui.Event._registry[event][gui_element_pattern] = nil
|
||
|
end
|
||
|
if tablelength(Gui.Event._registry[event]) == 0 then
|
||
|
Event.remove(event, Gui.Event.dispatch)
|
||
|
Gui.Event._registry[event] = nil
|
||
|
Gui.Event._dispatch[event] = false
|
||
|
end
|
||
|
end
|
||
|
return Gui.Event
|
||
|
end
|
||
|
|
||
|
--- Registers a function for a given gui element name or pattern when the element is clicked
|
||
|
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||
|
-- @param handler Function to call when gui element is clicked
|
||
|
-- @return #Gui
|
||
|
function Gui.on_click(gui_element_pattern, handler)
|
||
|
Gui.Event.register(defines.events.on_gui_click, gui_element_pattern, handler)
|
||
|
return Gui
|
||
|
end
|
||
|
|
||
|
--- Registers a function for a given gui element name or pattern when the element checked state changes
|
||
|
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||
|
-- @param handler Function to call when gui element checked state changes
|
||
|
-- @return #Gui
|
||
|
function Gui.on_checked_state_changed(gui_element_pattern, handler)
|
||
|
Gui.Event.register(defines.events.on_gui_checked_state_changed, gui_element_pattern, handler)
|
||
|
return Gui
|
||
|
end
|
||
|
|
||
|
--- Registers a function for a given gui element name or pattern when the element text changes
|
||
|
-- @param gui_element_pattern the name or string regular expression to match the gui element
|
||
|
-- @param handler Function to call when gui element text changes
|
||
|
-- @return #Gui
|
||
|
function Gui.on_text_changed(gui_element_pattern, handler)
|
||
|
Gui.Event.register(defines.events.on_gui_text_changed, gui_element_pattern, handler)
|
||
|
return Gui
|
||
|
end
|