305 lines
8.2 KiB
Lua
305 lines
8.2 KiB
Lua
local math = require("__flib__.math")
|
|
local on_tick_n = require("__flib__.on-tick-n")
|
|
|
|
local constants = require("constants")
|
|
|
|
local database = require("scripts.database")
|
|
local gui_util = require("scripts.gui.util")
|
|
local util = require("scripts.util")
|
|
|
|
local actions = {}
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.set_as_active(Gui, _, _)
|
|
Gui.player_table.guis.info._active_id = Gui.id
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param e on_gui_click
|
|
function actions.reset_location(Gui, _, e)
|
|
if e.button == defines.mouse_button_type.middle then
|
|
Gui.refs.root.force_auto_center()
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.close(Gui, _, _)
|
|
Gui:destroy()
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.bring_to_front(Gui, _, _)
|
|
if not Gui.state.docked then
|
|
Gui.refs.root.bring_to_front()
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.toggle_search(Gui, _, _)
|
|
local state = Gui.state
|
|
local refs = Gui.refs
|
|
|
|
local opened = state.search_opened
|
|
state.search_opened = not opened
|
|
|
|
local search_button = refs.titlebar.search_button
|
|
local search_textfield = refs.titlebar.search_textfield
|
|
if opened then
|
|
search_button.sprite = "utility/search_white"
|
|
search_button.style = "frame_action_button"
|
|
search_textfield.visible = false
|
|
|
|
if state.search_query ~= "" then
|
|
-- Reset query
|
|
search_textfield.text = ""
|
|
state.search_query = ""
|
|
-- Refresh page
|
|
Gui:update_contents()
|
|
end
|
|
else
|
|
-- Show search textfield
|
|
search_button.sprite = "utility/search_black"
|
|
search_button.style = "flib_selected_frame_action_button"
|
|
search_textfield.visible = true
|
|
search_textfield.focus()
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
--- @param e on_gui_click
|
|
function actions.navigate(Gui, msg, e)
|
|
-- Update position in history
|
|
local delta = msg.delta
|
|
local history = Gui.state.history
|
|
if e.shift then
|
|
if delta < 0 then
|
|
history._index = 1
|
|
else
|
|
history._index = #history
|
|
end
|
|
else
|
|
history._index = math.clamp(history._index + delta, 1, #history)
|
|
end
|
|
Gui:update_contents()
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
--- @param e on_gui_text_changed
|
|
function actions.update_search_query(Gui, msg, e)
|
|
local state = Gui.state
|
|
local id = msg.id
|
|
|
|
local query = string.lower(e.element.text)
|
|
-- Fuzzy search
|
|
if Gui.player_table.settings.general.search.fuzzy_search then
|
|
query = string.gsub(query, ".", "%1.*")
|
|
end
|
|
-- Input sanitization
|
|
for pattern, replacement in pairs(constants.input_sanitizers) do
|
|
query = string.gsub(query, pattern, replacement)
|
|
end
|
|
-- Save query
|
|
state.search_query = query
|
|
|
|
-- Remove scheduled update if one exists
|
|
if state.update_results_ident then
|
|
on_tick_n.remove(state.update_results_ident)
|
|
state.update_results_ident = nil
|
|
end
|
|
|
|
if query == "" then
|
|
-- Update now
|
|
Gui:update_contents({ refresh = true })
|
|
else
|
|
-- Update in a while
|
|
state.update_results_ident = on_tick_n.add(
|
|
game.tick + constants.search_timeout,
|
|
{ gui = "info", id = id, action = "update_search_results", player_index = e.player_index }
|
|
)
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.update_search_results(Gui, _, _)
|
|
-- Update based on query
|
|
Gui:update_contents({ refresh = true })
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param e on_gui_click
|
|
function actions.navigate_to(Gui, _, e)
|
|
local context = gui_util.navigate_to(e)
|
|
if context then
|
|
if e.button == defines.mouse_button_type.middle then
|
|
INFO_GUI.build(Gui.player, Gui.player_table, context)
|
|
else
|
|
Gui:update_contents({ new_context = context })
|
|
end
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
function actions.navigate_to_plain(Gui, msg, _)
|
|
Gui:update_contents({ new_context = msg.context })
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.open_in_tech_window(Gui, _, _)
|
|
Gui.player_table.flags.technology_gui_open = true
|
|
Gui.player.open_technology_gui(Gui:get_context().name)
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.go_to_base_fluid(Gui, _, _)
|
|
local base_fluid = database.fluid[Gui:get_context().name].prototype_name
|
|
Gui:update_contents({ new_context = { class = "fluid", name = base_fluid } })
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.toggle_quick_ref(Gui, _, _)
|
|
local player = Gui.player
|
|
-- Toggle quick ref GUI
|
|
local name = Gui:get_context().name
|
|
--- @type QuickRefGui?
|
|
local QuickRefGui = util.get_gui(player.index, "quick_ref", name)
|
|
local to_state = false
|
|
if QuickRefGui then
|
|
QuickRefGui:destroy()
|
|
else
|
|
to_state = true
|
|
QUICK_REF_GUI.build(player, Gui.player_table, name)
|
|
end
|
|
-- Update all quick ref buttons
|
|
for _, InfoGui in pairs(INFO_GUI.find_open_context(Gui.player_table, Gui:get_context())) do
|
|
InfoGui:dispatch({
|
|
action = "update_header_button",
|
|
button = "quick_ref_button",
|
|
to_state = to_state,
|
|
})
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.toggle_favorite(Gui, _, _)
|
|
local player_table = Gui.player_table
|
|
local favorites = player_table.favorites
|
|
local context = Gui:get_context()
|
|
local combined_name = context.class .. "." .. context.name
|
|
local to_state
|
|
if favorites[combined_name] then
|
|
to_state = false
|
|
favorites[combined_name] = nil
|
|
else
|
|
-- Copy the table instead of passing a reference
|
|
favorites[combined_name] = { class = context.class, name = context.name }
|
|
to_state = true
|
|
end
|
|
for _, InfoGui in pairs(INFO_GUI.find_open_context(Gui.player_table, context)) do
|
|
InfoGui:dispatch({ action = "update_header_button", button = "favorite_button", to_state = to_state })
|
|
end
|
|
local SearchGui = util.get_gui(Gui.player.index, "search")
|
|
if SearchGui and SearchGui.refs.window.visible then
|
|
SearchGui:dispatch("update_favorites")
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
function actions.update_header_button(Gui, msg, _)
|
|
local button = Gui.refs.header[msg.button]
|
|
if msg.to_state then
|
|
button.style = "flib_selected_tool_button"
|
|
button.tooltip = constants.header_button_tooltips[msg.button].selected
|
|
else
|
|
button.style = "tool_button"
|
|
button.tooltip = constants.header_button_tooltips[msg.button].unselected
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
function actions.open_list(Gui, msg, _)
|
|
local list_context = msg.context
|
|
local source = msg.source
|
|
local list = database[list_context.class][list_context.name][source]
|
|
if list and #list > 0 then
|
|
local first_obj = list[1]
|
|
OPEN_PAGE(Gui.player, Gui.player_table, {
|
|
class = first_obj.class,
|
|
name = first_obj.name,
|
|
list = {
|
|
context = list_context,
|
|
index = 1,
|
|
source = source,
|
|
},
|
|
})
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
function actions.toggle_collapsed(Gui, msg, _)
|
|
local context = msg.context
|
|
local component_index = msg.component_index
|
|
local component_ident = constants.pages[context.class][component_index]
|
|
if component_ident then
|
|
local state = Gui.state.components[component_index]
|
|
if state then
|
|
state.collapsed = not state.collapsed
|
|
Gui:update_contents({ refresh = true })
|
|
end
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
--- @param msg table
|
|
function actions.change_tech_level(Gui, msg, _)
|
|
local context = Gui:get_context()
|
|
local state = Gui.state
|
|
|
|
local context_data = database[context.class][context.name]
|
|
local min = context_data.min_level
|
|
local max = context_data.max_level
|
|
local new_level = math.clamp(state.selected_tech_level + msg.delta, min, max)
|
|
if new_level ~= state.selected_tech_level then
|
|
state.selected_tech_level = new_level
|
|
Gui:update_contents({ refresh = true })
|
|
end
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.detach_window(Gui, _, _)
|
|
local state = Gui.state
|
|
-- Just in case
|
|
if not state.docked then
|
|
return
|
|
end
|
|
|
|
local context = Gui:get_context()
|
|
|
|
-- Close this GUI and create a detached one
|
|
Gui:destroy()
|
|
OPEN_PAGE(Gui.player, Gui.player_table, context)
|
|
end
|
|
|
|
--- @param Gui InfoGui
|
|
function actions.print_object(Gui, _, _)
|
|
local context = Gui:get_context()
|
|
local obj_data = database[context.class][context.name]
|
|
|
|
if obj_data then
|
|
if __DebugAdapter then
|
|
__DebugAdapter.print(obj_data)
|
|
Gui.player.print("Object data has been printed to the debug console.")
|
|
else
|
|
log(serpent.block(obj_data))
|
|
Gui.player.print("Object data has been printed to the log file.")
|
|
end
|
|
end
|
|
end
|
|
|
|
return actions
|