mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
Refactor some of the Guis from the legacy plugin (#399)
* Fix bugs in core and add default args to Gui defs * Refactor production Gui * Refactor landfill blueprint button * Fix more bugs in core * Consistent naming of new guis * Refactor module inserter gui * Refactor surveillance gui * Add shorthand for data from arguments * Make element names consistent * Add types * Change how table rows work * Refactor player stats gui * Refactor quick actions gui * Refactor research milestones gui * Refactor player bonus gui * Refactor science production gui * Refactor autofill gui * Cleanup use of aligned flow * Rename "Gui.element" to "Gui.define" * Rename Gui types * Rename property_from_arg * Add guide for making guis * Add full reference document * Add condensed reference * Apply style guide to refactored guis * Bug fixes
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
--- @class ExpGui
|
||||
local ExpGui = require("modules/exp_gui")
|
||||
--- @class Gui
|
||||
local Gui = require("modules/exp_gui")
|
||||
|
||||
--- @class ExpGui.elements
|
||||
local elements = {}
|
||||
ExpGui.elements = elements
|
||||
--- @class Gui.elements
|
||||
local Elements = {}
|
||||
Gui.elements = Elements
|
||||
|
||||
--- @class Gui.elements.aligned_flow.opts
|
||||
--- @field horizontal_align ("left" | "center" | "right")?
|
||||
--- @field vertical_align ("top" | "center" | "bottom")?
|
||||
|
||||
--- A flow which aligns its content as specified
|
||||
elements.aligned_flow = ExpGui.element("aligned_flow")
|
||||
--- @class Gui.elements.aligned_flow: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, opts: Gui.elements.aligned_flow.opts?): LuaGuiElement
|
||||
Elements.aligned_flow = Gui.define("aligned_flow")
|
||||
:draw{
|
||||
type = "flow",
|
||||
name = ExpGui.property_from_arg("name"),
|
||||
name = Gui.from_argument("name"),
|
||||
}
|
||||
:style(function(def, element, parent, opts)
|
||||
opts = opts or {}
|
||||
opts = opts or {} --- @cast opts Gui.elements.aligned_flow.opts
|
||||
local vertical_align = opts.vertical_align or "center"
|
||||
local horizontal_align = opts.horizontal_align or "right"
|
||||
return {
|
||||
@@ -22,15 +28,18 @@ elements.aligned_flow = ExpGui.element("aligned_flow")
|
||||
vertically_stretchable = vertical_align ~= "center",
|
||||
horizontally_stretchable = horizontal_align ~= "center",
|
||||
}
|
||||
end)
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- A solid horizontal white bar element
|
||||
elements.bar = ExpGui.element("bar")
|
||||
--- @class Gui.elements.bar: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, width: number?): LuaGuiElement
|
||||
Elements.bar = Gui.define("bar")
|
||||
:draw{
|
||||
type = "progressbar",
|
||||
value = 1,
|
||||
}
|
||||
:style(function(def, element, parent, width)
|
||||
--- @cast width number?
|
||||
local style = element.style
|
||||
style.color = { r = 255, g = 255, b = 255 }
|
||||
style.height = 4
|
||||
@@ -39,50 +48,58 @@ elements.bar = ExpGui.element("bar")
|
||||
else
|
||||
style.horizontally_stretchable = true
|
||||
end
|
||||
end)
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- A label which is centered
|
||||
elements.centered_label = ExpGui.element("centered_label")
|
||||
--- @class Gui.elements.centered_label: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, width: number, caption: LocalisedString, tooltip: LocalisedString?): LuaGuiElement
|
||||
Elements.centered_label = Gui.define("centered_label")
|
||||
:draw{
|
||||
type = "label",
|
||||
caption = ExpGui.property_from_arg(2),
|
||||
tooltip = ExpGui.property_from_arg(3),
|
||||
caption = Gui.from_argument(2),
|
||||
tooltip = Gui.from_argument(3),
|
||||
}
|
||||
:style{
|
||||
horizontal_align = "center",
|
||||
single_line = false,
|
||||
width = ExpGui.property_from_arg(1),
|
||||
}
|
||||
width = Gui.from_argument(1),
|
||||
} --[[ @as any ]]
|
||||
|
||||
--- A label which has two white bars on either side of it
|
||||
elements.title_label = ExpGui.element("title_label")
|
||||
--- @class Gui.elements.title_label: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, width: number, caption: LocalisedString, tooltip: LocalisedString?): LuaGuiElement
|
||||
Elements.title_label = Gui.define("title_label")
|
||||
:draw(function(def, parent, width, caption, tooltip)
|
||||
local flow =
|
||||
parent.add{
|
||||
type = "flow"
|
||||
}
|
||||
|
||||
--- @cast width number
|
||||
--- @cast caption LocalisedString
|
||||
--- @cast tooltip LocalisedString?
|
||||
local flow = parent.add{
|
||||
type = "flow"
|
||||
}
|
||||
|
||||
flow.style.vertical_align = "center"
|
||||
elements.bar(flow, width)
|
||||
|
||||
local label =
|
||||
flow.add{
|
||||
type = "label",
|
||||
style = "frame_title",
|
||||
caption = caption,
|
||||
tooltip = tooltip,
|
||||
}
|
||||
Elements.bar(flow, width)
|
||||
|
||||
elements.bar(flow)
|
||||
local label = flow.add{
|
||||
type = "label",
|
||||
style = "frame_title",
|
||||
caption = caption,
|
||||
tooltip = tooltip,
|
||||
}
|
||||
|
||||
Elements.bar(flow)
|
||||
|
||||
return label
|
||||
end)
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- A fixed size vertical scroll pane
|
||||
elements.scroll_pane = ExpGui.element("scroll_pane")
|
||||
--- @class Gui.elements.scroll_pane: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, maximal_height: number, name: string?): LuaGuiElement
|
||||
Elements.scroll_pane = Gui.define("scroll_pane")
|
||||
:draw{
|
||||
type = "scroll-pane",
|
||||
name = ExpGui.property_from_arg(2),
|
||||
name = Gui.from_argument(2),
|
||||
direction = "vertical",
|
||||
horizontal_scroll_policy = "never",
|
||||
vertical_scroll_policy = "auto",
|
||||
@@ -90,14 +107,19 @@ elements.scroll_pane = ExpGui.element("scroll_pane")
|
||||
}
|
||||
:style{
|
||||
padding = { 1, 3 },
|
||||
maximal_height = ExpGui.property_from_arg(1),
|
||||
maximal_height = Gui.from_argument(1),
|
||||
horizontally_stretchable = true,
|
||||
}
|
||||
} --[[ @as any ]]
|
||||
|
||||
--- A fixed size vertical scroll pane containing a table
|
||||
elements.scroll_table = ExpGui.element("scroll_table")
|
||||
:draw(function(def, parent, height, column_count, scroll_name)
|
||||
local scroll_pane = elements.scroll_pane(parent, height, scroll_name)
|
||||
--- @class Gui.elements.scroll_table: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, maximal_height: number, column_count: number, scroll_name: string?): LuaGuiElement
|
||||
Elements.scroll_table = Gui.define("scroll_table")
|
||||
:draw(function(def, parent, maximal_height, column_count, scroll_name)
|
||||
--- @cast maximal_height number
|
||||
--- @cast column_count number
|
||||
--- @cast scroll_name string?
|
||||
local scroll_pane = Elements.scroll_pane(parent, maximal_height, scroll_name)
|
||||
|
||||
return scroll_pane.add{
|
||||
type = "table",
|
||||
@@ -106,25 +128,25 @@ elements.scroll_table = ExpGui.element("scroll_table")
|
||||
}
|
||||
end)
|
||||
:style{
|
||||
padding = 0,
|
||||
cell_padding = 0,
|
||||
padding = { 3, 2 },
|
||||
cell_padding = 1,
|
||||
vertical_align = "center",
|
||||
horizontally_stretchable = true,
|
||||
}
|
||||
} --[[ @as any ]]
|
||||
|
||||
--- A container frame
|
||||
elements.container = ExpGui.element("container")
|
||||
:draw(function(def, parent, width, container_name)
|
||||
local container =
|
||||
parent.add{
|
||||
type = "frame",
|
||||
name = container_name,
|
||||
}
|
||||
--- @class Gui.elements.container: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, minimal_width: number?, name: string?): LuaGuiElement
|
||||
Elements.container = Gui.define("container")
|
||||
:draw(function(def, parent, minimal_width, name)
|
||||
--- @cast minimal_width number?
|
||||
--- @cast name string?
|
||||
local container = parent.add{
|
||||
type = "frame",
|
||||
name = name,
|
||||
}
|
||||
|
||||
local style = container.style
|
||||
style.horizontally_stretchable = false
|
||||
style.minimal_width = width
|
||||
style.padding = 2
|
||||
container.style.padding = 2
|
||||
|
||||
return container.add{
|
||||
type = "frame",
|
||||
@@ -135,59 +157,176 @@ elements.container = ExpGui.element("container")
|
||||
end)
|
||||
:style{
|
||||
vertically_stretchable = false,
|
||||
}
|
||||
horizontally_stretchable = false,
|
||||
minimal_width = Gui.from_argument(1),
|
||||
} --[[ @as any ]]
|
||||
|
||||
--- Get the root element of a container
|
||||
--- @param container LuaGuiElement
|
||||
--- @return LuaGuiElement
|
||||
function Elements.container.get_root_element(container)
|
||||
return container.parent
|
||||
end
|
||||
|
||||
--- A frame within a container
|
||||
elements.subframe_base = ExpGui.element("container_subframe")
|
||||
--- @class Gui.elements.subframe_base: ExpElement
|
||||
--- @overload fun(parent: LuaGuiElement, style: string, name: string?): LuaGuiElement
|
||||
Elements.subframe_base = Gui.define("container_subframe")
|
||||
:draw{
|
||||
type = "frame",
|
||||
name = ExpGui.property_from_arg(2),
|
||||
style = ExpGui.property_from_arg(1),
|
||||
name = Gui.from_argument(2),
|
||||
style = Gui.from_argument(1),
|
||||
}
|
||||
:style{
|
||||
height = 0,
|
||||
minimal_height = 36,
|
||||
padding = { 3, 4 },
|
||||
padding = { 3, 6, 0, 6 },
|
||||
use_header_filler = false,
|
||||
horizontally_stretchable = true,
|
||||
}
|
||||
} --[[ @as any ]]
|
||||
|
||||
--- @class Gui.elements.header.opts
|
||||
--- @field name string?
|
||||
--- @field caption LocalisedString?
|
||||
--- @field tooltip LocalisedString?
|
||||
|
||||
--- A header frame within a container
|
||||
elements.header = ExpGui.element("container_header")
|
||||
--- @class Gui.elements.header: ExpElement
|
||||
--- @field label LuaGuiElement
|
||||
--- @overload fun(parent: LuaGuiElement, opts: Gui.elements.header.opts?): LuaGuiElement
|
||||
Elements.header = Gui.define("container_header")
|
||||
:draw(function(def, parent, opts)
|
||||
opts = opts or {}
|
||||
local subframe = elements.subframe_base(parent, "subheader_frame", opts.name)
|
||||
opts = opts or {} --- @cast opts Gui.elements.header.opts
|
||||
local subframe = Elements.subframe_base(parent, "subheader_frame", opts.name)
|
||||
|
||||
if opts.caption then
|
||||
subframe.add{
|
||||
type = "label",
|
||||
name = opts.label_name,
|
||||
name = "label",
|
||||
caption = opts.caption,
|
||||
tooltip = opts.tooltip,
|
||||
style = "frame_title",
|
||||
}
|
||||
end
|
||||
|
||||
return opts.no_flow and subframe or elements.aligned_flow(subframe, { name = "flow" })
|
||||
end)
|
||||
subframe.add{ type = "empty-widget" }.style.horizontally_stretchable = true
|
||||
|
||||
return subframe
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- @class Gui.elements.footer.opts
|
||||
--- @field name string?
|
||||
--- @field caption LocalisedString?
|
||||
--- @field tooltip LocalisedString?
|
||||
|
||||
--- A footer frame within a container
|
||||
elements.footer = ExpGui.element("container_footer")
|
||||
--- @class Gui.elements.footer: ExpElement
|
||||
--- @field label LuaGuiElement
|
||||
--- @overload fun(parent: LuaGuiElement, opts: Gui.elements.footer.opts?): LuaGuiElement
|
||||
Elements.footer = Gui.define("container_footer")
|
||||
:draw(function(def, parent, opts)
|
||||
opts = opts or {}
|
||||
local subframe = elements.subframe_base(parent, "subfooter_frame", opts.name)
|
||||
opts = opts or {} --- @cast opts Gui.elements.footer.opts
|
||||
local subframe = Elements.subframe_base(parent, "subfooter_frame", opts.name)
|
||||
|
||||
if opts.caption then
|
||||
subframe.add{
|
||||
type = "label",
|
||||
name = opts.label_name,
|
||||
name = "label",
|
||||
caption = opts.caption,
|
||||
tooltip = opts.tooltip,
|
||||
style = "frame_title",
|
||||
}
|
||||
end
|
||||
|
||||
return opts.no_flow and subframe or elements.aligned_flow(subframe, { name = "flow" })
|
||||
end)
|
||||
subframe.add{ type = "empty-widget" }.style.horizontally_stretchable = true
|
||||
|
||||
return elements
|
||||
return subframe
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- A button used to destroy its target when clicked, intended for screen frames
|
||||
--- @class Gui.elements.screen_frame_close: ExpElement
|
||||
--- @field data table<LuaGuiElement, LuaGuiElement>
|
||||
--- @overload fun(parent: LuaGuiElement, target: LuaGuiElement): LuaGuiElement
|
||||
Elements.screen_frame_close = Gui.define("screen_frame_close")
|
||||
:draw{
|
||||
type = "sprite-button",
|
||||
style = "frame_action_button",
|
||||
sprite = "utility/close",
|
||||
}
|
||||
:element_data(
|
||||
Gui.from_argument(1)
|
||||
)
|
||||
:on_click(function(def, player, element, event)
|
||||
--- @cast def Gui.elements.screen_frame_close
|
||||
Gui.destroy_if_valid(def.data[element])
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- A draggable frame with close button and button flow
|
||||
--- @class Gui.elements.screen_frame: ExpElement
|
||||
--- @field data table<LuaGuiElement, LuaGuiElement?>
|
||||
--- @overload fun(parent: LuaGuiElement, caption: LocalisedString?, button_flow: boolean?): LuaGuiElement
|
||||
Elements.screen_frame = Gui.define("screen_frame")
|
||||
:draw(function(def, parent, caption, button_flow)
|
||||
local container = parent.add{
|
||||
type = "frame",
|
||||
direction = "vertical",
|
||||
}
|
||||
container.style.padding = 2
|
||||
|
||||
local header = container.add{
|
||||
type = "flow",
|
||||
}
|
||||
|
||||
if caption then
|
||||
local label = header.add{
|
||||
type = "label",
|
||||
caption = caption,
|
||||
style = "frame_title"
|
||||
}
|
||||
label.style.top_margin = -3
|
||||
label.style.bottom_padding = 3
|
||||
end
|
||||
|
||||
local filler = header.add{
|
||||
type = "empty-widget",
|
||||
style = "draggable_space_header",
|
||||
}
|
||||
|
||||
filler.drag_target = container
|
||||
local filler_style = filler.style
|
||||
filler_style.horizontally_stretchable = true
|
||||
filler_style.vertically_stretchable = true
|
||||
filler_style.left_margin = caption and 4 or 0
|
||||
filler_style.natural_height = 24
|
||||
filler_style.height = 24
|
||||
|
||||
if button_flow then
|
||||
local _button_flow = header.add{ type = "flow" }
|
||||
def.data[container] = _button_flow
|
||||
_button_flow.style.padding = 0
|
||||
end
|
||||
|
||||
Elements.screen_frame_close(header, container)
|
||||
|
||||
return container.add{
|
||||
type = "frame",
|
||||
direction = "vertical",
|
||||
style = "inside_shallow_frame_packed",
|
||||
}
|
||||
end) --[[ @as any ]]
|
||||
|
||||
--- Get the button flow for a screen frame
|
||||
--- @param screen_frame LuaGuiElement
|
||||
--- @return LuaGuiElement
|
||||
function Elements.screen_frame.get_button_flow(screen_frame)
|
||||
return assert(Elements.screen_frame.data[screen_frame.parent], "Screen frame has no button flow")
|
||||
end
|
||||
|
||||
--- Get the root element of a screen frame
|
||||
--- @param screen_frame LuaGuiElement
|
||||
--- @return LuaGuiElement
|
||||
function Elements.screen_frame.get_root_element(screen_frame)
|
||||
return screen_frame.parent
|
||||
end
|
||||
|
||||
return Elements
|
||||
|
||||
Reference in New Issue
Block a user