Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

666 lines
28 KiB
Lua

require("ui.base.view_state")
-- The main GUI parts for the compact dialog
-- ** LOCAL UTIL **
local function determine_available_columns(lines, frame_width)
local frame_border_size = 12
local table_padding, table_spacing = 8, 12
local recipe_and_check_width = 58
local button_width, button_spacing = 36, 4
local max_module_count = 0
for _, line in pairs(lines) do
if line.subfloor == nil then
local module_kinds = ModuleSet.get_module_kind_amount(line.machine.module_set)
max_module_count = math.max(max_module_count, module_kinds)
end
if line.beacon ~= nil then
local module_kinds = ModuleSet.get_module_kind_amount(line.beacon.module_set)
max_module_count = math.max(max_module_count, module_kinds)
end
end
local used_width = 0
used_width = used_width + (frame_border_size * 2) -- border on both sides
used_width = used_width + (table_padding * 2) -- padding on both sides
used_width = used_width + (table_spacing * 4) -- 5 columns -> 4 spaces
used_width = used_width + recipe_and_check_width -- constant
-- Add up machines button, module buttons, and spacing for them
used_width = used_width + button_width + (max_module_count * button_width) + (max_module_count * button_spacing)
-- Calculate the remaining width and divide by the amount a button takes up
local available_columns = (frame_width - used_width + button_spacing) / (button_width + button_spacing)
return math.floor(available_columns) -- amount is floored as to not cause a horizontal scrollbar
end
local function determine_table_height(lines, column_counts)
local total_height = 0
for _, line in pairs(lines) do
local items_height = 0
for column, count in pairs(column_counts) do
local column_height = math.ceil(line[column].count / count)
items_height = math.max(items_height, column_height)
end
local machines_height = (line.beacon ~= nil) and 2 or 1
total_height = total_height + math.max(machines_height, items_height)
end
return total_height
end
local function determine_column_counts(lines, available_columns)
local column_counts = {Ingredient = 1, Product = 1, Byproduct = 0} -- ordered by priority
available_columns = available_columns - 2 -- two buttons are already assigned
local previous_height, increment = math.huge, 1
while available_columns > 0 do
local table_heights, minimal_height = {}, math.huge
for column, count in pairs(column_counts) do
local potential_column_counts = fancytable.shallow_copy(column_counts)
potential_column_counts[column] = count + increment
local new_height = determine_table_height(lines, potential_column_counts)
table_heights[column] = new_height
minimal_height = math.min(minimal_height, new_height)
end
-- If increasing any column by 1 doesn't change the height, try incrementing by more
-- until height is decreased, or no columns are available anymore
if not (minimal_height < previous_height) and increment < available_columns then
increment = increment + 1
else
for column, height in pairs(table_heights) do
if available_columns > 0 and height == minimal_height then
column_counts[column] = column_counts[column] + 1
available_columns = available_columns - 1
break
end
end
previous_height, increment = minimal_height, 1 -- reset these
end
end
return column_counts
end
local function add_checkmark_button(parent_flow, line, relevant_line)
parent_flow.add{type="checkbox", state=relevant_line.done, mouse_button_filter={"left"},
tags={mod="fp", on_gui_checked_state_changed="checkmark_compact_line", line_id=line.id}}
end
local function add_recipe_button(parent_flow, line, relevant_line, metadata)
local recipe_proto = relevant_line.recipe.proto
local style = (line.subfloor ~= nil) and "flib_slot_button_blue_small" or "flib_slot_button_default_small"
style = (relevant_line.done) and "flib_slot_button_grayscale_small" or style
local tooltip = (line.subfloor == nil) and {"fp.tt_title", recipe_proto.localised_name}
or {"", {"fp.tt_title", recipe_proto.localised_name}, metadata.recipe_tutorial_tt}
parent_flow.add{type="sprite-button", tags={mod="fp", on_gui_click="act_on_compact_recipe", line_id=line.id},
sprite=recipe_proto.sprite, tooltip=tooltip, style=style, mouse_button_filter={"left-and-right"}}
end
local function add_modules_flow(parent_flow, parent_type, line, metadata)
for _, module in ipairs(ModuleSet.get_in_order(line[parent_type].module_set)) do
local number_line = {"", "\n", module.amount, " ", {"fp.pl_module", module.amount}}
local tooltip = {"", {"fp.tt_title", module.proto.localised_name}, number_line, metadata.module_tutorial_tt}
local style = (line.done) and "flib_slot_button_grayscale_small" or "flib_slot_button_default_small"
parent_flow.add{type="sprite-button", sprite=module.proto.sprite, tooltip=tooltip,
tags={mod="fp", on_gui_click="act_on_compact_module", line_id=line.id, module_id=module.id,
parent_type=parent_type}, number=module.amount, style=style, mouse_button_filter={"left-and-right"}}
end
end
local function add_machine_flow(parent_flow, line, metadata)
if line.subfloor == nil then
local machine_flow = parent_flow.add{type="flow", direction="horizontal"}
local machine_proto = line.machine.proto
local count, tooltip_line = util.format.machine_count(line.machine.count, (line.production_ratio > 0), true)
local tooltip = {"", {"fp.tt_title", machine_proto.localised_name}, "\n", tooltip_line,
metadata.machine_tutorial_tt}
local style = (line.done) and "flib_slot_button_grayscale_small" or "flib_slot_button_default_small"
machine_flow.add{type="sprite-button", sprite=machine_proto.sprite, number=count,
tooltip=tooltip, tags={mod="fp", on_gui_click="act_on_compact_machine", type="machine", line_id=line.id},
style=style, mouse_button_filter={"left-and-right"}}
add_modules_flow(machine_flow, "machine", line, metadata)
end
end
local function add_beacon_flow(parent_flow, line, metadata)
if line.subfloor == nil and line.beacon ~= nil then
local beacon_flow = parent_flow.add{type="flow", direction="horizontal"}
local beacon_proto = line.beacon.proto
local plural_parameter = (line.beacon.amount == 1) and 1 or 2 -- needed because the amount can be decimal
local number_line = {"", "\n", line.beacon.amount, " ", {"fp.pl_beacon", plural_parameter}}
local tooltip = {"", {"fp.tt_title", beacon_proto.localised_name}, number_line, metadata.beacon_tutorial_tt}
local style = (line.done) and "flib_slot_button_grayscale_small" or "flib_slot_button_default_small"
beacon_flow.add{type="sprite-button", sprite=beacon_proto.sprite, number=line.beacon.amount,
tooltip=tooltip, tags={mod="fp", on_gui_click="act_on_compact_beacon", type="beacon", line_id=line.id},
style=style, mouse_button_filter={"left-and-right"}}
add_modules_flow(beacon_flow, "beacon", line, metadata)
end
end
local function add_item_flow(line, relevant_line, item_class, button_color, metadata, item_buttons)
local column_count = metadata.column_counts[item_class]
if column_count == 0 then metadata.parent.add{type="empty-widget"}; return end
local item_table = metadata.parent.add{type="table", column_count=column_count}
for _, item in ipairs(Line.get_in_order(line, item_class)) do
local proto, type = item.proto, item.proto.type
-- items/s/machine does not make sense for lines with subfloors, show items/s instead
local machine_count = (not line.subfloor) and line.machine.count or nil
local amount, number_tooltip = view_state.process_item(metadata.view_state_metadata, item, nil, machine_count)
if amount == -1 then goto skip_item end -- an amount of -1 means it was below the margin of error
local number_line = (number_tooltip) and {"", "\n", number_tooltip} or ""
local tooltip = {"", {"fp.tt_title", proto.localised_name}, number_line, metadata.item_tutorial_tt}
local style, enabled = "flib_slot_button_" .. button_color .. "_small", true
if relevant_line.done then style = "flib_slot_button_grayscale_small" end
if type == "entity" then
style = (relevant_line.done) and "flib_slot_button_transparent_grayscale_small"
or "flib_slot_button_transparent_small"
enabled = false
tooltip = {"", {"fp.tt_title_with_note", proto.localised_name, {"fp.raw_ore"}}, number_line}
end
local button = item_table.add{type="sprite-button", sprite=proto.sprite, number=amount, tooltip=tooltip,
tags={mod="fp", on_gui_click="act_on_compact_item", on_gui_hover="hover_compact_item",
on_gui_leave="leave_compact_item", line_id=line.id, class=item.class, item_id=item.id},
style=style, enabled=enabled, mouse_button_filter={"left-and-right"}}
button.raise_hover_events = true
item_buttons[type] = item_buttons[type] or {}
item_buttons[type][proto.name] = item_buttons[type][proto.name] or {}
table.insert(item_buttons[type][proto.name], {button=button, proper_style=style})
::skip_item::
end
if item_class == "Ingredient" and not line.subfloor and line.machine.fuel then
local fuel, machine_count = line.machine.fuel, line.machine.count
local amount, number_tooltip = view_state.process_item(metadata.view_state_metadata, fuel, nil, machine_count)
if amount == -1 then goto skip_fuel end -- an amount of -1 means it was below the margin of error
local name_line = {"fp.tt_title_with_note", fuel.proto.localised_name, {"fp.pl_fuel", 1}}
local number_line = (number_tooltip) and {"", "\n", number_tooltip} or ""
local tooltip = {"", name_line, number_line, metadata.item_tutorial_tt}
local style = (relevant_line.done) and "flib_slot_button_grayscale_small" or "flib_slot_button_cyan_small"
item_table.add{type="sprite-button", sprite=fuel.proto.sprite, style=style, number=amount,
tags={mod="fp", on_gui_click="act_on_compact_item", line_id=line.id, class="Fuel"},
tooltip=tooltip, mouse_button_filter={"left-and-right"}}
::skip_fuel::
end
end
local function refresh_compact_subfactory(player)
local player_table = util.globals.player_table(player)
local compact_elements = player_table.ui_state.compact_elements
local context = player_table.ui_state.context
local subfactory = context.subfactory
if not subfactory or not subfactory.valid then return end
local current_level = subfactory.selected_floor.level
local lines = Floor.get_in_order(context.floor, "Line")
util.raise.refresh(player, "view_state", compact_elements.view_state_table)
local attach_subfactory_products = player_table.preferences.attach_subfactory_products
compact_elements.name_label.caption = Subfactory.tostring(subfactory, attach_subfactory_products, true)
compact_elements.level_label.caption = {"fp.bold_label", {"", "- ", {"fp.level"}, " ", current_level}}
compact_elements.floor_up_button.enabled = (current_level > 1)
compact_elements.floor_top_button.enabled = (current_level > 1)
local production_table = compact_elements.production_table
production_table.clear()
-- Available columns for items only, as recipe and machines can't be 'compressed'
local frame_width = compact_elements.compact_frame.style.maximal_width
local available_columns = determine_available_columns(lines, frame_width)
if available_columns < 2 then available_columns = 2 end -- fix for too many modules or too high of a GUI scale
local column_counts = determine_column_counts(lines, available_columns)
local metadata = {
parent = production_table,
column_counts = column_counts,
view_state_metadata = view_state.generate_metadata(player, subfactory)
}
compact_elements.item_buttons = {} -- (re)set the item_buttons table
local item_buttons = compact_elements.item_buttons
if util.globals.preferences(player).tutorial_mode then
util.actions.tutorial_tooltip_list(metadata, player, {
recipe_tutorial_tt = "act_on_compact_recipe",
module_tutorial_tt = "act_on_compact_module",
machine_tutorial_tt = "act_on_compact_machine",
beacon_tutorial_tt = "act_on_compact_beacon",
item_tutorial_tt = "act_on_compact_item",
})
end
for _, line in ipairs(lines) do -- build the individual lines
local relevant_line = (line.subfloor) and line.subfloor.defining_line or line
if not relevant_line.active then goto skip_line end
-- Recipe and Checkmark
local recipe_flow = production_table.add{type="flow", direction="horizontal"}
recipe_flow.style.vertical_align = "center"
add_checkmark_button(recipe_flow, line, relevant_line)
add_recipe_button(recipe_flow, line, relevant_line, metadata)
-- Machine and Beacon
local machines_flow = production_table.add{type="flow", direction="vertical"}
add_machine_flow(machines_flow, line, metadata)
add_beacon_flow(machines_flow, line, metadata)
-- Products, Byproducts and Ingredients
add_item_flow(line, relevant_line, "Product", "default", metadata, item_buttons)
add_item_flow(line, relevant_line, "Byproduct", "red", metadata, item_buttons)
add_item_flow(line, relevant_line, "Ingredient", "green", metadata, item_buttons)
production_table.add{type="empty-widget", style="flib_horizontal_pusher"}
::skip_line::
end
end
local function build_compact_subfactory(player)
local ui_state = util.globals.ui_state(player)
local compact_elements = ui_state.compact_elements
-- Content frame
local content_frame = compact_elements.compact_frame.add{type="frame", direction="vertical",
style="inside_deep_frame"}
content_frame.style.vertically_stretchable = true
local subheader = content_frame.add{type="frame", direction="vertical", style="subheader_frame"}
subheader.style.maximal_height = 100 -- large value to nullify maximal_height
-- Flow view state
local flow_view_state = subheader.add{type="flow", direction="horizontal"}
flow_view_state.style.padding = {4, 4, 0, 0}
flow_view_state.add{type="empty-widget", style="flib_horizontal_pusher"}
view_state.rebuild_state(player) -- initializes the view_state
util.raise.build(player, "view_state", flow_view_state)
compact_elements["view_state_table"] = flow_view_state["table_view_state"]
subheader.add{type="line", direction="horizontal"}
-- Flow navigation
local flow_navigation = subheader.add{type="flow", direction="horizontal"}
flow_navigation.style.vertical_align = "center"
flow_navigation.style.margin = {4, 8}
local label_name = flow_navigation.add{type="label"}
label_name.style.font = "heading-2"
label_name.style.maximal_width = 260
compact_elements["name_label"] = label_name
local label_level = flow_navigation.add{type="label"}
label_level.style.margin = {0, 6, 0, 6}
compact_elements["level_label"] = label_level
local button_floor_up = flow_navigation.add{type="sprite-button", sprite="fp_sprite_arrow_line_up",
tooltip={"fp.floor_up_tt"}, tags={mod="fp", on_gui_click="change_compact_floor", destination="up"},
style="fp_sprite-button_rounded_mini", mouse_button_filter={"left"}}
compact_elements["floor_up_button"] = button_floor_up
local button_floor_top = flow_navigation.add{type="sprite-button", sprite="fp_sprite_arrow_line_bar_up",
tooltip={"fp.floor_top_tt"}, tags={mod="fp", on_gui_click="change_compact_floor", destination="top"},
style="fp_sprite-button_rounded_mini", mouse_button_filter={"left"}}
compact_elements["floor_top_button"] = button_floor_top
-- Production table
local scroll_pane_production = content_frame.add{type="scroll-pane", direction="vertical",
style="flib_naked_scroll_pane_no_padding"}
scroll_pane_production.style.horizontally_stretchable = true
local table_production = scroll_pane_production.add{type="table", column_count=6, style="fp_table_production"}
table_production.vertical_centering = false
table_production.style.horizontal_spacing = 12
table_production.style.vertical_spacing = 8
table_production.style.padding = {4, 8}
compact_elements["production_table"] = table_production
refresh_compact_subfactory(player)
end
local function handle_recipe_click(player, tags, action)
local context = util.globals.context(player)
local line = Floor.get(context.floor, "Line", tags.line_id)
local relevant_line = (line.subfloor) and line.subfloor.defining_line or line
local recipe = relevant_line.recipe
if action == "open_subfloor" then
if line.subfloor then
util.context.set_floor(player, line.subfloor)
refresh_compact_subfactory(player)
end
elseif action == "recipebook" then
util.open_in_recipebook(player, "recipe", recipe.proto.name)
end
end
local function handle_module_click(player, tags, action)
local context = util.globals.context(player)
local line = Floor.get(context.floor, "Line", tags.line_id)
-- I don't need to care about relevant lines here because this only gets called on lines without subfloor
local parent_entity = line[tags.parent_type]
local module = ModuleSet.get(parent_entity.module_set, tags.module_id)
if action == "recipebook" then
util.open_in_recipebook(player, "item", module.proto.name)
end
end
local function handle_machine_click(player, tags, action)
local context = util.globals.context(player)
local line = Floor.get(context.floor, "Line", tags.line_id)
-- I don't need to care about relevant lines here because this only gets called on lines without subfloor
if action == "put_into_cursor" then
util.cursor.set_entity(player, line, line.machine)
elseif action == "recipebook" then
util.open_in_recipebook(player, "entity", line.machine.proto.name)
end
end
local function handle_beacon_click(player, tags, action)
local context = util.globals.context(player)
local line = Floor.get(context.floor, "Line", tags.line_id)
-- I don't need to care about relevant lines here because this only gets called on lines without subfloor
if action == "put_into_cursor" then
util.cursor.set_entity(player, line, line.beacon)
elseif action == "recipebook" then
util.open_in_recipebook(player, "entity", line.beacon.proto.name)
end
end
local function handle_item_click(player, tags, action)
local context = util.globals.context(player)
local line = Floor.get(context.floor, "Line", tags.line_id)
local item = (tags.class == "Fuel") and line.machine.fuel or Line.get(line, tags.class, tags.item_id)
if action == "put_into_cursor" then
util.cursor.add_to_item_combinator(player, item.proto, item.amount)
elseif action == "recipebook" then
util.open_in_recipebook(player, item.proto.type, item.proto.name)
end
end
local function handle_hover_change(player, tags, event)
local ui_state = util.globals.ui_state(player)
local line = Floor.get(ui_state.context.floor, "Line", tags.line_id)
local proto = Line.get(line, tags.class, tags.item_id).proto
local relevant_buttons = ui_state.compact_elements.item_buttons[proto.type][proto.name]
for _, button_data in pairs(relevant_buttons) do
button_data.button.style = (event.name == defines.events.on_gui_hover)
and "flib_slot_button_pink_small" or button_data.proper_style
end
end
-- ** EVENTS **
local subfactory_listeners = {}
subfactory_listeners.gui = {
on_gui_click = {
{
name = "change_compact_floor",
handler = (function(player, tags, _)
local floor_changed = util.context.change_floor(player, tags.destination)
if floor_changed then refresh_compact_subfactory(player) end
end)
},
{
name = "act_on_compact_recipe",
modifier_actions = {
open_subfloor = {"left"},
recipebook = {"alt-right", {recipebook=true}}
},
handler = handle_recipe_click
},
{
name = "act_on_compact_module",
modifier_actions = {
recipebook = {"alt-right", {recipebook=true}}
},
handler = handle_module_click
},
{
name = "act_on_compact_machine",
modifier_actions = {
put_into_cursor = {"left"},
recipebook = {"alt-right", {recipebook=true}}
},
handler = handle_machine_click
},
{
name = "act_on_compact_beacon",
modifier_actions = {
put_into_cursor = {"left"},
recipebook = {"alt-right", {recipebook=true}}
},
handler = handle_beacon_click
},
{
name = "act_on_compact_item",
modifier_actions = {
put_into_cursor = {"left"},
recipebook = {"alt-right", {recipebook=true}}
},
handler = handle_item_click
}
},
on_gui_checked_state_changed = {
{
name = "checkmark_compact_line",
handler = (function(player, tags, _)
local line = Floor.get(util.globals.context(player).floor, "Line", tags.line_id)
local relevant_line = (line.subfloor) and line.subfloor.defining_line or line
relevant_line.done = not relevant_line.done
refresh_compact_subfactory(player)
end)
}
},
on_gui_hover = {
{
name = "hover_compact_item",
handler = handle_hover_change
}
},
on_gui_leave = {
{
name = "leave_compact_item",
handler = handle_hover_change
}
}
}
subfactory_listeners.misc = {
build_gui_element = (function(player, event)
if event.trigger == "compact_subfactory" then
build_compact_subfactory(player)
end
end),
refresh_gui_element = (function(player, event)
if event.trigger == "compact_subfactory" then
refresh_compact_subfactory(player)
end
end)
}
-- The frame surrounding the main part of the compact subfactory
local frame_dimensions = {width = 0.25, height = 0.8} -- as a percentage of the screen
local frame_location = {x = 10, y = 63} -- absolute, relative to 1080p with scale 1
-- ** LOCAL UTIL **
-- Set frame dimensions in a relative way, taking player resolution and scaling into account
local function set_compact_frame_dimensions(player, frame)
local resolution, scale = player.display_resolution, player.display_scale
local actual_resolution = {width=math.ceil(resolution.width / scale), height=math.ceil(resolution.height / scale)}
frame.style.width = actual_resolution.width * frame_dimensions.width
frame.style.maximal_height = actual_resolution.height * frame_dimensions.height
end
local function set_compact_frame_location(player, frame)
local scale = player.display_scale
frame.location = {frame_location.x * scale, frame_location.y * scale}
end
local function rebuild_compact_dialog(player, default_visibility)
local ui_state = util.globals.ui_state(player)
local compact_elements = ui_state.compact_elements
local interface_visible = default_visibility
local compact_frame = compact_elements.compact_frame
-- Delete the existing interface if there is one
if compact_frame ~= nil then
if compact_frame.valid then
interface_visible = compact_frame.visible
compact_frame.destroy()
end
ui_state.compact_elements = {} -- reset all compact element references
compact_elements = ui_state.compact_elements
end
local frame_compact_dialog = player.gui.screen.add{type="frame", direction="vertical",
visible=interface_visible, name="fp_frame_compact_dialog"}
set_compact_frame_location(player, frame_compact_dialog)
set_compact_frame_dimensions(player, frame_compact_dialog)
compact_elements["compact_frame"] = frame_compact_dialog
-- Title bar
local flow_title_bar = frame_compact_dialog.add{type="flow", direction="horizontal",
tags={mod="fp", on_gui_click="place_compact_dialog"}}
flow_title_bar.style.horizontal_spacing = 8
flow_title_bar.drag_target = frame_compact_dialog
flow_title_bar.add{type="label", caption={"mod-name.factoryplanner"}, style="frame_title",
ignored_by_interaction=true}
flow_title_bar.add{type="empty-widget", style="flib_titlebar_drag_handle",
ignored_by_interaction=true}
local button_switch = flow_title_bar.add{type="sprite-button", style="frame_action_button",
tags={mod="fp", on_gui_click="switch_to_main_view"}, tooltip={"fp.switch_to_main_view"},
sprite="fp_sprite_arrow_right_light", hovered_sprite="fp_sprite_arrow_right_dark",
clicked_sprite="fp_sprite_arrow_right_dark", mouse_button_filter={"left"}}
button_switch.style.padding = 2
local button_close = flow_title_bar.add{type="sprite-button", tags={mod="fp", on_gui_click="close_compact_dialog"},
sprite="utility/close_white", hovered_sprite="utility/close_black", clicked_sprite="utility/close_black",
tooltip={"fp.close_interface"}, style="frame_action_button", mouse_button_filter={"left"}}
button_close.style.padding = 1
util.raise.build(player, "compact_subfactory", nil)
return frame_compact_dialog
end
-- ** TOP LEVEL **
compact_dialog = {}
function compact_dialog.toggle(player)
local ui_state = util.globals.ui_state(player)
local frame_compact_dialog = ui_state.compact_elements.compact_frame
-- Doesn't set player.opened so other GUIs like the inventory can be opened when building
if frame_compact_dialog == nil or not frame_compact_dialog.valid then
rebuild_compact_dialog(player, true) -- refreshes on its own
else
local new_dialog_visibility = not frame_compact_dialog.visible
frame_compact_dialog.visible = new_dialog_visibility
if new_dialog_visibility then refresh_compact_subfactory(player) end
end
end
function compact_dialog.is_in_focus(player)
local frame_compact_dialog = util.globals.ui_state(player).compact_elements.compact_frame
return (frame_compact_dialog ~= nil and frame_compact_dialog.valid and frame_compact_dialog.visible)
end
-- ** EVENTS **
local dialog_listeners = {}
dialog_listeners.gui = {
on_gui_click = {
{
name = "switch_to_main_view",
handler = (function(player, _, _)
util.globals.flags(player).compact_view = false
compact_dialog.toggle(player)
main_dialog.toggle(player)
util.raise.refresh(player, "production", nil)
end)
},
{
name = "close_compact_dialog",
handler = (function(player, _, _)
compact_dialog.toggle(player)
end)
},
{
name = "place_compact_dialog",
handler = (function(player, _, event)
if event.button == defines.mouse_button_type.middle then
local ui_state = util.globals.ui_state(player)
local frame_compact_dialog = ui_state.compact_elements.compact_frame
set_compact_frame_location(player, frame_compact_dialog)
end
end)
}
}
}
dialog_listeners.misc = {
on_player_display_resolution_changed = (function(player, _)
rebuild_compact_dialog(player, false)
end),
on_player_display_scale_changed = (function(player, _)
rebuild_compact_dialog(player, false)
end),
on_lua_shortcut = (function(player, event)
if event.prototype_name == "fp_open_interface" and util.globals.flags(player).compact_view then
compact_dialog.toggle(player)
end
end),
fp_toggle_interface = (function(player, _)
if util.globals.flags(player).compact_view then compact_dialog.toggle(player) end
end)
}
return { subfactory_listeners, dialog_listeners }