mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Remove legacy gui module
This commit is contained in:
@@ -1 +0,0 @@
|
||||
return require("modules.exp_legacy.expcore.gui._require")
|
||||
@@ -1,144 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Used to simplify gui creation using factory functions called element defines
|
||||
@core Gui
|
||||
@alias Gui
|
||||
|
||||
@usage-- To draw your element you only need to call the factory function
|
||||
-- You are able to pass any other arguments that are used in your custom functions but the first is always the parent element
|
||||
local example_button_element = example_button(parent_element)
|
||||
|
||||
@usage-- Making a factory function for a button with the caption "Example Button"
|
||||
-- This method has all the same features as LuaGuiElement.add
|
||||
local example_button =
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button'
|
||||
}
|
||||
|
||||
@usage-- Making a factory function for a button which is contained within a flow
|
||||
-- This method is for when you still want to register event handlers but cant use the table method
|
||||
local example_flow_with_button =
|
||||
Gui.element(function(definition, parent, ...)
|
||||
-- ... shows that all other arguments from the factory call are passed to this function
|
||||
-- Here we are adding a flow which we will then later add a button to
|
||||
local flow =
|
||||
parent.add{ -- paraent is the element which is passed to the factory function
|
||||
name = 'example_flow',
|
||||
type = 'flow'
|
||||
}
|
||||
|
||||
-- Now we add the button to the flow that we created earlier
|
||||
local element = definition:triggers_event(
|
||||
flow.add{
|
||||
type = 'button',
|
||||
caption = 'Example Button'
|
||||
}
|
||||
)
|
||||
|
||||
-- You must return a new element, this is so styles can be applied and returned to the caller
|
||||
-- You may return any of your elements that you added, consider the context in which it will be used for which should be returned
|
||||
return element
|
||||
end)
|
||||
|
||||
@usage-- Styles can be added to any element define, simplest way mimics LuaGuiElement.style[key] = value
|
||||
local example_button =
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button',
|
||||
style = 'forward_button' -- factorio styles can be applied here
|
||||
}
|
||||
:style{
|
||||
height = 25, -- same as element.style.height = 25
|
||||
width = 100 -- same as element.style.width = 25
|
||||
}
|
||||
|
||||
@usage-- Styles can also have a custom function when the style is dynamic and depends on other factors
|
||||
-- Use this method if your style is dynamic and depends on other factors
|
||||
local example_button =
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button',
|
||||
style = 'forward_button' -- factorio styles can be applied here
|
||||
}
|
||||
:style(function(style, element, ...)
|
||||
-- style is the current style object for the elemenent
|
||||
-- element is the element that is being changed
|
||||
-- ... shows that all other arguments from the factory call are passed to this function
|
||||
local player = game.players[element.player_index]
|
||||
style.height = 25
|
||||
style.width = 100
|
||||
style.font_color = player.color
|
||||
end)
|
||||
|
||||
@usage-- You are able to register event handlers to your elements, these can be factorio events or custom ones
|
||||
-- All events are checked to be valid before raising any handlers, this means element.valid = true and player.valid = true
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button'
|
||||
}
|
||||
:on_click(function(player, element, event)
|
||||
-- player is the player who interacted with the element to cause the event
|
||||
-- element is a refrence to the element which caused the event
|
||||
-- event is a raw refrence to the event data if player and element are not enough
|
||||
player.print('Clicked: '..element.name)
|
||||
end)
|
||||
|
||||
@usage-- Example from core_defines, Gui.core_defines.hide_left_flow, called like: hide_left_flow(parent_element)
|
||||
--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible
|
||||
-- @element hide_left_flow
|
||||
local hide_left_flow =
|
||||
Gui.element{
|
||||
type = 'sprite-button',
|
||||
sprite = 'utility/close_black',
|
||||
style = 'tool_button',
|
||||
tooltip = {'expcore-gui.left-button-tooltip'}
|
||||
}
|
||||
:style{
|
||||
padding = -3,
|
||||
width = 18,
|
||||
height = 20
|
||||
}
|
||||
:on_click(function(player, _,_)
|
||||
Gui.hide_left_flow(player)
|
||||
end)
|
||||
|
||||
@usage-- Eample from defines, Gui.alignment, called like: Gui.alignment(parent, name, horizontal_align, vertical_align)
|
||||
-- Notice how _ are used to blank arguments that are not needed in that context and how they line up with above
|
||||
Gui.alignment =
|
||||
Gui.element(function(_, parent, name, _,_)
|
||||
return parent.add{
|
||||
name = name or 'alignment',
|
||||
type = 'flow',
|
||||
}
|
||||
end)
|
||||
:style(function(style, _,_, horizontal_align, vertical_align)
|
||||
style.padding = {1, 2}
|
||||
style.vertical_align = vertical_align or 'center'
|
||||
style.horizontal_align = horizontal_align or 'right'
|
||||
style.vertically_stretchable = style.vertical_align ~= 'center'
|
||||
style.horizontally_stretchable = style.horizontal_align ~= 'center'
|
||||
end)
|
||||
|
||||
]]
|
||||
|
||||
local ExpUtil = require("modules/exp_util")
|
||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||
require("modules.exp_legacy.expcore.gui.helper_functions")
|
||||
require("modules.exp_legacy.expcore.gui.core_defines")
|
||||
require("modules.exp_legacy.expcore.gui.top_flow")
|
||||
require("modules.exp_legacy.expcore.gui.left_flow")
|
||||
require("modules.exp_legacy.expcore.gui.defines")
|
||||
|
||||
local Roles = ExpUtil.optional_require("modules.exp_legacy.expcore.roles")
|
||||
local Event = ExpUtil.optional_require("modules/exp_legacy/utils/event")
|
||||
|
||||
if Roles and Event then
|
||||
Event.add(Roles.events.on_role_assigned, function(e)
|
||||
Gui.update_top_flow(game.players[e.player_index])
|
||||
end)
|
||||
Event.add(Roles.events.on_role_unassigned, function(e)
|
||||
Gui.update_top_flow(game.players[e.player_index])
|
||||
end)
|
||||
end
|
||||
|
||||
return Gui
|
||||
@@ -1,89 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Gui defines that are used internally by the gui system
|
||||
@module Gui
|
||||
]]
|
||||
|
||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||
local Event = require("modules/exp_legacy/utils/event")
|
||||
|
||||
--- Core Defines.
|
||||
-- @section coreDefines
|
||||
|
||||
--- Button which toggles the top flow elements, version which shows inside the top flow when top flow is visible
|
||||
-- @element hide_top_flow
|
||||
local hide_top_flow =
|
||||
Gui.element{
|
||||
type = "sprite-button",
|
||||
sprite = "utility/preset",
|
||||
style = "tool_button",
|
||||
tooltip = { "gui_util.button_tooltip" },
|
||||
name = Gui.unique_static_name,
|
||||
}
|
||||
:style{
|
||||
padding = -2,
|
||||
width = 18,
|
||||
height = 36,
|
||||
}
|
||||
:on_click(function(player, _, _)
|
||||
Gui.toggle_top_flow(player, false)
|
||||
end)
|
||||
Gui.core_defines.hide_top_flow = hide_top_flow
|
||||
|
||||
--- Button which toggles the top flow elements, version which shows inside the left flow when top flow is hidden
|
||||
-- @element show_top_flow
|
||||
local show_top_flow =
|
||||
Gui.element{
|
||||
type = "sprite-button",
|
||||
sprite = "utility/preset",
|
||||
style = "tool_button",
|
||||
tooltip = { "gui_util.button_tooltip" },
|
||||
name = Gui.unique_static_name,
|
||||
}
|
||||
:style{
|
||||
padding = -2,
|
||||
width = 18,
|
||||
height = 20,
|
||||
}
|
||||
:on_click(function(player, _, _)
|
||||
Gui.toggle_top_flow(player, true)
|
||||
end)
|
||||
Gui.core_defines.show_top_flow = show_top_flow
|
||||
|
||||
--- Button which hides the elements in the left flow, shows inside the left flow when frames are visible
|
||||
-- @element hide_left_flow
|
||||
local hide_left_flow =
|
||||
Gui.element{
|
||||
type = "sprite-button",
|
||||
sprite = "utility/close_black",
|
||||
style = "tool_button",
|
||||
tooltip = { "expcore-gui.left-button-tooltip" },
|
||||
name = Gui.unique_static_name,
|
||||
}
|
||||
:style{
|
||||
padding = -3,
|
||||
width = 18,
|
||||
height = 20,
|
||||
}
|
||||
:on_click(function(player, _, _)
|
||||
Gui.hide_left_flow(player)
|
||||
end)
|
||||
Gui.core_defines.hide_left_flow = hide_left_flow
|
||||
|
||||
--- Draw the core elements when a player joins the game
|
||||
Event.add(defines.events.on_player_created, function(event)
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
-- Draw the top flow
|
||||
local top_flow = Gui.get_top_flow(player)
|
||||
hide_top_flow(top_flow)
|
||||
Gui.update_top_flow(player)
|
||||
|
||||
-- Draw the left flow
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
local button_flow = left_flow.add{ type = "flow", name = "gui_core_buttons", direction = "vertical" }
|
||||
local show_top = show_top_flow(button_flow)
|
||||
local hide_left = hide_left_flow(button_flow)
|
||||
show_top.visible = false
|
||||
hide_left.visible = false
|
||||
Gui.draw_left_flow(player)
|
||||
end)
|
||||
@@ -1,301 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Common defines that are used by other modules, non of these are used internally
|
||||
@module Gui
|
||||
]]
|
||||
|
||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||
|
||||
--- Defines.
|
||||
-- @section defines
|
||||
|
||||
--[[-- Draw a flow used to align its child elements, default is right align
|
||||
@element Gui.alignment
|
||||
@tparam LuaGuiElement parent the parent element to which the alignment will be added
|
||||
@tparam[opt='alignment'] string name the name of the alignment flow which is added
|
||||
@tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in the flow
|
||||
@tparam[opt='center'] string vertical_align the vertical alignment of the elements in the flow
|
||||
@treturn LuaGuiElement the alignment flow that was created
|
||||
|
||||
@usage-- Adding a right align flow
|
||||
local alignment = Gui.alignment(element, 'example_right_alignment')
|
||||
|
||||
@usage-- Adding a horizontal center and top align flow
|
||||
local alignment = Gui.alignment(element, 'example_center_top_alignment', 'center', 'top')
|
||||
|
||||
]]
|
||||
Gui.alignment =
|
||||
Gui.element(function(_, parent, name, _, _)
|
||||
return parent.add{
|
||||
name = name or "alignment",
|
||||
type = "flow",
|
||||
}
|
||||
end)
|
||||
:style(function(style, _, _, horizontal_align, vertical_align)
|
||||
style.padding = { 1, 2 }
|
||||
style.vertical_align = vertical_align or "center"
|
||||
style.horizontal_align = horizontal_align or "right"
|
||||
style.vertically_stretchable = style.vertical_align ~= "center"
|
||||
style.horizontally_stretchable = style.horizontal_align ~= "center"
|
||||
end)
|
||||
|
||||
--[[-- Draw a scroll pane that has a table inside of it
|
||||
@element Gui.scroll_table
|
||||
@tparam LuaGuiElement parent the parent element to which the scroll table will be added
|
||||
@tparam number height the maximum height for the scroll pane
|
||||
@tparam number column_count the number of columns that the table will have
|
||||
@tparam[opt='scroll'] string name the name of the scroll pane that is added, the table is always called "table"
|
||||
@treturn LuaGuiElement the table that was created
|
||||
|
||||
@usage-- Adding a scroll table with max height of 200 and column count of 3
|
||||
local scroll_table = Gui.scroll_table(element, 200, 3)
|
||||
|
||||
]]
|
||||
Gui.scroll_table =
|
||||
Gui.element(function(_, parent, height, column_count, name)
|
||||
-- Draw the scroll
|
||||
local scroll_pane =
|
||||
parent.add{
|
||||
name = name or "scroll",
|
||||
type = "scroll-pane",
|
||||
direction = "vertical",
|
||||
horizontal_scroll_policy = "never",
|
||||
vertical_scroll_policy = "auto",
|
||||
style = "scroll_pane_under_subheader",
|
||||
}
|
||||
|
||||
-- Set the style of the scroll pane
|
||||
local scroll_style = scroll_pane.style
|
||||
scroll_style.padding = { 1, 3 }
|
||||
scroll_style.maximal_height = height
|
||||
scroll_style.horizontally_stretchable = true
|
||||
|
||||
-- Draw the table
|
||||
local scroll_table =
|
||||
scroll_pane.add{
|
||||
type = "table",
|
||||
name = "table",
|
||||
column_count = column_count,
|
||||
}
|
||||
|
||||
-- Return the scroll table
|
||||
return scroll_table
|
||||
end)
|
||||
:style{
|
||||
padding = 0,
|
||||
cell_padding = 0,
|
||||
vertical_align = "center",
|
||||
horizontally_stretchable = true,
|
||||
}
|
||||
|
||||
--[[-- Used to add a frame with the header style, has the option for a right alignment flow for buttons
|
||||
@element Gui.header
|
||||
@tparam LuaGuiElement parent the parent element to which the header will be added
|
||||
@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the header
|
||||
@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the header
|
||||
@tparam[opt=false] boolean add_alignment when true an alignment flow will be added to the header
|
||||
@tparam[opt='header'] string name the name of the header that is being added, the alignment is always called "alignment"
|
||||
@treturn LuaGuiElement either the header or the header alignment if add_alignment is true
|
||||
|
||||
@usage-- Adding a custom header with a label
|
||||
local header = Gui.header(
|
||||
element,
|
||||
'Example Caption',
|
||||
'Example Tooltip'
|
||||
)
|
||||
|
||||
]]
|
||||
Gui.header =
|
||||
Gui.element(function(_, parent, caption, tooltip, add_alignment, name, label_name)
|
||||
-- Draw the header
|
||||
local header =
|
||||
parent.add{
|
||||
name = name or "header",
|
||||
type = "frame",
|
||||
style = "subheader_frame",
|
||||
}
|
||||
|
||||
-- Change the style of the header
|
||||
local style = header.style
|
||||
style.padding = { 2, 4 }
|
||||
style.use_header_filler = false
|
||||
style.horizontally_stretchable = true
|
||||
|
||||
-- Draw the caption label
|
||||
if caption then
|
||||
header.add{
|
||||
name = label_name or "header_label",
|
||||
type = "label",
|
||||
style = "frame_title",
|
||||
caption = caption,
|
||||
tooltip = tooltip,
|
||||
}
|
||||
end
|
||||
|
||||
-- Return either the header or the added alignment
|
||||
return add_alignment and Gui.alignment(header) or header
|
||||
end)
|
||||
|
||||
--[[-- Used to add a frame with the footer style, has the option for a right alignment flow for buttons
|
||||
@element Gui.footer
|
||||
@tparam LuaGuiElement parent the parent element to which the footer will be added
|
||||
@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the footer
|
||||
@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the footer
|
||||
@tparam[opt=false] boolean add_alignment when true an alignment flow will be added to the footer
|
||||
@tparam[opt='footer'] string name the name of the footer that is being added, the alignment is always called "alignment"
|
||||
@treturn LuaGuiElement either the footer or the footer alignment if add_alignment is true
|
||||
|
||||
@usage-- Adding a custom footer with a label
|
||||
local footer = Gui.footer(
|
||||
element,
|
||||
'Example Caption',
|
||||
'Example Tooltip'
|
||||
)
|
||||
|
||||
]]
|
||||
Gui.footer =
|
||||
Gui.element(function(_, parent, caption, tooltip, add_alignment, name)
|
||||
-- Draw the header
|
||||
local footer =
|
||||
parent.add{
|
||||
name = name or "footer",
|
||||
type = "frame",
|
||||
style = "subfooter_frame",
|
||||
}
|
||||
|
||||
-- Change the style of the footer
|
||||
local style = footer.style
|
||||
style.padding = { 2, 4 }
|
||||
style.use_header_filler = false
|
||||
style.horizontally_stretchable = true
|
||||
|
||||
-- Draw the caption label
|
||||
if caption then
|
||||
footer.add{
|
||||
name = "footer_label",
|
||||
type = "label",
|
||||
style = "frame_title",
|
||||
caption = caption,
|
||||
tooltip = tooltip,
|
||||
}
|
||||
end
|
||||
|
||||
-- Return either the footer or the added alignment
|
||||
return add_alignment and Gui.alignment(footer) or footer
|
||||
end)
|
||||
|
||||
--[[-- Used for left frames to give them a nice boarder
|
||||
@element Gui.container
|
||||
@tparam LuaGuiElement parent the parent element to which the container will be added
|
||||
@tparam string name the name that you want to give to the outer frame, often just event_trigger
|
||||
@tparam number width the minimal width that the frame will have
|
||||
|
||||
@usage-- Adding a container as a base
|
||||
local container = Gui.container(parent, 'my_container', 200)
|
||||
|
||||
]]
|
||||
Gui.container =
|
||||
Gui.element(function(_, parent, name, _)
|
||||
-- Draw the external container
|
||||
local frame =
|
||||
parent.add{
|
||||
name = name,
|
||||
type = "frame",
|
||||
}
|
||||
frame.style.horizontally_stretchable = false
|
||||
|
||||
-- Return the container
|
||||
return frame.add{
|
||||
name = "container",
|
||||
type = "frame",
|
||||
direction = "vertical",
|
||||
style = "inside_shallow_frame_packed",
|
||||
}
|
||||
end)
|
||||
:style(function(style, element, _, width)
|
||||
style.vertically_stretchable = false
|
||||
local frame_style = element.parent.style
|
||||
frame_style.padding = 2
|
||||
frame_style.minimal_width = width
|
||||
end)
|
||||
|
||||
--[[-- Used to make a solid white bar in a gui
|
||||
@element Gui.bar
|
||||
@tparam LuaGuiElement parent the parent element to which the bar will be added
|
||||
@tparam number width the width of the bar that will be made, if not given bar will strech to fill the parent
|
||||
|
||||
@usage-- Adding a bar to a gui
|
||||
local bar = Gui.bar(parent, 100)
|
||||
|
||||
]]
|
||||
Gui.bar =
|
||||
Gui.element(function(_, parent)
|
||||
return parent.add{
|
||||
type = "progressbar",
|
||||
size = 1,
|
||||
value = 1,
|
||||
}
|
||||
end)
|
||||
:style(function(style, _, width)
|
||||
style.height = 3
|
||||
style.color = { r = 255, g = 255, b = 255 }
|
||||
if width then
|
||||
style.width = width
|
||||
else
|
||||
style.horizontally_stretchable = true
|
||||
end
|
||||
end)
|
||||
|
||||
--[[-- Used to make a label which is centered and of a certian size
|
||||
@element Gui.centered_label
|
||||
@tparam LuaGuiElement parent the parent element to which the label will be added
|
||||
@tparam number width the width of the label, must be given in order to center the caption
|
||||
@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the label
|
||||
@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the label
|
||||
|
||||
@usage-- Adding a centered label
|
||||
local label = Gui.centered_label(parent, 100, 'This is centered')
|
||||
|
||||
]]
|
||||
Gui.centered_label =
|
||||
Gui.element(function(_, parent, width, caption, tooltip)
|
||||
local label = parent.add{
|
||||
type = "label",
|
||||
caption = caption,
|
||||
tooltip = tooltip,
|
||||
}
|
||||
|
||||
local style = label.style
|
||||
style.horizontal_align = "center"
|
||||
style.single_line = false
|
||||
style.width = width
|
||||
|
||||
return label
|
||||
end)
|
||||
|
||||
--[[-- Used to make a title which has two bars on either side
|
||||
@element Gui.title_label
|
||||
@tparam LuaGuiElement parent the parent element to which the label will be added
|
||||
@tparam number width the width of the first bar, this can be used to position the label
|
||||
@tparam ?string|Concepts.LocalizedString caption the caption that will be shown on the label
|
||||
@tparam[opt] ?string|Concepts.LocalizedString tooltip the tooltip that will be shown on the label
|
||||
|
||||
@usage-- Adding a centered label
|
||||
local label = Gui.centered_label(parent, 100, 'This is centered')
|
||||
|
||||
]]
|
||||
Gui.title_label =
|
||||
Gui.element(function(_, parent, width, caption, tooltip)
|
||||
local title_flow = parent.add{ type = "flow" }
|
||||
title_flow.style.vertical_align = "center"
|
||||
|
||||
Gui.bar(title_flow, width)
|
||||
local title_label = title_flow.add{
|
||||
type = "label",
|
||||
caption = caption,
|
||||
tooltip = tooltip,
|
||||
style = "frame_title",
|
||||
}
|
||||
Gui.bar(title_flow)
|
||||
|
||||
return title_label
|
||||
end)
|
||||
@@ -1,91 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Functions used to help with the use of guis
|
||||
@module Gui
|
||||
]]
|
||||
|
||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||
|
||||
--- Helper Functions.
|
||||
-- @section helperFunctions
|
||||
|
||||
--[[-- Get the player that owns a gui element
|
||||
@tparam LuaGuiElement element the element to get the owner of
|
||||
@treturn LuaPlayer the player that owns this element
|
||||
|
||||
@usage-- Geting the owner of an element
|
||||
local player = Gui.get_player_from_element(element)
|
||||
|
||||
]]
|
||||
function Gui.get_player_from_element(element)
|
||||
if not element or not element.valid then return end
|
||||
return game.players[element.player_index]
|
||||
end
|
||||
|
||||
--[[-- Will toggle the enabled state of an element or set it to the one given
|
||||
@tparam LuaGuiElement element the element to toggle/set the enabled state of
|
||||
@tparam[opt] boolean state with given will set the state, else state will be toggled
|
||||
@treturn boolean the new enabled state that the element has
|
||||
|
||||
@usage-- Toggling the the enabled state
|
||||
local new_enabled_state = Gui.toggle_enabled_state(element)
|
||||
|
||||
]]
|
||||
function Gui.toggle_enabled_state(element, state)
|
||||
if not element or not element.valid then return end
|
||||
if state == nil then state = not element.enabled end
|
||||
element.enabled = state
|
||||
return state
|
||||
end
|
||||
|
||||
--[[-- Will toggle the visible state of an element or set it to the one given
|
||||
@tparam LuaGuiElement element the element to toggle/set the visible state of
|
||||
@tparam[opt] boolean state with given will set the state, else state will be toggled
|
||||
@treturn boolean the new visible state that the element has
|
||||
|
||||
@usage-- Toggling the the visible state
|
||||
local new_visible_state = Gui.toggle_visible_state(element)
|
||||
|
||||
]]
|
||||
function Gui.toggle_visible_state(element, state)
|
||||
if not element or not element.valid then return end
|
||||
if state == nil then state = not element.visible end
|
||||
element.visible = state
|
||||
return state
|
||||
end
|
||||
|
||||
--[[-- Destory a gui element without causing any errors, often because the element was already removed
|
||||
@tparam LuaGuiElement element the element that you want to remove
|
||||
@treturn boolean true if the element was valid and has been removed
|
||||
|
||||
@usage-- Remove a child element if it exists
|
||||
Gui.destroy_if_valid(element[child_name])
|
||||
|
||||
]]
|
||||
function Gui.destroy_if_valid(element)
|
||||
if not element or not element.valid then return false end
|
||||
element.destroy()
|
||||
return true
|
||||
end
|
||||
|
||||
--[[-- Returns a table to be used as the style for a sprite buttons, produces a sqaure button
|
||||
@tparam number size the size that you want the button to be
|
||||
@tparam[opt=-2] number padding the padding that you want on the sprite
|
||||
@tparam[opt] table style any extra style settings that you want to have
|
||||
@treturn table the style table to be used with element_define:style()
|
||||
|
||||
@usage-- Adding a sprite button with size 20
|
||||
local button =
|
||||
Gui.element{
|
||||
type = 'sprite-button',
|
||||
sprite = 'entity/inserter'
|
||||
}
|
||||
:style(Gui.sprite_style(20))
|
||||
|
||||
]]
|
||||
function Gui.sprite_style(size, padding, style)
|
||||
style = style or {}
|
||||
style.padding = padding or -2
|
||||
style.height = size
|
||||
style.width = size
|
||||
return style
|
||||
end
|
||||
@@ -1,277 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Used to define new gui elements and gui event handlers
|
||||
@module Gui
|
||||
]]
|
||||
|
||||
local ExpUtil = require("modules/exp_util")
|
||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||
local mod_gui = require "mod-gui"
|
||||
|
||||
local hide_left_flow = Gui.core_defines.hide_left_flow.name
|
||||
|
||||
--- Left Flow.
|
||||
-- @section leftFlow
|
||||
|
||||
-- Triggered when a user changed the visibility of a left flow element by clicking a button
|
||||
Gui.events.on_visibility_changed_by_click = "on_visibility_changed_by_click"
|
||||
|
||||
--- Contains the uids of the elements that will shown on the left flow and their join functions
|
||||
-- @table left_elements
|
||||
Gui.left_elements = {}
|
||||
|
||||
--[[-- Gets the flow refered to as the left flow, each player has one left flow
|
||||
@function Gui.get_left_flow(player)
|
||||
@tparam LuaPlayer player the player that you want to get the left flow for
|
||||
@treturn LuaGuiElement the left element flow
|
||||
|
||||
@usage-- Geting your left flow
|
||||
local left_flow = Gui.get_left_flow(game.player)
|
||||
|
||||
]]
|
||||
Gui.get_left_flow = mod_gui.get_frame_flow
|
||||
|
||||
--[[-- Sets an element define to be drawn to the left flow when a player joins, includes optional check
|
||||
@tparam[opt] ?boolean|function open_on_join called during first darw to decide if the element should be visible
|
||||
@treturn table the new element define that is used to register events to this element
|
||||
|
||||
@usage-- Adding the example button
|
||||
example_flow_with_button:add_to_left_flow(true)
|
||||
|
||||
]]
|
||||
function Gui._prototype_element:add_to_left_flow(open_on_join)
|
||||
ExpUtil.assert_not_runtime()
|
||||
if not self.name then error("Elements for the top flow must have a static name") end
|
||||
self.open_on_join = open_on_join or false
|
||||
table.insert(Gui.left_elements, self)
|
||||
return self
|
||||
end
|
||||
|
||||
--[[-- Creates a button on the top flow which will toggle the given element define, the define must exist in the left flow
|
||||
@tparam string sprite the sprite that you want to use on the button
|
||||
@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have
|
||||
@tparam table element_define the element define that you want to have toggled by this button, define must exist on the left flow
|
||||
@tparam[opt] function authenticator used to decide if the button should be visible to a player
|
||||
|
||||
@usage-- Add a button to toggle a left element
|
||||
local toolbar_button =
|
||||
Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', example_flow_with_button, function(player)
|
||||
return player.admin
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui.left_toolbar_button(sprite, tooltip, element_define, authenticator)
|
||||
local button = Gui.toolbar_button(sprite, tooltip, authenticator)
|
||||
|
||||
-- Add on_click handler to handle click events comming from the player
|
||||
button:on_click(function(player, _, _)
|
||||
-- Raise custom event that tells listening elements if the element has changed visibility by a player clicking
|
||||
-- Used in warp gui to handle the keep open logic
|
||||
button:raise_event{
|
||||
name = Gui.events.on_visibility_changed_by_click,
|
||||
element = Gui.get_top_element(player, button),
|
||||
state = Gui.toggle_left_element(player, element_define),
|
||||
}
|
||||
end)
|
||||
|
||||
-- Add property to the left flow element with the name of the button
|
||||
-- This is for the ability to reverse lookup the button from the left flow element
|
||||
element_define.toolbar_button = button
|
||||
button.left_flow_element = element_define
|
||||
return button
|
||||
end
|
||||
|
||||
Gui._left_flow_order_src = "<default>"
|
||||
--- Get the order of elements in the left flow, first argument is player but is unused in the default method
|
||||
function Gui.get_left_flow_order(_)
|
||||
return Gui.left_elements
|
||||
end
|
||||
|
||||
--- Inject a custom left flow order provider, this should accept a player and return a list of elements definitions to draw
|
||||
function Gui.inject_left_flow_order(provider)
|
||||
Gui.get_left_flow_order = provider
|
||||
local debug_info = debug.getinfo(2, "Sn")
|
||||
local file_name = debug_info.short_src:sub(10, -5)
|
||||
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
|
||||
Gui._left_flow_order_src = file_name .. ":" .. func_name
|
||||
end
|
||||
|
||||
--[[-- Draw all the left elements onto the left flow, internal use only with on join
|
||||
@tparam LuaPlayer player the player that you want to draw the elements for
|
||||
|
||||
@usage-- Draw all the left elements
|
||||
Gui.draw_left_flow(player)
|
||||
|
||||
]]
|
||||
function Gui.draw_left_flow(player)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
local hide_button = left_flow.gui_core_buttons[hide_left_flow]
|
||||
local show_hide_button = false
|
||||
|
||||
-- Get the order to draw the elements in
|
||||
local flow_order = Gui.get_left_flow_order(player)
|
||||
if #flow_order ~= #Gui.left_elements then
|
||||
error(string.format("Left flow order provider (%s) did not return the correct element count, expect %d got %d",
|
||||
Gui._left_flow_order_src, #Gui.left_elements, #flow_order
|
||||
))
|
||||
end
|
||||
|
||||
for _, element_define in ipairs(flow_order) do
|
||||
-- Draw the element to the left flow
|
||||
local draw_success, left_element = xpcall(function()
|
||||
return element_define(left_flow)
|
||||
end, debug.traceback)
|
||||
|
||||
if not draw_success then
|
||||
log("There as been an error with an element draw function: " .. element_define.defined_at .. "\n\t" .. left_element)
|
||||
goto continue
|
||||
end
|
||||
|
||||
-- Check if it should be open by default
|
||||
local open_on_join = element_define.open_on_join
|
||||
local visible = type(open_on_join) == "boolean" and open_on_join or false
|
||||
if type(open_on_join) == "function" then
|
||||
local success, err = xpcall(open_on_join, debug.traceback, player)
|
||||
if not success then
|
||||
log("There as been an error with an open on join hander for a gui element:\n\t" .. err)
|
||||
goto continue
|
||||
end
|
||||
visible = err
|
||||
end
|
||||
|
||||
-- Set the visible state of the element
|
||||
left_element.visible = visible
|
||||
show_hide_button = show_hide_button or visible
|
||||
|
||||
-- Check if the the element has a button attached
|
||||
if element_define.toolbar_button then
|
||||
Gui.toggle_toolbar_button(player, element_define.toolbar_button, visible)
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
||||
hide_button.visible = show_hide_button
|
||||
end
|
||||
|
||||
--- Reorder the left flow elements to match that returned by the provider, uses a method equivalent to insert sort
|
||||
function Gui.reorder_left_flow(player)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
|
||||
-- Get the order to draw the elements in
|
||||
local flow_order = Gui.get_left_flow_order(player)
|
||||
if #flow_order ~= #Gui.left_elements then
|
||||
error(string.format("Left flow order provider (%s) did not return the correct element count, expect %d got %d",
|
||||
Gui._left_flow_order_src, #Gui.left_elements, #flow_order
|
||||
))
|
||||
end
|
||||
|
||||
-- Reorder the elements, index 1 is the core ui buttons so +1 is required
|
||||
for index, element_define in ipairs(flow_order) do
|
||||
local element = left_flow[element_define.name]
|
||||
left_flow.swap_children(index + 1, element.get_index_in_parent())
|
||||
end
|
||||
end
|
||||
|
||||
--[[-- Update the visible state of the hide button, can be used to check if any frames are visible
|
||||
@tparam LuaPlayer player the player to update the left flow for
|
||||
@treturn boolean true if any left element is visible
|
||||
|
||||
@usage-- Check if any left elements are visible
|
||||
local visible = Gui.update_left_flow(player)
|
||||
|
||||
]]
|
||||
function Gui.update_left_flow(player)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
local hide_button = left_flow.gui_core_buttons[hide_left_flow]
|
||||
for _, element_define in ipairs(Gui.left_elements) do
|
||||
local left_element = left_flow[element_define.name]
|
||||
if left_element.visible then
|
||||
hide_button.visible = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
hide_button.visible = false
|
||||
return false
|
||||
end
|
||||
|
||||
--[[-- Hides all left elements for a player
|
||||
@tparam LuaPlayer player the player to hide the elements for
|
||||
|
||||
@usage-- Hide your left elements
|
||||
Gui.hide_left_flow(game.player)
|
||||
|
||||
]]
|
||||
function Gui.hide_left_flow(player)
|
||||
local top_flow = Gui.get_top_flow(player)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
local hide_button = left_flow.gui_core_buttons[hide_left_flow]
|
||||
|
||||
-- Set the visible state of all elements in the flow
|
||||
hide_button.visible = false
|
||||
for _, element_define in ipairs(Gui.left_elements) do
|
||||
left_flow[element_define.name].visible = false
|
||||
|
||||
-- Check if the the element has a toobar button attached
|
||||
if element_define.toolbar_button then
|
||||
-- Check if the topflow contains the button
|
||||
local button = top_flow[element_define.toolbar_button.name]
|
||||
if button then
|
||||
-- Style the button
|
||||
Gui.toggle_toolbar_button(player, element_define.toolbar_button, false)
|
||||
-- Raise the custom event if all of the top checks have passed
|
||||
element_define.toolbar_button:raise_event{
|
||||
name = Gui.events.on_visibility_changed_by_click,
|
||||
element = button,
|
||||
state = false,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Checks if an element is loaded, used internally when the normal left gui assumptions may not hold
|
||||
function Gui.left_flow_loaded(player, element_define)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
return left_flow[element_define.name] ~= nil
|
||||
end
|
||||
|
||||
--[[-- Get the element define that is in the left flow, use in events without an element refrence
|
||||
@tparam LuaPlayer player the player that you want to get the element for
|
||||
@tparam table element_define the element that you want to get
|
||||
@treturn LuaGuiElement the gui element linked to this define for this player
|
||||
|
||||
@usage-- Get your left element
|
||||
local frame = Gui.get_left_element(game.player, example_flow_with_button)
|
||||
|
||||
]]
|
||||
function Gui.get_left_element(player, element_define)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
return assert(left_flow[element_define.name], "Left element failed to load")
|
||||
end
|
||||
|
||||
--[[-- Toggles the visible state of a left element for a given player, can be used to set the visible state
|
||||
@tparam LuaPlayer player the player that you want to toggle the element for
|
||||
@tparam table element_define the element that you want to toggle
|
||||
@tparam[opt] boolean state with given will set the state, else state will be toggled
|
||||
@treturn boolean the new visible state of the element
|
||||
|
||||
@usage-- Toggle your example button
|
||||
Gui.toggle_top_flow(game.player, example_flow_with_button)
|
||||
|
||||
@usage-- Show your example button
|
||||
Gui.toggle_top_flow(game.player, example_flow_with_button, true)
|
||||
|
||||
]]
|
||||
function Gui.toggle_left_element(player, element_define, state)
|
||||
-- Set the visible state
|
||||
local element = Gui.get_left_element(player, element_define)
|
||||
if state == nil then state = not element.visible end
|
||||
element.visible = state
|
||||
Gui.update_left_flow(player)
|
||||
|
||||
-- Check if the the element has a button attached
|
||||
if element_define.toolbar_button then
|
||||
Gui.toggle_toolbar_button(player, element_define.toolbar_button, state)
|
||||
end
|
||||
return state
|
||||
end
|
||||
@@ -1,415 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Used to simplify gui creation using factory functions called element defines
|
||||
@module Gui
|
||||
]]
|
||||
|
||||
local ExpUtil = require("modules/exp_util")
|
||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||
|
||||
local Gui = {
|
||||
--- The current highest uid that is being used by a define, will not increase during runtime
|
||||
uid = 0,
|
||||
--- Used to automatically assign a unique static name to an element
|
||||
unique_static_name = {},
|
||||
--- String indexed table used to avoid conflict with custom event names, similar to how defines.events works
|
||||
events = {},
|
||||
--- Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime
|
||||
defines = {},
|
||||
--- An string indexed table of all the defines which are used by the core of the gui system, used for internal reference
|
||||
core_defines = {},
|
||||
--- Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debugging
|
||||
file_paths = {},
|
||||
--- Used to store extra information about elements as they get defined such as the params used and event handlers registered to them
|
||||
debug_info = {},
|
||||
--- The prototype used to store the functions of an element define
|
||||
_prototype_element = {},
|
||||
--- The prototype metatable applied to new element defines
|
||||
_mt_element = {},
|
||||
}
|
||||
|
||||
--- Allow access to the element prototype methods
|
||||
Gui._mt_element.__index = Gui._prototype_element
|
||||
|
||||
--- Allows the define to be called to draw the element
|
||||
function Gui._mt_element.__call(self, parent, ...)
|
||||
local element, no_events = self._draw(self, parent, ...)
|
||||
if self._style then self._style(element.style, element, ...) end
|
||||
|
||||
-- Asserts to catch common errors
|
||||
if element then
|
||||
if self.name and self.name ~= element.name then
|
||||
error("Static name \"" .. self.name .. "\" expected but got: " .. tostring(element.name))
|
||||
end
|
||||
local event_triggers = element.tags and element.tags.ExpGui_event_triggers
|
||||
if event_triggers and table.array_contains(event_triggers, self.uid) then
|
||||
error("Element::triggers_events should not be called on the value you return from the definition")
|
||||
end
|
||||
elseif self.name then
|
||||
error("Static name \"" .. self.name .. "\" expected but no element was returned from the definition")
|
||||
end
|
||||
|
||||
-- Register events by default, but allow skipping them
|
||||
if no_events == self.no_events then
|
||||
return element
|
||||
else
|
||||
return element and self:triggers_events(element)
|
||||
end
|
||||
end
|
||||
|
||||
--- Get where a function was defined as a string
|
||||
local function get_defined_at(level)
|
||||
local debug_info = debug.getinfo(level, "Sn")
|
||||
local file_name = debug_info.short_src:sub(10, -5)
|
||||
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
|
||||
return file_name .. ":" .. func_name
|
||||
end
|
||||
|
||||
--- Element Define.
|
||||
-- @section elementDefine
|
||||
|
||||
--[[-- Used to define new elements for your gui, can be used like LuaGuiElement.add or a custom function
|
||||
@tparam ?table|function element_define the define information for the gui element, same data as LuaGuiElement.add, or a custom function may be used
|
||||
@treturn table the new element define, this can be considered a factory for the element which can be called to draw the element to any other element
|
||||
|
||||
@usage-- Using element defines like LuaGuiElement.add
|
||||
-- This returns a factory function to draw a button with the caption "Example Button"
|
||||
local example_button =
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button'
|
||||
}
|
||||
|
||||
@usage-- Using element defines with a custom factory function
|
||||
-- This method can be used if you still want to be able register event handlers but it is too complex to be compatible with LuaGuiElement.add
|
||||
local example_flow_with_button =
|
||||
Gui.element(function(event_trigger, parent, ...)
|
||||
-- ... shows that all other arguments from the factory call are passed to this function
|
||||
-- parent is the element which was passed to the factory function where you should add your new element
|
||||
-- here we are adding a flow which we will then later add a button to
|
||||
local flow =
|
||||
parent.add{
|
||||
name = 'example_flow',
|
||||
type = 'flow'
|
||||
}
|
||||
|
||||
-- event_trigger should be the name of any elements you want to trigger your event handlers, such as on_click or on_state_changed
|
||||
-- now we add the button to the flow that we created earlier
|
||||
local element =
|
||||
flow.add{
|
||||
name = event_trigger,
|
||||
type = 'button',
|
||||
caption = 'Example Button'
|
||||
}
|
||||
|
||||
-- you must return your new element, this is so styles can be applied and returned to the caller
|
||||
-- you may return any of your elements that you add, consider the context in which it will be used for what should be returned
|
||||
return element
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui.element(element_define)
|
||||
ExpUtil.assert_not_runtime()
|
||||
-- Set the metatable to allow access to register events
|
||||
local element = setmetatable({}, Gui._mt_element)
|
||||
|
||||
-- Increment the uid counter
|
||||
local uid = Gui.uid + 1
|
||||
Gui.uid = uid
|
||||
element.uid = uid
|
||||
Gui.debug_info[uid] = { draw = "None", style = "None", events = {} }
|
||||
|
||||
-- Add the definition function
|
||||
if type(element_define) == "table" then
|
||||
Gui.debug_info[uid].draw = element_define
|
||||
if element_define.name == Gui.unique_static_name then
|
||||
element_define.name = "ExpGui_" .. tostring(uid)
|
||||
end
|
||||
for k, v in pairs(element_define) do
|
||||
if element[k] == nil then
|
||||
element[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
element._draw = function(_, parent)
|
||||
return parent.add(element_define)
|
||||
end
|
||||
else
|
||||
Gui.debug_info[uid].draw = get_defined_at(element_define)
|
||||
element._draw = element_define
|
||||
end
|
||||
|
||||
-- Add the define to the base module
|
||||
element.defined_at = get_defined_at(3)
|
||||
Gui.file_paths[uid] = element.defined_at
|
||||
Gui.defines[uid] = element
|
||||
|
||||
-- Return the element so event handers can be accessed
|
||||
return element
|
||||
end
|
||||
|
||||
--[[-- Used to extent your element define with a style factory, this style will be applied to your element when created, can also be a custom function
|
||||
@tparam ?table|function style_define style table where each key and value pair is treated like LuaGuiElement.style[key] = value, a custom function can be used
|
||||
@treturn table the element define is returned to allow for event handlers to be registered
|
||||
|
||||
@usage-- Using the table method of setting the style
|
||||
local example_button =
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button',
|
||||
style = 'forward_button' -- factorio styles can be applied here
|
||||
}
|
||||
:style{
|
||||
height = 25, -- same as element.style.height = 25
|
||||
width = 100 -- same as element.style.width = 25
|
||||
}
|
||||
|
||||
@usage-- Using the function method to set the style
|
||||
-- Use this method if your style is dynamic and depends on other factors
|
||||
local example_button =
|
||||
Gui.element{
|
||||
type = 'button',
|
||||
caption = 'Example Button',
|
||||
style = 'forward_button' -- factorio styles can be applied here
|
||||
}
|
||||
:style(function(style, element, ...)
|
||||
-- style is the current style object for the elemenent
|
||||
-- element is the element that is being changed
|
||||
-- ... shows that all other arguments from the factory call are passed to this function
|
||||
local player = game.players[element.player_index]
|
||||
style.height = 25
|
||||
style.width = 100
|
||||
style.font_color = player.color
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui._prototype_element:style(style_define)
|
||||
ExpUtil.assert_not_runtime()
|
||||
-- Add the definition function
|
||||
if type(style_define) == "table" then
|
||||
Gui.debug_info[self.uid].style = style_define
|
||||
self._style = function(style)
|
||||
for key, value in pairs(style_define) do
|
||||
style[key] = value
|
||||
end
|
||||
end
|
||||
else
|
||||
Gui.debug_info[self.uid].style = get_defined_at(style_define)
|
||||
self._style = style_define
|
||||
end
|
||||
|
||||
-- Return the element so event handers can be accessed
|
||||
return self
|
||||
end
|
||||
|
||||
--[[-- Enforce the fact the element has a static name, this is required for the cases when a function define is used
|
||||
@tparam[opt] string element The element that will trigger calls to the event handlers
|
||||
@treturn table the element define is returned to allow for event handlers to be registered
|
||||
]]
|
||||
function Gui._prototype_element:static_name(name)
|
||||
ExpUtil.assert_not_runtime()
|
||||
if name == Gui.unique_static_name then
|
||||
self.name = "ExpGui_" .. tostring(self.uid)
|
||||
else
|
||||
self.name = name
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--[[-- Used to link an element to an element define such that any event on the element will call the handlers on the element define
|
||||
-- You should not call this on the element you return from your constructor because this is done automatically
|
||||
@tparam LuaGuiElement element The element that will trigger calls to the event handlers
|
||||
@treturn LuaGuiElement The element passed as the argument to allow for cleaner returns
|
||||
]]
|
||||
function Gui._prototype_element:triggers_events(element)
|
||||
if not self._has_events then return element end
|
||||
local tags = element.tags
|
||||
if not tags then
|
||||
element.tags = { ExpGui_event_triggers = { self.uid } }
|
||||
return element
|
||||
elseif not tags.ExpGui_event_triggers then
|
||||
--- @diagnostic disable-next-line: name-style-check
|
||||
tags.ExpGui_event_triggers = { self.uid }
|
||||
elseif table.array_contains(tags.ExpGui_event_triggers, self.uid) then
|
||||
error("Element::triggers_events called multiple times on the same element with the same definition")
|
||||
else
|
||||
table.insert(tags.ExpGui_event_triggers, self.uid)
|
||||
end
|
||||
-- To modify a set of tags, the whole table needs to be written back to the respective property.
|
||||
element.tags = tags
|
||||
return element
|
||||
end
|
||||
|
||||
--- Explicitly skip events on the element returned by your definition function
|
||||
function Gui._prototype_element:no_events(element)
|
||||
return element, self.no_events
|
||||
end
|
||||
|
||||
--[[-- Set the handler which will be called for a custom event, only one handler can be used per event per element
|
||||
@tparam string event_name the name of the event you want to handler to be called on, often from Gui.events
|
||||
@tparam function handler the handler that you want to be called when the event is raised
|
||||
@treturn table the element define so more handleres can be registered
|
||||
|
||||
@usage-- Register a handler to "my_custom_event" for this element
|
||||
element_deinfe:on_event('my_custom_event', function(event)
|
||||
event.player.print(player.name)
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui._prototype_element:on_event(event_name, handler)
|
||||
ExpUtil.assert_not_runtime()
|
||||
table.insert(Gui.debug_info[self.uid].events, event_name)
|
||||
Gui.events[event_name] = event_name
|
||||
self[event_name] = handler
|
||||
self._has_events = true
|
||||
return self
|
||||
end
|
||||
|
||||
--[[-- Raise the handler which is attached to an event; external use should be limited to custom events
|
||||
@tparam table event the event table passed to the handler, must contain fields: name, element
|
||||
@treturn table the element define so more events can be raised
|
||||
|
||||
@usage Raising a custom event
|
||||
element_define:raise_event{
|
||||
name = 'my_custom_event',
|
||||
element = element
|
||||
}
|
||||
|
||||
]]
|
||||
function Gui._prototype_element:raise_event(event)
|
||||
-- Check the element is valid
|
||||
local element = event.element
|
||||
if not element or not element.valid then
|
||||
return self
|
||||
end
|
||||
|
||||
-- Get the event handler for this element
|
||||
local handler = self[event.name]
|
||||
if not handler then
|
||||
return self
|
||||
end
|
||||
|
||||
-- Get the player for this event
|
||||
local player_index = event.player_index or element.player_index
|
||||
local player = game.players[player_index]
|
||||
if not player or not player.valid then
|
||||
return self
|
||||
end
|
||||
event.player = player
|
||||
|
||||
local success, err = xpcall(handler, debug.traceback, player, element, event)
|
||||
if not success then
|
||||
error("There as been an error with an event handler for a gui element:\n\t" .. err)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
-- This function is used to link element define events and the events from the factorio api
|
||||
local function event_handler_factory(event_name)
|
||||
Event.add(event_name, function(event)
|
||||
local element = event.element
|
||||
if not element or not element.valid then return end
|
||||
local event_triggers = element.tags.ExpGui_event_triggers
|
||||
if not event_triggers then return end
|
||||
for _, uid in pairs(event_triggers) do
|
||||
local element_define = Gui.defines[uid]
|
||||
if element_define then
|
||||
element_define:raise_event(event)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.events[event_name] = event_name
|
||||
return function(self, handler)
|
||||
return self:on_event(event_name, handler)
|
||||
end
|
||||
end
|
||||
|
||||
--- Element Events.
|
||||
-- @section elementEvents
|
||||
|
||||
--- Called when the player opens a GUI.
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_open(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_open = event_handler_factory(defines.events.on_gui_opened)
|
||||
|
||||
--- Called when the player closes the GUI they have open.
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_close(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_close = event_handler_factory(defines.events.on_gui_closed)
|
||||
|
||||
--- Called when LuaGuiElement is clicked.
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_click(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_click = event_handler_factory(defines.events.on_gui_click)
|
||||
|
||||
--- Called when a LuaGuiElement is confirmed, for example by pressing Enter in a textfield.
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_confirmed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_confirmed = event_handler_factory(defines.events.on_gui_confirmed)
|
||||
|
||||
--- Called when LuaGuiElement checked state is changed (related to checkboxes and radio buttons).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_checked_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_checked_changed = event_handler_factory(defines.events.on_gui_checked_state_changed)
|
||||
|
||||
--- Called when LuaGuiElement element value is changed (related to choose element buttons).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_elem_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_elem_changed = event_handler_factory(defines.events.on_gui_elem_changed)
|
||||
|
||||
--- Called when LuaGuiElement element location is changed (related to frames in player.gui.screen).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_location_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_location_changed = event_handler_factory(defines.events.on_gui_location_changed)
|
||||
|
||||
--- Called when LuaGuiElement selected tab is changed (related to tabbed-panes).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_tab_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_tab_changed = event_handler_factory(defines.events.on_gui_selected_tab_changed)
|
||||
|
||||
--- Called when LuaGuiElement selection state is changed (related to drop-downs and listboxes).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_selection_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_selection_changed = event_handler_factory(defines.events.on_gui_selection_state_changed)
|
||||
|
||||
--- Called when LuaGuiElement switch state is changed (related to switches).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_switch_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events.on_gui_switch_state_changed)
|
||||
|
||||
--- Called when LuaGuiElement text is changed by the player.
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_text_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed)
|
||||
|
||||
--- Called when LuaGuiElement slider value is changed (related to the slider element).
|
||||
-- @tparam function handler the event handler which will be called
|
||||
-- @usage element_define:on_value_changed(function(event)
|
||||
-- event.player.print(table.inspect(event))
|
||||
-- end)
|
||||
Gui._prototype_element.on_value_changed = event_handler_factory(defines.events.on_gui_value_changed)
|
||||
|
||||
-- Module return
|
||||
return Gui
|
||||
@@ -1,316 +0,0 @@
|
||||
--[[-- Core Module - Gui
|
||||
- Controls the elements on the top flow
|
||||
@module Gui
|
||||
]]
|
||||
|
||||
local ExpUtil = require("modules/exp_util")
|
||||
local Gui = require("modules.exp_legacy.expcore.gui.prototype")
|
||||
local mod_gui = require "mod-gui" --- @dep mod-gui
|
||||
|
||||
local toolbar_button_size = 36
|
||||
local hide_top_flow = Gui.core_defines.hide_top_flow.name
|
||||
local show_top_flow = Gui.core_defines.show_top_flow.name
|
||||
|
||||
--- Top Flow.
|
||||
-- @section topFlow
|
||||
|
||||
-- Triggered when a user changed the visibility of a left flow element by clicking a button
|
||||
Gui.events.on_toolbar_button_toggled = "on_toolbar_button_toggled"
|
||||
|
||||
--- Contains the uids of the elements that will shown on the top flow and their auth functions
|
||||
-- @table top_elements
|
||||
Gui.top_elements = {}
|
||||
|
||||
--- The style that should be used for buttons on the top flow
|
||||
-- @field Gui.top_flow_button_style
|
||||
Gui.top_flow_button_style = mod_gui.button_style
|
||||
|
||||
--- The style that should be used for buttons on the top flow when their flow is visible
|
||||
-- @field Gui.top_flow_button_toggled_style
|
||||
Gui.top_flow_button_toggled_style = "menu_button_continue"
|
||||
|
||||
--[[-- Styles a top flow button depending on the state given
|
||||
@tparam LuaGuiElement button the button element to style
|
||||
@tparam boolean state The state the button is in
|
||||
|
||||
@usage-- Sets the button to the visible style
|
||||
Gui.toolbar_button_style(button, true)
|
||||
|
||||
@usage-- Sets the button to the hidden style
|
||||
Gui.toolbar_button_style(button, false)
|
||||
|
||||
]]
|
||||
function Gui.toolbar_button_style(button, state, size)
|
||||
--- @cast button LuaGuiElement
|
||||
if state then
|
||||
button.style = Gui.top_flow_button_toggled_style
|
||||
else
|
||||
button.style = Gui.top_flow_button_style
|
||||
end
|
||||
button.style.minimal_width = size or toolbar_button_size
|
||||
button.style.height = size or toolbar_button_size
|
||||
button.style.padding = -2
|
||||
end
|
||||
|
||||
--[[-- Gets the flow refered to as the top flow, each player has one top flow
|
||||
@function Gui.get_top_flow(player)
|
||||
@tparam LuaPlayer player the player that you want to get the flow for
|
||||
@treturn LuaGuiElement the top element flow
|
||||
|
||||
@usage-- Geting your top flow
|
||||
local top_flow = Gui.get_top_flow(game.player)
|
||||
|
||||
]]
|
||||
Gui.get_top_flow = mod_gui.get_button_flow
|
||||
|
||||
--[[-- Sets an element define to be drawn to the top flow when a player joins, includes optional authenticator
|
||||
@tparam[opt] function authenticator called during toggle or update to decide weather the element should be visible
|
||||
@treturn table the new element define to allow event handlers to be registered
|
||||
|
||||
@usage-- Adding an element to the top flow on join
|
||||
example_button:add_to_top_flow(function(player)
|
||||
-- example button will only be shown if the player is an admin
|
||||
-- note button will not update its state when player.admin is changed Gui.update_top_flow must be called for this
|
||||
return player.admin
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui._prototype_element:add_to_top_flow(authenticator)
|
||||
ExpUtil.assert_not_runtime()
|
||||
if not self.name then error("Elements for the top flow must have a static name") end
|
||||
self.authenticator = authenticator or true
|
||||
table.insert(Gui.top_elements, self)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns true if the top flow has visible elements
|
||||
function Gui.top_flow_has_visible_elements(player)
|
||||
local top_flow = Gui.get_top_flow(player)
|
||||
|
||||
for _, child in pairs(top_flow.children) do
|
||||
if child.name ~= hide_top_flow then
|
||||
if child.visible then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
Gui._top_flow_order_src = "<default>"
|
||||
--- Get the order of elements in the top flow, first argument is player but is unused in the default method
|
||||
function Gui.get_top_flow_order(_)
|
||||
return Gui.top_elements
|
||||
end
|
||||
|
||||
--- Inject a custom top flow order provider, this should accept a player and return a list of elements definitions to draw
|
||||
function Gui.inject_top_flow_order(provider)
|
||||
Gui.get_top_flow_order = provider
|
||||
local debug_info = debug.getinfo(2, "Sn")
|
||||
local file_name = debug_info.short_src:sub(10, -5)
|
||||
local func_name = debug_info.name or ("<anonymous:" .. debug_info.linedefined .. ">")
|
||||
Gui._top_flow_order_src = file_name .. ":" .. func_name
|
||||
end
|
||||
|
||||
--[[-- Updates the visible state of all the elements on the players top flow, uses authenticator
|
||||
@tparam LuaPlayer player the player that you want to update the top flow for
|
||||
|
||||
@usage-- Update your top flow
|
||||
Gui.update_top_flow(game.player)
|
||||
|
||||
]]
|
||||
function Gui.update_top_flow(player)
|
||||
local top_flow = Gui.get_top_flow(player)
|
||||
|
||||
-- Get the order to draw the elements in
|
||||
local flow_order = Gui.get_top_flow_order(player)
|
||||
if #flow_order ~= #Gui.top_elements then
|
||||
error(string.format("Top flow order provider (%s) did not return the correct element count, expect %d got %d",
|
||||
Gui._top_flow_order_src, #Gui.top_elements, #flow_order
|
||||
))
|
||||
end
|
||||
|
||||
-- Set the visible state of all elements in the flow
|
||||
for index, element_define in ipairs(flow_order) do
|
||||
-- Ensure the element exists
|
||||
local element = top_flow[element_define.name]
|
||||
if not element then
|
||||
element = element_define(top_flow)
|
||||
else
|
||||
top_flow.swap_children(index + 1, element.get_index_in_parent())
|
||||
end
|
||||
|
||||
-- Set the visible state
|
||||
local allowed = element_define.authenticator
|
||||
if type(allowed) == "function" then allowed = allowed(player) end
|
||||
element.visible = allowed or false
|
||||
|
||||
-- If its not visible and there is a left element, then hide it
|
||||
if element_define.left_flow_element and not element.visible and Gui.left_flow_loaded(player, element_define.left_flow_element) then
|
||||
Gui.toggle_left_element(player, element_define.left_flow_element, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if there are any visible elements in the top flow
|
||||
if not Gui.top_flow_has_visible_elements(player) then
|
||||
-- None are visible so hide the top_flow and its show button
|
||||
Gui.toggle_top_flow(player, false)
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
local show_button = left_flow.gui_core_buttons[show_top_flow]
|
||||
show_button.visible = false
|
||||
end
|
||||
end
|
||||
|
||||
--- Reorder the top flow elements to match that returned by the provider, uses a method equivalent to insert sort
|
||||
function Gui.reorder_top_flow(player)
|
||||
local top_flow = Gui.get_top_flow(player)
|
||||
|
||||
-- Get the order to draw the elements in
|
||||
local flow_order = Gui.get_top_flow_order(player)
|
||||
if #flow_order ~= #Gui.top_elements then
|
||||
error(string.format("Top flow order provider (%s) did not return the correct element count, expect %d got %d",
|
||||
Gui._top_flow_order_src, #Gui.top_elements, #flow_order
|
||||
))
|
||||
end
|
||||
|
||||
-- Reorder the elements, index 1 is the core ui buttons so +1 is required
|
||||
for index, element_define in ipairs(flow_order) do
|
||||
local element = top_flow[element_define.name]
|
||||
top_flow.swap_children(index + 1, element.get_index_in_parent())
|
||||
end
|
||||
end
|
||||
|
||||
--[[-- Toggles the visible state of all the elements on a players top flow, effects all elements
|
||||
@tparam LuaPlayer player the player that you want to toggle the top flow for
|
||||
@tparam[opt] boolean state if given then the state will be set to this
|
||||
@treturn boolean the new visible state of the top flow
|
||||
|
||||
@usage-- Toggle your flow
|
||||
Gui.toggle_top_flow(game.player)
|
||||
|
||||
@usage-- Open your top flow
|
||||
Gui.toggle_top_flow(game.player, true)
|
||||
|
||||
]]
|
||||
function Gui.toggle_top_flow(player, state)
|
||||
-- Get the top flow, we need the parent as we want to toggle the outer frame
|
||||
local top_flow = Gui.get_top_flow(player).parent --- @cast top_flow -nil
|
||||
if state == nil then state = not top_flow.visible end
|
||||
|
||||
-- Get the show button for the top flow
|
||||
local left_flow = Gui.get_left_flow(player)
|
||||
local show_button = left_flow.gui_core_buttons[show_top_flow]
|
||||
|
||||
-- Change the visibility of the top flow and show top flow button
|
||||
show_button.visible = not state
|
||||
top_flow.visible = state
|
||||
|
||||
return state
|
||||
end
|
||||
|
||||
--[[-- Get the element define that is in the top flow, use in events without an element refrence
|
||||
@tparam LuaPlayer player the player that you want to get the element for
|
||||
@tparam table element_define the element that you want to get
|
||||
@treturn LuaGuiElement the gui element linked to this define for this player
|
||||
|
||||
@usage-- Get your top element
|
||||
local button = Gui.get_top_element(game.player, example_button)
|
||||
|
||||
]]
|
||||
function Gui.get_top_element(player, element_define)
|
||||
local top_flow = Gui.get_top_flow(player)
|
||||
return assert(top_flow[element_define.name], "Top element failed to load")
|
||||
end
|
||||
|
||||
--[[-- Toggles the state of a toolbar button for a given player, can be used to set the visual state
|
||||
@tparam LuaPlayer player the player that you want to toggle the element for
|
||||
@tparam table element_define the element that you want to toggle
|
||||
@tparam[opt] boolean state with given will set the state, else state will be toggled
|
||||
@treturn boolean the new visible state of the element
|
||||
|
||||
@usage-- Toggle your example button
|
||||
Gui.toggle_toolbar_button(game.player, toolbar_button)
|
||||
|
||||
@usage-- Show your example button
|
||||
Gui.toggle_toolbar_button(game.player, toolbar_button, true)
|
||||
|
||||
]]
|
||||
function Gui.toggle_toolbar_button(player, element_define, state)
|
||||
local toolbar_button = Gui.get_top_element(player, element_define)
|
||||
if state == nil then state = toolbar_button.style.name ~= Gui.top_flow_button_toggled_style end
|
||||
Gui.toolbar_button_style(toolbar_button, state, toolbar_button.style.minimal_width)
|
||||
element_define:raise_event{
|
||||
name = Gui.events.on_toolbar_button_toggled,
|
||||
element = toolbar_button,
|
||||
player = player,
|
||||
state = state,
|
||||
}
|
||||
return state
|
||||
end
|
||||
|
||||
--[[-- Creates a button on the top flow with consistent styling
|
||||
@tparam string sprite the sprite that you want to use on the button
|
||||
@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have
|
||||
@tparam[opt] function authenticator used to decide if the button should be visible to a player
|
||||
|
||||
@usage-- Add a button to the toolbar
|
||||
local toolbar_button =
|
||||
Gui.left_toolbar_button('entity/inserter', 'Nothing to see here', function(player)
|
||||
return player.admin
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui.toolbar_button(sprite, tooltip, authenticator)
|
||||
return Gui.element{
|
||||
type = "sprite-button",
|
||||
sprite = sprite,
|
||||
tooltip = tooltip,
|
||||
style = Gui.top_flow_button_style,
|
||||
name = Gui.unique_static_name,
|
||||
}
|
||||
:style{
|
||||
minimal_width = toolbar_button_size,
|
||||
height = toolbar_button_size,
|
||||
padding = -2,
|
||||
}
|
||||
:add_to_top_flow(authenticator)
|
||||
end
|
||||
|
||||
--[[-- Creates a toggle button on the top flow with consistent styling
|
||||
@tparam string sprite the sprite that you want to use on the button
|
||||
@tparam ?string|Concepts.LocalizedString tooltip the tooltip that you want the button to have
|
||||
@tparam[opt] function authenticator used to decide if the button should be visible to a player
|
||||
|
||||
@usage-- Add a button to the toolbar
|
||||
local toolbar_button =
|
||||
Gui.toolbar_toggle_button('entity/inserter', 'Nothing to see here', function(player)
|
||||
return player.admin
|
||||
end)
|
||||
:on_event(Gui.events.on_toolbar_button_toggled, function(player, element, event)
|
||||
game.print(table.inspect(event))
|
||||
end)
|
||||
|
||||
]]
|
||||
function Gui.toolbar_toggle_button(sprite, tooltip, authenticator)
|
||||
local button =
|
||||
Gui.element{
|
||||
type = "sprite-button",
|
||||
sprite = sprite,
|
||||
tooltip = tooltip,
|
||||
style = Gui.top_flow_button_style,
|
||||
name = Gui.unique_static_name,
|
||||
}
|
||||
:style{
|
||||
minimal_width = toolbar_button_size,
|
||||
height = toolbar_button_size,
|
||||
padding = -2,
|
||||
}
|
||||
:add_to_top_flow(authenticator)
|
||||
|
||||
button:on_click(function(player, _, _)
|
||||
Gui.toggle_toolbar_button(player, button)
|
||||
end)
|
||||
|
||||
return button
|
||||
end
|
||||
@@ -6,12 +6,6 @@ game-message-unassign=__1__ has been unassigned from __2__ by __3__
|
||||
reject-role=Invalid Role Name.
|
||||
reject-player-role=Player has a higher role.
|
||||
|
||||
[gui_util]
|
||||
button_tooltip=Shows/hides the toolbar.
|
||||
|
||||
[expcore-gui]
|
||||
left-button-tooltip=Hide all open windows.
|
||||
|
||||
[expcore-data]
|
||||
description-preference=Allows you to set/get your data saving preference.
|
||||
description-data=Writes all your player data to a file on your computer.
|
||||
|
||||
@@ -6,12 +6,6 @@ game-message-unassign=__1__ 已被 __3__ 取消指派到身分組 __2__
|
||||
reject-role=無效的身分組。
|
||||
reject-player-role=用戶已有更高的身分組。
|
||||
|
||||
[gui_util]
|
||||
button_tooltip=是否顯示工具欄。
|
||||
|
||||
[expcore-gui]
|
||||
left-button-tooltip=關閉所有打開的視窗。
|
||||
|
||||
[expcore-data]
|
||||
description-preference=允許寫入資料。
|
||||
description-data=把用戶資料寫入電腦
|
||||
|
||||
@@ -6,12 +6,6 @@ game-message-unassign=__1__ 已被 __3__ 取消指派到身分組 __2__
|
||||
reject-role=無效的身分組。
|
||||
reject-player-role=用戶已有更高的身分組。
|
||||
|
||||
[gui_util]
|
||||
button_tooltip=是否顯示工具欄。
|
||||
|
||||
[expcore-gui]
|
||||
left-button-tooltip=關閉所有打開的視窗。
|
||||
|
||||
[expcore-data]
|
||||
description-preference=允許寫入資料。
|
||||
description-data=把用戶資料寫入電腦
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
local Storage = require("modules/exp_util/storage")
|
||||
local FlyingText = require("modules/exp_util/flying_text")
|
||||
local Gui = require("modules/exp_gui")
|
||||
local Roles = require("modules.exp_legacy.expcore.roles") -- @dep expcore.gui
|
||||
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||
local config = require("modules.exp_legacy.config.gui.autofill") -- @dep config.gui.autofill
|
||||
local Event = require("modules/exp_legacy/utils/event") -- @dep utils.event
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
local ExpUtil = require("modules/exp_util")
|
||||
local Gui = require("modules/exp_gui")
|
||||
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.gui
|
||||
local Roles = require("modules.exp_legacy.expcore.roles")
|
||||
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
||||
local config = require("modules.exp_legacy.config.gui.science") --- @dep config.gui.science
|
||||
local Production = require("modules.exp_legacy.modules.control.production") --- @dep modules.control.production
|
||||
|
||||
Reference in New Issue
Block a user