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