diff --git a/config/_file_loader.lua b/config/_file_loader.lua index f7ad4c42..1b21e619 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -44,7 +44,7 @@ return { 'modules.gui.warp-list', 'modules.gui.task-list', 'modules.gui.player-list', - --'modules.commands.debug', + 'modules.commands.debug', -- Config Files 'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins 'config.expcore-commands.auth_roles', -- commands must be allowed via the role config diff --git a/expcore/gui.lua b/expcore/gui.lua index e6874e31..de0cd8f9 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -87,6 +87,9 @@ local Gui = { --- An index used for debuging to find the file where different elements where registered -- @table file_paths file_paths = {}, + --- An index used for debuging to show the raw data used to define an element + -- @table debug_info + debug_info = {}, --- The element prototype which is returned from Gui.element -- @table _prototype_element _prototype_element = {}, @@ -154,14 +157,17 @@ function Gui.element(element_define) Gui.uid = uid local name = tostring(uid) element.name = name + Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } -- Add the defination function if type(element_define) == 'table' then + Gui.debug_info[name].draw = element_define element_define.name = name element._draw = function(_,parent) return parent.add(element_define) end else + Gui.debug_info[name].draw = 'Function' element._draw = element_define end @@ -206,12 +212,14 @@ end) function Gui._prototype_element:style(style_define) -- Add the defination function if type(style_define) == 'table' then + Gui.debug_info[self.name].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' self._style = style_define end @@ -281,6 +289,7 @@ local function event_handler_factory(event_name) Event.add(event_name, general_event_handler) return function(self,handler) + table.insert(Gui.debug_info[self.name].events,debug.getinfo(1, "n").name) self[event_name] = handler return self end @@ -331,7 +340,7 @@ Gui._prototype_element.on_switch_changed = event_handler_factory(defines.events. --- Called when LuaGuiElement text is changed by the player. -- @tparam function handler the event handler which will be called -Gui._prototype_element.on_text_change = event_handler_factory(defines.events.on_gui_text_changed) +Gui._prototype_element.on_text_changed = event_handler_factory(defines.events.on_gui_text_changed) --- Called when LuaGuiElement slider value is changed (related to the slider element). -- @tparam function handler the event handler which will be called diff --git a/modules/commands/debug.lua b/modules/commands/debug.lua index f0be73ba..e29786a6 100644 --- a/modules/commands/debug.lua +++ b/modules/commands/debug.lua @@ -9,6 +9,6 @@ local Commands = require 'expcore.commands' --- @dep expcore.commands --- Opens the debug pannel for viewing tables. -- @command debug Commands.new_command('debug','Opens the debug pannel for viewing tables.') -:register(function(player,raw) +:register(function(player) DebugView.open_dubug(player) end) \ No newline at end of file diff --git a/modules/gui/debug/event_view.lua b/modules/gui/debug/event_view.lua index bc372007..cae93e60 100644 --- a/modules/gui/debug/event_view.lua +++ b/modules/gui/debug/event_view.lua @@ -1,7 +1,7 @@ -local Event = require 'utils.event' --- @dep utils.event -local table = require 'utils.table' --- @dep utils.table -local Gui = require 'utils.gui' --- @dep utils.gui -local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model +local Event = require 'utils.event' +local table = require 'utils.table' +local Gui = require 'utils.gui' +local Model = require 'modules.gui.debug.model' local format = string.format local insert = table.insert @@ -19,13 +19,16 @@ local name_lookup = {} -- GUI names local checkbox_name = Gui.uid_name() +local filter_name = Gui.uid_name() +local clear_filter_name = Gui.uid_name() -- global tables local enabled = {} local last_events = {} global.debug_event_view = { enabled = enabled, - last_events = last_events + last_events = last_events, + filter = '' } function Public.on_open_debug() @@ -90,24 +93,73 @@ end table.sort(grid_builder) -function Public.show(container) - local main_frame_flow = container.add({type = 'flow', direction = 'vertical'}) - local scroll_pane = main_frame_flow.add({type = 'scroll-pane'}) - local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true}) - +local function redraw_event_table(gui_table, filter) for _, event_name in pairs(grid_builder) do - local index = events[event_name] - gui_table.add({type = 'flow'}).add { - name = checkbox_name, - type = 'checkbox', - state = enabled[index] or false, - caption = event_name - } + if filter == '' or event_name:find(filter) then + local index = events[event_name] + gui_table.add({type = 'flow'}).add { + name = checkbox_name, + type = 'checkbox', + state = enabled[index] or false, + caption = event_name + } + end end end +function Public.show(container) + local filter = global.debug_event_view.filter + + local main_frame_flow = container.add({type = 'flow', direction = 'vertical'}) + + local filter_flow = main_frame_flow.add({type = 'flow', direction = 'horizontal'}) + filter_flow.add({type = 'label', caption = 'filter'}) + local filter_textfield = filter_flow.add({type = 'textfield', name = filter_name, text = filter}) + local clear_button = filter_flow.add({type = 'button', name = clear_filter_name, caption = 'clear'}) + + local scroll_pane = main_frame_flow.add({type = 'scroll-pane'}) + local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true}) + + Gui.set_data(filter_textfield, gui_table) + Gui.set_data(clear_button, {gui_table = gui_table, filter_textfield = filter_textfield}) + + redraw_event_table(gui_table, filter) +end + Gui.on_checked_state_changed(checkbox_name, on_gui_checked_state_changed) +Gui.on_text_changed( + filter_name, + function(event) + local element = event.element + local gui_table = Gui.get_data(element) + + local filter = element.text:gsub(' ', '_') + + global.debug_event_view.filter = filter + element.text = filter + + gui_table.clear() + redraw_event_table(gui_table, filter) + end +) + +Gui.on_click( + clear_filter_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + local filter_textfield = data.filter_textfield + local gui_table = data.gui_table + + filter_textfield.text = '' + global.debug_event_view.filter = '' + + gui_table.clear() + redraw_event_table(gui_table, '') + end +) + -- Event registers (TODO: turn to removable hooks.. maybe) for name, id in pairs(events) do name_lookup[id] = name diff --git a/modules/gui/debug/expcore_gui_view.lua b/modules/gui/debug/expcore_gui_view.lua new file mode 100644 index 00000000..cf95e894 --- /dev/null +++ b/modules/gui/debug/expcore_gui_view.lua @@ -0,0 +1,128 @@ +local Gui = require 'utils.gui' --- @dep utils.gui +local ExpGui = require 'expcore.gui' --- @dep utils.global +local Color = require 'resources.color_presets' --- @dep resources.color_presets +local Model = require 'modules.gui.debug.model' --- @dep modules.gui.debug.model + +local dump = Model.dump +local dump_text = Model.dump_text +local concat = table.concat + +local Public = {} + +local header_name = Gui.uid_name() +local left_panel_name = Gui.uid_name() +local right_panel_name = Gui.uid_name() +local input_text_box_name = Gui.uid_name() +local refresh_name = Gui.uid_name() + +Public.name = 'Elements' + +function Public.show(container) + local main_flow = container.add {type = 'flow', direction = 'horizontal'} + + local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name} + local left_panel_style = left_panel.style + left_panel_style.width = 300 + + for element_id, file_path in pairs(ExpGui.file_paths) do + local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = element_id..' - '..file_path} + Gui.set_data(header, element_id) + end + + local right_flow = main_flow.add {type = 'flow', direction = 'vertical'} + + local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'} + + local input_text_box = right_top_flow.add {type = 'text-box', name = input_text_box_name} + local input_text_box_style = input_text_box.style + input_text_box_style.horizontally_stretchable = true + input_text_box_style.height = 32 + input_text_box_style.maximal_width = 1000 + + local refresh_button = + right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'} + local refresh_button_style = refresh_button.style + refresh_button_style.width = 32 + refresh_button_style.height = 32 + + local right_panel = right_flow.add {type = 'text-box', name = right_panel_name} + right_panel.read_only = true + right_panel.selectable = true + + local right_panel_style = right_panel.style + right_panel_style.vertically_stretchable = true + right_panel_style.horizontally_stretchable = true + right_panel_style.maximal_width = 1000 + right_panel_style.maximal_height = 1000 + + local data = { + right_panel = right_panel, + input_text_box = input_text_box, + selected_header = nil + } + + Gui.set_data(input_text_box, data) + Gui.set_data(left_panel, data) + Gui.set_data(refresh_button, data) +end + +Gui.on_click( + header_name, + function(event) + local element = event.element + local element_id = Gui.get_data(element) + + local left_panel = element.parent.parent + local data = Gui.get_data(left_panel) + local right_panel = data.right_panel + local selected_header = data.selected_header + local input_text_box = data.input_text_box + + if selected_header then + selected_header.style.font_color = Color.white + end + + element.style.font_color = Color.orange + data.selected_header = element + + input_text_box.text = concat {'Gui.defines[', element_id, ']'} + input_text_box.style.font_color = Color.black + + local content = dump(ExpGui.debug_info[element_id]) or 'nil' + right_panel.text = content + end +) + +local function update_dump(text_input, data, player) + local suc, ouput = dump_text(text_input.text, player) + if not suc then + text_input.style.font_color = Color.red + else + text_input.style.font_color = Color.black + data.right_panel.text = ouput + end +end + +Gui.on_text_changed( + input_text_box_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + + update_dump(element, data, event.player) + end +) + +Gui.on_click( + refresh_name, + function(event) + local element = event.element + local data = Gui.get_data(element) + + local input_text_box = data.input_text_box + + update_dump(input_text_box, data, event.player) + end +) + +return Public diff --git a/modules/gui/debug/expcore_store_view.lua b/modules/gui/debug/expcore_store_view.lua index 2d115992..300acc2d 100644 --- a/modules/gui/debug/expcore_store_view.lua +++ b/modules/gui/debug/expcore_store_view.lua @@ -24,8 +24,8 @@ function Public.show(container) local left_panel_style = left_panel.style left_panel_style.width = 300 - for store_id, token_name in pairs(Store.file_paths) do - local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = store_id..' - '..token_name} + for store_id, file_path in pairs(Store.file_paths) do + local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = store_id..' - '..file_path} Gui.set_data(header, store_id) end diff --git a/modules/gui/debug/main_view.lua b/modules/gui/debug/main_view.lua index 3c286a46..9807329c 100644 --- a/modules/gui/debug/main_view.lua +++ b/modules/gui/debug/main_view.lua @@ -6,6 +6,7 @@ local Public = {} local pages = { require 'modules.gui.debug.redmew_global_view', require 'modules.gui.debug.expcore_store_view', + require 'modules.gui.debug.expcore_gui_view', require 'modules.gui.debug.global_view', require 'modules.gui.debug.package_view', require 'modules.gui.debug._g_view', @@ -31,7 +32,7 @@ function Public.open_dubug(player) return end - frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3001', direction = 'vertical'} + frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3002', direction = 'vertical'} local frame_style = frame.style frame_style.height = 600 frame_style.width = 900 diff --git a/utils/gui.lua b/utils/gui.lua index 764037e0..36fc1d61 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -1,11 +1,7 @@ -local Token = require 'utils.token' --- @dep utils.token -local Event = require 'utils.event' --- @dep utils.event -local Game = require 'utils.game' --- @dep utils.game local Global = require 'utils.global' --- @dep utils.global -local mod_gui = require 'mod-gui' --- @dep mod-gui +local ExpGui = require 'expcore.gui' --- @dep expcore.gui local Gui = {} - local data = {} Global.register( @@ -15,12 +11,9 @@ Global.register( end ) -local top_elements = {} -local on_visible_handlers = {} -local on_pre_hidden_handlers = {} - function Gui.uid_name() - return tostring(Token.uid()) + local new_element = ExpGui.element() + return new_element.name end -- Associates data with the LuaGuiElement. If data is nil then removes the data @@ -75,219 +68,62 @@ function Gui.clear(element) element.clear() end -local function handler_factory(event_id) - local handlers - - local function on_event(event) - local element = event.element - if not element or not element.valid then - return - end - - local handler = handlers[element.name] - if not handler then - return - end - - local player = Game.get_player_by_index(event.player_index) - if not player or not player.valid then - return - end - event.player = player - - handler(event) - end - +local function handler_factory(event_name) return function(element_name, handler) - if not handlers then - handlers = {} - Event.add(event_id, on_event) - end - - handlers[element_name] = handler + local element = ExpGui.defines[element_name] + if not element then return end + element[event_name](element,function(_,_,event) + handler(event) + end) end end -local function custom_handler_factory(handlers) - return function(element_name, handler) - handlers[element_name] = handler - end -end - -local function custom_raise(handlers, element, player) - local handler = handlers[element.name] - if not handler then - return - end - - handler({element = element, player = player}) -end - -- Register a handler for the on_gui_checked_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_checked_state_changed = handler_factory(defines.events.on_gui_checked_state_changed) +Gui.on_checked_state_changed = handler_factory('on_checked_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(defines.events.on_gui_click) +Gui.on_click = handler_factory('on_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(defines.events.on_gui_closed) +Gui.on_custom_close = handler_factory('on_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(defines.events.on_gui_elem_changed) +Gui.on_elem_changed = handler_factory('on_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(defines.events.on_gui_selection_state_changed) +Gui.on_selection_state_changed = handler_factory('on_selection_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(defines.events.on_gui_text_changed) +Gui.on_text_changed = handler_factory('on_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(defines.events.on_gui_value_changed) - --- Register a handler for when the player shows the top LuaGuiElements with element_name. --- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility. --- 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_player_show_top = custom_handler_factory(on_visible_handlers) - --- Register a handler for when the player hides the top LuaGuiElements with element_name. --- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility. --- 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_pre_player_hide_top = custom_handler_factory(on_pre_hidden_handlers) - ---- Allows the player to show / hide this element. --- The element must be in Gui.get_top_element_flow(player) --- This function must be called in the control stage, i.e not inside an event. --- @param element_name This name must be globally unique. -function Gui.allow_player_to_toggle_top_element_visibility(element_name) - if _LIFECYCLE ~= _STAGE.control then - error('can only be called during the control stage', 2) - end - top_elements[#top_elements + 1] = element_name -end +Gui.on_value_changed = handler_factory('on_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 -function Gui.get_top_element_flow(player) - player = Game.get_player_from_any(player) - return mod_gui.get_button_flow(player) -end - -local toggle_button_name = Gui.uid_name() -Gui.top_toggle_button_name = toggle_button_name - -Event.add( - defines.events.on_player_created, - function(event) - local player = Game.get_player_by_index(event.player_index) - - if not player or not player.valid then - return - end - - local top = Gui.get_top_element_flow(player) - - local b = top.add { - type = 'button', - name = toggle_button_name, - style = mod_gui.button_style, - caption = '<', - tooltip = {'gui_util.button_tooltip'} - } - local style = b.style - style.width = 18 - style.height = 36 - style.left_padding = 0 - style.top_padding = 0 - style.right_padding = 0 - style.bottom_padding = 0 - style.font = 'default-small-bold' - end -) - -Gui.on_click( - toggle_button_name, - function(event) - local button = event.element - local player = event.player - local top = Gui.get_top_element_flow(player) - - if button.caption == '<' then - for i = 1, #top_elements do - local name = top_elements[i] - local ele = top[name] - if ele and ele.valid then - if ele.visible then - custom_raise(on_pre_hidden_handlers, ele, player) - ele.visible = false - end - end - end - - button.caption = '>' - button.style.height = 24 - else - for i = 1, #top_elements do - local name = top_elements[i] - local ele = top[name] - if ele and ele.valid then - if not ele.visible then - ele.visible = true - custom_raise(on_visible_handlers, ele, player) - end - end - end - - button.caption = '<' - button.style.height = 36 - end - end -) - -if _DEBUG then - local concat = table.concat - - local names = {} - Gui.names = names - - function Gui.uid_name() - local info = debug.getinfo(2, 'Sl') - local filepath = info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - local line = info.currentline - - local token = tostring(Token.uid()) - - local name = concat {token, ' - ', filepath, ':line:', line} - names[token] = name - - return token - end -end +Gui.get_top_element_flow = ExpGui.get_top_flow return Gui \ No newline at end of file