mirror of
https://github.com/Xevion/project-cybersyn.git
synced 2025-12-11 10:08:17 -06:00
merged gui
This commit is contained in:
84
cybersyn/locale/en/manager.cfg
Normal file
84
cybersyn/locale/en/manager.cfg
Normal file
@@ -0,0 +1,84 @@
|
||||
[controls]
|
||||
cybersyn-toggle-gui=Toggle LTN Manager
|
||||
|
||||
[cybersyn-gui]
|
||||
alert-delivery-failed=Delivery failed
|
||||
alert-delivery-failed-description=The train took too long to perform its task and was abandoned by LTN, or the train was otherwise invalidated. You can configure how long LTN will wait for a train in the mod settings.\n\nThe planned shipment is listed in green.
|
||||
alert-provider-missing-cargo-description=Not all of the intended cargo was loaded before the train left the provider.\n\nGreen indicates the intended shipment, red indicates the actual shipment.
|
||||
alert-provider-missing-cargo=Provider - missing cargo
|
||||
alert-provider-unscheduled-cargo-description=The train left the provider with unscheduled / unintended cargo.\n\nGreen indicates the planned shipment, red indicates the unscheduled load.
|
||||
alert-provider-unscheduled-cargo=Provider - unscheduled cargo
|
||||
alert-requester-remaining-cargo-description=Not all materials were unloaded from the train before it left the station, and it has returned to its depot with the leftover cargo.\n\nThe leftover items are listed in red.
|
||||
alert-requester-remaining-cargo=Requester - remaining cargo
|
||||
alert-requester-unscheduled-cargo-description=The train arrived at the requester with unscheduled / unintended cargo.\n\nGreen indicates the planned shipment, red indicates the unscheduled load.
|
||||
alert-requester-unscheduled-cargo=Requester - unscheduled cargo
|
||||
alerts=Alerts
|
||||
all-paren=(All)
|
||||
clear-history=Clear history
|
||||
composition=Composition
|
||||
composition-description=The train's layout.\nL = Locomotive\nC = Cargo wagon\nF = Fluid wagon\nA = Artillery wagon\n< > = Direction
|
||||
control-signals=Control signals
|
||||
delete-alert=Delete alert
|
||||
delete-all-alerts=Delete all alerts
|
||||
delivering-to=Delivering to
|
||||
depot=Depot
|
||||
depots=Depots
|
||||
dispatcher-disabled-description=The LTN dispatcher is disabled; no new deliveries will be created. Re-enable the dispatcher via the map settings or by using the hotkey.
|
||||
dispatcher-disabled=LTN dispatcher is disabled!
|
||||
fetching-from=Fetching from
|
||||
finished=Finished
|
||||
history=History
|
||||
in-transit=In transit
|
||||
inventory=Inventory
|
||||
keep-open=Keep open
|
||||
loading-at=Loading at
|
||||
name=Name
|
||||
network-id-label=Network ID:
|
||||
network-id=Network ID
|
||||
no-alerts=[img=warning-white] No alerts
|
||||
no-depots=[img=warning-white] No depots
|
||||
no-history=[img=warning-white] No history
|
||||
no-stations=[img=warning-white] No stations
|
||||
not-available=Not available
|
||||
no-trains=[img=warning-white] No trains
|
||||
open-ltn-combinator-gui=[font=default-semibold][color=128,206,240]Control:[/color][/font] Open LTN Combinator GUI
|
||||
open-station-gui=Open station GUI\n[font=default-semibold][color=128,206,240]Shift:[/color][/font] Open station on map
|
||||
open-train-gui=Open train GUI
|
||||
parked-at-depot=Parked at depot
|
||||
parked-at-depot-with-residue=Parked at depot with residue
|
||||
provided=Provided
|
||||
provided-requested-description=Green = provided\nRed = requested
|
||||
provided-requested=Provided / requested
|
||||
refresh-tooltip=Refresh\n[font=default-semibold][color=128,206,240]Shift:[/color][/font] Toggle auto-refresh
|
||||
requested=Requested
|
||||
returning-to-depot=Returning to depot
|
||||
route=Route
|
||||
runtime=Runtime
|
||||
search-label=Search:
|
||||
shipments-description=Green = Inbound\nBlue = Outbound
|
||||
shipment=Shipment
|
||||
shipments=Shipments
|
||||
stations=Stations
|
||||
status-description=[img=flib_indicator_green]1 = normal status\n[img=flib_indicator_blue]n = LTN Controlled Train parked at stop, n = number of trains\n[img=flib_indicator_yellow]n = Stop is part of a scheduled delivery, n = number of trains\n[img=flib_indicator_white]1 = Error - not initialized\n[img=flib_indicator_red]1 = Error - short circuit\n[img=flib_indicator_red]2 = Error - deactivated stop
|
||||
status=Status
|
||||
surface-label=Surface:
|
||||
time=Time
|
||||
train-id=Train ID
|
||||
trains=Trains
|
||||
type=Type
|
||||
unloading-at=Unloading at
|
||||
|
||||
[cybersyn-message]
|
||||
error-ltn-combinator-not-found=Could not find an LTN Combinator for this station.
|
||||
error-station-is-invalid=Station is invalid, please refresh the GUI.
|
||||
error-train-is-invalid=Train is invalid, please refresh the GUI.
|
||||
|
||||
[cybersyn-mod-setting-description]
|
||||
iterations-per-tick=Decrease this number if you're having performance issues.
|
||||
|
||||
[cybersyn-mod-setting-name]
|
||||
history-length=History length
|
||||
iterations-per-tick=Iterations per tick [img=info]
|
||||
|
||||
[shortcut-name]
|
||||
cybersyn-toggle-gui=Toggle LTN Manager
|
||||
329
cybersyn/prototypes/gui-style.lua
Normal file
329
cybersyn/prototypes/gui-style.lua
Normal file
@@ -0,0 +1,329 @@
|
||||
local constants = require("constants")
|
||||
|
||||
local util = require("prototypes.util")
|
||||
|
||||
local styles = data.raw["gui-style"]["default"]
|
||||
|
||||
-- local depot_button_height = 89
|
||||
|
||||
-- BUTTON STYLES
|
||||
|
||||
-- smaller flib slot buttons
|
||||
for _, color in ipairs({ "default", "red", "green", "blue" }) do
|
||||
styles["ltnm_small_slot_button_" .. color] = {
|
||||
type = "button_style",
|
||||
parent = "flib_slot_button_" .. color,
|
||||
size = 36,
|
||||
}
|
||||
styles["ltnm_selected_small_slot_button_" .. color] = {
|
||||
type = "button_style",
|
||||
parent = "flib_selected_slot_button_" .. color,
|
||||
size = 36,
|
||||
}
|
||||
end
|
||||
|
||||
styles.ltnm_train_minimap_button = {
|
||||
type = "button_style",
|
||||
parent = "button",
|
||||
size = 90,
|
||||
default_graphical_set = {},
|
||||
hovered_graphical_set = {
|
||||
base = { position = { 81, 80 }, size = 1, opacity = 0.7 },
|
||||
},
|
||||
clicked_graphical_set = { position = { 70, 146 }, size = 1, opacity = 0.7 },
|
||||
}
|
||||
|
||||
-- CHECKBOX STYLES
|
||||
|
||||
-- inactive is grey until hovered
|
||||
-- checked = ascending, unchecked = descending
|
||||
styles.ltnm_sort_checkbox = {
|
||||
type = "checkbox_style",
|
||||
font = "default-bold",
|
||||
-- font_color = bold_font_color,
|
||||
padding = 0,
|
||||
default_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-down-white.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
hovered_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-down-hover.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
clicked_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-down-white.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
disabled_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-down-white.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
selected_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-up-white.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
selected_hovered_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-up-hover.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
selected_clicked_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-up-white.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
selected_disabled_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-up-white.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
checkmark = util.empty_checkmark,
|
||||
disabled_checkmark = util.empty_checkmark,
|
||||
text_padding = 5,
|
||||
}
|
||||
|
||||
-- selected is orange by default
|
||||
styles.ltnm_selected_sort_checkbox = {
|
||||
type = "checkbox_style",
|
||||
parent = "ltnm_sort_checkbox",
|
||||
-- font_color = bold_font_color,
|
||||
default_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-down-active.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
selected_graphical_set = {
|
||||
filename = "__core__/graphics/arrows/table-header-sort-arrow-up-active.png",
|
||||
size = { 16, 16 },
|
||||
scale = 0.5,
|
||||
},
|
||||
}
|
||||
|
||||
-- FLOW STYLES
|
||||
|
||||
styles.ltnm_warning_flow = {
|
||||
type = "horizontal_flow_style",
|
||||
padding = 12,
|
||||
horizontal_align = "center",
|
||||
vertical_align = "center",
|
||||
vertical_spacing = 8,
|
||||
horizontally_stretchable = "on",
|
||||
vertically_stretchable = "on",
|
||||
}
|
||||
|
||||
-- FRAME STYLES
|
||||
|
||||
styles.ltnm_main_content_frame = {
|
||||
type = "frame_style",
|
||||
parent = "deep_frame_in_shallow_frame",
|
||||
height = constants.gui_content_frame_height,
|
||||
}
|
||||
|
||||
styles.ltnm_main_toolbar_frame = {
|
||||
type = "frame_style",
|
||||
parent = "subheader_frame",
|
||||
bottom_margin = 12,
|
||||
horizontal_flow_style = {
|
||||
type = "horizontal_flow_style",
|
||||
horizontal_spacing = 12,
|
||||
vertical_align = "center",
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_small_slot_table_frame_light = {
|
||||
type = "frame_style",
|
||||
parent = "ltnm_table_inset_frame_light",
|
||||
minimal_height = 36,
|
||||
background_graphical_set = {
|
||||
base = {
|
||||
position = { 282, 17 },
|
||||
corner_size = 8,
|
||||
overall_tiling_horizontal_padding = 4,
|
||||
overall_tiling_horizontal_size = 28,
|
||||
overall_tiling_horizontal_spacing = 8,
|
||||
overall_tiling_vertical_padding = 4,
|
||||
overall_tiling_vertical_size = 28,
|
||||
overall_tiling_vertical_spacing = 8,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_small_slot_table_frame_dark = {
|
||||
type = "frame_style",
|
||||
parent = "ltnm_table_inset_frame_dark",
|
||||
minimal_height = 36,
|
||||
background_graphical_set = {
|
||||
base = {
|
||||
position = { 282, 17 },
|
||||
corner_size = 8,
|
||||
overall_tiling_horizontal_padding = 4,
|
||||
overall_tiling_horizontal_size = 28,
|
||||
overall_tiling_horizontal_spacing = 8,
|
||||
overall_tiling_vertical_padding = 4,
|
||||
overall_tiling_vertical_size = 28,
|
||||
overall_tiling_vertical_spacing = 8,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_table_inset_frame_light = {
|
||||
type = "frame_style",
|
||||
parent = "deep_frame_in_shallow_frame",
|
||||
}
|
||||
|
||||
styles.ltnm_table_inset_frame_dark = {
|
||||
type = "frame_style",
|
||||
parent = "deep_frame_in_shallow_frame",
|
||||
graphical_set = {
|
||||
base = {
|
||||
position = { 51, 0 },
|
||||
corner_size = 8,
|
||||
center = { position = { 42, 8 }, size = { 1, 1 } },
|
||||
draw_type = "outer",
|
||||
},
|
||||
shadow = default_inner_shadow,
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_table_row_frame_light = {
|
||||
type = "frame_style",
|
||||
parent = "statistics_table_item_frame",
|
||||
top_padding = 8,
|
||||
bottom_padding = 8,
|
||||
left_padding = 8,
|
||||
right_padding = 8,
|
||||
minimal_height = 52,
|
||||
horizontal_flow_style = {
|
||||
type = "horizontal_flow_style",
|
||||
vertical_align = "center",
|
||||
horizontal_spacing = 10,
|
||||
horizontally_stretchable = "on",
|
||||
},
|
||||
graphical_set = {
|
||||
base = {
|
||||
center = { position = { 76, 8 }, size = { 1, 1 } },
|
||||
-- bottom = {position = {8, 40}, size = {1, 8}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_table_row_frame_dark = {
|
||||
type = "frame_style",
|
||||
parent = "ltnm_table_row_frame_light",
|
||||
-- graphical_set = {
|
||||
-- base = {bottom = {position = {8, 40}, size = {1, 8}}},
|
||||
-- },
|
||||
graphical_set = {},
|
||||
}
|
||||
|
||||
styles.ltnm_table_toolbar_frame = {
|
||||
type = "frame_style",
|
||||
parent = "subheader_frame",
|
||||
left_padding = 9,
|
||||
right_padding = 7 + 12, -- For scrollbar
|
||||
horizontally_stretchable = "on", -- FIXME: This causes the GUI to jump when the scrollbar appears
|
||||
horizontal_flow_style = {
|
||||
type = "horizontal_flow_style",
|
||||
horizontal_spacing = 10,
|
||||
vertical_align = "center",
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_main_warning_frame = {
|
||||
type = "frame_style",
|
||||
parent = "deep_frame_in_shallow_frame",
|
||||
height = constants.gui_content_frame_height,
|
||||
graphical_set = {
|
||||
base = {
|
||||
position = { 85, 0 },
|
||||
corner_size = 8,
|
||||
center = { position = { 411, 25 }, size = { 1, 1 } },
|
||||
draw_type = "outer",
|
||||
},
|
||||
shadow = default_inner_shadow,
|
||||
},
|
||||
}
|
||||
|
||||
-- LABEL STYLES
|
||||
|
||||
local hovered_label_color = {
|
||||
r = 0.5 * (1 + default_orange_color.r),
|
||||
g = 0.5 * (1 + default_orange_color.g),
|
||||
b = 0.5 * (1 + default_orange_color.b),
|
||||
}
|
||||
|
||||
styles.ltnm_clickable_semibold_label = {
|
||||
type = "label_style",
|
||||
parent = "ltnm_semibold_label",
|
||||
hovered_font_color = hovered_label_color,
|
||||
disabled_font_color = hovered_label_color,
|
||||
}
|
||||
|
||||
styles.ltnm_minimap_label = {
|
||||
type = "label_style",
|
||||
font = "default-game",
|
||||
font_color = default_font_color,
|
||||
size = 90,
|
||||
vertical_align = "bottom",
|
||||
horizontal_align = "right",
|
||||
right_padding = 4,
|
||||
}
|
||||
|
||||
styles.ltnm_semibold_label = {
|
||||
type = "label_style",
|
||||
font = "default-semibold",
|
||||
}
|
||||
|
||||
-- MINIMAP STYLES
|
||||
|
||||
styles.ltnm_train_minimap = {
|
||||
type = "minimap_style",
|
||||
size = 90,
|
||||
}
|
||||
|
||||
-- SCROLL PANE STYLES
|
||||
|
||||
styles.ltnm_table_scroll_pane = {
|
||||
type = "scroll_pane_style",
|
||||
parent = "flib_naked_scroll_pane_no_padding",
|
||||
vertical_flow_style = {
|
||||
type = "vertical_flow_style",
|
||||
vertical_spacing = 0,
|
||||
},
|
||||
}
|
||||
|
||||
styles.ltnm_slot_table_scroll_pane = {
|
||||
type = "scroll_pane_style",
|
||||
parent = "flib_naked_scroll_pane_no_padding",
|
||||
horizontally_squashable = "off",
|
||||
background_graphical_set = {
|
||||
base = {
|
||||
position = { 282, 17 },
|
||||
corner_size = 8,
|
||||
overall_tiling_horizontal_padding = 4,
|
||||
overall_tiling_horizontal_size = 32,
|
||||
overall_tiling_horizontal_spacing = 8,
|
||||
overall_tiling_vertical_padding = 4,
|
||||
overall_tiling_vertical_size = 32,
|
||||
overall_tiling_vertical_spacing = 8,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- TABBED PANE STYLES
|
||||
|
||||
styles.ltnm_tabbed_pane = {
|
||||
type = "tabbed_pane_style",
|
||||
tab_content_frame = {
|
||||
type = "frame_style",
|
||||
parent = "tabbed_pane_frame",
|
||||
left_padding = 12,
|
||||
right_padding = 12,
|
||||
bottom_padding = 8,
|
||||
},
|
||||
}
|
||||
23
cybersyn/prototypes/util.lua
Normal file
23
cybersyn/prototypes/util.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
local util = {}
|
||||
|
||||
local data_util = require("__flib__.data-util")
|
||||
|
||||
for key, value in pairs(require("__core__.lualib.util")) do
|
||||
util[key] = value
|
||||
end
|
||||
|
||||
util.paths = {
|
||||
nav_icons = "__LtnManager__/graphics/gui/frame-action-icons.png",
|
||||
shortcut_icons = "__LtnManager__/graphics/shortcut/ltn-manager-shortcut.png",
|
||||
}
|
||||
|
||||
util.empty_checkmark = {
|
||||
filename = data_util.empty_image,
|
||||
priority = "very-low",
|
||||
width = 1,
|
||||
height = 1,
|
||||
frame_count = 1,
|
||||
scale = 8,
|
||||
}
|
||||
|
||||
return util
|
||||
@@ -190,9 +190,9 @@ function register_gui_actions()
|
||||
["setting"] = handle_setting,
|
||||
["setting_flip"] = handle_setting_flip,
|
||||
})
|
||||
flib_gui.handle_events()
|
||||
script.on_event(defines.events.on_gui_opened, on_gui_opened)
|
||||
script.on_event(defines.events.on_gui_closed, on_gui_closed)
|
||||
flib_gui.handle_events()
|
||||
end
|
||||
|
||||
---@param comb LuaEntity
|
||||
|
||||
21
cybersyn/scripts/gui/LICENSE
Normal file
21
cybersyn/scripts/gui/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 raiguard
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
195
cybersyn/scripts/gui/actions.lua
Normal file
195
cybersyn/scripts/gui/actions.lua
Normal file
@@ -0,0 +1,195 @@
|
||||
local train_util = require("__flib__.train")
|
||||
|
||||
local constants = require("scripts.gui.constants")
|
||||
|
||||
local util = require("scripts.gui.util")
|
||||
|
||||
local actions = {}
|
||||
|
||||
local function toggle_fab(elem, sprite, state)
|
||||
if state then
|
||||
elem.style = "flib_selected_frame_action_button"
|
||||
elem.sprite = sprite .. "_black"
|
||||
else
|
||||
elem.style = "frame_action_button"
|
||||
elem.sprite = sprite .. "_white"
|
||||
end
|
||||
end
|
||||
|
||||
function actions.close(Gui)
|
||||
Gui:close()
|
||||
end
|
||||
|
||||
function actions.recenter(Gui)
|
||||
Gui.refs.window.force_auto_center()
|
||||
end
|
||||
|
||||
function actions.toggle_auto_refresh(Gui)
|
||||
Gui.state.auto_refresh = not Gui.state.auto_refresh
|
||||
toggle_fab(Gui.refs.titlebar.refresh_button, "ltnm_refresh", Gui.state.auto_refresh)
|
||||
end
|
||||
|
||||
function actions.toggle_pinned(Gui)
|
||||
Gui.state.pinned = not Gui.state.pinned
|
||||
toggle_fab(Gui.refs.titlebar.pin_button, "ltnm_pin", Gui.state.pinned)
|
||||
|
||||
if Gui.state.pinned then
|
||||
Gui.state.pinning = true
|
||||
Gui.player.opened = nil
|
||||
Gui.state.pinning = false
|
||||
else
|
||||
Gui.player.opened = Gui.refs.window
|
||||
Gui.refs.window.force_auto_center()
|
||||
end
|
||||
end
|
||||
|
||||
function actions.update_text_search_query(Gui, _, e)
|
||||
local query = e.text
|
||||
-- Input sanitization
|
||||
for pattern, replacement in pairs(constants.input_sanitizers) do
|
||||
query = string.gsub(query, pattern, replacement)
|
||||
end
|
||||
Gui.state.search_query = query
|
||||
|
||||
if Gui.state.search_job then
|
||||
on_tick_n.remove(Gui.state.search_job)
|
||||
end
|
||||
|
||||
if #query == 0 then
|
||||
Gui:schedule_update()
|
||||
else
|
||||
Gui.state.search_job = on_tick_n.add(
|
||||
game.tick + 30,
|
||||
{ gui = "main", action = "update", player_index = Gui.player.index }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function actions.update_network_id_query(Gui)
|
||||
Gui.state.network_id = tonumber(Gui.refs.toolbar.network_id_field.text) or -1
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.open_train_gui(Gui, msg)
|
||||
local train_id = msg.train_id
|
||||
local train_data = Gui.state.ltn_data.trains[train_id]
|
||||
|
||||
if not train_data or not train_data.train.valid then
|
||||
util.error_flying_text(Gui.player, { "message.ltnm-error-train-is-invalid" })
|
||||
return
|
||||
end
|
||||
|
||||
train_util.open_gui(Gui.player.index, train_data.train)
|
||||
end
|
||||
|
||||
function actions.open_station_gui(Gui, msg, e)
|
||||
local station_id = msg.station_id
|
||||
local station_data = Gui.state.ltn_data.stations[station_id]
|
||||
|
||||
if not station_data or not station_data.entity.valid then
|
||||
util.error_flying_text(Gui.player, { "message.ltnm-error-station-is-invalid" })
|
||||
return
|
||||
end
|
||||
|
||||
--- @type LuaPlayer
|
||||
local player = Gui.player
|
||||
|
||||
if e.shift then
|
||||
player.zoom_to_world(station_data.entity.position, 1)
|
||||
|
||||
rendering.draw_circle({
|
||||
color = constants.colors.red.tbl,
|
||||
target = station_data.entity.position,
|
||||
surface = station_data.entity.surface,
|
||||
radius = 0.5,
|
||||
filled = false,
|
||||
width = 5,
|
||||
time_to_live = 60 * 3,
|
||||
players = { player },
|
||||
})
|
||||
|
||||
if not Gui.state.pinned then
|
||||
Gui:close()
|
||||
end
|
||||
elseif e.control and remote.interfaces["ltn-combinator"] then
|
||||
if not remote.call("ltn-combinator", "open_ltn_combinator", e.player_index, station_data.lamp_control, true) then
|
||||
util.error_flying_text(player, { "message.ltnm-error-ltn-combinator-not-found" })
|
||||
end
|
||||
else
|
||||
player.opened = station_data.entity
|
||||
end
|
||||
end
|
||||
|
||||
function actions.toggle_sort(Gui, msg, e)
|
||||
local tab = msg.tab
|
||||
local column = msg.column
|
||||
|
||||
local sorts = Gui.state.sorts[tab]
|
||||
local active_column = sorts._active
|
||||
if active_column == column then
|
||||
sorts[column] = e.element.state
|
||||
else
|
||||
sorts._active = column
|
||||
e.element.state = sorts[column]
|
||||
|
||||
local widths = Gui.widths[tab]
|
||||
|
||||
local old_checkbox = Gui.refs[tab].toolbar[active_column .. "_checkbox"]
|
||||
old_checkbox.style = "ltnm_sort_checkbox"
|
||||
if widths[active_column .. "_checkbox_stretchy"] then
|
||||
old_checkbox.style.horizontally_stretchable = true
|
||||
else
|
||||
old_checkbox.style.width = widths[active_column]
|
||||
end
|
||||
e.element.style = "ltnm_selected_sort_checkbox"
|
||||
if widths[column .. "_checkbox_stretchy"] then
|
||||
e.element.style.horizontally_stretchable = true
|
||||
else
|
||||
e.element.style.width = widths[column]
|
||||
end
|
||||
end
|
||||
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.update(Gui)
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.change_tab(Gui, msg)
|
||||
Gui.state.active_tab = msg.tab
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.change_surface(Gui, _, e)
|
||||
local selected_index = e.element.selected_index
|
||||
local selected_surface_index = Gui.state.ltn_data.surfaces.selected_to_index[selected_index]
|
||||
if selected_surface_index then
|
||||
Gui.state.surface = selected_surface_index
|
||||
Gui:schedule_update()
|
||||
end
|
||||
end
|
||||
|
||||
function actions.clear_history(Gui)
|
||||
global.flags.deleted_history = true
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.delete_alert(Gui, msg)
|
||||
global.active_data.alerts_to_delete[msg.alert_id] = true
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.delete_all_alerts(Gui)
|
||||
global.flags.deleted_all_alerts = true
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
function actions.focus_search(Gui)
|
||||
if not Gui.pinned then
|
||||
Gui.refs.toolbar.text_search_field.select_all()
|
||||
Gui.refs.toolbar.text_search_field.focus()
|
||||
end
|
||||
end
|
||||
|
||||
return actions
|
||||
227
cybersyn/scripts/gui/alerts.lua
Normal file
227
cybersyn/scripts/gui/alerts.lua
Normal file
@@ -0,0 +1,227 @@
|
||||
local gui = require("__flib__.gui")
|
||||
local misc = require("__flib__.misc")
|
||||
|
||||
local constants = require("constants")
|
||||
local util = require("scripts.util")
|
||||
|
||||
local templates = require("templates")
|
||||
|
||||
local alerts_tab = {}
|
||||
|
||||
function alerts_tab.build(widths)
|
||||
return {
|
||||
tab = {
|
||||
type = "tab",
|
||||
caption = { "gui.ltnm-alerts" },
|
||||
ref = { "alerts", "tab" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "change_tab", tab = "alerts" },
|
||||
},
|
||||
},
|
||||
content = {
|
||||
type = "frame",
|
||||
style = "ltnm_main_content_frame",
|
||||
direction = "vertical",
|
||||
ref = { "alerts", "content_frame" },
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_table_toolbar_frame",
|
||||
style_mods = { right_padding = 4 },
|
||||
templates.sort_checkbox(widths, "alerts", "time", true, nil, true),
|
||||
templates.sort_checkbox(widths, "alerts", "train_id", false),
|
||||
templates.sort_checkbox(widths, "alerts", "route", false),
|
||||
templates.sort_checkbox(widths, "alerts", "network_id", false),
|
||||
templates.sort_checkbox(nil, "alerts", "type", false),
|
||||
{
|
||||
type = "sprite-button",
|
||||
style = "tool_button_red",
|
||||
sprite = "utility/trash",
|
||||
tooltip = { "gui.ltnm-delete-all-alerts" },
|
||||
ref = { "alerts", "delete_all_button" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "delete_all_alerts" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type = "scroll-pane", style = "ltnm_table_scroll_pane", ref = { "alerts", "scroll_pane" } },
|
||||
{
|
||||
type = "flow",
|
||||
style = "ltnm_warning_flow",
|
||||
visible = false,
|
||||
ref = { "alerts", "warning_flow" },
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_semibold_label",
|
||||
caption = { "gui.ltnm-no-alerts" },
|
||||
ref = { "alerts", "warning_label" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function alerts_tab.update(self)
|
||||
local dictionaries = self.player_table.dictionaries
|
||||
|
||||
local state = self.state
|
||||
local refs = self.refs.alerts
|
||||
local widths = self.widths
|
||||
|
||||
local search_query = state.search_query
|
||||
local search_network_id = state.network_id
|
||||
local search_surface = state.surface
|
||||
|
||||
local ltn_alerts = state.ltn_data.alerts
|
||||
local alerts_to_delete = global.active_data.alerts_to_delete
|
||||
|
||||
local scroll_pane = refs.scroll_pane
|
||||
local children = scroll_pane.children
|
||||
|
||||
local sorts = state.sorts[state.active_tab]
|
||||
local active_sort = sorts._active
|
||||
local sorted_alerts = state.ltn_data.sorted_alerts[active_sort]
|
||||
|
||||
local table_index = 0
|
||||
|
||||
-- False = ascending (arrow down), True = descending (arrow up)
|
||||
local start, finish, step
|
||||
if sorts[active_sort] then
|
||||
start = #sorted_alerts
|
||||
finish = 1
|
||||
step = -1
|
||||
else
|
||||
start = 1
|
||||
finish = #sorted_alerts
|
||||
step = 1
|
||||
end
|
||||
|
||||
if not global.flags.deleted_all_alerts then
|
||||
for sorted_index = start, finish, step do
|
||||
local alert_id = sorted_alerts[sorted_index]
|
||||
local alerts_entry = ltn_alerts[alert_id]
|
||||
|
||||
if
|
||||
(search_surface == -1 or (alerts_entry.train.surface_index == search_surface))
|
||||
and bit32.btest(alerts_entry.train.network_id, search_network_id)
|
||||
and (#search_query == 0 or string.find(
|
||||
alerts_entry.search_strings[self.player.index] or "",
|
||||
string.lower(search_query)
|
||||
))
|
||||
and not alerts_to_delete[alert_id]
|
||||
then
|
||||
table_index = table_index + 1
|
||||
local row = children[table_index]
|
||||
local color = table_index % 2 == 0 and "dark" or "light"
|
||||
if not row then
|
||||
row = gui.add(scroll_pane, {
|
||||
type = "frame",
|
||||
style = "ltnm_table_row_frame_" .. color,
|
||||
{ type = "label", style_mods = { width = widths.alerts.time } },
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.alerts.train_id, horizontal_align = "center" },
|
||||
tooltip = { "gui.ltnm-open-train-gui" },
|
||||
},
|
||||
{
|
||||
type = "flow",
|
||||
style_mods = { vertical_spacing = 0 },
|
||||
direction = "vertical",
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.alerts.route },
|
||||
tooltip = constants.open_station_gui_tooltip,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.alerts.route },
|
||||
tooltip = constants.open_station_gui_tooltip,
|
||||
},
|
||||
},
|
||||
{ type = "label", style_mods = { width = widths.alerts.network_id, horizontal_align = "center" } },
|
||||
{ type = "label", style_mods = { width = widths.alerts.type } },
|
||||
{
|
||||
type = "frame",
|
||||
name = "contents_frame",
|
||||
style = "ltnm_small_slot_table_frame_" .. color,
|
||||
style_mods = { width = widths.alerts.contents },
|
||||
{ type = "table", name = "contents_table", style = "slot_table", column_count = 4 },
|
||||
},
|
||||
{
|
||||
type = "sprite-button",
|
||||
style = "tool_button_red",
|
||||
sprite = "utility/trash",
|
||||
tooltip = { "gui.ltnm-delete-alert" },
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
gui.update(row, {
|
||||
{ elem_mods = { caption = misc.ticks_to_timestring(alerts_entry.time) } },
|
||||
{
|
||||
elem_mods = { caption = alerts_entry.train_id },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_train_gui", train_id = alerts_entry.train_id },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
elem_mods = { caption = alerts_entry.train.from },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_station_gui", station_id = alerts_entry.train.from_id },
|
||||
},
|
||||
},
|
||||
{
|
||||
elem_mods = {
|
||||
caption = "[color=" .. constants.colors.caption.str .. "]->[/color] " .. alerts_entry.train.to,
|
||||
},
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_station_gui", station_id = alerts_entry.train.to_id },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ elem_mods = { caption = util.signed_int32(alerts_entry.train.network_id) } },
|
||||
{
|
||||
elem_mods = {
|
||||
caption = { "gui.ltnm-alert-" .. string.gsub(alerts_entry.type, "_", "-") },
|
||||
tooltip = { "gui.ltnm-alert-" .. string.gsub(alerts_entry.type, "_", "-") .. "-description" },
|
||||
},
|
||||
},
|
||||
{},
|
||||
{
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "delete_alert", alert_id = alert_id },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
util.slot_table_update(row.contents_frame.contents_table, {
|
||||
{ color = "green", entries = alerts_entry.planned_shipment or {}, translations = dictionaries.materials },
|
||||
{ color = "red", entries = alerts_entry.actual_shipment or {}, translations = dictionaries.materials },
|
||||
{ color = "red", entries = alerts_entry.unscheduled_load or {}, translations = dictionaries.materials },
|
||||
{ color = "red", entries = alerts_entry.remaining_load or {}, translations = dictionaries.materials },
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for child_index = table_index + 1, #children do
|
||||
children[child_index].destroy()
|
||||
end
|
||||
|
||||
if table_index == 0 then
|
||||
refs.warning_flow.visible = true
|
||||
scroll_pane.visible = false
|
||||
refs.content_frame.style = "ltnm_main_warning_frame"
|
||||
refs.delete_all_button.enabled = false
|
||||
else
|
||||
refs.warning_flow.visible = false
|
||||
scroll_pane.visible = true
|
||||
refs.content_frame.style = "ltnm_main_content_frame"
|
||||
refs.delete_all_button.enabled = true
|
||||
end
|
||||
end
|
||||
|
||||
return alerts_tab
|
||||
152
cybersyn/scripts/gui/constants.lua
Normal file
152
cybersyn/scripts/gui/constants.lua
Normal file
@@ -0,0 +1,152 @@
|
||||
local constants = {}
|
||||
|
||||
constants.colors = {
|
||||
caption = {
|
||||
str = "255, 230, 192",
|
||||
tbl = { 255, 230, 192 },
|
||||
},
|
||||
green = {
|
||||
str = "69, 255, 69",
|
||||
tbl = { 69, 255, 69 },
|
||||
},
|
||||
info = {
|
||||
str = "128, 206, 240",
|
||||
tbl = { 128, 206, 240 },
|
||||
},
|
||||
red = {
|
||||
str = "255, 69, 69",
|
||||
tbl = { 255, 69, 69 },
|
||||
},
|
||||
station_circle = {
|
||||
str = "255, 50, 50, 190",
|
||||
tbl = { 255, 50, 50, 190 },
|
||||
},
|
||||
yellow = {
|
||||
str = "255, 240, 69",
|
||||
tbl = { 255, 240, 69 },
|
||||
},
|
||||
white = {
|
||||
str = "255, 255, 255",
|
||||
tbl = { 255, 255, 255 },
|
||||
},
|
||||
}
|
||||
|
||||
-- dictionary locale identifier -> dictionary of hardcoded GUI sizes
|
||||
constants.gui = {
|
||||
en = {
|
||||
trains = {
|
||||
train_id = 90,
|
||||
status = 378,
|
||||
composition = 200,
|
||||
depot = 149,
|
||||
shipment = 36 * 6,
|
||||
shipment_columns = 6,
|
||||
},
|
||||
stations = {
|
||||
name = 238,
|
||||
status = 53,
|
||||
network_id = 84,
|
||||
provided_requested = 36 * 6,
|
||||
provided_requested_columns = 6,
|
||||
shipments = 36 * 5,
|
||||
shipments_columns = 5,
|
||||
control_signals = 36 * 7,
|
||||
control_signals_columns = 7,
|
||||
},
|
||||
depots = {
|
||||
name = 200,
|
||||
network_id = 84,
|
||||
status = 200,
|
||||
trains = 200,
|
||||
},
|
||||
history = {
|
||||
train_id = 60,
|
||||
route = 357,
|
||||
depot = 160,
|
||||
network_id = 84,
|
||||
runtime = 68,
|
||||
finished = 68,
|
||||
shipment = (36 * 6),
|
||||
shipment_checkbox_stretchy = true,
|
||||
},
|
||||
alerts = {
|
||||
time = 68,
|
||||
train_id = 60,
|
||||
route = 326,
|
||||
network_id = 84,
|
||||
type = 230,
|
||||
type_checkbox_stretchy = true,
|
||||
contents = 36 * 6,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
constants.gui_content_frame_height = 744
|
||||
constants.gui_inventory_table_height = 40 * 18
|
||||
|
||||
constants.gui_translations = {
|
||||
delivering_to = { "gui.ltnm-delivering-to" },
|
||||
fetching_from = { "gui.ltnm-fetching-from" },
|
||||
loading_at = { "gui.ltnm-loading-at" },
|
||||
not_available = { "gui.ltnm-not-available" },
|
||||
parked_at_depot_with_residue = { "gui.ltnm-parked-at-depot-with-residue" },
|
||||
parked_at_depot = { "gui.ltnm-parked-at-depot" },
|
||||
returning_to_depot = { "gui.ltnm-returning-to-depot" },
|
||||
unloading_at = { "gui.ltnm-unloading-at" },
|
||||
}
|
||||
|
||||
constants.input_sanitizers = {
|
||||
["%%"] = "%%%%",
|
||||
["%("] = "%%(",
|
||||
["%)"] = "%%)",
|
||||
["%.^[%*]"] = "%%.",
|
||||
["%+"] = "%%+",
|
||||
["%-"] = "%%-",
|
||||
["^[%.]%*"] = "%%*",
|
||||
["%?"] = "%%?",
|
||||
["%["] = "%%[",
|
||||
["%]"] = "%%]",
|
||||
["%^"] = "%%^",
|
||||
["%$"] = "%%$",
|
||||
}
|
||||
|
||||
constants.ltn_control_signals = {
|
||||
["ltn-depot"] = true,
|
||||
["ltn-depot-priority"] = true,
|
||||
-- excluded because it's shown as a separate column
|
||||
-- ["ltn-network-id"] = true,
|
||||
["ltn-min-train-length"] = true,
|
||||
["ltn-max-train-length"] = true,
|
||||
["ltn-max-trains"] = true,
|
||||
["ltn-provider-threshold"] = true,
|
||||
["ltn-provider-stack-threshold"] = true,
|
||||
["ltn-provider-priority"] = true,
|
||||
["ltn-locked-slots"] = true,
|
||||
["ltn-requester-threshold"] = true,
|
||||
["ltn-requester-stack-threshold"] = true,
|
||||
["ltn-requester-priority"] = true,
|
||||
["ltn-disable-warnings"] = true,
|
||||
}
|
||||
|
||||
constants.ltn_event_names = {
|
||||
on_stops_updated = true,
|
||||
on_dispatcher_updated = true,
|
||||
-- on_delivery_pickup_complete = true,
|
||||
on_delivery_completed = true,
|
||||
on_delivery_failed = true,
|
||||
-- on_dispatcher_no_train_found = true,
|
||||
on_provider_missing_cargo = true,
|
||||
on_provider_unscheduled_cargo = true,
|
||||
on_requester_remaining_cargo = true,
|
||||
on_requester_unscheduled_cargo = true,
|
||||
}
|
||||
|
||||
if script then
|
||||
constants.open_station_gui_tooltip = {
|
||||
"",
|
||||
{ "gui.ltnm-open-station-gui" },
|
||||
remote.interfaces["ltn-combinator"] and { "", "\n", { "gui.ltnm-open-ltn-combinator-gui" } } or nil,
|
||||
}
|
||||
end
|
||||
|
||||
return constants
|
||||
144
cybersyn/scripts/gui/depots.lua
Normal file
144
cybersyn/scripts/gui/depots.lua
Normal file
@@ -0,0 +1,144 @@
|
||||
local gui = require("__flib__.gui")
|
||||
|
||||
local templates = require("templates")
|
||||
|
||||
local depots_tab = {}
|
||||
|
||||
function depots_tab.build(widths)
|
||||
return {
|
||||
tab = {
|
||||
type = "tab",
|
||||
caption = { "gui.ltnm-depots" },
|
||||
ref = { "depots", "tab" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "change_tab", tab = "depots" },
|
||||
},
|
||||
},
|
||||
content = {
|
||||
type = "frame",
|
||||
style = "ltnm_main_content_frame",
|
||||
direction = "vertical",
|
||||
ref = { "depots", "content_frame" },
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_table_toolbar_frame",
|
||||
style_mods = { right_padding = 4 },
|
||||
templates.sort_checkbox(widths, "depots", "name", true, nil, true),
|
||||
templates.sort_checkbox(widths, "depots", "network_id", false),
|
||||
templates.sort_checkbox(widths, "depots", "status", false, { "gui.ltnm-status-description" }),
|
||||
templates.sort_checkbox(widths, "depots", "trains", false),
|
||||
},
|
||||
{ type = "scroll-pane", style = "ltnm_table_scroll_pane", ref = { "depots", "scroll_pane" } },
|
||||
{
|
||||
type = "flow",
|
||||
style = "ltnm_warning_flow",
|
||||
visible = false,
|
||||
ref = { "depots", "warning_flow" },
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_semibold_label",
|
||||
caption = { "gui.ltnm-no-depots" },
|
||||
ref = { "depots", "warning_label" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function depots_tab.update(self)
|
||||
local state = self.state
|
||||
local refs = self.refs.depots
|
||||
local widths = self.widths.depots
|
||||
|
||||
local search_query = state.search_query
|
||||
local search_network_id = state.network_id
|
||||
local search_surface = state.surface
|
||||
|
||||
local ltn_depots = state.ltn_data.depots
|
||||
local scroll_pane = refs.scroll_pane
|
||||
local children = scroll_pane.children
|
||||
|
||||
local sorts = state.sorts.depots
|
||||
local active_sort = sorts._active
|
||||
local sorted_depots = state.ltn_data.sorted_depots[active_sort]
|
||||
|
||||
local table_index = 0
|
||||
|
||||
-- False = ascending (arrow down), True = descending (arrow up)
|
||||
local start, finish, step
|
||||
if sorts[active_sort] then
|
||||
start = #sorted_depots
|
||||
finish = 1
|
||||
step = -1
|
||||
else
|
||||
start = 1
|
||||
finish = #sorted_depots
|
||||
step = 1
|
||||
end
|
||||
|
||||
for sorted_index = start, finish, step do
|
||||
local depot_name = sorted_depots[sorted_index]
|
||||
local depot_data = ltn_depots[depot_name]
|
||||
|
||||
if
|
||||
(search_surface == -1 or depot_data.surfaces[search_surface])
|
||||
and bit32.btest(depot_data.network_id, search_network_id)
|
||||
and (#search_query == 0 or string.find(depot_data.search_string, string.lower(search_query)))
|
||||
then
|
||||
table_index = table_index + 1
|
||||
local row = children[table_index]
|
||||
local color = table_index % 2 == 0 and "dark" or "light"
|
||||
if not row then
|
||||
row = gui.add(scroll_pane, {
|
||||
type = "frame",
|
||||
style = "ltnm_table_row_frame_" .. color,
|
||||
{ type = "label", style_mods = { width = widths.name } },
|
||||
{ type = "label", style_mods = { width = widths.network_id, horizontal_align = "center" } },
|
||||
{ type = "flow", name = "statuses_flow", style_mods = { width = widths.status } },
|
||||
{ type = "label", style_mods = { width = widths.trains } },
|
||||
})
|
||||
end
|
||||
|
||||
gui.update(row, {
|
||||
{ elem_mods = { caption = depot_name } },
|
||||
{ elem_mods = { caption = depot_data.network_id } },
|
||||
{},
|
||||
{ elem_mods = { caption = depot_data.trains_string } },
|
||||
})
|
||||
|
||||
local statuses_flow = row.statuses_flow
|
||||
local statuses_children = statuses_flow.children
|
||||
local status_index = 0
|
||||
for color, count in pairs(depot_data.statuses) do
|
||||
status_index = status_index + 1
|
||||
local status_flow = statuses_children[status_index]
|
||||
if not status_flow then
|
||||
status_flow = gui.add(statuses_flow, templates.status_indicator())
|
||||
end
|
||||
gui.update(status_flow, {
|
||||
{ elem_mods = { sprite = "flib_indicator_" .. color } },
|
||||
{ elem_mods = { caption = count } },
|
||||
})
|
||||
end
|
||||
for child_index = status_index + 1, #statuses_children do
|
||||
statuses_children[child_index].destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for child_index = table_index + 1, #children do
|
||||
children[child_index].destroy()
|
||||
end
|
||||
|
||||
if table_index == 0 then
|
||||
refs.warning_flow.visible = true
|
||||
scroll_pane.visible = false
|
||||
refs.content_frame.style = "ltnm_main_warning_frame"
|
||||
else
|
||||
refs.warning_flow.visible = false
|
||||
scroll_pane.visible = true
|
||||
refs.content_frame.style = "ltnm_main_content_frame"
|
||||
end
|
||||
end
|
||||
|
||||
return depots_tab
|
||||
208
cybersyn/scripts/gui/history.lua
Normal file
208
cybersyn/scripts/gui/history.lua
Normal file
@@ -0,0 +1,208 @@
|
||||
local gui = require("__flib__.gui")
|
||||
local misc = require("__flib__.misc")
|
||||
|
||||
local constants = require("constants")
|
||||
local util = require("scripts.util")
|
||||
|
||||
local templates = require("templates")
|
||||
|
||||
local history_tab = {}
|
||||
|
||||
function history_tab.build(widths)
|
||||
return {
|
||||
tab = {
|
||||
type = "tab",
|
||||
caption = { "gui.ltnm-history" },
|
||||
ref = { "history", "tab" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "change_tab", tab = "history" },
|
||||
},
|
||||
},
|
||||
content = {
|
||||
type = "frame",
|
||||
style = "ltnm_main_content_frame",
|
||||
direction = "vertical",
|
||||
ref = { "history", "content_frame" },
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_table_toolbar_frame",
|
||||
style_mods = { right_padding = 4 },
|
||||
templates.sort_checkbox(widths, "history", "train_id", false),
|
||||
templates.sort_checkbox(widths, "history", "route", false),
|
||||
templates.sort_checkbox(widths, "history", "depot", false),
|
||||
templates.sort_checkbox(widths, "history", "network_id", false),
|
||||
templates.sort_checkbox(widths, "history", "runtime", false),
|
||||
templates.sort_checkbox(widths, "history", "finished", true, nil, true),
|
||||
templates.sort_checkbox(nil, "history", "shipment", false),
|
||||
{
|
||||
type = "sprite-button",
|
||||
style = "tool_button_red",
|
||||
sprite = "utility/trash",
|
||||
tooltip = { "gui.ltnm-clear-history" },
|
||||
ref = { "history", "clear_button" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "clear_history" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ type = "scroll-pane", style = "ltnm_table_scroll_pane", ref = { "history", "scroll_pane" } },
|
||||
{
|
||||
type = "flow",
|
||||
style = "ltnm_warning_flow",
|
||||
visible = false,
|
||||
ref = { "history", "warning_flow" },
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_semibold_label",
|
||||
caption = { "gui.ltnm-no-history" },
|
||||
ref = { "history", "warning_label" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function history_tab.update(self)
|
||||
local dictionaries = self.player_table.dictionaries
|
||||
|
||||
local state = self.state
|
||||
local refs = self.refs.history
|
||||
local widths = self.widths
|
||||
|
||||
local search_query = state.search_query
|
||||
local search_network_id = state.network_id
|
||||
local search_surface = state.surface
|
||||
|
||||
local ltn_history = state.ltn_data.history
|
||||
local scroll_pane = refs.scroll_pane
|
||||
local children = scroll_pane.children
|
||||
|
||||
local sorts = state.sorts[state.active_tab]
|
||||
local active_sort = sorts._active
|
||||
local sorted_history = state.ltn_data.sorted_history[active_sort]
|
||||
|
||||
local table_index = 0
|
||||
|
||||
-- False = ascending (arrow down), True = descending (arrow up)
|
||||
local start, finish, step
|
||||
if sorts[active_sort] then
|
||||
start = #sorted_history
|
||||
finish = 1
|
||||
step = -1
|
||||
else
|
||||
start = 1
|
||||
finish = #sorted_history
|
||||
step = 1
|
||||
end
|
||||
|
||||
if not global.flags.deleted_history then
|
||||
for sorted_index = start, finish, step do
|
||||
local history_id = sorted_history[sorted_index]
|
||||
local history_entry = ltn_history[history_id]
|
||||
|
||||
if
|
||||
(search_surface == -1 or (history_entry.surface_index == search_surface))
|
||||
and bit32.btest(history_entry.network_id, search_network_id)
|
||||
and (
|
||||
#search_query == 0 or string.find(history_entry.search_strings[self.player.index], string.lower(search_query))
|
||||
)
|
||||
then
|
||||
table_index = table_index + 1
|
||||
local row = children[table_index]
|
||||
local color = table_index % 2 == 0 and "dark" or "light"
|
||||
if not row then
|
||||
row = gui.add(scroll_pane, {
|
||||
type = "frame",
|
||||
style = "ltnm_table_row_frame_" .. color,
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.history.train_id, horizontal_align = "center" },
|
||||
tooltip = constants.open_station_gui_tooltip,
|
||||
},
|
||||
{
|
||||
type = "flow",
|
||||
style_mods = { vertical_spacing = 0 },
|
||||
direction = "vertical",
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.history.route },
|
||||
tooltip = constants.open_station_gui_tooltip,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.history.route },
|
||||
tooltip = constants.open_station_gui_tooltip,
|
||||
},
|
||||
},
|
||||
{ type = "label", style_mods = { width = widths.history.depot } },
|
||||
{ type = "label", style_mods = { width = widths.history.network_id, horizontal_align = "center" } },
|
||||
{ type = "label", style_mods = { width = widths.history.finished, horizontal_align = "center" } },
|
||||
{ type = "label", style_mods = { width = widths.history.runtime, horizontal_align = "center" } },
|
||||
{
|
||||
type = "frame",
|
||||
name = "shipment_frame",
|
||||
style = "ltnm_small_slot_table_frame_" .. color,
|
||||
style_mods = { width = widths.history.shipment },
|
||||
{ type = "table", name = "shipment_table", style = "slot_table", column_count = 4 },
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
gui.update(row, {
|
||||
{
|
||||
elem_mods = { caption = history_entry.train_id },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_train_gui", train_id = history_entry.train_id },
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
elem_mods = { caption = history_entry.from },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_station_gui", station_id = history_entry.from_id },
|
||||
},
|
||||
},
|
||||
{
|
||||
elem_mods = {
|
||||
caption = "[color=" .. constants.colors.caption.str .. "]->[/color] " .. history_entry.to,
|
||||
},
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_station_gui", station_id = history_entry.to_id },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ elem_mods = { caption = history_entry.depot } },
|
||||
{ elem_mods = { caption = util.signed_int32(history_entry.network_id) } },
|
||||
{ elem_mods = { caption = misc.ticks_to_timestring(history_entry.runtime) } },
|
||||
{ elem_mods = { caption = misc.ticks_to_timestring(history_entry.finished) } },
|
||||
})
|
||||
|
||||
util.slot_table_update(
|
||||
row.shipment_frame.shipment_table,
|
||||
{ { color = "default", entries = history_entry.shipment, translations = dictionaries.materials } }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for child_index = table_index + 1, #children do
|
||||
children[child_index].destroy()
|
||||
end
|
||||
|
||||
if table_index == 0 then
|
||||
refs.warning_flow.visible = true
|
||||
scroll_pane.visible = false
|
||||
refs.content_frame.style = "ltnm_main_warning_frame"
|
||||
refs.clear_button.enabled = false
|
||||
else
|
||||
refs.warning_flow.visible = false
|
||||
scroll_pane.visible = true
|
||||
refs.content_frame.style = "ltnm_main_content_frame"
|
||||
refs.clear_button.enabled = true
|
||||
end
|
||||
end
|
||||
|
||||
return history_tab
|
||||
87
cybersyn/scripts/gui/inventory.lua
Normal file
87
cybersyn/scripts/gui/inventory.lua
Normal file
@@ -0,0 +1,87 @@
|
||||
local misc = require("__flib__.misc")
|
||||
|
||||
local templates = require("templates")
|
||||
|
||||
local inventory_tab = {}
|
||||
|
||||
function inventory_tab.build()
|
||||
return {
|
||||
tab = {
|
||||
type = "tab",
|
||||
caption = { "gui.ltnm-inventory" },
|
||||
ref = { "inventory", "tab" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "change_tab", tab = "inventory" },
|
||||
},
|
||||
},
|
||||
content = {
|
||||
type = "flow",
|
||||
style_mods = { horizontal_spacing = 12 },
|
||||
direction = "horizontal",
|
||||
ref = { "inventory", "content_frame" },
|
||||
templates.inventory_slot_table("provided", 12),
|
||||
templates.inventory_slot_table("in_transit", 8),
|
||||
templates.inventory_slot_table("requested", 6),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local function update_table(self, name, color)
|
||||
local translations = self.player_table.dictionaries.materials
|
||||
|
||||
local state = self.state
|
||||
local refs = self.refs.inventory
|
||||
|
||||
local search_query = state.search_query
|
||||
local search_network_id = state.network_id
|
||||
local search_surface = state.surface
|
||||
|
||||
local ltn_inventory = state.ltn_data.inventory[name][search_surface]
|
||||
|
||||
local i = 0
|
||||
|
||||
local table = refs[name].table
|
||||
local children = table.children
|
||||
|
||||
for name, count_by_network_id in pairs(ltn_inventory or {}) do
|
||||
if
|
||||
bit32.btest(count_by_network_id.combined_id, search_network_id)
|
||||
and string.find(string.lower(translations[name]), string.lower(search_query))
|
||||
then
|
||||
local running_count = 0
|
||||
for network_id, count in pairs(count_by_network_id) do
|
||||
if network_id ~= "combined_id" and bit32.btest(network_id, search_network_id) then
|
||||
running_count = running_count + count
|
||||
end
|
||||
end
|
||||
|
||||
if running_count > 0 then
|
||||
i = i + 1
|
||||
local button = children[i]
|
||||
if not button then
|
||||
button = table.add({ type = "sprite-button", style = "flib_slot_button_" .. color, enabled = false })
|
||||
end
|
||||
button.sprite = string.gsub(name, ",", "/")
|
||||
button.number = running_count
|
||||
button.tooltip = "[img="
|
||||
.. string.gsub(name, ",", "/")
|
||||
.. "] [font=default-semibold]"
|
||||
.. translations[name]
|
||||
.. "[/font]\n"
|
||||
.. misc.delineate_number(running_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for j = i + 1, #children do
|
||||
children[j].destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function inventory_tab.update(self)
|
||||
update_table(self, "provided", "green")
|
||||
update_table(self, "in_transit", "blue")
|
||||
update_table(self, "requested", "red")
|
||||
end
|
||||
|
||||
return inventory_tab
|
||||
270
cybersyn/scripts/gui/manager.lua
Normal file
270
cybersyn/scripts/gui/manager.lua
Normal file
@@ -0,0 +1,270 @@
|
||||
local gui = require("__flib__.gui-lite")
|
||||
|
||||
local constants = require("scripts.gui.constants")
|
||||
|
||||
--local actions = require("scripts.gui.actions")
|
||||
local templates = require("scripts.gui.templates")
|
||||
|
||||
local trains_tab = require("scripts.gui.trains")
|
||||
--local depots_tab = require("scripts.gui.depots")
|
||||
--local stations_tab = require("scripts.gui.stations")
|
||||
--local inventory_tab = require("scripts.gui.inventory")
|
||||
--local history_tab = require("scripts.gui.history")
|
||||
--local alerts_tab = require("scripts.gui.alerts")
|
||||
|
||||
|
||||
function Index:dispatch(msg, e)
|
||||
-- "Transform" the action based on criteria
|
||||
if msg.transform == "handle_refresh_click" then
|
||||
if e.shift then
|
||||
msg.action = "toggle_auto_refresh"
|
||||
else
|
||||
self.state.ltn_data = global.data
|
||||
self.do_update = true
|
||||
end
|
||||
elseif msg.transform == "handle_titlebar_click" then
|
||||
if e.button == defines.mouse_button_type.middle then
|
||||
msg.action = "recenter"
|
||||
end
|
||||
end
|
||||
|
||||
-- Dispatch the associated action
|
||||
if msg.action then
|
||||
local func = self.actions[msg.action]
|
||||
if func then
|
||||
func(self, msg, e)
|
||||
else
|
||||
log("Attempted to call action `" .. msg.action .. "` for which there is no handler yet.")
|
||||
end
|
||||
end
|
||||
|
||||
-- Update if necessary
|
||||
if self.do_update then
|
||||
self:update()
|
||||
self.do_update = false
|
||||
end
|
||||
end
|
||||
|
||||
function Index:schedule_update()
|
||||
self.do_update = true
|
||||
end
|
||||
|
||||
|
||||
local manager = {}
|
||||
|
||||
|
||||
function manager.build(player, player_data)
|
||||
local widths = constants.gui["en"]
|
||||
---@type table<string, LuaGuiElement>
|
||||
local refs = {}
|
||||
|
||||
local _, window = gui.add(player.gui.screen, {
|
||||
{
|
||||
name = "manager_window",
|
||||
type = "frame",
|
||||
direction = "vertical",
|
||||
visible = false,
|
||||
handler = manager_handle.close,
|
||||
children = {
|
||||
{
|
||||
name = "manager_titlebar",
|
||||
type = "flow",
|
||||
style = "flib_titlebar_flow",
|
||||
handler = manager_handle.titlebar_click,
|
||||
children = {
|
||||
{ type = "label", style = "frame_title", caption = { "mod-name.LtnManager" }, ignored_by_interaction = true },
|
||||
{ type = "empty-widget", style = "flib_titlebar_drag_handle", ignored_by_interaction = true },
|
||||
{
|
||||
name = "manager_dispatcher_status_label",
|
||||
type = "label",
|
||||
style = "bold_label",
|
||||
style_mods = { font_color = constants.colors.red.tbl, left_margin = -4, top_margin = 1 },
|
||||
caption = { "gui.ltnm-dispatcher-disabled" },
|
||||
tooltip = { "gui.ltnm-dispatcher-disabled-description" },
|
||||
visible = not settings.global["cybersyn-enable-planner"].value,
|
||||
},
|
||||
templates.frame_action_button("manager_pin_button", "ltnm_pin", { "gui.ltnm-keep-open" }, manager_handle.pin),--on_gui_clicked
|
||||
templates.frame_action_button("manager_refresh_button", "ltnm_refresh", { "gui.ltnm-refresh-tooltip" }, manager_handle.refresh_click),--on_gui_clicked
|
||||
templates.frame_action_button(nil, "utility/close", { "gui.close-instruction" }, manager_handle.close),--on_gui_clicked
|
||||
},
|
||||
},
|
||||
{
|
||||
type = "frame",
|
||||
style = "inside_deep_frame",
|
||||
direction = "vertical",
|
||||
children = {
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_main_toolbar_frame",
|
||||
children = {
|
||||
{ type = "label", style = "subheader_caption_label", caption = { "gui.ltnm-search-label" } },
|
||||
{
|
||||
name = "manager_text_search_field",
|
||||
type = "textfield",
|
||||
clear_and_focus_on_right_click = true,
|
||||
handler = manager_handle.update_text_search_query, --on_gui_text_changed
|
||||
},
|
||||
{ type = "empty-widget", style = "flib_horizontal_pusher" },
|
||||
{ type = "label", style = "caption_label", caption = { "gui.ltnm-network-id-label" } },
|
||||
{
|
||||
name = "manager_network_id_field",
|
||||
type = "textfield",
|
||||
style_mods = { width = 120 },
|
||||
numeric = true,
|
||||
allow_negative = true,
|
||||
clear_and_focus_on_right_click = true,
|
||||
text = "-1",
|
||||
handler = manager_handle.update_network_id_query, --on_gui_text_changed
|
||||
},
|
||||
{ type = "label", style = "caption_label", caption = { "gui.ltnm-surface-label" } },
|
||||
{
|
||||
name = "manager_surface_dropdown",
|
||||
type = "drop-down",
|
||||
handler = manager_handle.change_surface, --on_gui_selection_state_changed
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "manager_tabbed_pane",
|
||||
type = "tabbed-pane",
|
||||
style = "ltnm_tabbed_pane",
|
||||
children = {
|
||||
trains_tab.build(widths, refs),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, refs)
|
||||
|
||||
|
||||
|
||||
refs.manager_titlebar.drag_target = window
|
||||
window.force_auto_center()
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.destroy(player, refs)
|
||||
refs.manager_window.destroy()
|
||||
|
||||
player.set_shortcut_toggled("ltnm-toggle-gui", false)
|
||||
player.set_shortcut_available("ltnm-toggle-gui", false)
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.open(player, player_data, refs)
|
||||
refs.manager_window.bring_to_front()
|
||||
refs.manager_window.visible = true
|
||||
player_data.visible = true
|
||||
|
||||
if not player_data.pinning then
|
||||
player.opened = refs.manager_window
|
||||
end
|
||||
|
||||
player.set_shortcut_toggled("ltnm-toggle-gui", true)
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.close(player, player_data, refs)
|
||||
if player_data.pinning then
|
||||
return
|
||||
end
|
||||
|
||||
refs.manager_window.visible = false
|
||||
player_data.visible = false
|
||||
|
||||
if player.opened == refs.manager_window then
|
||||
player.opened = nil
|
||||
end
|
||||
|
||||
player.set_shortcut_toggled("ltnm-toggle-gui", false)
|
||||
end
|
||||
|
||||
|
||||
manager.handle = {}
|
||||
|
||||
--- @param e GuiEventData
|
||||
function manager.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, refs)
|
||||
end
|
||||
|
||||
|
||||
local function toggle_fab(elem, sprite, state)
|
||||
if state then
|
||||
elem.style = "flib_selected_frame_action_button"
|
||||
elem.sprite = sprite .. "_black"
|
||||
else
|
||||
elem.style = "frame_action_button"
|
||||
elem.sprite = sprite .. "_white"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
manager.handle.close = manager.close
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.handle.recenter(player, player_data, refs)
|
||||
refs.window.force_auto_center()
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.handle.toggle_auto_refresh(player, player_data, refs)
|
||||
player_data.auto_refresh = not player_data.auto_refresh
|
||||
toggle_fab(refs.manager_refresh_button, "ltnm_refresh", player_data.auto_refresh)
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.handle.toggle_pinned(player, player_data, refs)
|
||||
player_data.pinned = not player_data.pinned
|
||||
toggle_fab(refs.manager_pin_button, "ltnm_pin", player_data.pinned)
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.handle.update_text_search_query(player, player_data, refs)
|
||||
local query = e.text
|
||||
-- Input sanitization
|
||||
for pattern, replacement in pairs(constants.input_sanitizers) do
|
||||
query = string.gsub(query, pattern, replacement)
|
||||
end
|
||||
Gui.state.search_query = query
|
||||
|
||||
if Gui.state.search_job then
|
||||
on_tick_n.remove(Gui.state.search_job)
|
||||
end
|
||||
|
||||
if #query == 0 then
|
||||
Gui:schedule_update()
|
||||
else
|
||||
Gui.state.search_job = on_tick_n.add(
|
||||
game.tick + 30,
|
||||
{ gui = "main", action = "update", player_index = Gui.player.index }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--- @param player LuaPlayer
|
||||
--- @param player_data PlayerData
|
||||
--- @param refs table<string, LuaGuiElement>
|
||||
function manager.handle.update_network_id_query(player, player_data, refs)
|
||||
Gui.state.network_id = tonumber(Gui.refs.toolbar.network_id_field.text) or -1
|
||||
Gui:schedule_update()
|
||||
end
|
||||
|
||||
return manager
|
||||
174
cybersyn/scripts/gui/stations.lua
Normal file
174
cybersyn/scripts/gui/stations.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
local gui = require("__flib__.gui")
|
||||
|
||||
local constants = require("constants")
|
||||
|
||||
local util = require("scripts.util")
|
||||
|
||||
local templates = require("templates")
|
||||
|
||||
local stations_tab = {}
|
||||
|
||||
function stations_tab.build(widths)
|
||||
return {
|
||||
tab = {
|
||||
type = "tab",
|
||||
caption = { "gui.ltnm-stations" },
|
||||
ref = { "stations", "tab" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "change_tab", tab = "stations" },
|
||||
},
|
||||
},
|
||||
content = {
|
||||
type = "frame",
|
||||
style = "ltnm_main_content_frame",
|
||||
direction = "vertical",
|
||||
ref = { "stations", "content_frame" },
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_table_toolbar_frame",
|
||||
templates.sort_checkbox(widths, "stations", "name", true),
|
||||
templates.sort_checkbox(widths, "stations", "status", false, { "gui.ltnm-status-description" }),
|
||||
templates.sort_checkbox(widths, "stations", "network_id", false),
|
||||
templates.sort_checkbox(
|
||||
widths,
|
||||
"stations",
|
||||
"provided_requested",
|
||||
false,
|
||||
{ "gui.ltnm-provided-requested-description" }
|
||||
),
|
||||
templates.sort_checkbox(widths, "stations", "shipments", false, { "gui.ltnm-shipments-description" }),
|
||||
templates.sort_checkbox(widths, "stations", "control_signals", false),
|
||||
},
|
||||
{ type = "scroll-pane", style = "ltnm_table_scroll_pane", ref = { "stations", "scroll_pane" } },
|
||||
{
|
||||
type = "flow",
|
||||
style = "ltnm_warning_flow",
|
||||
visible = false,
|
||||
ref = { "stations", "warning_flow" },
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_semibold_label",
|
||||
caption = { "gui.ltnm-no-stations" },
|
||||
ref = { "stations", "warning_label" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function stations_tab.update(self)
|
||||
local dictionaries = self.player_table.dictionaries
|
||||
|
||||
local state = self.state
|
||||
local refs = self.refs.stations
|
||||
local widths = self.widths.stations
|
||||
|
||||
local search_query = state.search_query
|
||||
local search_network_id = state.network_id
|
||||
local search_surface = state.surface
|
||||
|
||||
local ltn_stations = state.ltn_data.stations
|
||||
local scroll_pane = refs.scroll_pane
|
||||
local children = scroll_pane.children
|
||||
|
||||
local sorts = state.sorts.stations
|
||||
local active_sort = sorts._active
|
||||
local sorted_stations = state.ltn_data.sorted_stations[active_sort]
|
||||
|
||||
local table_index = 0
|
||||
|
||||
-- False = ascending (arrow down), True = descending (arrow up)
|
||||
local start, finish, step
|
||||
if sorts[active_sort] then
|
||||
start = #sorted_stations
|
||||
finish = 1
|
||||
step = -1
|
||||
else
|
||||
start = 1
|
||||
finish = #sorted_stations
|
||||
step = 1
|
||||
end
|
||||
|
||||
for sorted_index = start, finish, step do
|
||||
local station_id = sorted_stations[sorted_index]
|
||||
local station_data = ltn_stations[station_id]
|
||||
|
||||
if station_data.entity.valid then
|
||||
if
|
||||
(search_surface == -1 or station_data.entity.surface.index == search_surface)
|
||||
and bit32.btest(station_data.network_id, search_network_id)
|
||||
and (
|
||||
#search_query == 0 or string.find(station_data.search_strings[self.player.index], string.lower(search_query))
|
||||
)
|
||||
then
|
||||
table_index = table_index + 1
|
||||
local row = children[table_index]
|
||||
local color = table_index % 2 == 0 and "dark" or "light"
|
||||
if not row then
|
||||
row = gui.add(scroll_pane, {
|
||||
type = "frame",
|
||||
style = "ltnm_table_row_frame_" .. color,
|
||||
{
|
||||
type = "label",
|
||||
style = "ltnm_clickable_semibold_label",
|
||||
style_mods = { width = widths.name },
|
||||
tooltip = constants.open_station_gui_tooltip,
|
||||
},
|
||||
templates.status_indicator(widths.status, true),
|
||||
{ type = "label", style_mods = { width = widths.network_id, horizontal_align = "center" } },
|
||||
templates.small_slot_table(widths, color, "provided_requested"),
|
||||
templates.small_slot_table(widths, color, "shipments"),
|
||||
templates.small_slot_table(widths, color, "control_signals"),
|
||||
})
|
||||
end
|
||||
|
||||
gui.update(row, {
|
||||
{
|
||||
elem_mods = { caption = station_data.name },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_station_gui", station_id = station_id },
|
||||
},
|
||||
},
|
||||
{
|
||||
{ elem_mods = { sprite = "flib_indicator_" .. station_data.status.color } },
|
||||
{ elem_mods = { caption = station_data.status.count } },
|
||||
},
|
||||
{ elem_mods = { caption = station_data.network_id } },
|
||||
})
|
||||
|
||||
util.slot_table_update(row.provided_requested_frame.provided_requested_table, {
|
||||
{ color = "green", entries = station_data.provided, translations = dictionaries.materials },
|
||||
{ color = "red", entries = station_data.requested, translations = dictionaries.materials },
|
||||
})
|
||||
util.slot_table_update(row.shipments_frame.shipments_table, {
|
||||
{ color = "green", entries = station_data.inbound, translations = dictionaries.materials },
|
||||
{ color = "blue", entries = station_data.outbound, translations = dictionaries.materials },
|
||||
})
|
||||
util.slot_table_update(row.control_signals_frame.control_signals_table, {
|
||||
{
|
||||
color = "default",
|
||||
entries = station_data.control_signals,
|
||||
translations = dictionaries.virtual_signals,
|
||||
type = "virtual-signal",
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for child_index = table_index + 1, #children do
|
||||
children[child_index].destroy()
|
||||
end
|
||||
|
||||
if table_index == 0 then
|
||||
refs.warning_flow.visible = true
|
||||
scroll_pane.visible = false
|
||||
refs.content_frame.style = "ltnm_main_warning_frame"
|
||||
else
|
||||
refs.warning_flow.visible = false
|
||||
scroll_pane.visible = true
|
||||
refs.content_frame.style = "ltnm_main_content_frame"
|
||||
end
|
||||
end
|
||||
|
||||
return stations_tab
|
||||
100
cybersyn/scripts/gui/templates.lua
Normal file
100
cybersyn/scripts/gui/templates.lua
Normal file
@@ -0,0 +1,100 @@
|
||||
local constants = require("constants")
|
||||
|
||||
local templates = {}
|
||||
|
||||
--- Creates a frame action button, automatically accounting for inverted sprites.
|
||||
--- @param name string?
|
||||
--- @param sprite string?
|
||||
--- @param tooltip LocalisedString?
|
||||
--- @param handler GuiElemHandler?
|
||||
--- @param tags Tags?
|
||||
function templates.frame_action_button(name, sprite, tooltip, handler, tags)
|
||||
return {
|
||||
type = "sprite-button",
|
||||
name = name,
|
||||
style = "frame_action_button",
|
||||
sprite = sprite .. "_white",
|
||||
hovered_sprite = sprite .. "_black",
|
||||
clicked_sprite = sprite .. "_black",
|
||||
mouse_button_filter = { "left" },
|
||||
tooltip = tooltip,
|
||||
handler = handler,
|
||||
tags = tags,
|
||||
}
|
||||
end
|
||||
|
||||
--- Creates a full-sized scrollable slot table for the inventory tab.
|
||||
--- @param name string
|
||||
--- @param columns uint
|
||||
function templates.inventory_slot_table(name, columns)
|
||||
return {
|
||||
type = "flow",
|
||||
direction = "vertical",
|
||||
{ type = "label", style = "bold_label", caption = { "gui.ltnm-" .. string.gsub(name, "_", "-") } },
|
||||
{
|
||||
type = "frame",
|
||||
style = "deep_frame_in_shallow_frame",
|
||||
style_mods = { height = constants.gui_inventory_table_height },
|
||||
ref = { "inventory", name, "frame" },
|
||||
{
|
||||
type = "scroll-pane",
|
||||
style = "ltnm_slot_table_scroll_pane",
|
||||
style_mods = { width = 40 * columns + 12, minimal_height = constants.gui_inventory_table_height },
|
||||
vertical_scroll_policy = "auto-and-reserve-space",
|
||||
-- vertical_scroll_policy = "always",
|
||||
ref = { "inventory", name, "scroll_pane" },
|
||||
{ type = "table", style = "slot_table", column_count = columns, ref = { "inventory", name, "table" } },
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
--- Creates a small non-scrollable slot table.
|
||||
--- @param widths table
|
||||
--- @param color string
|
||||
--- @param name string
|
||||
function templates.small_slot_table(widths, color, name)
|
||||
return {
|
||||
type = "frame",
|
||||
name = name .. "_frame",
|
||||
style = "ltnm_small_slot_table_frame_" .. color,
|
||||
style_mods = { width = widths[name] },
|
||||
{ type = "table", name = name .. "_table", style = "slot_table", column_count = widths[name .. "_columns"] },
|
||||
}
|
||||
end
|
||||
|
||||
--- Creates a column header with a sort toggle.
|
||||
--- @param widths table
|
||||
--- @param tab string
|
||||
--- @param column string
|
||||
--- @param selected boolean
|
||||
--- @param tooltip LocalisedString
|
||||
function templates.sort_checkbox(widths, tab, column, selected, tooltip, state)
|
||||
if state == nil then
|
||||
state = false
|
||||
end
|
||||
return {
|
||||
type = "checkbox",
|
||||
style = selected and "ltnm_selected_sort_checkbox" or "ltnm_sort_checkbox",
|
||||
style_mods = { width = widths and widths[tab][column] or nil, horizontally_stretchable = not widths },
|
||||
caption = { "gui.ltnm-" .. string.gsub(column, "_", "-") },
|
||||
tooltip = tooltip,
|
||||
state = state,
|
||||
ref = { tab, "toolbar", column .. "_checkbox" },
|
||||
actions = {
|
||||
on_checked_state_changed = { gui = "main", tab = tab, action = "toggle_sort", column = column },
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function templates.status_indicator(width, center)
|
||||
return {
|
||||
type = "flow",
|
||||
style = "flib_indicator_flow",
|
||||
style_mods = { horizontal_align = center and "center" or nil, width = width },
|
||||
{ type = "sprite", style = "flib_indicator" },
|
||||
{ type = "label" },
|
||||
}
|
||||
end
|
||||
|
||||
return templates
|
||||
151
cybersyn/scripts/gui/trains.lua
Normal file
151
cybersyn/scripts/gui/trains.lua
Normal file
@@ -0,0 +1,151 @@
|
||||
local gui = require("__flib__.gui-lite")
|
||||
|
||||
local constants = require("constants")
|
||||
local util = require("scripts.gui.util")
|
||||
|
||||
local templates = require("templates")
|
||||
|
||||
local trains_tab = {}
|
||||
|
||||
|
||||
function trains_tab.build(map_data, player_id, player_data)
|
||||
local widths = constants.gui["en"]
|
||||
|
||||
local search_query = player_data.search_query
|
||||
local search_network_flag = player_data.network_flag
|
||||
local search_network = player_data.network
|
||||
|
||||
local trains_sorted = player_data.trains_sorted
|
||||
|
||||
---@type GuiElemDef
|
||||
local train_list = {}
|
||||
--if not sorted_trains then
|
||||
-- sorted_trains = {}
|
||||
-- ids = {}
|
||||
-- for id, train in pairs(map_data) do
|
||||
-- local i = #ids + 1
|
||||
-- ids[i] = id
|
||||
-- sorted_trains[i] = train
|
||||
-- end
|
||||
-- dual_sort(ids, sorted_trains)
|
||||
--end
|
||||
if #trains_sorted == 0 then
|
||||
train_list[1] = {
|
||||
type = "label",
|
||||
style = "ltnm_semibold_label",
|
||||
caption = { "gui.ltnm-no-trains" },
|
||||
ref = { "trains", "warning_label" },
|
||||
}
|
||||
else
|
||||
local start, finish, step
|
||||
if player_data.trains_ascending then
|
||||
start = #trains_sorted
|
||||
finish = 1
|
||||
step = -1
|
||||
else
|
||||
start = 1
|
||||
finish = #trains_sorted
|
||||
step = 1
|
||||
end
|
||||
|
||||
local gui_idx = 1
|
||||
for idx = start, finish, step do
|
||||
local train_id = trains_sorted[idx]
|
||||
local train = map_data.trains[train_id]
|
||||
|
||||
if
|
||||
true
|
||||
then
|
||||
local color = gui_idx % 2 == 0 and "dark" or "light"
|
||||
train_list[gui_idx] = {
|
||||
type = "frame",
|
||||
style = "ltnm_table_row_frame_" .. color,
|
||||
children = {
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_table_inset_frame_" .. color,
|
||||
children = {
|
||||
type = "minimap",
|
||||
style = "ltnm_train_minimap",
|
||||
{ type = "label", style = "ltnm_minimap_label" },
|
||||
{
|
||||
type = "button",
|
||||
style = "ltnm_train_minimap_button",
|
||||
tooltip = { "gui.ltnm-open-train-gui" },
|
||||
elem_mods = { entity = get_any_train_entity(train.entity) },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "open_train_gui", train_id = train_id },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
style_mods = { width = widths.trains.composition },
|
||||
elem_mods = { caption = train.composition },
|
||||
},
|
||||
{
|
||||
type = "label", style_mods = { width = widths.trains.depot },
|
||||
elem_mods = { caption = train.depot },
|
||||
},
|
||||
{
|
||||
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"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
gui_idx = gui_idx + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
tab = {
|
||||
type = "tab",
|
||||
caption = #trains_sorted == 0 and { "gui.ltnm-trains" } or { "gui.ltnm-trains", #train_list },
|
||||
badge_text = misc.delineate_number(#ltn_data.sorted_trains.composition),
|
||||
ref = { "trains", "tab" },
|
||||
actions = {
|
||||
on_click = { gui = "main", action = "change_tab", tab = "trains" },
|
||||
},
|
||||
},
|
||||
content = {
|
||||
type = "frame",
|
||||
style = "ltnm_main_content_frame",
|
||||
direction = "vertical",
|
||||
ref = { "trains", "content_frame" },
|
||||
children = {
|
||||
{
|
||||
type = "frame",
|
||||
style = "ltnm_table_toolbar_frame",
|
||||
templates.sort_checkbox(widths, "trains", "train_id", true),
|
||||
templates.sort_checkbox(widths, "trains", "status", false),
|
||||
templates.sort_checkbox(widths, "trains", "composition", false, { "gui.ltnm-composition-description" }),
|
||||
templates.sort_checkbox(widths, "trains", "depot", false),
|
||||
templates.sort_checkbox(widths, "trains", "shipment", false),
|
||||
},
|
||||
{ type = "scroll-pane", style = "ltnm_table_scroll_pane", ref = { "trains", "scroll_pane" } },
|
||||
{
|
||||
type = "flow",
|
||||
style = "ltnm_warning_flow",
|
||||
visible = false,
|
||||
ref = { "trains", "warning_flow" },
|
||||
children = train_list,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
return trains_tab
|
||||
90
cybersyn/scripts/gui/util.lua
Normal file
90
cybersyn/scripts/gui/util.lua
Normal file
@@ -0,0 +1,90 @@
|
||||
local gui = require("__flib__.gui-lite")
|
||||
local format = require("__flib__.format")
|
||||
|
||||
local util = {}
|
||||
|
||||
--- Create a flying text at the player's cursor with an error sound.
|
||||
--- @param player LuaPlayer
|
||||
--- @param message LocalisedString
|
||||
function util.error_flying_text(player, message)
|
||||
player.create_local_flying_text({ create_at_cursor = true, text = message })
|
||||
player.play_sound({ path = "utility/cannot_build" })
|
||||
end
|
||||
|
||||
function util.gui_list(parent, iterator, test, build, update, ...)
|
||||
local children = parent.children
|
||||
local i = 0
|
||||
|
||||
for k, v in table.unpack(iterator) do
|
||||
local passed = test(v, k, i, ...)
|
||||
if passed then
|
||||
i = i + 1
|
||||
local child = children[i]
|
||||
if not child then
|
||||
gui.build(parent, { build(...) })
|
||||
child = parent.children[i]
|
||||
end
|
||||
gui.update(child, update(v, k, i, ...))
|
||||
end
|
||||
end
|
||||
|
||||
for j = i + 1, #children do
|
||||
children[j].destroy()
|
||||
end
|
||||
end
|
||||
|
||||
--- Updates a slot table based on the passed criteria.
|
||||
--- @param manifest Manifest
|
||||
--- @param color string
|
||||
--- @return GuiElemDef[]
|
||||
function util.slot_table_build(manifest, color)
|
||||
local children = {}
|
||||
local i = 1
|
||||
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[i] = {
|
||||
type = "sprite-button",
|
||||
enabled = false,
|
||||
style = "ltnm_small_slot_button_" .. color,
|
||||
sprite = sprite,
|
||||
tooltip = {
|
||||
"",
|
||||
"[img=" .. sprite .. "]",
|
||||
{ "item-name." .. name },
|
||||
"\n"..format.number(count),
|
||||
},
|
||||
}
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return children
|
||||
end
|
||||
|
||||
function util.sorted_iterator(arr, src_tbl, sort_state)
|
||||
local step = sort_state and 1 or -1
|
||||
local i = sort_state and 1 or #arr
|
||||
|
||||
return function()
|
||||
local j = i + step
|
||||
if arr[j] then
|
||||
i = j
|
||||
local arr_value = arr[j]
|
||||
return arr_value, src_tbl[arr_value]
|
||||
end
|
||||
end,
|
||||
arr
|
||||
end
|
||||
|
||||
local MAX_INT = 2147483648 -- math.pow(2, 31)
|
||||
function util.signed_int32(val)
|
||||
return (val >= MAX_INT and val - (2 * MAX_INT)) or val
|
||||
end
|
||||
|
||||
return util
|
||||
@@ -49,3 +49,46 @@ end
|
||||
function irpairs(a)
|
||||
return irnext, a, 0
|
||||
end
|
||||
|
||||
---@generic V
|
||||
---@param arr Array<V>
|
||||
---@param comp fun(a: V, b: V) A comparison function for sorting. Must return truthy if `a < b`.
|
||||
function stable_sort(arr, comp)
|
||||
local size = #arr
|
||||
for i = 2, size do
|
||||
local a = arr[i]
|
||||
local j = i
|
||||
while j > 1 do
|
||||
local b = arr[j - 1]
|
||||
if comp(a, b) then
|
||||
arr[j] = b
|
||||
j = j - 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
arr[j] = a
|
||||
end
|
||||
end
|
||||
|
||||
---@param values number[]
|
||||
---@param keys any[]
|
||||
function dual_sort(values, keys)
|
||||
local size = #values
|
||||
for i = 2, size do
|
||||
local a = values[i]
|
||||
local j = i
|
||||
while j > 1 do
|
||||
local b = values[j - 1]
|
||||
if a < b then
|
||||
values[j] = b
|
||||
keys[j] = keys[j - 1]
|
||||
j = j - 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
values[j] = a
|
||||
keys[j] = keys[i]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -102,4 +102,13 @@ data:extend({
|
||||
setting_type = "runtime-global",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
type = "int-setting",
|
||||
name = "cybersyn-history-length",
|
||||
setting_type = "runtime-global",
|
||||
minimum_value = 10,
|
||||
maximum_value = 1000,
|
||||
default_value = 50,
|
||||
order = "ea",
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user