diff --git a/exp_gui/module/control.lua b/exp_gui/module/control.lua index 761b0ed6..a2491682 100644 --- a/exp_gui/module/control.lua +++ b/exp_gui/module/control.lua @@ -19,7 +19,7 @@ end) --- @class ExpGui local ExpGui = { element = ExpElement.create, - property_from_args = ExpElement.property_from_args, + property_from_arg = ExpElement.property_from_arg, property_from_name = ExpElement.property_from_name, top_elements = {}, --- @type table left_elements = {}, --- @type table diff --git a/exp_gui/module/elements.lua b/exp_gui/module/elements.lua new file mode 100644 index 00000000..e8c0e99e --- /dev/null +++ b/exp_gui/module/elements.lua @@ -0,0 +1,189 @@ +--- @class ExpGui +local ExpGui = require("modules/exp_gui") + +--- @class ExpGui.elements +local elements = {} +ExpGui.elements = elements + +--- A flow which aligns its content as specified +elements.aligned_flow = ExpGui.element("aligned_flow") + :draw{ + type = "flow", + name = ExpGui.property_from_arg("name"), + } + :style(function(def, element, parent, opts) + opts = opts or {} + return { + padding = { 1, 2 }, + vertical_align = opts.vertical_align or "center", + horizontal_align = opts.horizontal_align or "right", + vertically_stretchable = opts.vertical_align and opts.vertical_align ~= "center", + horizontally_stretchable = opts.horizontal_align and opts.horizontal_align ~= "center", + } + end) + +--- A solid horizontal white bar element +elements.bar = ExpGui.element("bar") + :draw{ + type = "progressbar", + value = 1, + } + :style(function(def, element, parent, width) + local style = element.style + style.color = { r = 255, g = 255, b = 255 } + style.height = 4 + if width then + style.width = width + else + style.horizontally_stretchable = true + end + end) + +--- A label which is centered +elements.centered_label = ExpGui.element("centered_label") + :draw{ + type = "label", + caption = ExpGui.property_from_arg(2), + tooltip = ExpGui.property_from_arg(3), + } + :style{ + horizontal_align = "center", + single_line = false, + width = ExpGui.property_from_arg(1), + } + +--- A label which has two white bars on either side of it +elements.title_label = ExpGui.element("title_label") + :draw(function(def, parent, width, caption, tooltip) + local flow = + parent.add{ + type = "flow" + } + + flow.style.vertical_align = "center" + elements.bar(flow, width) + + local label = + flow.add{ + type = "label", + style = "frame_title", + caption = caption, + tooltip = tooltip, + } + + elements.bar(flow) + + return label + end) + +--- A fixed size vertical scroll pane +elements.scroll_pane = ExpGui.element("scroll_pane") + :draw{ + type = "scroll-pane", + name = ExpGui.property_from_arg(2), + direction = "vertical", + horizontal_scroll_policy = "never", + vertical_scroll_policy = "auto", + style = "scroll_pane_under_subheader", + } + :style{ + padding = { 1, 3 }, + maximal_height = ExpGui.property_from_arg(1), + horizontally_stretchable = true, + } + +--- A fixed size vertical scroll pane containing a table +elements.scroll_table = ExpGui.element("scroll_table") + :draw(function(def, parent, height, column_count, scroll_name) + local scroll_pane = elements.scroll_pane(parent, height, scroll_name) + + return scroll_pane.add{ + type = "table", + name = "table", + column_count = column_count, + } + end) + :style{ + padding = 0, + cell_padding = 0, + vertical_align = "center", + horizontally_stretchable = true, + } + +--- A container frame +elements.container = ExpGui.element("container") + :draw(function(def, parent, width, container_name) + local container = + parent.add{ + type = "frame", + name = container_name, + } + + local style = container.style + style.horizontally_stretchable = false + style.minimal_width = width + style.padding = 2 + + return container.add{ + type = "frame", + name = "frame", + direction = "vertical", + style = "inside_shallow_frame_packed", + } + end) + :style{ + vertically_stretchable = false, + } + +--- A frame within a container +elements.subframe_base = ExpGui.element("container_subframe") + :draw{ + type = "frame", + name = ExpGui.property_from_arg(2), + style = ExpGui.property_from_arg(1), + } + :style{ + padding = { 2, 4 }, + use_header_filler = false, + horizontally_stretchable = true, + } + +--- A header frame within a container +elements.header = ExpGui.element("container_header") + :draw(function(def, parent, opts) + opts = opts or {} + local subframe = elements.subframe_base(parent, "subheader_frame", opts.name) + + if opts.caption then + subframe.add{ + type = "label", + name = opts.label_name, + caption = opts.caption, + tooltip = opts.tooltip, + style = "frame_title", + } + end + + return elements.aligned_flow(subframe, { name = "flow" }) + end) + +--- A footer frame within a container +elements.footer = ExpGui.element("container_footer") + :draw(function(def, parent, opts) + opts = opts or {} + local subframe = elements.subframe_base(parent, "subfooter_frame", opts.name) + + if opts.caption then + subframe.add{ + type = "label", + name = opts.label_name, + caption = opts.caption, + tooltip = opts.tooltip, + style = "frame_title", + } + end + + return elements.aligned_flow(subframe, { name = "flow" }) + end) + +return elements diff --git a/exp_gui/module/module.json b/exp_gui/module/module.json index 25c05fdb..2566ff90 100644 --- a/exp_gui/module/module.json +++ b/exp_gui/module/module.json @@ -7,7 +7,9 @@ "control.lua" ], "require": [ - "core_elements.lua" + "core_elements.lua", + "elements.lua", + "styles.lua" ], "dependencies": { "clusterio": "*", diff --git a/exp_gui/module/prototype.lua b/exp_gui/module/prototype.lua index 31c4c56b..42956a2b 100644 --- a/exp_gui/module/prototype.lua +++ b/exp_gui/module/prototype.lua @@ -60,24 +60,24 @@ function ExpElement.property_from_name() return ExpElement.property_from_name end ---- Used to signal that a property should be taken from the arguments ---- @param arg_number number? ---- @return [function, number?] -function ExpElement.property_from_args(arg_number) - return { ExpElement.property_from_args, arg_number } +--- Used to signal that a property should be taken from the arguments, a string means key of last arg +--- @param arg number|string|nil +--- @return [function, number|string|nil] +function ExpElement.property_from_arg(arg) + return { ExpElement.property_from_arg, arg } end --- Extract the from args properties from a definition --- @param definition table ---- @return string[] +--- @return table function ExpElement._prototype:_extract_signals(definition) local from_args = {} for k, v in pairs(definition) do - if v == ExpElement.property_from_args then + if v == ExpElement.property_from_arg then from_args[#from_args + 1] = k elseif v == ExpElement.property_from_name then definition[k] = self.name - elseif type(v) == "table" and v[1] == ExpElement.property_from_args then + elseif type(v) == "table" and rawget(v, 1) == ExpElement.property_from_arg then from_args[v[2] or (#from_args + 1)] = k end end @@ -179,8 +179,10 @@ function ExpElement._prototype:track_all_elements() return self end +--- @alias ExpElement.add_param LuaGuiElement.add_param | table + --- Set the draw definition ---- @param definition table | ExpElement.DrawCallback +--- @param definition ExpElement.add_param | ExpElement.DrawCallback --- @return ExpElement function ExpElement._prototype:draw(definition) ExpUtil.assert_not_runtime() @@ -193,7 +195,7 @@ function ExpElement._prototype:draw(definition) local from_args = self:_extract_signals(definition) self._debug.draw_definition = definition - if #from_args == 0 then + if not next(from_args) then self._draw = function(_, parent) return parent.add(definition) end @@ -203,8 +205,14 @@ function ExpElement._prototype:draw(definition) self._debug.draw_from_args = from_args self._draw = function(_, parent, ...) local args = { ... } + local last = args[#args] or args + -- 'or args' used instead of empty table for i, k in pairs(from_args) do - definition[k] = args[i] + if type(i) == "string" then + definition[k] = last[i] + else + definition[k] = args[i] + end end return parent.add(definition) end diff --git a/exp_gui/module/styles.lua b/exp_gui/module/styles.lua new file mode 100644 index 00000000..6d8fa31d --- /dev/null +++ b/exp_gui/module/styles.lua @@ -0,0 +1,16 @@ +--- @class ExpGui +local ExpGui = require("modules/exp_gui") + +--- @class ExpGui.styles +local styles = {} +ExpGui.styles = styles + +function styles.sprite(style) + style = style or {} + if not style.padding then + style.padding = -2 + end + return style +end + +return styles diff --git a/exp_legacy/module/config/_file_loader.lua b/exp_legacy/module/config/_file_loader.lua index a80a1a8d..fec5505e 100644 --- a/exp_legacy/module/config/_file_loader.lua +++ b/exp_legacy/module/config/_file_loader.lua @@ -43,9 +43,9 @@ return { "modules.data.language", --- GUI - --"modules.gui.readme", + "modules.gui.readme", --"modules.gui.rocket-info", - --"modules.gui.science-info", + "modules.gui.science-info", --"modules.gui.autofill", --"modules.gui.task-list", --"modules.gui.warp-list", diff --git a/exp_legacy/module/config/gui/science.lua b/exp_legacy/module/config/gui/science.lua index 572de9d2..b8128bbe 100644 --- a/exp_legacy/module/config/gui/science.lua +++ b/exp_legacy/module/config/gui/science.lua @@ -13,4 +13,9 @@ return { "production-science-pack", "utility-science-pack", "space-science-pack", + "metallurgic-science-pack", + "agricultural-science-pack", + "electromagnetic-science-pack", + "cryogenic-science-pack", + "promethium-science-pack", } diff --git a/exp_legacy/module/modules/gui/readme.lua b/exp_legacy/module/modules/gui/readme.lua index 7159977a..a563310a 100644 --- a/exp_legacy/module/modules/gui/readme.lua +++ b/exp_legacy/module/modules/gui/readme.lua @@ -5,8 +5,8 @@ ]] local ExpUtil = require("modules/exp_util") +local Gui = require("modules/exp_gui") local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event -local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local Commands = require("modules/exp_commands") --- @dep expcore.commands local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data @@ -23,9 +23,8 @@ local title_width = 270 -- controls the centering of the titles local scroll_height = 275 -- controls the height of the scrolls --- Sub content area used within the content areas --- @element sub_content -local sub_content = - Gui.element{ +local sub_content = Gui.element("readme_sub_content") + :draw{ type = "frame", direction = "vertical", style = "inside_deep_frame", @@ -38,10 +37,9 @@ local sub_content = } --- Table which has a title above it above it --- @element title_table -local title_table = - Gui.element(function(_, parent, bar_size, caption, column_count) - Gui.title_label(parent, bar_size, caption) +local title_table = Gui.element("readme_title_table") + :draw(function(_, parent, bar_size, caption, column_count) + Gui.elements.title_label(parent, bar_size, caption) return parent.add{ type = "table", @@ -56,10 +54,9 @@ local title_table = horizontally_stretchable = true, } ---- Scroll to be used with Gui.title_label tables --- @element title_table_scroll -local title_table_scroll = - Gui.element{ +--- Scroll to be used with Gui.elements.title_label tables +local title_table_scroll = Gui.element("readme_title_table_scroll") + :draw{ type = "scroll-pane", direction = "vertical", horizontal_scroll_policy = "never", @@ -73,9 +70,8 @@ local title_table_scroll = } --- Used to connect to servers in server list --- @element join_server -local join_server = - Gui.element(function(_, parent, server_id, wrong_version) +local join_server = Gui.element("readme_join_server") + :draw(function(_, parent, server_id, wrong_version) local status = External.get_server_status(server_id) or "Offline" if wrong_version then status = "Version" end local flow = parent.add{ name = server_id, type = "flow" } @@ -103,22 +99,25 @@ local join_server = return button end) - :style(Gui.sprite_style(20, -1)) - :on_click(function(player, element, _) - local server_id = element.parent.name + :style{ + size = 20, + padding = -1, + } + :on_click(function(def, event) + local player = Gui.get_player(event) + local server_id = event.element.parent.name External.request_connection(player, server_id, true) end) local welcome_time_format = ExpUtil.format_time_factory_locale{ format = "long", days = true, hours = true, minutes = true } --- Content area for the welcome tab --- @element welcome_content -define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, - Gui.element(function(_, parent) +define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, Gui.element("readme_welcome") + :draw(function(_, parent) local server_details = { name = "ExpGaming S0 - Local", welcome = "Failed to load description: disconnected from external api.", reset_time = "Non Set", branch = "Unknown" } if External.valid() then server_details = External.get_current_server() end local container = parent.add{ type = "flow", direction = "vertical" } - local player = Gui.get_player_from_element(parent) + local player = Gui.get_player(parent) -- Set up the top flow with logos local top_flow = container.add{ type = "flow" } @@ -128,9 +127,9 @@ define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, top_vertical_flow.style.horizontal_align = "center" -- Add the title and description to the top flow - Gui.title_label(top_vertical_flow, 62, "Welcome to " .. server_details.name) - Gui.centered_label(top_vertical_flow, 380, server_details.welcome) - Gui.bar(container) + Gui.elements.title_label(top_vertical_flow, 62, "Welcome to " .. server_details.name) + Gui.elements.centered_label(top_vertical_flow, 380, server_details.welcome) + Gui.elements.bar(container) -- Get the names of the roles the player has local player_roles = Roles.get_player_roles(player) @@ -142,75 +141,72 @@ define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, -- Add the other information to the gui container.add{ type = "flow" }.style.height = 4 local online_time = welcome_time_format(game.tick) - Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-general", server_details.reset_time, online_time }) - Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-roles", table.concat(role_names, ", ") }) - Gui.centered_label(sub_content(container), frame_width, { "readme.welcome-chat" }) + Gui.elements.centered_label(sub_content(container), frame_width, { "readme.welcome-general", server_details.reset_time, online_time }) + Gui.elements.centered_label(sub_content(container), frame_width, { "readme.welcome-roles", table.concat(role_names, ", ") }) + Gui.elements.centered_label(sub_content(container), frame_width, { "readme.welcome-chat" }) return container end)) --- Content area for the rules tab --- @element rules_content -define_tab({ "readme.rules-tab" }, { "readme.rules-tooltip" }, - Gui.element(function(_, parent) +define_tab({ "readme.rules-tab" }, { "readme.rules-tooltip" }, Gui.element("readme_rules") + :draw(function(_, parent) local container = parent.add{ type = "flow", direction = "vertical" } -- Add the title and description to the content - Gui.title_label(container, title_width - 3, { "readme.rules-tab" }) - Gui.centered_label(container, frame_width, { "readme.rules-general" }) - Gui.bar(container) + Gui.elements.title_label(container, title_width - 3, { "readme.rules-tab" }) + Gui.elements.centered_label(container, frame_width, { "readme.rules-general" }) + Gui.elements.bar(container) container.add{ type = "flow" } -- Add a table for the rules - local rules = Gui.scroll_table(container, scroll_height, 1) --[[@as LuaGuiElement]] + local rules = Gui.elements.scroll_table(container, scroll_height, 1) --[[@as LuaGuiElement]] rules.style = "bordered_table" rules.style.cell_padding = 4 -- Add the rules to the table for i = 1, 15 do - Gui.centered_label(rules, 565, { "readme.rules-" .. i }) + Gui.elements.centered_label(rules, 565, { "readme.rules-" .. i }) end return container end)) --- Content area for the commands tab --- @element commands_content -define_tab({ "readme.commands-tab" }, { "readme.commands-tooltip" }, - Gui.element(function(_, parent) +define_tab({ "readme.commands-tab" }, { "readme.commands-tooltip" }, Gui.element("readme_commands") + :draw(function(_, parent) local container = parent.add{ type = "flow", direction = "vertical" } - local player = Gui.get_player_from_element(parent) + local player = Gui.get_player(parent) -- Add the title and description to the content - Gui.title_label(container, title_width - 20, { "readme.commands-tab" }) - Gui.centered_label(container, frame_width, { "readme.commands-general" }) - Gui.bar(container) + Gui.elements.title_label(container, title_width - 20, { "readme.commands-tab" }) + Gui.elements.centered_label(container, frame_width, { "readme.commands-general" }) + Gui.elements.bar(container) container.add{ type = "flow" } -- Add a table for the commands - local commands = Gui.scroll_table(container, scroll_height, 2) --[[@as LuaGuiElement]] + local commands = Gui.elements.scroll_table(container, scroll_height, 2) --[[@as LuaGuiElement]] commands.style = "bordered_table" commands.style.cell_padding = 0 -- Add the rules to the table for name, command in pairs(Commands.list_for_player(player)) do - Gui.centered_label(commands, 120, name) - Gui.centered_label(commands, 450, command.description) + Gui.elements.centered_label(commands, 120, name) + Gui.elements.centered_label(commands, 450, command.description) end return container end)) --- Content area for the servers tab --- @element servers_content -define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, - Gui.element(function(_, parent) +define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, Gui.element("readme_servers") + :draw(function(_, parent) local container = parent.add{ type = "flow", direction = "vertical" } -- Add the title and description to the content - Gui.title_label(container, title_width - 10, { "readme.servers-tab" }) - Gui.centered_label(container, frame_width, { "readme.servers-general" }) - Gui.bar(container) + Gui.elements.title_label(container, title_width - 10, { "readme.servers-tab" }) + Gui.elements.centered_label(container, frame_width, { "readme.servers-general" }) + Gui.elements.bar(container) container.add{ type = "flow" } -- Draw the scroll @@ -222,15 +218,15 @@ define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, local factorio_servers = title_table(scroll_pane, 225, { "readme.servers-factorio" }, 3) local current_version = External.get_current_server().version for server_id, server in pairs(External.get_servers()) do - Gui.centered_label(factorio_servers, 110, server.short_name) - Gui.centered_label(factorio_servers, 436, server.description) + Gui.elements.centered_label(factorio_servers, 110, server.short_name) + Gui.elements.centered_label(factorio_servers, 436, server.description) join_server(factorio_servers, server_id, current_version ~= server.version and server.version) end else local factorio_servers = title_table(scroll_pane, 225, { "readme.servers-factorio" }, 2) for i = 1, 8 do - Gui.centered_label(factorio_servers, 110, { "readme.servers-" .. i }) - Gui.centered_label(factorio_servers, 460, { "readme.servers-d" .. i }) + Gui.elements.centered_label(factorio_servers, 110, { "readme.servers-" .. i }) + Gui.elements.centered_label(factorio_servers, 460, { "readme.servers-d" .. i }) end end @@ -238,23 +234,22 @@ define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, local external_links = title_table(scroll_pane, 235, { "readme.servers-external" }, 2) for _, key in ipairs{ "discord", "website", "patreon", "status", "github" } do local upper_key = key:gsub("^%l", string.upper) - Gui.centered_label(external_links, 110, upper_key) - Gui.centered_label(external_links, 460, { "links." .. key }, { "readme.servers-open-in-browser" }) + Gui.elements.centered_label(external_links, 110, upper_key) + Gui.elements.centered_label(external_links, 460, { "links." .. key }, { "readme.servers-open-in-browser" }) end return container end)) --- Content area for the servers tab --- @element backers_content -define_tab({ "readme.backers-tab" }, { "readme.backers-tooltip" }, - Gui.element(function(_, parent) +define_tab({ "readme.backers-tab" }, { "readme.backers-tooltip" }, Gui.element("readme_backers") + :draw(function(_, parent) local container = parent.add{ type = "flow", direction = "vertical" } -- Add the title and description to the content - Gui.title_label(container, title_width - 10, { "readme.backers-tab" }) - Gui.centered_label(container, frame_width, { "readme.backers-general" }) - Gui.bar(container) + Gui.elements.title_label(container, title_width - 10, { "readme.backers-tab" }) + Gui.elements.centered_label(container, frame_width, { "readme.backers-general" }) + Gui.elements.bar(container) container.add{ type = "flow" } -- Find which players will go where @@ -296,12 +291,12 @@ define_tab({ "readme.backers-tab" }, { "readme.backers-tooltip" }, for _, players in ipairs(groups) do local table = title_table(scroll_pane, players._width, players._title, 4) for _, player_name in ipairs(players) do - Gui.centered_label(table, 140, player_name) + Gui.elements.centered_label(table, 140, player_name) end if #players < 4 then for i = 1, 4 - #players do - Gui.centered_label(table, 140) + Gui.elements.centered_label(table, 140) end end end @@ -310,11 +305,10 @@ define_tab({ "readme.backers-tab" }, { "readme.backers-tooltip" }, end)) --- Content area for the player data tab --- @element commands_content -define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, - Gui.element(function(_, parent) +define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, Gui.element("readme_data") + :draw(function(_, parent) local container = parent.add{ type = "flow", direction = "vertical" } - local player = Gui.get_player_from_element(parent) + local player = Gui.get_player(parent) local player_name = player.name local enum = PlayerData.PreferenceEnum @@ -323,24 +317,24 @@ define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, preference = enum[preference] -- Add the title and description to the content - Gui.title_label(container, title_width, { "readme.data-tab" }) - Gui.centered_label(container, frame_width, { "readme.data-general" }) - Gui.bar(container) + Gui.elements.title_label(container, title_width, { "readme.data-tab" }) + Gui.elements.centered_label(container, frame_width, { "readme.data-general" }) + Gui.elements.bar(container) container.add{ type = "flow" } local scroll_pane = title_table_scroll(container) -- Add the required area local required = title_table(scroll_pane, 250, { "readme.data-required" }, 2) - Gui.centered_label(required, 150, preference_meta.name, preference_meta.tooltip) - Gui.centered_label(required, 420, { "expcore-data.preference-" .. enum[preference] }, preference_meta.value_tooltip) + Gui.elements.centered_label(required, 150, preference_meta.name, preference_meta.tooltip) + Gui.elements.centered_label(required, 420, { "expcore-data.preference-" .. enum[preference] }, preference_meta.value_tooltip) for name, child in pairs(PlayerData.Required.children) do local metadata = child.metadata local value = child:get(player_name) if value ~= nil or metadata.show_always then if metadata.stringify then value = metadata.stringify(value) end - Gui.centered_label(required, 150, metadata.name or { "exp-required." .. name }, metadata.tooltip or { "exp-required." .. name .. "-tooltip" }) - Gui.centered_label(required, 420, tostring(value), metadata.value_tooltip or { "exp-required." .. name .. "-value-tooltip" }) + Gui.elements.centered_label(required, 150, metadata.name or { "exp-required." .. name }, metadata.tooltip or { "exp-required." .. name .. "-tooltip" }) + Gui.elements.centered_label(required, 420, tostring(value), metadata.value_tooltip or { "exp-required." .. name .. "-value-tooltip" }) end end @@ -353,8 +347,8 @@ define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, if not metadata.permission or Roles.player_allowed(player, metadata.permission) then if metadata.stringify then value = metadata.stringify(value) end if value == nil then value = "None set" end - Gui.centered_label(settings, 150, metadata.name or { "exp-settings." .. name }, metadata.tooltip or { "exp-settings." .. name .. "-tooltip" }) - Gui.centered_label(settings, 420, tostring(value), metadata.value_tooltip or { "exp-settings." .. name .. "-value-tooltip" }) + Gui.elements.centered_label(settings, 150, metadata.name or { "exp-settings." .. name }, metadata.tooltip or { "exp-settings." .. name .. "-tooltip" }) + Gui.elements.centered_label(settings, 420, tostring(value), metadata.value_tooltip or { "exp-settings." .. name .. "-value-tooltip" }) end end end @@ -374,12 +368,12 @@ define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, else value = format_number(value or 0, false) end - Gui.centered_label(statistics, 150, metadata.name or { "exp-statistics." .. name }, metadata.tooltip or { "exp-statistics." .. name .. "-tooltip" }) - Gui.centered_label(statistics, 130, { "readme.data-format", value, metadata.unit or "" }, metadata.value_tooltip or { "exp-statistics." .. name .. "-tooltip" }) + Gui.elements.centered_label(statistics, 150, metadata.name or { "exp-statistics." .. name }, metadata.tooltip or { "exp-statistics." .. name .. "-tooltip" }) + Gui.elements.centered_label(statistics, 130, { "readme.data-format", value, metadata.unit or "" }, metadata.value_tooltip or { "exp-statistics." .. name .. "-tooltip" }) end end - if count > 0 then for i = 1, count do Gui.centered_label(statistics, 140) end end + if count > 0 then for i = 1, count do Gui.elements.centered_label(statistics, 140) end end end -- Add the misc area @@ -394,8 +388,8 @@ define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, local value = child:get(player_name) if value ~= nil or metadata.show_always then if metadata.stringify then value = metadata.stringify(value) end - Gui.centered_label(misc, 150, metadata.name or name, metadata.tooltip) - Gui.centered_label(misc, 420, tostring(value), metadata.value_tooltip) + Gui.elements.centered_label(misc, 150, metadata.name or name, metadata.tooltip) + Gui.elements.centered_label(misc, 420, tostring(value), metadata.value_tooltip) end end end @@ -405,18 +399,17 @@ define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, end)) --- Main readme container for the center flow --- @element readme local readme_toggle -local readme = - Gui.element(function(definition, parent) +local readme = Gui.element("readme") + :draw(function(def, parent) local container = parent.add{ - name = definition.name, + name = def.name, type = "frame", style = "invisible_frame", } -- Add the left hand side of the frame back, removed because of frame_tabbed_pane style - local left_alignment = Gui.alignment(container, nil, nil, "bottom") + local left_alignment = Gui.elements.aligned_flow(container, { vertical_align = "bottom" }) left_alignment.style.padding = { 32, 0, 0, 0 } local left_side = @@ -443,22 +436,31 @@ local readme = return container end) - :static_name(Gui.unique_static_name) - :on_open(function(player) - Gui.toggle_toolbar_button(player, readme_toggle, true) + :on_opened(function(def, event) + local player = Gui.get_player(event) + local button = Gui.get_top_element(readme_toggle, player) + Gui.set_toolbar_button_style(button, true) end) - :on_close(function(player, element) - Gui.toggle_toolbar_button(player, readme_toggle, false) - Gui.destroy_if_valid(element) + :on_closed(function(def, event) + local player = Gui.get_player(event) + local button = Gui.get_top_element(readme_toggle, player) + Gui.set_toolbar_button_style(button, false) + Gui.destroy_if_valid(event.element) end) --- Toggle button for the readme gui --- @element readme_toggle readme_toggle = - Gui.toolbar_button("virtual-signal/signal-info", { "readme.main-tooltip" }, function(player) - return Roles.player_allowed(player, "gui/readme") - end) - :on_click(function(player, _) + Gui.create_toolbar_button{ + name = "readme_toggle", + auto_toggle = true, + sprite = "virtual-signal/signal-info", + tooltip = { "readme.main-tooltip" }, + visible = function(player, element) + return Roles.player_allowed(player, "gui/readme") + end + } + :on_click(function(def, event) + local player = Gui.get_player(event) local center = player.gui.center if center[readme.name] then player.opened = nil @@ -475,18 +477,13 @@ Event.add(defines.events.on_player_created, function(event) player.opened = element end) ---- When a player joins clear center unless the player has something open -Event.add(defines.events.on_player_joined_game, function(event) +local function clear_readme(event) local player = game.players[event.player_index] if not player.opened then - player.gui.center.clear() + Gui.destroy_if_valid(player.gui.center[readme.name]) end -end) +end ---- When a player respawns clear center unless the player has something open -Event.add(defines.events.on_player_respawned, function(event) - local player = game.players[event.player_index] - if not player.opened then - player.gui.center.clear() - end -end) +--- When a player joins or respawns, clear center unless the player has something open +Event.add(defines.events.on_player_joined_game, clear_readme) +Event.add(defines.events.on_player_respawned, clear_readme) diff --git a/exp_legacy/module/modules/gui/science-info.lua b/exp_legacy/module/modules/gui/science-info.lua index e751a258..65ee9c28 100644 --- a/exp_legacy/module/modules/gui/science-info.lua +++ b/exp_legacy/module/modules/gui/science-info.lua @@ -5,7 +5,7 @@ ]] local ExpUtil = require("modules/exp_util") -local Gui = require("modules.exp_legacy.expcore.gui") --- @dep expcore.gui +local Gui = require("modules/exp_gui") local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.gui local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event local config = require("modules.exp_legacy.config.gui.science") --- @dep config.gui.science @@ -17,16 +17,23 @@ local long_time_format = ExpUtil.format_time_factory_locale{ format = "long", ho local null_time_clock = { "science-info.eta-time", clock_time_format(nil) } local null_time_long = long_time_format(nil) ---- Data label that contains the value and the surfix +--- Remove invalid science packs, this can result from a certain mod not being loaded +for i = #config, 1, -1 do + if not prototypes.item[config[i]] then + table.remove(config, i) + end +end + +--- Data label that contains the value and the suffix -- @element production_label -local production_label = - Gui.element(function(_, parent, production_label_data) +local production_label = Gui.element("science_info_production_label") + :draw(function(_, parent, production_label_data) local name = production_label_data.name local tooltip = production_label_data.tooltip local color = production_label_data.color -- Add an alignment for the number - local alignment = Gui.alignment(parent, name) + local alignment = Gui.elements.aligned_flow(parent, { name = name }) -- Add the main value label local element = @@ -40,19 +47,19 @@ local production_label = -- Change the style element.style.font_color = color - -- Add the surfix label - local surfix_element = + -- Add the suffix label + local suffix_element = parent.add{ - name = "surfix-" .. name, + name = "suffix-" .. name, type = "label", - caption = { "science-info.unit", production_label_data.surfix }, + caption = { "science-info.unit", production_label_data.suffix }, tooltip = tooltip, } -- Change the style - local surfix_element_style = surfix_element.style - surfix_element_style.font_color = color - surfix_element_style.right_margin = 1 + local suffix_element_style = suffix_element.style + suffix_element_style.font_color = color + suffix_element_style.right_margin = 1 -- Return the value label return element @@ -61,12 +68,12 @@ local production_label = -- Get the data that is used with the production label local function get_production_label_data(name, tooltip, value, cutout, secondary) local data_colour = Production.get_color(config.color_cutoff * cutout, value, secondary) - local surfix, caption = Production.format_number(value) + local suffix, caption = Production.format_number(value) return { name = name, caption = caption, - surfix = surfix, + suffix = suffix, tooltip = tooltip, color = data_colour, } @@ -84,17 +91,17 @@ local function update_production_label(parent, production_label_data) production_label_element.tooltip = production_label_data.tooltip production_label_element.style.font_color = color - -- Update the surfix label - local surfix_element = parent["surfix-" .. name] - surfix_element.caption = { "science-info.unit", production_label_data.surfix } - surfix_element.tooltip = tooltip - surfix_element.style.font_color = color + -- Update the suffix label + local suffix_element = parent["suffix-" .. name] + suffix_element.caption = { "science-info.unit", production_label_data.suffix } + suffix_element.tooltip = tooltip + suffix_element.style.font_color = color end --- Adds 4 elements that show the data for a science pack -- @element science_pack_base -local science_pack_base = - Gui.element(function(_, parent, science_pack_data) +local science_pack_base = Gui.element("science_info_science_pack_base") + :draw(function(_, parent, science_pack_data) local science_pack = science_pack_data.science_pack -- Draw the icon for the science pack @@ -262,18 +269,21 @@ end --- Main task list container for the left flow -- @element task_list_container -local science_info_container = - Gui.element(function(definition, parent) - local player = Gui.get_player_from_element(parent) +local science_info = Gui.element("science_info") + :draw(function(def, parent) + local player = Gui.get_player(parent) -- Draw the internal container - local container = Gui.container(parent, definition.name, 200) + local container = Gui.elements.container(parent, 200) -- Draw the header - Gui.header(container, { "science-info.main-caption" }, { "science-info.main-tooltip" }) + Gui.elements.header(container, { + caption = { "science-info.main-caption" }, + tooltip = { "science-info.main-tooltip" }, + }) -- Draw the scroll table for the tasks - local scroll_table = Gui.scroll_table(container, 178, 4) + local scroll_table = Gui.elements.scroll_table(container, 178, 4, "scroll") -- Draw the no packs label local no_packs_label = @@ -292,7 +302,11 @@ local science_info_container = -- Add the footer and eta if config.show_eta then -- Draw the footer - local footer = Gui.footer(container, { "science-info.eta-caption" }, { "science-info.eta-tooltip" }, true) + local footer = Gui.elements.footer(container, { + name = "footer", + caption = { "science-info.eta-caption" }, + tooltip = { "science-info.eta-tooltip" }, + }) -- Draw the eta label local eta_label = @@ -313,17 +327,21 @@ local science_info_container = update_science_pack(scroll_table, get_science_pack_data(player, science_pack)) end - -- Return the exteral container + -- Return the external container return container.parent end) - :static_name(Gui.unique_static_name) - :add_to_left_flow() ---- Button on the top flow used to toggle the task list container --- @element toggle_science_info -Gui.left_toolbar_button("entity/lab", { "science-info.main-tooltip" }, science_info_container, function(player) - return Roles.player_allowed(player, "gui/science-info") -end) +--- Add the element to the left flow with a toolbar button +Gui.add_left_element(science_info, false) +Gui.create_toolbar_button{ + name = "science_info_toggle", + left_element = science_info, + sprite = "entity/lab", + tooltip = { "science-info.main-tooltip" }, + visible = function(player, element) + return Roles.player_allowed(player, "gui/science-info") + end +} --- Updates the gui every 1 second Event.on_nth_tick(60, function() @@ -331,11 +349,11 @@ Event.on_nth_tick(60, function() local force_eta_data = {} for _, player in pairs(game.connected_players) do local force_name = player.force.name - local frame = Gui.get_left_element(player, science_info_container) - local container = frame.container + local container = Gui.get_left_element(science_info, player) + local frame = container.frame -- Update the science packs - local scroll_table = container.scroll.table + local scroll_table = frame.scroll.table local pack_data = force_pack_data[force_name] if not pack_data then -- No data in cache so it needs to be generated @@ -355,7 +373,7 @@ Event.on_nth_tick(60, function() -- Update the eta times if not config.show_eta then return end - local eta_label = container.footer.alignment.label + local eta_label = frame.footer.flow.label local eta_data = force_eta_data[force_name] if not eta_data then -- No data in chache so it needs to be generated