From 51480e4ca5e2716450d1889fb43181e1fe275431 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sun, 1 Oct 2023 22:40:49 +0100 Subject: [PATCH 1/4] Update core files --- expcore/gui/core_defines.lua | 10 +++-- expcore/gui/left_flow.lua | 1 + expcore/gui/prototype.lua | 74 +++++++++++++++++++++++++----------- expcore/gui/top_flow.lua | 4 +- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua index 50e3ec09..272adab7 100644 --- a/expcore/gui/core_defines.lua +++ b/expcore/gui/core_defines.lua @@ -16,7 +16,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/preset', style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} + tooltip = {'gui_util.button_tooltip'}, + name = Gui.unique_static_name } :style{ padding = -2, @@ -35,7 +36,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/preset', style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} + tooltip = {'gui_util.button_tooltip'}, + name = Gui.unique_static_name } :style{ padding = -2, @@ -54,7 +56,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/close_black', style = 'tool_button', - tooltip = {'expcore-gui.left-button-tooltip'} + tooltip = {'expcore-gui.left-button-tooltip'}, + name = Gui.unique_static_name } :style{ padding = -3, @@ -83,5 +86,4 @@ Event.add(defines.events.on_player_created, function(event) show_top.visible = false hide_left.visible = false Gui.draw_left_flow(player) - end) \ No newline at end of file diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 42f02655..5f780304 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -38,6 +38,7 @@ example_flow_with_button:add_to_left_flow(true) ]] function Gui._prototype_element:add_to_left_flow(open_on_join) + if not self.name then error("Elements for the top flow must have a static name") end Gui.left_elements[self.name] = open_on_join or false return self end diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 8bd7a644..ed77f293 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -8,24 +8,31 @@ local Event = require '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 refrence + --- 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 debuging + --- 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 infomation about elements as they get defined such as the params used and event handlers registered to them + --- 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 = { __call = function(self, parent, ...) - local element = self._draw(self.name, parent, ...) + local element = self._draw(self, parent, ...) if self._style then self._style(element.style, element, ...) end - return element + return self:triggers_events(element) + end, + __index = function(self, key) + if self._draw_data then + return self._draw_data[key] + end end } } @@ -76,32 +83,35 @@ end) ]] function Gui.element(element_define) + _C.error_if_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 - local name = tostring(uid) - element.name = name - Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } + element.uid = uid + Gui.debug_info[uid] = { draw = 'None', style = 'None', events = {} } - -- Add the defination function + -- Add the definition function if type(element_define) == 'table' then - Gui.debug_info[name].draw = element_define - element_define.name = name + Gui.debug_info[uid].draw = element_define + if element_define.name == Gui.unique_static_name then + element_define.name = "ExpGui_"..tostring(uid) + end + element._draw_data = element_define element._draw = function(_, parent) return parent.add(element_define) end else - Gui.debug_info[name].draw = 'Function' + Gui.debug_info[uid].draw = 'Function' element._draw = element_define end -- Add the define to the base module local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - Gui.file_paths[name] = file_path - Gui.defines[name] = element + Gui.file_paths[uid] = file_path + Gui.defines[uid] = element -- Return the element so event handers can be accessed return element @@ -143,16 +153,16 @@ end) ]] function Gui._prototype_element:style(style_define) - -- Add the defination function + -- Add the definition function if type(style_define) == 'table' then - Gui.debug_info[self.name].style = style_define + 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.name].style = 'Function' + Gui.debug_info[self.uid].style = 'Function' self._style = style_define end @@ -160,6 +170,21 @@ function Gui._prototype_element:style(style_define) 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 +@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) + local event_triggers = element.tags.ExpGuiTriggers + if not event_triggers then + event_triggers = { self.uid } + else + table.insert(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.ExpGuiTriggers = event_triggers +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 @@ -172,7 +197,7 @@ end) ]] function Gui._prototype_element:on_custom_event(event_name, handler) - table.insert(Gui.debug_info[self.name].events, event_name) + table.insert(Gui.debug_info[self.uid].events, event_name) Gui.events[event_name] = event_name self[event_name] = handler return self @@ -222,13 +247,18 @@ 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 element_define = Gui.defines[element.name] - if not element_define then return end - element_define:raise_custom_event(event) + local event_triggers = element.tags.ExpGuiTriggers + if not event_triggers then return end + for _, uid in event_triggers do + local element_define = Gui.defines[uid] + if not element_define then + element_define:raise_custom_event(event) + end + end end) return function(self, handler) - table.insert(Gui.debug_info[self.name].events, debug.getinfo(1, "n").name) + table.insert(Gui.debug_info[self.uid].events, debug.getinfo(1, "n").name) self[event_name] = handler return self end diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index 064ee906..dd8f8070 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -48,6 +48,7 @@ end) ]] function Gui._prototype_element:add_to_top_flow(authenticator) + if not self.name then error("Elements for the top flow must have a static name") end Gui.top_elements[self.name] = authenticator or true return self end @@ -138,7 +139,8 @@ function Gui.toolbar_button(sprite, tooltip, authenticator) type = 'sprite-button', sprite = sprite, tooltip = tooltip, - style = Gui.top_flow_button_style + style = Gui.top_flow_button_style, + name = Gui.unique_static_name } :style{ minimal_width = 36, From edbfcd3afd3e19cb62ff614119327b12aa716476 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sun, 1 Oct 2023 23:44:38 +0100 Subject: [PATCH 2/4] Migrate gui modules --- expcore/gui/prototype.lua | 22 +++++++++-- modules/gui/autofill.lua | 34 ++++++++--------- modules/gui/module.lua | 6 +-- modules/gui/player-list.lua | 16 ++++---- modules/gui/readme.lua | 24 ++++++------ modules/gui/research.lua | 5 ++- modules/gui/rocket-info.lua | 45 +++++++++++----------- modules/gui/science-info.lua | 5 ++- modules/gui/server-ups.lua | 3 +- modules/gui/task-list.lua | 33 ++++++++-------- modules/gui/vlayer.lua | 5 ++- modules/gui/warp-list.lua | 74 ++++++++++++++++++++---------------- utils/gui.lua | 4 +- 13 files changed, 153 insertions(+), 123 deletions(-) diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index ed77f293..f79b6d7a 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -27,6 +27,9 @@ local Gui = { __call = function(self, parent, ...) local element = self._draw(self, parent, ...) if self._style then self._style(element.style, element, ...) end + if self.name and self.name ~= element.name then + error("Static name \""..self.name.."\" expected but got: "..tostring(element.name)) + end return self:triggers_events(element) end, __index = function(self, key) @@ -170,19 +173,32 @@ function Gui._prototype_element:style(style_define) 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) + 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 @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) - local event_triggers = element.tags.ExpGuiTriggers + local event_triggers = element.tags.ExpGui_event_triggers if not event_triggers then event_triggers = { self.uid } else table.insert(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.ExpGuiTriggers = event_triggers + element.tags.ExpGui_event_triggers = event_triggers end --[[-- Set the handler which will be called for a custom event, only one handler can be used per event per element @@ -247,7 +263,7 @@ 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.ExpGuiTriggers + local event_triggers = element.tags.ExpGui_event_triggers if not event_triggers then return end for _, uid in event_triggers do local element_define = Gui.defines[uid] diff --git a/modules/gui/autofill.lua b/modules/gui/autofill.lua index 8084dfbd..bb7cc089 100644 --- a/modules/gui/autofill.lua +++ b/modules/gui/autofill.lua @@ -32,7 +32,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/expand_dark', hovered_sprite = 'utility/expand', - tooltip = {'autofill.toggle-section-tooltip'} + tooltip = {'autofill.toggle-section-tooltip'}, + name = Gui.unique_static_name } :style(Gui.sprite_style(20)) :on_click(function(_, element, _) @@ -50,14 +51,6 @@ Gui.element{ end end) ---- Used to assign an event to the header label to trigger a toggle --- @element header_toggle -local header_toggle = Gui.element() -:on_click(function(_, element, event) - event.element = element.parent.alignment[toggle_section.name] - toggle_section:raise_custom_event(event) -end) - --- Toggle enitity button, used for toggling autofill for the specific entity -- All entity autofill settings will be ignored if its disabled -- @element entity_toggle @@ -95,16 +88,18 @@ end) --- Draw a section header and main scroll -- @element autofill_section_container local section = -Gui.element(function(_, parent, section_name, table_size) +Gui.element(function(definition, parent, section_name, table_size) -- Draw the header for the section local header = Gui.header( parent, {'autofill.toggle-section-caption', rich_img('item', section_name), {'entity-name.'..section_name}}, {'autofill.toggle-section-tooltip'}, true, - section_name..'-header', - header_toggle.name + section_name..'-header' ) + + definition:triggers_events(header.parent.header_label) + -- Right aligned button to toggle the section header.caption = section_name entity_toggle(header, section_name) @@ -120,13 +115,16 @@ Gui.element(function(_, parent, section_name, table_size) return section_table end) +:on_click(function(_, element, event) + event.element = element.parent.alignment[toggle_section.name] + toggle_section:raise_custom_event(event) +end) --- Toggle item button, used for toggling autofill for the specific item -- @element toggle_item_button local toggle_item_button = -Gui.element(function(event_trigger, parent, item) +Gui.element(function(_, parent, item) return parent.add{ - name = event_trigger, type = 'sprite-button', sprite = 'item/'..item.name, tooltip = {'autofill.toggle-tooltip', rich_img('item', item.name), item.category}, @@ -161,9 +159,8 @@ end) --- Amount text field for a autofill item -- @element amount_textfield local amount_textfield = -Gui.element(function(event_trigger, parent, item) +Gui.element(function(_, parent, item) return parent.add{ - name = event_trigger, type = 'textfield', text = item.amount, tooltip = {'autofill.amount-tooltip', item.category }, @@ -233,9 +230,9 @@ end) --- Main gui container for the left flow -- @element autofill_container autofill_container = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) -- Draw the internal container - local container = Gui.container(parent, event_trigger) + local container = Gui.container(parent, definition.name) -- Draw the scroll container local scroll_table = Gui.scroll_table(container, 400, 1, 'autofill-scroll-table') -- Set the scroll panel to always show the scrollbar (not doing this will result in a changing gui size) @@ -293,6 +290,7 @@ Gui.element(function(event_trigger, parent) -- Return the external container return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() --- Button on the top flow used to toggle autofill container diff --git a/modules/gui/module.lua b/modules/gui/module.lua index 7cd5d94a..5d32d1d3 100644 --- a/modules/gui/module.lua +++ b/modules/gui/module.lua @@ -171,7 +171,6 @@ end local button_apply = Gui.element{ - name = 'module_b', type = 'button', caption = 'Apply', style = 'button' @@ -184,8 +183,8 @@ Gui.element{ end) module_container = -Gui.element(function(event_trigger, parent) - local container = Gui.container(parent, event_trigger, (config.module_slot_max + 2) * 36) +Gui.element(function(definition, parent) + local container = Gui.container(parent, definition.name, (config.module_slot_max + 2) * 36) Gui.header(container, 'Module Inserter', '', true) local scroll_table = Gui.scroll_table(container, (config.module_slot_max + 2) * 36, config.module_slot_max + 1) @@ -214,6 +213,7 @@ Gui.element(function(event_trigger, parent) return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() Gui.left_toolbar_button('item/productivity-module-3', {'module.main-tooltip'}, module_container, function(player) diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 27dc5226..e04d2375 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -29,7 +29,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/expand_dots_white', tooltip = {'player-list.open-action-bar'}, - style = 'frame_button' + style = 'frame_button', + name = Gui.unique_static_name } :style{ padding = -2, @@ -85,21 +86,21 @@ end) --- Set of elements that are used to make up a row of the player table -- @element add_player_base local add_player_base = -Gui.element(function(event_trigger, parent, player_data) +Gui.element(function(definition, parent, player_data) -- Add the button to open the action bar local toggle_action_bar_flow = parent.add{ type = 'flow', name = player_data.name } open_action_bar(toggle_action_bar_flow) -- Add the player name - local player_name_flow = parent.add{ type = 'flow', name = 'player-name-'..player_data.index } - local player_name = player_name_flow.add{ + local player_name = parent.add{ type = 'label', - name = event_trigger, + name = 'player-name-'..player_data.index, caption = player_data.name, tooltip = {'player-list.open-map', player_data.name, player_data.tag, player_data.role_name} } player_name.style.padding = {0, 2,0, 0} player_name.style.font_color = player_data.chat_color + definition:triggers_events(player_name) -- Add the time played label local alignment = Gui.alignment(parent, 'player-time-'..player_data.index) @@ -202,9 +203,9 @@ end --- Main player list container for the left flow -- @element player_list_container local player_list_container = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) -- Draw the internal container - local container = Gui.container(parent, event_trigger, 200) + local container = Gui.container(parent, definition.name, 200) -- Draw the scroll table for the players local scroll_table = Gui.scroll_table(container, 184, 3) @@ -255,6 +256,7 @@ Gui.element(function(event_trigger, parent) -- Return the exteral container return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow(true) --- Button on the top flow used to toggle the player list container diff --git a/modules/gui/readme.lua b/modules/gui/readme.lua index ca38e40e..af264d47 100644 --- a/modules/gui/readme.lua +++ b/modules/gui/readme.lua @@ -25,13 +25,11 @@ local scroll_height = 275 -- controls the height of the scrolls --- Sub content area used within the content areas -- @element sub_content local sub_content = -Gui.element(function(_, parent) - return parent.add{ - type = 'frame', - direction = 'vertical', - style = 'inside_deep_frame' - } -end) +Gui.element{ + type = 'frame', + direction = 'vertical', + style = 'inside_deep_frame' +} :style{ horizontally_stretchable = true, horizontal_align = 'center', @@ -77,17 +75,16 @@ Gui.element{ --- Used to connect to servers in server list -- @element join_server local join_server = -Gui.element(function(event_trigger, parent, server_id, wrong_version) +Gui.element(function(definition, parent, server_id, wrong_version) local status = External.get_server_status(server_id) or 'Offline' if wrong_version then status = 'Version' end local flow = parent.add{ name = server_id, type = 'flow' } - local button = flow.add{ - name = event_trigger, + local button = definition:triggers_events(flow.add{ type = 'sprite-button', sprite = 'utility/circuit_network_panel_white', --- network panel white, warning white, download white hovered_sprite = 'utility/circuit_network_panel_black', --- network panel black, warning black, download black tooltip = {'readme.servers-connect-'..status, wrong_version} - } + }) if status == 'Offline' or status == 'Current' then button.enabled = false @@ -404,9 +401,9 @@ end)) -- @element readme local readme_toggle local readme = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) local container = parent.add{ - name = event_trigger, + name = definition.name, type = 'frame', style = 'invisible_frame' } @@ -439,6 +436,7 @@ Gui.element(function(event_trigger, parent) return container end) +:static_name(Gui.unique_static_name) :on_open(function(player) local toggle_button = Gui.get_top_element(player, readme_toggle) Gui.toolbar_button_style(toggle_button, true) diff --git a/modules/gui/research.lua b/modules/gui/research.lua index daf514e6..663c6c93 100644 --- a/modules/gui/research.lua +++ b/modules/gui/research.lua @@ -55,8 +55,8 @@ for i=1, #config.milestone do end local clock_container = -Gui.element(function(event_trigger, parent) - local container = Gui.container(parent, event_trigger, 200) +Gui.element(function(definition, parent) + local container = Gui.container(parent, definition.name, 200) local scroll_table = Gui.scroll_table(container, 400, 4) scroll_table.add{ @@ -143,6 +143,7 @@ Gui.element(function(event_trigger, parent) return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() Gui.left_toolbar_button('item/space-science-pack', {'expcom-res.main-tooltip'}, clock_container, function(player) diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index a8cb673c..e0a38ceb 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -43,7 +43,8 @@ local toggle_launch = Gui.element{ type = 'sprite-button', sprite = 'utility/play', - tooltip = {'rocket-info.toggle-rocket-tooltip'} + tooltip = {'rocket-info.toggle-rocket-tooltip'}, + name = Gui.unique_static_name } :style(Gui.sprite_style(16)) :on_click(function(_, element, _) @@ -66,7 +67,8 @@ local launch_rocket = Gui.element{ type = 'sprite-button', sprite = 'utility/center', - tooltip = {'rocket-info.launch-tooltip'} + tooltip = {'rocket-info.launch-tooltip'}, + name = Gui.unique_static_name } :style(Gui.sprite_style(16, -1)) :on_click(function(player, element, _) @@ -82,10 +84,9 @@ end) --- XY cords that allow zoom to map when pressed -- @element silo_cords local silo_cords = -Gui.element(function(event_trigger, parent, silo_data) +Gui.element(function(definition, parent, silo_data) local silo_name = silo_data.silo_name local pos = silo_data.position - local name = config.progress.allow_zoom_to_map and event_trigger or nil local tooltip = config.progress.allow_zoom_to_map and {'rocket-info.progress-label-tooltip'} or nil -- Add the x cord flow @@ -97,9 +98,8 @@ Gui.element(function(event_trigger, parent, silo_data) flow_x.style.padding = {0, 2,0, 1} -- Add the x cord label - flow_x.add{ + local label_x = flow_x.add{ type = 'label', - name = name, caption = {'rocket-info.progress-x-pos', pos.x}, tooltip = tooltip } @@ -113,13 +113,16 @@ Gui.element(function(event_trigger, parent, silo_data) flow_y.style.padding = {0, 2,0, 1} -- Add the y cord label - flow_y.add{ + local label_y = flow_y.add{ type = 'label', - name = name, caption = {'rocket-info.progress-y-pos', pos.y}, tooltip = tooltip } + if config.progress.allow_zoom_to_map then + definition:triggers_events(label_x) + definition:triggers_events(label_y) + end end) :on_click(function(player, element, _) local rocket_silo_name = element.parent.caption @@ -422,7 +425,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/expand_dark', hovered_sprite = 'utility/expand', - tooltip = {'rocket-info.toggle-section-tooltip'} + tooltip = {'rocket-info.toggle-section-tooltip'}, + name = Gui.unique_static_name } :style(Gui.sprite_style(20)) :on_click(function(_, element, _) @@ -440,27 +444,19 @@ Gui.element{ end end) --- Used to assign an event to the header label to trigger a toggle --- @element header_toggle -local header_toggle = Gui.element() -:on_click(function(_, element, event) - event.element = element.parent.alignment[toggle_section.name] - toggle_section:raise_custom_event(event) -end) - -- Draw a section header and main scroll -- @element rocket_list_container local section = -Gui.element(function(_, parent, section_name, table_size) +Gui.element(function(definition, parent, section_name, table_size) -- Draw the header for the section local header = Gui.header( parent, {'rocket-info.section-caption-'..section_name}, {'rocket-info.section-tooltip-'..section_name}, true, - section_name..'-header', - header_toggle.name + section_name..'-header' ) + definition:triggers_events(header.parent.header_label) -- Right aligned button to toggle the section header.caption = section_name @@ -473,13 +469,17 @@ Gui.element(function(_, parent, section_name, table_size) -- Return the flow table return scroll_table end) +:on_click(function(_, element, event) + event.element = element.parent.alignment[toggle_section.name] + toggle_section:raise_custom_event(event) +end) --- Main gui container for the left flow -- @element rocket_list_container local rocket_list_container = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) -- Draw the internal container - local container = Gui.container(parent, event_trigger, 200) + local container = Gui.container(parent, definition.name, 200) -- Set the container style local style = container.style @@ -516,6 +516,7 @@ Gui.element(function(event_trigger, parent) -- Return the exteral container return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow(function(player) return player.force.rockets_launched > 0 and Roles.player_allowed(player, 'gui/rocket-info') end) diff --git a/modules/gui/science-info.lua b/modules/gui/science-info.lua index 345ab04a..97395ca7 100644 --- a/modules/gui/science-info.lua +++ b/modules/gui/science-info.lua @@ -261,11 +261,11 @@ end --- Main task list container for the left flow -- @element task_list_container local science_info_container = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) local player = Gui.get_player_from_element(parent) -- Draw the internal container - local container = Gui.container(parent, event_trigger, 200) + local container = Gui.container(parent, definition.name, 200) -- Draw the header Gui.header(container, {'science-info.main-caption'}, {'science-info.main-tooltip'}) @@ -315,6 +315,7 @@ Gui.element(function(event_trigger, parent) -- Return the exteral container return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() --- Button on the top flow used to toggle the task list container diff --git a/modules/gui/server-ups.lua b/modules/gui/server-ups.lua index 19fa57aa..af643bdc 100644 --- a/modules/gui/server-ups.lua +++ b/modules/gui/server-ups.lua @@ -23,7 +23,8 @@ UsesServerUps:set_metadata{ local server_ups = Gui.element{ type = 'label', - caption = 'SUPS = 60.0' + caption = 'SUPS = 60.0', + name = Gui.unique_static_name } :style{ font = 'default-game' diff --git a/modules/gui/task-list.lua b/modules/gui/task-list.lua index 03ccd65d..e985ce75 100644 --- a/modules/gui/task-list.lua +++ b/modules/gui/task-list.lua @@ -85,7 +85,8 @@ local add_new_task = type = "sprite-button", sprite = "utility/add", tooltip = {"task-list.add-tooltip"}, - style = "tool_button" + style = "tool_button", + name = Gui.unique_static_name }:style(Styles.sprite22):on_click( function(player, _, _) -- Disable editing @@ -164,20 +165,16 @@ local subfooter_label = --- Action flow that contains action buttons -- @element subfooter_actions local subfooter_actions = - Gui.element( - function(_, parent) - return parent.add { - type = "flow", - name = "actions" - } - end -) + Gui.element { + type = "flow", + name = "actions" +} --- Button element with a flow around it to fix duplicate name inside of the scroll flow -- @element task_list_item local task_list_item = Gui.element( - function(event_trigger, parent, task) + function(definition, parent, task) local flow = parent.add { type = "flow", @@ -187,11 +184,12 @@ local task_list_item = flow.style.horizontally_stretchable = true local button = flow.add { - name = event_trigger, + name = definition.name, type = "button", style = "list_box_item", caption = task.title } + definition:triggers_events(button) button.style.horizontally_stretchable = true button.style.horizontally_squashable = true return flow @@ -201,7 +199,7 @@ local task_list_item = local task_id = element.parent.caption PlayerSelected:set(player, task_id) end -) +):static_name(Gui.unique_static_name) --- Scrollable list of all tasks -- @element task_list @@ -239,6 +237,7 @@ local task_list = local task_view_edit_button = Gui.element { type = "button", + name = Gui.unique_static_name, caption = {"", "[img=utility/rename_icon_normal] ", {"task-list.edit"}}, tooltip = {"task-list.edit-tooltip"}, style = "shortcut_bar_button" @@ -271,6 +270,7 @@ Gui.element{ local task_view_delete_button = Gui.element { type = "button", + name = Gui.unique_static_name, caption = {"", "[img=utility/trash] ", {"task-list.delete"}}, tooltip = {"task-list.delete-tooltip"}, style = "shortcut_bar_button_red" @@ -342,6 +342,7 @@ local task_create_confirm_button -- @element task_message_textfield local task_message_textfield = Gui.element { + name = Gui.unique_static_name, type = "text-box", text = "" }:style( @@ -370,6 +371,7 @@ local task_message_textfield = task_edit_confirm_button = Gui.element { type = "button", + name = Gui.unique_static_name, caption = {"", "[img=utility/check_mark] ", {"task-list.confirm"}}, tooltip = {"task-list.confirm-tooltip"}, style = "shortcut_bar_button_green" @@ -424,6 +426,7 @@ local task_edit_footer = task_create_confirm_button = Gui.element { type = "button", + name = Gui.unique_static_name, caption = {"", "[img=utility/check_mark] ", {"task-list.confirm"}}, tooltip = {"task-list.confirm-tooltip"}, style = "shortcut_bar_button_green", @@ -496,9 +499,9 @@ end -- @element task_list_container local task_list_container = Gui.element( - function(event_trigger, parent) + function(definition, parent) -- Draw the internal container - local container = Gui.container(parent, event_trigger, 268) + local container = Gui.container(parent, definition.name, 268) container.style.maximal_width = 268 container.style.minimal_width = 268 @@ -526,7 +529,7 @@ local task_list_container = -- Return the external container return container.parent end -):add_to_left_flow( +):static_name(Gui.unique_static_name):add_to_left_flow( function(player) local task_ids = Tasks.get_force_task_ids(player.force.name) return #task_ids > 0 diff --git a/modules/gui/vlayer.lua b/modules/gui/vlayer.lua index 1b3d3999..1e830aa8 100644 --- a/modules/gui/vlayer.lua +++ b/modules/gui/vlayer.lua @@ -345,9 +345,9 @@ end) --- The main container for the vlayer gui -- @element vlayer_container local vlayer_container = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) local player = Gui.get_player_from_element(parent) - local container = Gui.container(parent, event_trigger, 320) + local container = Gui.container(parent, definition.name, 320) vlayer_display_set(container, 'vlayer_st_1') vlayer_control_set(container, 'vlayer_st_2') @@ -362,6 +362,7 @@ Gui.element(function(event_trigger, parent) table[vlayer_gui_control_remove.name].visible = visible return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() --- Button on the top flow used to toggle the task list container diff --git a/modules/gui/warp-list.lua b/modules/gui/warp-list.lua index 4928d66e..2c3383db 100644 --- a/modules/gui/warp-list.lua +++ b/modules/gui/warp-list.lua @@ -81,7 +81,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/add', tooltip = {'warp-list.add-tooltip'}, - style = 'shortcut_bar_button' + style = 'shortcut_bar_button', + name = Gui.unique_static_name } :style(Styles.sprite22) :on_click(function(player, _) @@ -148,7 +149,7 @@ end) --- Warp icon button, this will trigger a warp when the player is able to -- @element warp_icon_button local warp_icon_button = -Gui.element(function(event_trigger, parent, warp) +Gui.element(function(definition, parent, warp) local warp_position = warp.position -- The SpritePath type is not the same as the SignalID type @@ -158,15 +159,16 @@ Gui.element(function(event_trigger, parent, warp) end -- Draw the element - return parent.add{ - name = event_trigger, + return definition:triggers_events(parent.add{ type = 'sprite-button', sprite = sprite, + name = definition.name, tooltip = {'warp-list.goto-tooltip', warp_position.x, warp_position.y}, style = 'slot_button' - } + }) end) :style(Styles.sprite32) +:static_name(Gui.unique_static_name) :on_click(function(player, element, _) if element.type == 'choose-elem-button' then return end local warp_id = element.parent.caption @@ -183,30 +185,31 @@ end) --- The button that is visible when the warp is in edit state -- @element warp_icon_editing local warp_icon_editing = -Gui.element(function(event_trigger, parent, warp) - return parent.add{ - name = event_trigger, +Gui.element(function(definition, parent, warp) + return definition:triggers_events(parent.add{ + name = definition.name, type = 'choose-elem-button', elem_type = 'signal', signal = {type = warp.icon.type, name = warp.icon.name}, tooltip = {'warp-list.goto-edit'} - } + }) end) +:static_name(Gui.unique_static_name) :style(Styles.sprite32) --- Warp label, visible if the player is not in edit state -- @element warp_label local warp_label = -Gui.element(function(event_trigger, parent, warp) +Gui.element(function(definition, parent, warp) local last_edit_name = warp.last_edit_name local last_edit_time = warp.last_edit_time -- Draw the element - return parent.add{ - name = event_trigger, + return definition:triggers_events(parent.add{ type = 'label', caption = warp.name, - tooltip = {'warp-list.last-edit', last_edit_name, format_time(last_edit_time)} - } + tooltip = {'warp-list.last-edit', last_edit_name, format_time(last_edit_time)}, + name = definition.name + }) end) :style{ single_line = true, @@ -220,19 +223,17 @@ end) local position = warp.position player.zoom_to_world(position, 1.5) end) +:static_name(Gui.unique_static_name) --- Warp status, visible if the player is not in edit state --- This will show if the warp is connected or not -- @element warp_status local warp_status = -Gui.element(function(event_trigger, parent) - -- Draw the element - return parent.add{ - name = event_trigger, - type = 'label', - caption = '[img=utility/electricity_icon_unplugged]', -- Temporary icon - } -end) +Gui.element{ + type = 'label', + caption = '[img=utility/electricity_icon_unplugged]', -- Temporary icon + name = Gui.unique_static_name +} :style{ -- When editing mode because textbox is larger the icon would move up. top_padding = 1, @@ -242,14 +243,14 @@ end) --- Warp textfield, visible if the player is in edit state -- @element warp_textfield local warp_textfield = -Gui.element(function(event_trigger, parent, warp) +Gui.element(function(definition, parent, warp) -- Draw the element - return parent.add{ - name = event_trigger, + return definition:triggers_events(parent.add{ type = 'textfield', text = warp.name, - clear_and_focus_on_right_click = true - } + clear_and_focus_on_right_click = true, + name = definition.name + }) end) :style{ -- Required fields to make it squashable and strechable. @@ -270,6 +271,7 @@ end) Warps.set_editing(warp_id, player.name) Warps.update_warp(warp_id, warp_name, warp_icon, player.name) end) +:static_name(Gui.unique_static_name) --- Confirms the edit to name or icon of the warp @@ -279,7 +281,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/confirm_slot', tooltip = {'warp-list.confirm-tooltip'}, - style = 'shortcut_bar_button_green' + style = 'shortcut_bar_button_green', + name = Gui.unique_static_name } :style(Styles.sprite22) :on_click(function(player, element) @@ -297,7 +300,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/close_black', tooltip = {'warp-list.cancel-tooltip'}, - style = 'shortcut_bar_button_red' + style = 'shortcut_bar_button_red', + name = Gui.unique_static_name } :style(Styles.sprite22) :on_click(function(player, element) @@ -318,7 +322,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/trash', tooltip = {'warp-list.remove-tooltip'}, - style = 'shortcut_bar_button_red' + style = 'shortcut_bar_button_red', + name = Gui.unique_static_name } :style(Styles.sprite22) :on_click(function(_, element) @@ -333,7 +338,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/rename_icon_normal', tooltip = {'warp-list.edit-tooltip-none'}, - style = 'shortcut_bar_button' + style = 'shortcut_bar_button', + name = Gui.unique_static_name } :style(Styles.sprite22) :on_click(function(player, element) @@ -402,6 +408,7 @@ end local warp_timer = Gui.element{ type = 'progressbar', + name = Gui.unique_static_name, tooltip = {'warp-list.timer-tooltip-zero', config.cooldown_duration}, minimum_value = 0, maximum_value = config.cooldown_duration*config.update_smoothing @@ -626,13 +633,13 @@ end --- Main warp list container for the left flow -- @element warp_list_container warp_list_container = -Gui.element(function(event_trigger, parent) +Gui.element(function(definition, parent) local player = Gui.get_player_from_element(parent) -- Check if user has permission to add warps local allow_add_warp = check_player_permissions(player, 'allow_add_warp') -- Draw the internal container - local container = Gui.container(parent, event_trigger, allow_add_warp and 268 or 220) + local container = Gui.container(parent, definition.name, allow_add_warp and 268 or 220) -- Draw the header local header = Gui.header( @@ -685,6 +692,7 @@ Gui.element(function(event_trigger, parent) -- Return the external container return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() --- Button on the top flow used to toggle the warp list container diff --git a/utils/gui.lua b/utils/gui.lua index 12bb4806..95985d86 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -13,7 +13,7 @@ Global.register( function Gui.uid_name() local new_element = ExpGui.element() - return new_element.name + return tostring(new_element.uid) end -- Associates data with the LuaGuiElement. If data is nil then removes the data @@ -70,7 +70,7 @@ end local function handler_factory(event_name) return function(element_name, handler) - local element = ExpGui.defines[element_name] + local element = ExpGui.defines[tonumber(element_name)] if not element then return end element[event_name](element, function(_, _,event) handler(event) From f7eb9c0c37429e452cdc26e35d70bbcd311f5c89 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:56:58 +0100 Subject: [PATCH 3/4] Final Fixes --- expcore/gui/_require.lua | 14 ++++++------- expcore/gui/left_flow.lua | 22 ++++++++++----------- expcore/gui/prototype.lua | 38 +++++++++++++++++++----------------- expcore/gui/top_flow.lua | 8 ++++---- modules/control/spectate.lua | 19 ++++++++++-------- modules/gui/autofill.lua | 7 +++---- utils/gui.lua | 33 +++++++++++++++++-------------- 7 files changed, 73 insertions(+), 68 deletions(-) diff --git a/expcore/gui/_require.lua b/expcore/gui/_require.lua index 78aac647..318ab37b 100644 --- a/expcore/gui/_require.lua +++ b/expcore/gui/_require.lua @@ -18,7 +18,7 @@ Gui.element{ @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(event_trigger, parent, ...) +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 = @@ -28,12 +28,12 @@ Gui.element(function(event_trigger, parent, ...) } -- Now we add the button to the flow that we created earlier - local element = - flow.add{ - name = event_trigger, -- event_trigger should be the name of any elements you want to trigger your event handlers - type = 'button', - caption = 'Example Button' - } + 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 diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 5f780304..813b254f 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -39,7 +39,7 @@ example_flow_with_button:add_to_left_flow(true) ]] function Gui._prototype_element:add_to_left_flow(open_on_join) if not self.name then error("Elements for the top flow must have a static name") end - Gui.left_elements[self.name] = open_on_join or false + Gui.left_elements[self] = open_on_join or false return self end @@ -92,14 +92,14 @@ function Gui.draw_left_flow(player) local hide_button = left_flow.gui_core_buttons[hide_left_flow] local show_hide_button = false - for name, open_on_join in pairs(Gui.left_elements) do + for element_define, open_on_join in pairs(Gui.left_elements) do -- Draw the element to the left flow - local draw_success, left_element = pcall(function() - return Gui.defines[name](left_flow) - end) + local draw_success, left_element = xpcall(function() + return element_define(left_flow) + end, debug.traceback) if not draw_success then - error('There as been an error with an element draw function:\n\t'..left_element) + error('There as been an error with an element draw function: '..element_define.defined_at..'\n\t'..left_element) end -- Check if it should be open by default @@ -117,7 +117,6 @@ function Gui.draw_left_flow(player) show_hide_button = show_hide_button or visible -- Get the assosiated element define - local element_define = Gui.defines[name] local top_flow = Gui.get_top_flow(player) -- Check if the the element has a button attached @@ -145,8 +144,8 @@ 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 name, _ in pairs(Gui.left_elements) do - local left_element = left_flow[name] + for element_define, _ in pairs(Gui.left_elements) do + local left_element = left_flow[element_define.name] if left_element.visible then hide_button.visible = true return true @@ -170,11 +169,10 @@ function Gui.hide_left_flow(player) -- Set the visible state of all elements in the flow hide_button.visible = false - for name, _ in pairs(Gui.left_elements) do - left_flow[name].visible = false + for element_define, _ in pairs(Gui.left_elements) do + left_flow[element_define.name].visible = false -- Check if the the element has a toobar button attached - local element_define = Gui.defines[name] if element_define.toolbar_button then -- Check if the topflow contains the button local button = top_flow[element_define.toolbar_button] diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index f79b6d7a..d63591f4 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -30,12 +30,7 @@ local Gui = { if self.name and self.name ~= element.name then error("Static name \""..self.name.."\" expected but got: "..tostring(element.name)) end - return self:triggers_events(element) - end, - __index = function(self, key) - if self._draw_data then - return self._draw_data[key] - end + return element and self:triggers_events(element) end } } @@ -102,7 +97,7 @@ function Gui.element(element_define) if element_define.name == Gui.unique_static_name then element_define.name = "ExpGui_"..tostring(uid) end - element._draw_data = element_define + element.name = element_define.name element._draw = function(_, parent) return parent.add(element_define) end @@ -112,8 +107,11 @@ function Gui.element(element_define) end -- Add the define to the base module - local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - Gui.file_paths[uid] = file_path + local debug_info = debug.getinfo(2, "Sn") + local file_name = debug_info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) + local func_name = debug_info.name or "" + element.defined_at = file_name..":"..func_name + Gui.file_paths[uid] = element.defined_at Gui.defines[uid] = element -- Return the element so event handers can be accessed @@ -179,7 +177,7 @@ end ]] function Gui._prototype_element:static_name(name) if name == Gui.unique_static_name then - self.name = "ExpGui_"..tostring(self.uid) + self.name = "ExpGui_"..tostring(self.uid) else self.name = name end @@ -191,14 +189,18 @@ end @treturn LuaGuiElement The element passed as the argument to allow for cleaner returns ]] function Gui._prototype_element:triggers_events(element) - local event_triggers = element.tags.ExpGui_event_triggers - if not event_triggers then - event_triggers = { self.uid } + local tags = element.tags + if not tags then + element.tags = { ExpGui_event_triggers = { self.uid } } + return element + elseif not tags.ExpGui_event_triggers then + tags.ExpGui_event_triggers = { self.uid } else - table.insert(event_triggers, self.uid) + 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.ExpGui_event_triggers = event_triggers + element.tags = tags + return element end --[[-- Set the handler which will be called for a custom event, only one handler can be used per event per element @@ -251,7 +253,7 @@ function Gui._prototype_element:raise_custom_event(event) end event.player = player - local success, err = pcall(handler, player, element, event) + 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 @@ -265,9 +267,9 @@ local function event_handler_factory(event_name) 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 event_triggers do + for _, uid in pairs(event_triggers) do local element_define = Gui.defines[uid] - if not element_define then + if element_define then element_define:raise_custom_event(event) end end diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index dd8f8070..8e38fa8f 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -49,7 +49,7 @@ end) ]] function Gui._prototype_element:add_to_top_flow(authenticator) if not self.name then error("Elements for the top flow must have a static name") end - Gui.top_elements[self.name] = authenticator or true + Gui.top_elements[self] = authenticator or true return self end @@ -66,11 +66,11 @@ function Gui.update_top_flow(player) local is_visible = hide_button.visible -- Set the visible state of all elements in the flow - for name, authenticator in pairs(Gui.top_elements) do + for element_define, authenticator in pairs(Gui.top_elements) do -- Ensure the element exists - local element = top_flow[name] + local element = top_flow[element_define.name] if not element then - element = Gui.defines[name](top_flow) + element = element_define(top_flow) end -- Set the visible state diff --git a/modules/control/spectate.lua b/modules/control/spectate.lua index 715bf1ed..8a235e2e 100644 --- a/modules/control/spectate.lua +++ b/modules/control/spectate.lua @@ -103,15 +103,17 @@ end --- Label used to show that the player is following, also used to allow esc to stop following -- @element follow_label follow_label = -Gui.element(function(event_trigger, parent, target) - Gui.destroy_if_valid(parent[event_trigger]) +Gui.element(function(definition, parent, target) + Gui.destroy_if_valid(parent[definition.name]) - local label = parent.add{ - name = event_trigger, - type = 'label', - style = 'heading_1_label', - caption = 'Following '..target.name..'.\nClick here or press esc to stop following.' - } + local label = definition:triggers_events( + parent.add{ + type = 'label', + style = 'heading_1_label', + caption = 'Following '..target.name..'.\nClick here or press esc to stop following.', + name = definition.name + } + ) local player = Gui.get_player_from_element(parent) local res = player.display_resolution @@ -122,6 +124,7 @@ Gui.element(function(event_trigger, parent, target) return label end) +:static_name(Gui.unique_static_name) :on_click(Public.stop_follow) :on_close(function(player) -- Don't call set_controller during on_close as it invalidates the controller diff --git a/modules/gui/autofill.lua b/modules/gui/autofill.lua index bb7cc089..495e988d 100644 --- a/modules/gui/autofill.lua +++ b/modules/gui/autofill.lua @@ -54,14 +54,13 @@ end) --- Toggle enitity button, used for toggling autofill for the specific entity -- All entity autofill settings will be ignored if its disabled -- @element entity_toggle -local entity_toggle = Gui.element(function(event_trigger, parent, entity_name) - return parent.add{ - name = event_trigger, +local entity_toggle = Gui.element(function(definition, parent, entity_name) + return definition:triggers_events(parent.add{ type = 'sprite-button', sprite = 'utility/confirm_slot', tooltip = {'autofill.toggle-entity-tooltip', rich_img('item', entity_name)}, style = 'shortcut_bar_button_green' - } + }) end) :style(Gui.sprite_style(22)) :on_click(function(player, element, _) diff --git a/utils/gui.lua b/utils/gui.lua index 95985d86..c29e0039 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -1,8 +1,10 @@ local Global = require 'utils.global' --- @dep utils.global -local ExpGui = require 'expcore.gui' --- @dep expcore.gui +local Event = require 'utils.event' --- @dep expcore.gui +local mod_gui = require 'mod-gui' --- @dep mod-gui local Gui = {} local data = {} +local uid = 0 Global.register( data, @@ -12,8 +14,8 @@ Global.register( ) function Gui.uid_name() - local new_element = ExpGui.element() - return tostring(new_element.uid) + uid = uid + 1 + return "Redmew_"..uid end -- Associates data with the LuaGuiElement. If data is nil then removes the data @@ -70,10 +72,11 @@ end local function handler_factory(event_name) return function(element_name, handler) - local element = ExpGui.defines[tonumber(element_name)] - if not element then return end - element[event_name](element, function(_, _,event) - handler(event) + Event.add(defines.events[event_name], function(event) + if event.element and event.element.valid and event.element.name == element_name then + event.player = game.get_player(event.player_index) + handler(event) + end end) end end @@ -82,48 +85,48 @@ end -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_checked_state_changed = handler_factory('on_checked_changed') +Gui.on_checked_state_changed = handler_factory('on_gui_checked_state_changed') -- Register a handler for the on_gui_click event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_click = handler_factory('on_click') +Gui.on_click = handler_factory('on_gui_click') -- Register a handler for the on_gui_closed event for a custom LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_custom_close = handler_factory('on_closed') +Gui.on_custom_close = handler_factory('on_gui_closed') -- Register a handler for the on_gui_elem_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_elem_changed = handler_factory('on_elem_changed') +Gui.on_elem_changed = handler_factory('on_gui_elem_changed') -- Register a handler for the on_gui_selection_state_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_selection_state_changed = handler_factory('on_selection_changed') +Gui.on_selection_state_changed = handler_factory('on_gui_selection_state_changed') -- Register a handler for the on_gui_text_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_text_changed = handler_factory('on_text_changed') +Gui.on_text_changed = handler_factory('on_gui_text_changed') -- Register a handler for the on_gui_value_changed event for LuaGuiElements with element_name. -- Can only have one handler per element name. -- Guarantees that the element and the player are valid when calling the handler. -- Adds a player field to the event table. -Gui.on_value_changed = handler_factory('on_value_changed') +Gui.on_value_changed = handler_factory('on_gui_value_changed') --- Returns the flow where top elements can be added and will be effected by google visibility -- For the toggle to work it must be registed with Gui.allow_player_to_toggle_top_element_visibility(element_name) -- @tparam LuaPlayer player pointer to the player who has the gui -- @treturn LuaGuiElement the top element flow -Gui.get_top_element_flow = ExpGui.get_top_flow +Gui.get_top_element_flow = mod_gui.get_button_flow return Gui \ No newline at end of file From 3f0df9b9b0359cf860cda869c680cdfea7ab963a Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sat, 30 Dec 2023 17:34:13 +0000 Subject: [PATCH 4/4] Migrate new Guis --- modules/gui/playerdata.lua | 37 ++++++++++++++++++------------------ modules/gui/surveillance.lua | 28 ++++++++++++++------------- modules/gui/vlayer.lua | 5 +++++ 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/modules/gui/playerdata.lua b/modules/gui/playerdata.lua index 75ddba46..c7985a90 100644 --- a/modules/gui/playerdata.lua +++ b/modules/gui/playerdata.lua @@ -16,13 +16,11 @@ local label_width = { ['total'] = 480 } -local function format_clock(value) +local function format_time_short(value) return format_time(value*3600, { hours=true, minutes=true, - seconds=false, - time=false, - string=true + seconds=false }) end @@ -33,49 +31,49 @@ end local playerStats = PlayerData.Statistics local computed_stats = { DamageDeathRatio = { - default = '0.00', + default = format_number_n(0), calculate = function(player_name) return format_number_n(playerStats['DamageDealt']:get(player_name, 0) / playerStats['Deaths']:get(player_name, 1)) end }, KillDeathRatio = { - default = '0.00', + default = format_number_n(0), calculate = function(player_name) return format_number_n(playerStats['Kills']:get(player_name, 0) / playerStats['Deaths']:get(player_name, 1)) end }, SessionTime = { - default = format_clock(0), + default = format_time_short(0), calculate = function(player_name) - return format_clock((playerStats['Playtime']:get(player_name, 0) - playerStats['AfkTime']:get(player_name, 0)) / playerStats['JoinCount']:get(player_name, 1)) + return format_time_short((playerStats['Playtime']:get(player_name, 0) - playerStats['AfkTime']:get(player_name, 0)) / playerStats['JoinCount']:get(player_name, 1)) end }, BuildRatio = { - default = '0.00', + default = format_number_n(0), calculate = function(player_name) return format_number_n(playerStats['MachinesBuilt']:get(player_name, 0) / playerStats['MachinesRemoved']:get(player_name, 1)) end }, RocketPerHour = { - default = '0.00', + default = format_number_n(0), calculate = function(player_name) return format_number_n(playerStats['RocketsLaunched']:get(player_name, 0) * 60 / playerStats['Playtime']:get(player_name, 1)) end }, TreeKillPerMinute = { - default = '0.00', + default = format_number_n(0), calculate = function(player_name) return format_number_n(playerStats['TreesDestroyed']:get(player_name, 0) / playerStats['Playtime']:get(player_name, 1)) end }, NetPlayTime = { - default = format_clock(0), + default = format_time_short(0), calculate = function(player_name) - return format_clock((playerStats['Playtime']:get(player_name, 0) - playerStats['AfkTime']:get(player_name, 0))) + return format_time_short((playerStats['Playtime']:get(player_name, 0) - playerStats['AfkTime']:get(player_name, 0))) end }, AFKTimeRatio = { - default = '0.00', + default = format_number_n(0), calculate = function(player_name) return format_number_n(playerStats['AfkTime']:get(player_name, 0) * 100 / playerStats['Playtime']:get(player_name, 1)) end @@ -137,9 +135,9 @@ local function pd_update(table, player_name) end local pd_username_player = -Gui.element(function(name, parent, player_list) +Gui.element(function(definition, parent, player_list) return parent.add{ - name = name, + name = definition.name, type = 'drop-down', items = player_list, selected_index = #player_list > 0 and 1 @@ -152,10 +150,12 @@ end) local table = element.parent.parent.parent.parent['pd_st_2'].disp.table pd_update(table, player_name) end) +:static_name(Gui.unique_static_name) local pd_username_update = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'update' }:style{ width = 128 @@ -181,8 +181,8 @@ Gui.element(function(_, parent, name, player_list) end) pd_container = -Gui.element(function(event_trigger, parent) - local container = Gui.container(parent, event_trigger, label_width['total']) +Gui.element(function(definition, parent) + local container = Gui.container(parent, definition.name, label_width['total']) local player_list = {} for _, player in pairs(game.connected_players) do @@ -194,6 +194,7 @@ Gui.element(function(event_trigger, parent) return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() Gui.left_toolbar_button('item/power-armor-mk2', 'Player Data GUI', pd_container, function(player) diff --git a/modules/gui/surveillance.lua b/modules/gui/surveillance.lua index 6cc4a6ad..5a5adb98 100644 --- a/modules/gui/surveillance.lua +++ b/modules/gui/surveillance.lua @@ -5,12 +5,10 @@ local Gui = require 'expcore.gui' --- @dep expcore.gui local Roles = require 'expcore.roles' --- @dep expcore.roles local Event = require 'utils.event' --- @dep utils.event -local cctv_container - local cctv_player = -Gui.element(function(name, parent, player_list) +Gui.element(function(definition, parent, player_list) return parent.add{ - name = name, + name = definition.name, type = 'drop-down', items = player_list, selected_index = #player_list > 0 and 1 @@ -19,11 +17,11 @@ end) :style{ horizontally_stretchable = true } +:static_name(Gui.unique_static_name) -local cctv_type = +local cctv_status = Gui.element{ type = 'drop-down', - name = 'cctv_status', items = {'Enable', 'Disable'}, selected_index = 2 }:style{ @@ -36,10 +34,10 @@ Gui.element{ end end) -local cctv_status = +local cctv_type = Gui.element{ type = 'drop-down', - name = 'cctv_status', + name = Gui.unique_static_name, items = {'Player', 'Static'}, selected_index = 1 }:style{ @@ -49,6 +47,7 @@ Gui.element{ local cctv_location = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'set' }:style{ width = 48 @@ -59,6 +58,7 @@ end) local zoom_in = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = '+' }:style{ width = 32 @@ -72,6 +72,7 @@ end) local zoom_out = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = '-' }:style{ width = 32 @@ -88,8 +89,8 @@ Gui.element(function(_, parent, name, player_list) local buttons = Gui.scroll_table(camera_set, 480, 6, 'buttons') cctv_player(buttons, player_list) - cctv_type(buttons) cctv_status(buttons) + cctv_type(buttons) cctv_location(buttons) zoom_out(buttons) zoom_in(buttons) @@ -108,9 +109,9 @@ Gui.element(function(_, parent, name, player_list) return camera_set end) -cctv_container = -Gui.element(function(event_trigger, parent) - local container = Gui.container(parent, event_trigger, 480) +local cctv_container = +Gui.element(function(definition, parent) + local container = Gui.container(parent, definition.name, 480) local scroll = container.add{name='scroll', type='scroll-pane', direction='vertical'} scroll.style.maximal_height = 704 local player_list = {} @@ -124,6 +125,7 @@ Gui.element(function(event_trigger, parent) return container.parent end) +:static_name(Gui.unique_static_name) :add_to_left_flow() Gui.left_toolbar_button('entity/radar', 'Surveillance GUI', cctv_container, function(player) @@ -154,7 +156,7 @@ Event.add(defines.events.on_tick, function(_) for i=1, 2 do local scroll_table_name = 'cctv_st_' .. i local current_camera_set = frame.container.scroll[scroll_table_name] - local switch_index = current_camera_set.buttons.table[cctv_status.name].selected_index + local switch_index = current_camera_set.buttons.table[cctv_type.name].selected_index if switch_index == 1 then local selected_index = current_camera_set.buttons.table[cctv_player.name].selected_index diff --git a/modules/gui/vlayer.lua b/modules/gui/vlayer.lua index 1e830aa8..ef2b0a6c 100644 --- a/modules/gui/vlayer.lua +++ b/modules/gui/vlayer.lua @@ -229,6 +229,7 @@ end local vlayer_gui_control_storage_input = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'Add Input Storage' }:style{ width = 160 @@ -248,6 +249,7 @@ end) local vlayer_gui_control_storage_output = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'Add Output Storage' }:style{ width = 160 @@ -267,6 +269,7 @@ end) local vlayer_gui_control_circuit = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'Add Circuit' }:style{ width = 160 @@ -286,6 +289,7 @@ end) local vlayer_gui_control_power = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'Add Power' }:style{ width = 160 @@ -308,6 +312,7 @@ end) local vlayer_gui_control_remove = Gui.element{ type = 'button', + name = Gui.unique_static_name, caption = 'Remove Special' }:style{ width = 160