From 3a5599fcd26668f79fd59c155fdc7d496d749df8 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 21 May 2019 19:04:46 +0100 Subject: [PATCH] Refactor of left frames --- expcore/Gui/left.lua | 309 +++++++++++++++++++++------------------- expcore/Gui/test.lua | 22 ++- expcore/Gui/toolbar.lua | 1 - expcore/gui.lua | 31 ++-- 4 files changed, 189 insertions(+), 174 deletions(-) diff --git a/expcore/Gui/left.lua b/expcore/Gui/left.lua index 75f8fb70..b3d431f3 100644 --- a/expcore/Gui/left.lua +++ b/expcore/Gui/left.lua @@ -1,30 +1,48 @@ ---- Gui structure for the toolbar (just under top left) +--- Gui structure define for left frames --[[ ->>>> Example Format - local left_gui_frame = LeftFrames.new_frame() +>>>> Example formating - LeftFrames.set_open_by_default(left_gui_frame,true) - - LeftFrames.on_update(left_gui_frame,function(frame,player) - frame.add('Hello, World!') + -- first we add config that relates to the button on the toolbar, all normal button functions are present + local left_frame = + Gui.new_left_frame('test-left-frame') + :set_caption('Test Left Gui') + :set_post_authenticator(function(player,button_name) + return global.show_test_gui end) + -- then we add the config for the left frame, on_draw should draw the gui from an empty frame, on_update should take a frame from on_draw on edit it + :set_open_by_default() + :on_draw(function(_player,frame) + for _,player in pairs(game.connected_players) do + frame.add{ + type='label', + caption=player.name + } + end + end) + + -- now we can use the action factory to call events on the gui, actions are: 'update', 'update_all', 'redraw', 'redraw_all' + Event.add(defines.events.on_player_joined_game,left_frame 'update_all') + Event.add(defines.events.on_player_left_game,left_frame 'update_all') + >>>> Functions LeftFrames.get_flow(player) --- Gets the left frame flow for a player + LeftFrames.get_frame(name,player) --- Gets one frame from the left flow by its name LeftFrames.get_open(player) --- Gets all open frames for a player, if non are open it will remove the close all button - LeftFrames.get_frame(player,name) --- Gets one frame from the left flow by its name - LeftFrames.toggle_frame(player,name,state) --- Toggles the visiblty of a left frame, or sets its visiblty state + LeftFrames.toggle_frame(name,player,state) --- Toggles the visiblty of a left frame, or sets its visiblty state - LeftFrames.new_frame(name) --- Makes a new frame that can be used with on_update and adds a toggle button to the toolbar - LeftFrames.add_frame(define_name,permision_name) --- Similar to new_frame but using an already defined name (this will still add a button to the toolbar) + LeftFrames.new_frame(permision_name) --- Creates a new left frame define + LeftFrames._prototype:set_open_by_default(state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean + LeftFrames._prototype:get_frame(player) --- Gets the frame for this define from the left frame flow + LeftFrames._prototype:is_open(player) --- Returns if the player currently has this define visible + LeftFrames._prototype:toggle(player) --- Toggles the visiblty of the left frame - LeftFrames.set_open_by_default(define_name,state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean - LeftFrames.on_update(define_name,callback) --- Registeres an update function for the gui that will be used to redraw the gui (frame is cleared before call) - LeftFrames.update(define_name,player) --- Clears the gui frame for the player and calls the update callback + LeftFrames._prototype:update(player) --- Updates the contents of the left frame, first tries update callback, oter wise will clear and redraw + LeftFrames._prototype:update_all(update_offline) --- Updates the frame for all players, see update + LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame + LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw - LeftFrames.update_all_frames(player) --- Clears all frames and then re-draws all frames - LeftFrames.update_all_players(define_name,update_offline) --- Clears and returns the gui frame for all players - LeftFrames.update_all(update_offline) --- Clears and updates all frames for all players + LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add ]] local Gui = require 'expcore.gui.core' local Toolbar = require 'expcore.gui.toolbar' @@ -34,10 +52,15 @@ local Game = require 'utils.game' local Event = require 'utils.event' local LeftFrames = { - buttons={}, - draw_functions={}, - open_by_default={} + frames={}, + _prototype=Gui._prototype_factory{ + on_draw = Gui._event_factory('on_draw'), + on_update = Gui._event_factory('on_update') + } } +setmetatable(LeftFrames._prototype, { + __index = Buttons._prototype +}) --- Gets the left frame flow for a player -- @tparam player LuaPlayer the player to get the flow of @@ -47,6 +70,18 @@ function LeftFrames.get_flow(player) return mod_gui.get_frame_flow(player) end +--- Gets one frame from the left flow by its name +-- @tparam name string the name of the gui frame to get +-- @tparam player LuaPlayer the player to get the frame of +-- @treturn LuaGuiElement the frame in the left frame flow with that name +function LeftFrames.get_frame(name,player) + local define = LeftFrames.frames[name] + if not define then + return error('Left Frame '..name..' is not defined.',2) + end + return define:get_frame(player) +end + --- Gets all open frames for a player, if non are open it will remove the close all button -- @tparam player LuaPlayer the player to get the flow of -- @treturn table contains all the open (and registered) frames for the player @@ -54,181 +89,169 @@ function LeftFrames.get_open(player) local open = {} local flow = LeftFrames.get_flow(player) - for _,child in pairs(flow.children) do - if LeftFrames.buttons[child.name] then - if child.valid and child.visible then - table.insert(open,child) - end + for _,define in pairs(LeftFrames.frames) do + if define:is_open(player) then + table.insert(open,define) end end - flow[LeftFrames.toogle_button.name].visible = #open ~= 0 + flow[LeftFrames.toggle_button.name].visible = #open ~= 0 return open end ---- Gets one frame from the left flow by its name --- @tparam player LuaPlayer the player to get the frame of --- @tparam name string the name of the gui frame to get --- @treturn LuaGuiElement the frame in the left frame flow with that name -function LeftFrames.get_frame(player,name) - local flow = LeftFrames.get_flow(player) - if flow[name] and flow[name].valid then - return flow[name] - end -end - --- Toggles the visiblty of a left frame, or sets its visiblty state --- @tparam player LuaPlayer the player to get the frame of -- @tparam name string the name of the gui frame to toggle +-- @tparam player LuaPlayer the player to get the frame of -- @tparam[opt] state boolean when given will be the state that the visiblty is set to -- @treturn boolean the new state of the visiblity -function LeftFrames.toggle_frame(player,name,state) - local frame = LeftFrames.get_frame(player,name) +function LeftFrames.toggle_frame(name,player,state) + local define = LeftFrames.frames[name] + if not define then + return error('Left Frame '..name..' is not defined.',2) + end + + local frame = LeftFrames.get_frame(name,player) if state ~= nil then frame.visible = state else Gui.toggle_visible(frame) end + LeftFrames.get_open(player) + return frame.visible end ---- Gets the button that was created for this left frame --- @tparam define_name the name of the left gui frame from new_frame --- @treturn table the define for the toggle button -function LeftFrames.get_button(define_name) - return LeftFrames.buttons[define_name] -end +--- Creates a new left frame define +-- @tparam permision_name string the name that can be used with the permision system +-- @treturn table the new left frame define +function LeftFrames.new_frame(permision_name) ---- Makes a new frame that can be used with on_update and adds a toggle button to the toolbar --- @tparam[opt] name string when given allows an alias to the button for the permission system --- @treturn string the name of the left frame to be used with on_update --- @treturn table the button define that was created -function LeftFrames.new_frame(name) - local frame_name = Gui.uid_name() - local button = LeftFrames.add_frame(frame_name,name) - return frame_name, button -end + local self = Toolbar.new_button(permision_name) ---- Similar to new_frame but using an already defined name (this will still add a button to the toolbar) --- @tparam define_name string the name that is used to refrence this frame (like what is returned by new_frame) --- @tparam[opt] name string when given allows an alias to the button for the permission system --- @treturn table the button define that was created -function LeftFrames.add_frame(define_name,permision_name) - LeftFrames.buttons[define_name] = - Toolbar.new_button(permision_name) - :on_click(function(player,_element) - LeftFrames.toggle_frame(player,define_name) + local mt = getmetatable(self) + mt.__index = LeftFrames._prototype + mt.__call = self.event_handler + + self:on_click(function(player,_element) + self:toggle(player) end) - return LeftFrames.buttons[define_name] + + LeftFrames.frames[self.name] = self + + return self end --- Sets if the frame is visible when a player joins, can also be a function to return a boolean --- @tparam define_name the name of the left gui frame from new_frame -- @tparam[opt=true] state ?boolean|function the default state of the visiblty, can be a function -- state param - player LuaPlayer - the player that has joined the game -- state param - define_name string - the define name for the frame -- state return - boolean - false will hide the frame -function LeftFrames.set_open_by_default(define_name,state) - if not LeftFrames.buttons[define_name] then - return error('Left frame is not registered',2) +function LeftFrames._prototype:set_open_by_default(state) + if state == false then + self.open_by_default = false + else + self.open_by_default = state end - - LeftFrames.draw_functions[define_name] = state + return self end ---- Registeres an update function for the gui that will be used to redraw the gui (frame is cleared before call) --- @tparam define_name the name of the left gui frame from new_frame --- @tparam callback function the function which is called to update the gui frame --- callback param - frame LuaGuiElement - the frame which has be cleared to have its elements redrawn --- callback param - player LuaPlayer - the player who owns the frame -function LeftFrames.on_update(define_name,callback) - if not LeftFrames.buttons[define_name] then - return error('Left frame is not registered',2) - end - - LeftFrames.draw_functions[define_name] = callback -end - ---- Returns a function that can be called from a factorio event to update the frame --- @tparam define_name string the name of the left gui frame from new_frame --- @treturn function when this function is called it will update the frame from event.player_index -function LeftFrames.update_factory(define_name) - if not LeftFrames.draw_functions[define_name] then - return error('Left frame has no update callback',2) - end - - return function(event) - LeftFrames.update(define_name,event.player_index) +--- Gets the frame for this define from the left frame flow +-- @tparam player LuaPlayer the player to get the frame of +-- @treturn LuaGuiElement the frame in the left frame flow for this define +function LeftFrames._prototype:get_frame(player) + local flow = LeftFrames.get_flow(player) + if flow[self.name] and flow[self.name].valid then + return flow[self.name] end end ---- Clears the gui frame for the player and calls the update callback --- @tparam define_name the name of the left gui frame from new_frame --- @tparam player LuaPlayer the player to update the frame for -function LeftFrames.update(define_name,player) - player = Game.get_player_from_any(player) - local frame = LeftFrames.get_frame(player,define_name) - frame.clear() - if LeftFrames.draw_functions[define_name] then - LeftFrames.draw_functions[define_name](frame,player) - end +--- Returns if the player currently has this define visible +-- @tparam player LuaPlayer the player to get the frame of +-- @treturn boolean true if it is open/visible +function LeftFrames._prototype:is_open(player) + local frame = self:get_frame(player) + return frame and frame.visible or false end ---- Clears all frames and then re-draws all frames --- @tparam player LuaPlayer the player to update the frames for -function LeftFrames.update_all_frames(player) - player = Game.get_player_from_any(player) - for define_name,draw_function in pairs(LeftFrames.draw_functions) do - local frame = LeftFrames.get_frame(player,define_name) +--- Toggles the visiblty of the left frame +-- @tparam player LuaPlayer the player to toggle the frame of +-- @treturn boolean the new state of the visiblity +function LeftFrames._prototype:toggle(player) + local frame = self:get_frame(player) + Gui.toggle_visible(frame) + LeftFrames.get_open(player) + return frame.visible +end + +--- Updates the contents of the left frame, first tries update callback, oter wise will clear and redraw +-- @tparam player LuaPlayer the player to update the frame of +function LeftFrames._prototype:update(player) + local frame = self:get_frame(player) + if self.events.on_update then + self.events.on_update(player,frame) + elseif self.events.on_draw then frame.clear() - draw_function(frame,player) + self.events.on_draw(player,frame) end end ---- Clears and returns the gui frame for all players --- @tparam define_name the name of the left gui frame from new_frame --- @tparam[opt=false] update_offline boolean when true will also update the frame for offline players -function LeftFrames.update_all_players(define_name,update_offline) - local players = update_offline and game.players or game.connected_players +--- Updates the frame for all players, see update +-- @tparam[opt=false] update_offline boolean when true will update the frame for offline players +function LeftFrames._prototype:update_all(update_offline) + local players = update_offline == true and game.players or game.connected_players for _,player in pairs(players) do - LeftFrames.update(define_name,player) + self:update(player) end end ---- Clears and updates all frames for all players --- @tparam[opt=false] update_offline boolean when true will also update the frame for offline players -function LeftFrames.update_all(update_offline) - local players = update_offline and game.players or game.connected_players +--- Redraws the frame by calling on_draw, will always clear the frame +-- @tparam player LuaPlayer the player to update the frame of +function LeftFrames._prototype:redraw(player) + local frame = self:get_frame(player) + frame.claer() + if self.events.on_draw then + self.events.on_draw(player,frame) + end +end + +--- Redraws the frame for all players, see redraw +-- @tparam[opt=false] update_offline boolean when true will update the frame for offline players +function LeftFrames._prototype:redraw_all(update_offline) + local players = update_offline == true and game.players or game.connected_players for _,player in pairs(players) do - LeftFrames.update_all_frames(player) + self:redraw(player) end end -LeftFrames.toogle_button = +--- Creates an event handler that will trigger one of its functions, use with Event.add +-- @tparam[opt=update] action string the action to take on this event +function LeftFrames._prototype:event_handler(action) + action = action or 'update' + return function(event) + local player = Game.get_player_by_index(event.player_index) + self[action](self,player) + end +end + +LeftFrames.toggle_button = Buttons.new_button() :set_tooltip('Close Windows') :set_caption('<') -:on_click(function(player,_element) - local flow = LeftFrames.get_flow(player) - - for _,child in pairs(flow.children) do - if LeftFrames.buttons[child.name] then - if child.valid and child.visible then - child.visible = false - end - end +:on_click(function(player,element) + for _,define in pairs(LeftFrames.frames) do + local frame = LeftFrames.get_frame(define.name,player) + frame.visible = false end - - _element.visible = false + element.visible = false end) Event.add(defines.events.on_player_created,function(event) local player = Game.get_player_by_index(event.player_index) local flow = LeftFrames.get_flow(player) - local style = LeftFrames.toogle_button(flow).style + local style = LeftFrames.toggle_button(flow).style style.width = 18 style.height = 36 style.left_padding = 0 @@ -237,25 +260,25 @@ Event.add(defines.events.on_player_created,function(event) style.bottom_padding = 0 style.font = 'default-small-bold' - for define_name,_ in pairs(LeftFrames.buttons) do + for _,define in pairs(LeftFrames.frames) do local frame = flow.add{ type='frame', - name=define_name + name=define.name } - if LeftFrames.draw_functions[define_name] then - LeftFrames.draw_functions[define_name](frame,player) + if define.events.on_draw then + define.events.on_draw(player,frame) end - if LeftFrames.open_by_default[define_name] == false then + if define.open_by_default == false then frame.visible = false - elseif type(LeftFrames.open_by_default[define_name]) == 'function' then - if not LeftFrames.open_by_default[define_name](player,define_name) then + elseif type(define.open_by_default) == 'function' then + if not define.open_by_default(player,define.name) then frame.visible = false end end - if not Toolbar.allowed(player,define_name) then + if not Toolbar.allowed(player,define.name) then frame.visible = false end diff --git a/expcore/Gui/test.lua b/expcore/Gui/test.lua index 889e380c..3a1a013c 100644 --- a/expcore/Gui/test.lua +++ b/expcore/Gui/test.lua @@ -97,12 +97,15 @@ end) > Left frame which holds all online player names, updates when player leaves or joins ]] -local left_frame_name,left_gui_button = +local left_frame = Gui.new_left_frame('test-left-frame') +:set_caption('Test Left Gui') +:set_post_authenticator(function(player,button_name) + return global.show_test_gui +end) -Gui.set_left_open_by_default(left_frame_name,true) - -Gui.on_left_update(left_frame_name,function(frame,_player) +:set_open_by_default() +:on_draw(function(_player,frame) for _,player in pairs(game.connected_players) do frame.add{ type='label', @@ -111,15 +114,8 @@ Gui.on_left_update(left_frame_name,function(frame,_player) end end) -left_gui_button -:set_caption('Test Left Gui') -:set_post_authenticator(function(player,button_name) - return global.show_test_gui -end) - -local update_left_frame = Gui.left_update_factory(left_frame_name) -Event.add(defines.events.on_player_joined_game,update_left_frame) -Event.add(defines.events.on_player_left_game,update_left_frame) +Event.add(defines.events.on_player_joined_game,left_frame 'update_all') +Event.add(defines.events.on_player_left_game,left_frame 'update_all') --[[ Button Tests diff --git a/expcore/Gui/toolbar.lua b/expcore/Gui/toolbar.lua index 90fbab04..87843f5a 100644 --- a/expcore/Gui/toolbar.lua +++ b/expcore/Gui/toolbar.lua @@ -78,7 +78,6 @@ function Toolbar.update(player) element.enabled = false end end - log(table.inspect(Toolbar.buttons)) end --- When there is a new player they will have the toolbar update diff --git a/expcore/gui.lua b/expcore/gui.lua index 0e68c80c..321c1def 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -155,31 +155,28 @@ Gui.classes.toolbar = Toolbar ]] local LeftFrames = require('expcore.gui.left') +Gui.get_left_frame_flow = LeftFrames.get_flow +Gui.toggle_left_frame = LeftFrames.toggle_frame Gui.new_left_frame = LeftFrames.new_frame -Gui.add_frame_to_left_frames = LeftFrames.add_frame -Gui.set_left_open_by_default = LeftFrames.set_open_by_default -Gui.on_left_update = LeftFrames.on_update -Gui.left_update_factory = LeftFrames.update_factory -Gui.update_left_frames = LeftFrames.update_all_frames -Gui.update_left_frame = LeftFrames.update -Gui.get_left_frame = LeftFrames.get_frame Gui.classes.left_frames = LeftFrames --[[ LeftFrames.get_flow(player) --- Gets the left frame flow for a player + LeftFrames.get_frame(name,player) --- Gets one frame from the left flow by its name LeftFrames.get_open(player) --- Gets all open frames for a player, if non are open it will remove the close all button - LeftFrames.get_frame(player,name) --- Gets one frame from the left flow by its name - LeftFrames.toggle_frame(player,name,state) --- Toggles the visiblty of a left frame, or sets its visiblty state + LeftFrames.toggle_frame(name,player,state) --- Toggles the visiblty of a left frame, or sets its visiblty state - LeftFrames.new_frame(name) --- Makes a new frame that can be used with on_update and adds a toggle button to the toolbar - LeftFrames.add_frame(define_name,permision_name) --- Similar to new_frame but using an already defined name (this will still add a button to the toolbar) + LeftFrames.new_frame(permision_name) --- Creates a new left frame define + LeftFrames._prototype:set_open_by_default(state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean + LeftFrames._prototype:get_frame(player) --- Gets the frame for this define from the left frame flow + LeftFrames._prototype:is_open(player) --- Returns if the player currently has this define visible + LeftFrames._prototype:toggle(player) --- Toggles the visiblty of the left frame - LeftFrames.set_open_by_default(define_name,state) --- Sets if the frame is visible when a player joins, can also be a function to return a boolean - LeftFrames.on_update(define_name,callback) --- Registeres an update function for the gui that will be used to redraw the gui (frame is cleared before call) - LeftFrames.update(define_name,player) --- Clears the gui frame for the player and calls the update callback + LeftFrames._prototype:update(player) --- Updates the contents of the left frame, first tries update callback, oter wise will clear and redraw + LeftFrames._prototype:update_all(update_offline) --- Updates the frame for all players, see update + LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame + LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw - LeftFrames.update_all_frames(player) --- Clears all frames and then re-draws all frames - LeftFrames.update_all_players(define_name,update_offline) --- Clears and returns the gui frame for all players - LeftFrames.update_all(update_offline) --- Clears and updates all frames for all players + LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add ]] return Gui \ No newline at end of file