126 lines
4.4 KiB
Lua
126 lines
4.4 KiB
Lua
local bounding_box = require("__flib__.bounding-box")
|
|
local gui = require("__flib__.gui")
|
|
local math = require("__flib__.math")
|
|
local table = require("__flib__.table")
|
|
|
|
local constants = require("constants")
|
|
|
|
local database = require("scripts.database")
|
|
local formatter = require("scripts.formatter")
|
|
|
|
local gui_util = {}
|
|
|
|
-- The calling GUI will navigate to the context that is returned, if any
|
|
-- Actions that do not open a page will not return a context
|
|
function gui_util.navigate_to(e)
|
|
local tags = gui.get_tags(e.element)
|
|
local context = tags.context
|
|
|
|
local modifiers = {}
|
|
for name, modifier in pairs({ control = e.control, shift = e.shift, alt = e.alt }) do
|
|
if modifier then
|
|
modifiers[#modifiers + 1] = name
|
|
end
|
|
end
|
|
|
|
for _, interaction in pairs(constants.interactions[context.class]) do
|
|
if table.deep_compare(interaction.modifiers, modifiers) then
|
|
local action = interaction.action
|
|
local context_data = database[context.class][context.name]
|
|
local player = game.get_player(e.player_index) --[[@as LuaPlayer]]
|
|
|
|
if action == "view_details" then
|
|
return context
|
|
elseif action == "view_product_details" and #context_data.products == 1 then
|
|
return context_data.products[1]
|
|
elseif action == "get_blueprint" then
|
|
local blueprint_result = tags.blueprint_result
|
|
if blueprint_result then
|
|
local cursor_stack = player.cursor_stack
|
|
player.clear_cursor()
|
|
if cursor_stack and cursor_stack.valid then
|
|
local collision_box = game.entity_prototypes[blueprint_result.name].collision_box
|
|
local height = bounding_box.height(collision_box)
|
|
local width = bounding_box.width(collision_box)
|
|
cursor_stack.set_stack({ name = "blueprint", count = 1 })
|
|
cursor_stack.set_blueprint_entities({
|
|
{
|
|
entity_number = 1,
|
|
name = blueprint_result.name,
|
|
position = {
|
|
-- Entities with an even number of tiles to a side need to be set at -0.5 instead of 0
|
|
math.ceil(width) % 2 == 0 and -0.5 or 0,
|
|
math.ceil(height) % 2 == 0 and -0.5 or 0,
|
|
},
|
|
recipe = blueprint_result.recipe,
|
|
},
|
|
})
|
|
player.add_to_clipboard(cursor_stack)
|
|
player.activate_paste()
|
|
end
|
|
else
|
|
player.create_local_flying_text({
|
|
text = { "message.rb-cannot-create-blueprint" },
|
|
create_at_cursor = true,
|
|
})
|
|
player.play_sound({ path = "utility/cannot_build" })
|
|
end
|
|
elseif action == "open_in_technology_window" then
|
|
local player_table = global.players[e.player_index]
|
|
player_table.flags.technology_gui_open = true
|
|
player.open_technology_gui(context.name)
|
|
elseif action == "view_source" then
|
|
local source = context_data[interaction.source]
|
|
if source then
|
|
return source
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function gui_util.update_list_box(pane, source_tbl, player_data, iterator, options)
|
|
local i = 0
|
|
local children = pane.children
|
|
local add = pane.add
|
|
for _, obj_ident in iterator(source_tbl) do
|
|
local obj_data = database[obj_ident.class][obj_ident.name]
|
|
local info = formatter(obj_data, player_data, options)
|
|
if info then
|
|
i = i + 1
|
|
local style = info.researched and "rb_list_box_item" or "rb_unresearched_list_box_item"
|
|
local item = children[i]
|
|
if item then
|
|
item.style = style
|
|
item.caption = info.caption
|
|
item.tooltip = info.tooltip
|
|
item.enabled = info.num_interactions > 0
|
|
gui.update_tags(item, { context = { class = obj_ident.class, name = obj_ident.name } })
|
|
else
|
|
add({
|
|
type = "button",
|
|
style = style,
|
|
caption = info.caption,
|
|
tooltip = info.tooltip,
|
|
enabled = info.num_interactions > 0,
|
|
mouse_button_filter = { "left", "middle" },
|
|
tags = {
|
|
[script.mod_name] = {
|
|
context = { class = obj_ident.class, name = obj_ident.name },
|
|
flib = {
|
|
on_click = { gui = "search", action = "open_object" },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
end
|
|
end
|
|
end
|
|
-- Destroy extraneous items
|
|
for j = i + 1, #children do
|
|
children[j].destroy()
|
|
end
|
|
end
|
|
|
|
return gui_util
|