170 lines
6.4 KiB
Lua
170 lines
6.4 KiB
Lua
local mod_gui = require("mod-gui")
|
|
|
|
local _gui = { switch = {}, mod = {} }
|
|
|
|
-- Adds an on/off-switch including a label with tooltip to the given flow
|
|
-- Automatically converts boolean state to the appropriate switch_state
|
|
---@param parent_flow LuaGuiElement
|
|
---@param action string
|
|
---@param additional_tags Tags
|
|
---@param state SwitchState
|
|
---@param caption LocalisedString?
|
|
---@param tooltip LocalisedString?
|
|
---@param label_first boolean?
|
|
---@return LuaGuiElement created_switch
|
|
function _gui.switch.add_on_off(parent_flow, action, additional_tags, state, caption, tooltip, label_first)
|
|
if type(state) == "boolean" then state = util.gui.switch.convert_to_state(state) end
|
|
|
|
local flow = parent_flow.add{type="flow", direction="horizontal"}
|
|
flow.style.vertical_align = "center"
|
|
local switch, label ---@type LuaGuiElement, LuaGuiElement
|
|
|
|
local function add_switch()
|
|
additional_tags.mod = "fp"; additional_tags.on_gui_switch_state_changed = action
|
|
switch = flow.add{type="switch", tags=additional_tags, switch_state=state,
|
|
left_label_caption={"fp.on"}, right_label_caption={"fp.off"}}
|
|
end
|
|
|
|
local function add_label()
|
|
caption = (tooltip ~= nil) and {"", caption, " [img=info]"} or caption
|
|
label = flow.add{type="label", caption=caption, tooltip=tooltip}
|
|
label.style.font = "default-semibold"
|
|
end
|
|
|
|
if label_first then add_label(); add_switch(); label.style.right_margin = 8
|
|
else add_switch(); add_label(); label.style.left_margin = 8 end
|
|
|
|
return switch
|
|
end
|
|
|
|
---@param state SwitchState
|
|
---@return boolean converted_state
|
|
function _gui.switch.convert_to_boolean(state)
|
|
return (state == "left") and true or false
|
|
end
|
|
|
|
---@param boolean boolean
|
|
---@return SwitchState converted_state
|
|
function _gui.switch.convert_to_state(boolean)
|
|
return boolean and "left" or "right"
|
|
end
|
|
|
|
|
|
-- Destroys the toggle-main-dialog-button if present
|
|
---@param player LuaPlayer
|
|
local function destroy_mod_gui(player)
|
|
local button_flow = mod_gui.get_button_flow(player)
|
|
local mod_gui_button = button_flow["fp_button_toggle_interface"]
|
|
|
|
if mod_gui_button then
|
|
-- parent.parent is to check that I'm not deleting a top level element. Now, I have no idea how that
|
|
-- could ever be a top level element, but oh well, can't know everything now can we?
|
|
if #button_flow.children_names == 1 and button_flow.parent.parent then
|
|
-- Remove whole frame if FP is the last button in there
|
|
button_flow.parent.destroy()
|
|
else
|
|
mod_gui_button.destroy()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Toggles the visibility of the toggle-main-dialog-button
|
|
---@param player LuaPlayer
|
|
function _gui.toggle_mod_gui(player)
|
|
local enable = util.globals.settings(player).show_gui_button
|
|
|
|
local frame_flow = mod_gui.get_button_flow(player)
|
|
local mod_gui_button = frame_flow["fp_button_toggle_interface"]
|
|
|
|
if enable and not mod_gui_button then
|
|
local tooltip = {"", {"shortcut-name.fp_open_interface"}, " (", {"fp.toggle_interface"}, ")"}
|
|
local button = frame_flow.add{type="sprite-button", name="fp_button_toggle_interface",
|
|
sprite="fp_mod_gui", tooltip=tooltip, tags={mod="fp", on_gui_click="mod_gui_toggle_interface"},
|
|
style=mod_gui.button_style, mouse_button_filter={"left"}}
|
|
button.style.padding = 6
|
|
elseif mod_gui_button then -- use the destroy function for possible cleanup reasons
|
|
destroy_mod_gui(player)
|
|
end
|
|
end
|
|
|
|
|
|
-- Properly centers the given frame (need width/height parameters cause no API-read exists)
|
|
---@param player LuaPlayer
|
|
---@param frame LuaGuiElement
|
|
---@param dimensions DisplayResolution
|
|
function _gui.properly_center_frame(player, frame, dimensions)
|
|
local resolution, scale = player.display_resolution, player.display_scale
|
|
local x_offset = ((resolution.width - (dimensions.width * scale)) / 2)
|
|
local y_offset = ((resolution.height - (dimensions.height * scale)) / 2)
|
|
frame.location = {x_offset, y_offset}
|
|
end
|
|
|
|
---@param textfield LuaGuiElement
|
|
function _gui.setup_textfield(textfield)
|
|
textfield.lose_focus_on_confirm = true
|
|
textfield.clear_and_focus_on_right_click = true
|
|
end
|
|
|
|
---@param textfield LuaGuiElement
|
|
---@param decimal boolean
|
|
---@param negative boolean
|
|
function _gui.setup_numeric_textfield(textfield, decimal, negative)
|
|
textfield.lose_focus_on_confirm = true
|
|
textfield.clear_and_focus_on_right_click = true
|
|
textfield.numeric = true
|
|
textfield.allow_decimal = (decimal or false)
|
|
textfield.allow_negative = (negative or false)
|
|
end
|
|
|
|
---@param textfield LuaGuiElement
|
|
function _gui.select_all(textfield)
|
|
textfield.focus()
|
|
textfield.select_all()
|
|
end
|
|
|
|
-- Destroys all GUIs so they are loaded anew the next time they are shown
|
|
---@param player LuaPlayer
|
|
function _gui.reset_player(player)
|
|
destroy_mod_gui(player) -- mod_gui button
|
|
|
|
for _, gui_element in pairs(player.gui.screen.children) do -- all mod frames
|
|
if gui_element.valid and gui_element.get_mod() == "factoryplanner" then
|
|
gui_element.destroy()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Formats the given effects for use in a tooltip
|
|
---@param effects ModuleEffects
|
|
---@param limit_effects boolean
|
|
---@return LocalisedString
|
|
function _gui.format_module_effects(effects, limit_effects)
|
|
local tooltip_lines, effect_applies = {"", "\n"}, false
|
|
local lower_bound, upper_bound = MAGIC_NUMBERS.effects_lower_bound, MAGIC_NUMBERS.effects_upper_bound
|
|
|
|
for effect_name, effect_value in pairs(effects) do
|
|
if effect_value ~= 0 then
|
|
effect_applies = true
|
|
local capped_indication = "" ---@type LocalisedString
|
|
|
|
if limit_effects then
|
|
if effect_name == "productivity" and effect_value < 0 then
|
|
effect_value, capped_indication = 0, {"fp.effect_maxed"}
|
|
elseif effect_value < lower_bound then
|
|
effect_value, capped_indication = lower_bound, {"fp.effect_maxed"}
|
|
elseif effect_value > upper_bound then
|
|
effect_value, capped_indication = upper_bound, {"fp.effect_maxed"}
|
|
end
|
|
end
|
|
|
|
-- Force display of either a '+' or '-', also round the result
|
|
local display_value = ("%+d"):format(math.floor((effect_value * 100) + 0.5))
|
|
table.insert(tooltip_lines, {"fp.effect_line", {"fp." .. effect_name}, display_value, capped_indication})
|
|
end
|
|
end
|
|
|
|
return (effect_applies) and tooltip_lines or ""
|
|
end
|
|
|
|
return _gui
|