From fd3d62ea9d9bef3e5ff3f04126a81af1e658fdb5 Mon Sep 17 00:00:00 2001 From: Will Berry <73126355+wdberry@users.noreply.github.com> Date: Thu, 9 Mar 2023 16:45:14 -0500 Subject: [PATCH 1/5] Trains tab initial testing --- cybersyn/scripts/gui/manager.lua | 4 +- cybersyn/scripts/gui/stations.lua | 4 - cybersyn/scripts/gui/trains.lua | 152 +++++++++++++++++++----------- cybersyn/scripts/gui/util.lua | 41 ++++---- 4 files changed, 122 insertions(+), 79 deletions(-) diff --git a/cybersyn/scripts/gui/manager.lua b/cybersyn/scripts/gui/manager.lua index dafe4e3..32f5de6 100644 --- a/cybersyn/scripts/gui/manager.lua +++ b/cybersyn/scripts/gui/manager.lua @@ -6,7 +6,7 @@ local constants = require("scripts.gui.constants") local templates = require("scripts.gui.templates") local stations_tab = require("scripts.gui.stations") ---local trains_tab = require("scripts.gui.trains") +local trains_tab = require("scripts.gui.trains") --local depots_tab = require("scripts.gui.depots") local inventory_tab = require("scripts.gui.inventory") --local history_tab = require("scripts.gui.history") @@ -103,6 +103,7 @@ function manager.create(player) name = "manager_tabbed_pane", type = "tabbed-pane", style = "ltnm_tabbed_pane", + trains_tab.create(widths), stations_tab.create(widths), inventory_tab.create(), selected_tab_index = 1, @@ -162,6 +163,7 @@ function manager.update(map_data, player_data) manager.build(player_data) stations_tab.build(map_data, player_data) inventory_tab.build(map_data, player_data) + trains_tab.build(map_data,player_data) end diff --git a/cybersyn/scripts/gui/stations.lua b/cybersyn/scripts/gui/stations.lua index abe61fc..992efe3 100644 --- a/cybersyn/scripts/gui/stations.lua +++ b/cybersyn/scripts/gui/stations.lua @@ -99,10 +99,6 @@ function stations_tab.build(map_data, player_data) end if search_network_name then - --nil matches all? - if search_network_name == nil then - goto has_match - end if search_network_name ~= station.network_name then goto continue end diff --git a/cybersyn/scripts/gui/trains.lua b/cybersyn/scripts/gui/trains.lua index 91498b6..683de00 100644 --- a/cybersyn/scripts/gui/trains.lua +++ b/cybersyn/scripts/gui/trains.lua @@ -1,4 +1,4 @@ -local format = require("__flib__.format") +local train_util = require("__flib__.train") local gui = require("__flib__.gui-lite") local constants = require("constants") @@ -8,21 +8,59 @@ local templates = require("scripts.gui.templates") local trains_tab = {} +function trains_tab.create(widths) + return { + tab = { + name = "manager_trains_tab", + type = "tab", + --caption = #trains_sorted == 0 and { "cybersyn-gui.trains" } or { "cybersyn-gui.trains", #train_list }, + caption = { "cybersyn-gui.trains" }, + --badge_text = format.number(#ltn_data.sorted_trains.composition), + --handler = trains_tab.handle.change_tab, --on_click + tags = { tab = "trains_tab" }, + }, + content = { + name = "manager_trains_tab_content_frame", + type = "frame", + style = "ltnm_main_content_frame", + direction = "vertical", + children = { + { + type = "frame", + style = "ltnm_table_toolbar_frame", + templates.sort_checkbox(widths, "trains", "status", false), + templates.sort_checkbox(widths, "trains", "layout", false, { "cybersyn-gui.composition-description" }), + templates.sort_checkbox(widths, "trains", "depot", false), + templates.sort_checkbox(widths, "trains", "shipment", false), + }, + { name = "manager_trains_tab_scroll_pane", type = "scroll-pane", style = "ltnm_table_scroll_pane" }, + { + name = "trains_warning_flow", + type = "flow", + style = "ltnm_warning_flow", + }, + }, + }, + } +end --- @param map_data MapData --- @param player_data PlayerData --- @return GuiElemDef function trains_tab.build(map_data, player_data) local widths = constants.gui["en"] + local refs = player_data.refs + local search_query = player_data.search_query local search_item = player_data.search_item local search_network_name = player_data.search_network_name local search_network_mask = player_data.search_network_mask local search_surface_idx = player_data.search_surface_idx - + + local trains = map_data.trains local trains_sorted = {} - for id, train in pairs(map_data.trains) do + for id, train in pairs(trains) do if search_network_name then if search_network_name ~= train.network_name then goto continue @@ -47,6 +85,9 @@ function trains_tab.build(map_data, player_data) end if search_surface_idx then + if search_surface_idx == -1 then + goto has_match + end local entity = get_any_train_entity(train.entity) if not entity then goto continue @@ -54,6 +95,7 @@ function trains_tab.build(map_data, player_data) if entity.surface.index ~= search_surface_idx then goto continue end + ::has_match:: end if search_item then @@ -126,106 +168,110 @@ function trains_tab.build(map_data, player_data) return a < b end) + local scroll_pane = refs.manager_trains_tab_scroll_pane + if next(scroll_pane.children) ~= nil then + refs.manager_trains_tab_scroll_pane.clear() + end - ---@type GuiElemDef - local train_list = {} if #trains_sorted == 0 then - train_list[1] = { + gui.add(scroll_pane, { type = "label", style = "ltnm_semibold_label", caption = { "cybersyn-gui.no-trains" }, - } + }) else for idx, train_id in ipairs(trains_sorted) do local train = map_data.trains[train_id] local depot = map_data.depots[train.depot_id] local depot_name = depot.entity_stop.valid and depot.entity_stop.backer_name or "" + local train_entity = train.entity + local locomotive + if train_entity.locomotives["front_movers"][1] then + locomotive = train_entity.locomotives["front_movers"][1] + else + locomotive = train_entity.locomotives["back_movers"][1] + end + local manifest = {} + if train.manifest ~= nil then + manifest = train.manifest + end local color = idx % 2 == 0 and "dark" or "light" - train_list[idx] = { + gui.add(scroll_pane, { type = "frame", style = "ltnm_table_row_frame_" .. color, - children = { { type = "frame", style = "ltnm_table_inset_frame_" .. color, - children = { + { type = "minimap", + name = "train_minimap", style = "ltnm_train_minimap", { type = "label", style = "ltnm_minimap_label" }, { type = "button", style = "ltnm_train_minimap_button", tooltip = { "cybersyn-gui.open-train-gui" }, - elem_mods = { entity = get_any_train_entity(train.entity) }, - handler = trains_tab.handle.open_train_gui, --on_click tags = { train_id = train_id }, + handler = trains_tab.handle.open_train_gui, --on_click }, }, }, { type = "label", style_mods = { width = widths.trains.composition }, - elem_mods = { caption = train.layout_id }, + caption = train.layout_id, }, { type = "label", style_mods = { width = widths.trains.depot }, - elem_mods = { caption = depot_name }, + caption = depot_name, }, { type = "frame", name = "shipment_frame", style = "ltnm_small_slot_table_frame_" .. color, style_mods = { width = widths.trains.shipment }, - children = { { type = "table", name = "shipment_table", style = "slot_table", column_count = widths.trains.shipment_columns, - children = util.slot_table_build(train.manifest, "default"), + { }, }, }, - }, - }, - } + }, refs) + refs.train_minimap.entity = locomotive + gui.add(refs.shipment_table, util.slot_table_build_from_manifest(manifest, "default")) end end - - return { - tab = { - name = "trains_tab", - type = "tab", - caption = #trains_sorted == 0 and { "cybersyn-gui.trains" } or { "cybersyn-gui.trains", #train_list }, - --badge_text = format.number(#ltn_data.sorted_trains.composition), - handler = trains_tab.handle.change_tab, --on_click - tags = { tab = "trains_tab" }, - }, - content = { - name = "trains_content_frame", - type = "frame", - style = "ltnm_main_content_frame", - direction = "vertical", - children = { - { - type = "frame", - style = "ltnm_table_toolbar_frame", - templates.sort_checkbox(widths, "trains", "status", false), - templates.sort_checkbox(widths, "trains", "layout", false, { "cybersyn-gui.composition-description" }), - templates.sort_checkbox(widths, "trains", "depot", false), - templates.sort_checkbox(widths, "trains", "shipment", false), - }, - { name = "trains_scroll_pane", type = "scroll-pane", style = "ltnm_table_scroll_pane" }, - { - name = "trains_warning_flow", - type = "flow", - style = "ltnm_warning_flow", - children = train_list, - }, - }, - }, - } end +trains_tab.handle = {} + +--- @param e {player_index: uint} +function trains_tab.wrapper(e, handler) + local player = game.get_player(e.player_index) + if not player then return end + local player_data = global.manager.players[e.player_index] + handler(player, player_data, player_data.refs, e) +end + +--- @param e GuiEventData +--- @param player_data PlayerData +function trains_tab.handle.open_train_gui(player, player_data, refs, e) + local train_id = e.element.tags.train_id + --- @type Train + local train = global.trains[train_id] + local train_entity = train.entity + + if not train_entity or not train_entity.valid then + util.error_flying_text(gui.player, { "message.ltnm-error-train-is-invalid" }) + return + end + train_util.open_gui(player.index, train_entity) +end + +gui.add_handlers(trains_tab.handle, trains_tab.wrapper) + return trains_tab diff --git a/cybersyn/scripts/gui/util.lua b/cybersyn/scripts/gui/util.lua index c7b7a6c..dbd1b0c 100644 --- a/cybersyn/scripts/gui/util.lua +++ b/cybersyn/scripts/gui/util.lua @@ -64,27 +64,26 @@ end function util.slot_table_build_from_manifest(manifest, color) ---@type GuiElemDef[] local children = {} - for _, item in pairs(manifest) do - local name = item.name - local sprite - if item.type then - sprite = item.type .. "/" .. name - else - sprite = string.gsub(name, ",", "/") - end - if game.is_valid_sprite_path(sprite) then - children[#children + 1] = { - type = "sprite-button", - enabled = false, - style = "ltnm_small_slot_button_" .. color, - sprite = sprite, - tooltip = { - "", - "[img=" .. sprite .. "]", - { "item-name." .. name }, - "\n"..format.number(count), - }, - } + if manifest then + for _, item in pairs(manifest) do + local name = item.name + local count = item.count + local sprite, img_path, item_string = util.generate_item_references(name) + if game.is_valid_sprite_path(sprite) then + children[#children + 1] = { + type = "sprite-button", + enabled = false, + style = "ltnm_small_slot_button_" .. color, + sprite = sprite, + number = count, + tooltip = { + "", + img_path, + { item_string }, + "\n"..format.number(count), + }, + } + end end end return children From 8d182cbc3bbf2d3d04a9c0b141bd6fb2083526bd Mon Sep 17 00:00:00 2001 From: Will Berry <73126355+wdberry@users.noreply.github.com> Date: Fri, 10 Mar 2023 09:33:26 -0500 Subject: [PATCH 2/5] Fix invalid train object reference by validating train is valid before adding it to the list --- cybersyn/scripts/gui/trains.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cybersyn/scripts/gui/trains.lua b/cybersyn/scripts/gui/trains.lua index 683de00..b9aa1e1 100644 --- a/cybersyn/scripts/gui/trains.lua +++ b/cybersyn/scripts/gui/trains.lua @@ -61,6 +61,9 @@ function trains_tab.build(map_data, player_data) local trains_sorted = {} for id, train in pairs(trains) do + if not train.entity.valid then + goto continue + end if search_network_name then if search_network_name ~= train.network_name then goto continue From a16a5fc01529365c4c792e7f5701be2d00809d5c Mon Sep 17 00:00:00 2001 From: Will Berry <73126355+wdberry@users.noreply.github.com> Date: Fri, 10 Mar 2023 12:45:40 -0500 Subject: [PATCH 3/5] Add logic from upstream to only refresh train tab if selected and allow for query limt --- cybersyn/scripts/gui/trains.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cybersyn/scripts/gui/trains.lua b/cybersyn/scripts/gui/trains.lua index f9c9487..82309c3 100644 --- a/cybersyn/scripts/gui/trains.lua +++ b/cybersyn/scripts/gui/trains.lua @@ -16,7 +16,7 @@ function trains_tab.create(widths) --caption = #trains_sorted == 0 and { "cybersyn-gui.trains" } or { "cybersyn-gui.trains", #train_list }, caption = { "cybersyn-gui.trains" }, --badge_text = format.number(#ltn_data.sorted_trains.composition), - --handler = trains_tab.handle.change_tab, --on_click + handler = trains_tab.handle.on_trains_tab_selected, --on_click tags = { tab = "trains_tab" }, }, content = { @@ -281,6 +281,12 @@ function trains_tab.handle.open_train_gui(player, player_data, refs, e) train_util.open_gui(player.index, train_entity) end +---@param player LuaPlayer +---@param player_data PlayerData +function trains_tab.handle.on_trains_tab_selected(player, player_data) + player_data.selected_tab = "trains_tab" +end + gui.add_handlers(trains_tab.handle, trains_tab.wrapper) return trains_tab From efeb2d5c8b232e3e7a6d92f46290762f158cb218 Mon Sep 17 00:00:00 2001 From: Will Berry <73126355+wdberry@users.noreply.github.com> Date: Fri, 10 Mar 2023 13:29:22 -0500 Subject: [PATCH 4/5] Fix invalid reference --- cybersyn/scripts/gui/stations.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cybersyn/scripts/gui/stations.lua b/cybersyn/scripts/gui/stations.lua index dc965a3..7c8f6b3 100644 --- a/cybersyn/scripts/gui/stations.lua +++ b/cybersyn/scripts/gui/stations.lua @@ -285,7 +285,7 @@ function stations_tab.handle.open_station_gui(player, player_data, refs, e) if e.shift then if station_entity.surface ~= player.surface then - util.error_flying_text(gui.player, { "cybersyn-message.error-cross-surface-camera-invalid" }) + util.error_flying_text(player, { "cybersyn-message.error-cross-surface-camera-invalid" }) else player.zoom_to_world(station_entity.position, 1, station_entity) From 3aa3eb970aa7acd2cf1f3d391394037c1d326406 Mon Sep 17 00:00:00 2001 From: Will Berry <73126355+wdberry@users.noreply.github.com> Date: Fri, 10 Mar 2023 19:42:23 -0500 Subject: [PATCH 5/5] Allow partial match on train item search --- cybersyn/scripts/gui/trains.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cybersyn/scripts/gui/trains.lua b/cybersyn/scripts/gui/trains.lua index 82309c3..a157d8c 100644 --- a/cybersyn/scripts/gui/trains.lua +++ b/cybersyn/scripts/gui/trains.lua @@ -108,7 +108,7 @@ function trains_tab.build(map_data, player_data, query_limit) goto continue end for i, v in ipairs(train.manifest) do - if v.name == search_item then + if string.match(v.name, search_item) then goto has_match end end