Cleaned up gui

This commit is contained in:
Cooldude2606
2019-06-14 20:00:16 +01:00
parent b13940b74c
commit ccd14da823
21 changed files with 598 additions and 677 deletions

View File

@@ -3,43 +3,47 @@
local Gui = require 'expcore.gui.core'
--[[
Gui._prototype_factory(tbl) --- Used internally to create new prototypes for element defines
Gui._event_factory(name) --- Used internally to create event handler adders for element defines
Gui._store_factory(callback) --- Used internally to create store adders for element defines
Gui._sync_store_factory(callback) --- Used internally to create synced store adders for element defines
Gui._define_factory(prototype) --- Used internally to create new element defines from a class prototype
Core
Gui._prototype:uid() --- Gets the uid for the element define
Gui._prototype:debug_name(name) --- Sets a debug alias for the define
Gui._prototype:set_caption(caption) --- Sets the caption for the element define
Gui._prototype:set_tooltip(tooltip) --- Sets the tooltip for the element define
Gui._prototype:set_style(style,callback) --- Sets the style for the element define
Gui._prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Gui._prototype:on_element_update(callback) --- Add a hander to run on the general value update event, different classes will handle this event differently
Gui._prototype:set_pre_authenticator(callback) --- Sets an authenticator that blocks the draw function if check fails
Gui._prototype:set_post_authenticator(callback) --- Sets an authenticator that disables the element if check fails
Gui._prototype:draw_to(element) --- Draws the element using what is in the draw_data table, allows use of authenticator if present, registers new instances if store present
Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype
Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to
Gui._prototype:add_store(categorize) --- Adds a store location for the define that will save the state of the element, categorize is a function that returns a string
Gui._prototype:add_sync_store(location,categorize) --- Adds a store location for the define that will sync between games, categorize is a function that returns a string
Gui._prototype:on_store_update(callback) --- Adds a event callback for when the store changes are other events are not gauenteted to be raised
Gui.player_store(element) --- A categorize function to be used with add_store, each player has their own value
Gui.force_store(element) --- A categorize function to be used with add_store, each force has its own value
Gui.surface_store(element) --- A categorize function to be used with add_store, each surface has its own value
Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value
Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value
Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value
Gui._prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Gui._prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Gui.get_store(name,category) --- Gets the value that is stored for a given element define, category needed if categorize function used
Gui.set_store(name,category,value) --- Sets the value stored for a given element define, category needed if categorize function used
Gui.toggle_enable(element) --- Will toggle the enabled state of an element
Gui.toggle_enabled(element) --- Will toggle the enabled state of an element
Gui.toggle_visible(element) --- Will toggle the visiblity of an element
Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element
Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style
Gui.create_right_align(element,flow_name) --- Allows the creation of a right align flow to place elements into
Gui.create_alignment(element,flow_name) --- Allows the creation of a right align flow to place elements into
Gui.destory_if_valid(element) --- Destroies an element but tests for it being present and valid first
Prototype Constructor
Constructor.event(event_name) --- Creates a new function to add functions to an event handler
Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables
Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define
Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set
Base Prototype
Prototype:uid() --- Gets the uid for the element define
Prototype:debug_name(value) --- Sets a debug alias for the define
Prototype:set_caption(value) --- Sets the caption for the element define
Prototype:set_tooltip(value) --- Sets the tooltip for the element define
Prototype:set_style(style,callback) --- Sets the style for the element define
Prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails
Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails
Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element
Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used
]]
local Instances = require 'expcore.gui.instances'
@@ -48,8 +52,20 @@ Gui.get_instances = Instances.get_elements
Gui.add_instance = Instances.get_elements
Gui.update_instances = Instances.apply_to_elements
Gui.classes.instances = Instances
--[[
Instances.has_categories(name) --- Returns if a instnace group has a categorise function; must be registerd
Instances.is_registered(name) --- Returns if the given name is a registered instance group
Instances.register(name,categorise) --- Registers the name of an instance group to allow for storing element instances
local Button = require 'expcore.gui.buttons'
Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered
Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered
Instances.get_valid_elements(name,category,callback) --- Gets all valid element instances and has the option of running a callback on those that are valid
Instances.unregistered_add_element(name,category,element) --- A version of add_element that does not require the group to be registered
Instances.unregistered_get_elements(name,category,callback) --- A version of get_elements that does not require the group to be registered
]]
local Button = require 'expcore.gui.elements.buttons'
Gui.new_button = Button.new_button
Gui.classes.button = Button
--[[
@@ -64,7 +80,7 @@ Gui.classes.button = Button
Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button
]]
local Checkbox = require 'expcore.gui.checkboxs'
local Checkbox = require 'expcore.gui.elements.checkboxs'
Gui.new_checkbox = Checkbox.new_checkbox
Gui.new_radiobutton = Checkbox.new_radiobutton
Gui.new_radiobutton_option_set = Checkbox.new_option_set
@@ -86,7 +102,7 @@ Gui.classes.checkbox = Checkbox
Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobutotn in a element to false (unless excluded) and can act recursivly
]]
local Dropdown = require 'expcore.gui.dropdown'
local Dropdown = require 'expcore.gui.elements.dropdown'
Gui.new_dropdown = Dropdown.new_dropdown
Gui.new_list_box = Dropdown.new_list_box
Gui.classes.dropdown = Dropdown
@@ -105,7 +121,7 @@ Gui.classes.dropdown = Dropdown
Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index
]]
local Slider = require 'expcore.gui.slider'
local Slider = require 'expcore.gui.elements.slider'
Gui.new_slider = Slider.new_slider
Gui.classes.slider = Slider
--[[
@@ -114,13 +130,12 @@ Gui.classes.slider = Slider
Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates
Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates
Slider._prototype:use_notches(state) --- Adds notches to the slider
Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider
Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player
Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider
]]
local Text = require 'expcore.gui.text'
local Text = require 'expcore.gui.elements.text'
Gui.new_text_filed = Text.new_text_field
Gui.new_text_box = Text.new_text_box
Gui.classes.text = Text
@@ -137,7 +152,7 @@ Gui.classes.text = Text
Text._prototype_box:set_read_only(state) --- Sets the text box to be read only
]]
local ElemButton = require 'expcore.gui.elem-button'
local ElemButton = require 'expcore.gui.elements.elem-button'
Gui.new_elem_button = ElemButton.new_elem_button
Gui.classes.elem_button = ElemButton
--[[
@@ -150,7 +165,7 @@ Gui.classes.elem_button = ElemButton
ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string
]]
local ProgressBar = require 'expcore.gui.progress-bar'
local ProgressBar = require 'expcore.gui.elements.progress-bar'
Gui.new_progressbar = ProgressBar.new_progressbar
Gui.set_progressbar_maximum = ProgressBar.set_maximum
Gui.increment_progressbar = ProgressBar.increment
@@ -177,7 +192,7 @@ Gui.classes.progressbar = ProgressBar
ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggeres, can filter which elements are decremented
]]
local Toolbar = require 'expcore.gui.toolbar'
local Toolbar = require 'expcore.gui.concepts.toolbar'
Gui.new_toolbar_button = Toolbar.new_button
Gui.add_button_to_toolbar = Toolbar.add_button
Gui.update_toolbar = Toolbar.update
@@ -188,7 +203,7 @@ Gui.classes.toolbar = Toolbar
Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return
]]
local LeftFrames = require 'expcore.gui.left'
local LeftFrames = require 'expcore.gui.concepts.left'
Gui.get_left_frame_flow = LeftFrames.get_flow
Gui.toggle_left_frame = LeftFrames.toggle_frame
Gui.new_left_frame = LeftFrames.new_frame
@@ -217,7 +232,7 @@ Gui.classes.left_frames = LeftFrames
LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
local CenterFrames = require 'expcore.gui.center'
local CenterFrames = require 'expcore.gui.concepts.center'
Gui.get_center_flow = CenterFrames.get_flow
Gui.toggle_center_frame = CenterFrames.toggle_frame
Gui.draw_center_frame = CenterFrames.draw_frame
@@ -240,7 +255,7 @@ Gui.classes.center_frames = CenterFrames
CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
local PopupFrames = require 'expcore.gui.popups'
local PopupFrames = require 'expcore.gui.concepts.popups'
Gui.get_popup_flow = PopupFrames.get_flow
Gui.open_popup = PopupFrames.open
Gui.new_popup = PopupFrames.new_popup

View File

@@ -16,12 +16,13 @@
CenterFrames._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'
local Prototype = require 'expcore.gui.prototype'
local Toolbar = require 'expcore.gui.concepts.toolbar'
local Game = require 'utils.game'
local CenterFrames = {
_prototype = Gui._prototype_factory{
on_draw = Gui._event_factory('on_draw')
_prototype = Prototype.extend{
on_creation = Prototype.event
}
}
@@ -141,9 +142,7 @@ function CenterFrames._prototype:draw_frame(player)
player.opened = frame
end
if self.events.on_draw then
self.events.on_draw(player,frame)
end
self:raise_event('on_creation',player,frame)
return frame
end

View File

@@ -49,18 +49,19 @@
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'
local Buttons = require 'expcore.gui.buttons'
local Prototype = require 'expcore.gui.prototype'
local Toolbar = require 'expcore.gui.concepts.toolbar'
local Buttons = require 'expcore.gui.elements.buttons'
local mod_gui = require 'mod-gui'
local Game = require 'utils.game'
local Event = require 'utils.event'
local LeftFrames = {
frames={},
_prototype=Gui._prototype_factory{
on_draw = Gui._event_factory('on_draw'),
on_update = Gui._event_factory('on_update'),
on_player_toggle = Gui._event_factory('on_player_toggle')
_prototype=Prototype.extend{
on_creation = Prototype.event,
on_update = Prototype.event,
on_player_toggle = Prototype.event
}
}
setmetatable(LeftFrames._prototype, {
@@ -132,7 +133,6 @@ end
-- @tparam string permision_name the name that can be used with the permision system
-- @treturn table the new left frame define
function LeftFrames.new_frame(permision_name)
local self = Toolbar.new_button(permision_name)
local mt = getmetatable(self)
@@ -141,11 +141,8 @@ function LeftFrames.new_frame(permision_name)
self:on_click(function(player,_element)
local visible = self:toggle(player)
if self.events.on_player_toggle then
local frame = self:get_frame(player)
self.events.on_player_toggle(player,frame,visible)
end
local frame = self:get_frame(player)
self:raise_event('on_player_toggle',player,frame,visible)
end)
LeftFrames.frames[self.name] = self
@@ -187,9 +184,7 @@ function LeftFrames._prototype:_internal_draw(player)
direction=self.direction
}
if self.events.on_draw then
self.events.on_draw(player,frame)
end
self:raise_event('on_creation',player,frame)
if not self.open_by_default then
frame.visible = false
@@ -240,11 +235,9 @@ end
-- @tparam LuaPlayer player 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
if self:raise_event('on_update',player,frame) == 0 then
frame.clear()
self.events.on_draw(player,frame)
self:raise_event('on_creation',player,frame)
end
end
@@ -262,9 +255,7 @@ end
function LeftFrames._prototype:redraw(player)
local frame = self:get_frame(player)
frame.clear()
if self.events.on_draw then
self.events.on_draw(player,frame)
end
self:raise_event('on_creation',player,frame)
end
--- Redraws the frame for all players, see redraw
@@ -297,10 +288,7 @@ Buttons.new_button()
for _,define in pairs(LeftFrames.frames) do
local frame = LeftFrames.get_frame(define.name,player)
frame.visible = false
if define.events.on_player_toggle then
define.events.on_player_toggle(player,frame,false)
end
define:raise_event('on_player_toggle',player,frame,false)
end
element.visible = false
end)

View File

@@ -12,10 +12,11 @@
PopupFrames._prototype:open(player,open_time,...) --- Opens this define for a player, can be given open time and any other params for the draw function
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
local Event = require 'utils.event'
local ProgressBar = require 'expcore.gui.progress-bar'
local Button = require 'expcore.gui.buttons'
local ProgressBar = require 'expcore.gui.elements.progress-bar'
local Button = require 'expcore.gui.elements.buttons'
local mod_gui = require 'mod-gui'
local Color = require 'resources.color_presets'
local Global = require 'utils.global'
@@ -25,8 +26,8 @@ local PopupFrames = {
popup_flow_name = Gui.uid_name(),
main_frame_name = Gui.uid_name(),
close_frame_name = Gui.uid_name(),
_prototype = Gui._prototype_factory{
on_draw = Gui._event_factory('on_draw')
_prototype = Prototype.extend{
on_creation = Prototype.event
}
}
Global.register(PopupFrames.paused_popups,function(tbl)
@@ -120,20 +121,16 @@ end)
-- @tparam[opt] string name the optional debug name that can be added
-- @treturn table the new popup frame define
function PopupFrames.new_popup(name)
local self = Gui._define_factory(PopupFrames._prototype)
local self = Gui.new_define(PopupFrames._prototype,name)
self.draw_data.type = 'flow'
self.draw_data.direction = 'vertical'
if name then
self:debug_name(name)
end
local mt = getmetatable(self)
mt.__call = function(tbl,player,open_time,...)
return tbl:open(player,open_time,...)
end
self.post_draw = function(element,maximum,...)
self:on_draw(function(player,element,maximum,...)
-- main content frame
local frame = element.add{
type='flow',
@@ -172,11 +169,8 @@ function PopupFrames.new_popup(name)
close_button_style.height = 20
-- event trigger to draw the gui content
if self.events.on_draw then
local player = Game.get_player_by_index(element.player_index)
self.events.on_draw(player,frame,...)
end
end
self:raise_event('on_creation',player,frame,...)
end)
return self
end

View File

@@ -14,8 +14,8 @@
Toolbar.add_button(button) --- Adds an existing buttton to the toolbar
Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return
]]
local Buttons = require 'expcore.gui.buttons'
local Gui = require 'expcore.gui.core'
local Buttons = require 'expcore.gui.elements.buttons'
local Roles = require 'expcore.roles'
local Event = require 'utils.event'
local Game = require 'utils.game'

View File

@@ -16,12 +16,7 @@
Note that all event handlers will include event.player as a valid player and that if the player or the
element is not valid then the callback will not be run.
>>>> Interal factory functions
There are a few factory function that are used by the class definations the use of these function are important to
know about but should only be used when making a new class deination rather than an element defination. See one of
the existing class definations for an example of when to use these.
>>>> Basic prototype functions
>>>> Basic prototype functions (see expcore.gui.prototype)
Using a class defination you can create a new element dinfation in our examples we will be using the checkbox.
local checkbox_example = Gui.new_checkbox()
@@ -74,14 +69,14 @@
return global.checkbox_example_allow_post_auth
end)
>>>> Using store
>>>> Using store (see expcore.gui.prototype and expcore.gui.instances)
A powerful assept of this gui system is allowing an automatic store for the state of a gui element, this means that when a gui is closed and re-opened
the elements which have a store will retain they value even if the element was previously destroied. The store is not limited to only per player and can
be catergorised by any method you want such as one that is shared between all players or by all players on a force. Using a method that is not limited to
one player means that when one player changes the state of the element it will be automaticlly updated for all other player (even if the element is already drawn)
and so this is a powerful and easy way to sync gui elements.
-- note the example below is the same as checkbox_example:add_store(Gui.player_store)
-- note the example below is the same as checkbox_example:add_store(Gui.categorize_by_player)
checkbox_example:add_store(function(element)
local player = Game.get_player_by_index(element.player_index)
return player.force.name
@@ -89,7 +84,7 @@
Of course this tool is not limited to only player interactions; the current satate of a define can be gotten using a number of methods and the value can
even be updated by the script and have all instances of the element define be updated. When you use a category then we must give a category to the get
and set functions; in our case we used Gui.player_store which uses the player's name as the category which is why 'Cooldude2606' is given as a argument,
and set functions; in our case we used Gui.categorize_by_player which uses the player's name as the category which is why 'Cooldude2606' is given as a argument,
if we did not set a function for add_store then all instances for all players have the same value and so a category is not required.
checkbox_example:get_store('Cooldude2606')
@@ -112,333 +107,55 @@
Gui.new_checkbox()
:set_caption('Example Checkbox')
:set_tooltip('Example checkbox')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Example checkbox is now: '..tostring(value))
end)
>>>> Functions
Gui._prototype_factory(tbl) --- Used internally to create new prototypes for element defines
Gui._event_factory(name) --- Used internally to create event handler adders for element defines
Gui._store_factory(callback) --- Used internally to create store adders for element defines
Gui._sync_store_factory(callback) --- Used internally to create synced store adders for element defines
Gui._define_factory(prototype) --- Used internally to create new element defines from a class prototype
Gui._prototype:uid() --- Gets the uid for the element define
Gui._prototype:debug_name(name) --- Sets a debug alias for the define
Gui._prototype:set_caption(caption) --- Sets the caption for the element define
Gui._prototype:set_tooltip(tooltip) --- Sets the tooltip for the element define
Gui._prototype:set_style(style,callback) --- Sets the style for the element define
Gui._prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Gui._prototype:on_element_update(callback) --- Add a hander to run on the general value update event, different classes will handle this event differently
Gui._prototype:set_pre_authenticator(callback) --- Sets an authenticator that blocks the draw function if check fails
Gui._prototype:set_post_authenticator(callback) --- Sets an authenticator that disables the element if check fails
Gui._prototype:draw_to(element) --- Draws the element using what is in the draw_data table, allows use of authenticator if present, registers new instances if store present
Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype
Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to
Gui._prototype:add_store(categorize) --- Adds a store location for the define that will save the state of the element, categorize is a function that returns a string
Gui._prototype:add_sync_store(location,categorize) --- Adds a store location for the define that will sync between games, categorize is a function that returns a string
Gui._prototype:on_store_update(callback) --- Adds a event callback for when the store changes are other events are not gauenteted to be raised
Gui.player_store(element) --- A categorize function to be used with add_store, each player has their own value
Gui.force_store(element) --- A categorize function to be used with add_store, each force has its own value
Gui.surface_store(element) --- A categorize function to be used with add_store, each surface has its own value
Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value
Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value
Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value
Gui._prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Gui._prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Gui.get_store(name,category) --- Gets the value that is stored for a given element define, category needed if categorize function used
Gui.set_store(name,category,value) --- Sets the value stored for a given element define, category needed if categorize function used
Gui.toggle_enable(element) --- Will toggle the enabled state of an element
Gui.toggle_enabled(element) --- Will toggle the enabled state of an element
Gui.toggle_visible(element) --- Will toggle the visiblity of an element
Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element
Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style
Gui.create_right_align(element,flow_name) --- Allows the creation of a right align flow to place elements into
Gui.create_alignment(element,flow_name) --- Allows the creation of a right align flow to place elements into
Gui.destory_if_valid(element) --- Destroies an element but tests for it being present and valid first
]]
local Gui = require 'utils.gui'
local Game = require 'utils.game'
local Store = require 'expcore.store'
local Instances = require 'expcore.gui.instances'
Gui._prototype = {} -- Stores the base prototype of all element defines
Gui.classes = {} -- Stores the class definations used to create element defines
Gui.defines = {} -- Stores the indivdual element definations
Gui.names = {} -- Stores debug names to link to gui uids
--- Used internally to create new prototypes for element defines
-- @tparam table tbl table a that will have functions added to it
-- @treturn table the new table with the keys added to it
function Gui._prototype_factory(tbl)
for k,v in pairs(Gui._prototype) do
if not tbl[k] then tbl[k] = v end
end
return tbl
end
--- Used internally to create event handler adders for element defines
-- @tparam string name the key that the event will be stored under, should be the same as the event name
-- @treturn function the function that can be used to add an event handler
function Gui._event_factory(name)
--- Gui._prototype:on_event(callback)
--- Add a hander to run on this event, replace event with the event, different classes have different events
-- @tparam function callback the function that will be called on the event
-- callback param - player LuaPlayer - the player who owns the gui element
-- callback param - element LuaGuiElement - the element that caused the event
-- callback param - value any - (not always present) the updated value for the element
-- callback param - ... any - other class defines may add more params
-- @treturn self the element define to allow chaining
return function(self,callback)
if type(callback) ~= 'function' then
return error('Event callback must be a function',2)
end
self.events[name] = callback
return self
end
end
--- Used internally to create store adders for element defines
-- @tparam callback a callback is called when there is an update to the stored value and stould set the state of the element
-- @treturn function the function that can be used to add a store the the define
function Gui._store_factory(callback)
--- Gui._prototype:add_store(categorize)
--- Adds a store location for the define that will save the state of the element, categorize is a function that returns a string
-- @tparam[opt] function categorize if present will be called to convert an element into a category string
-- categorize param - element LuaGuiElement - the element that needs to be converted
-- categorize return - string - a determistic string that referses to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,categorize)
if self.store then return end
self.store = Store.uid_location()
self.categorize = categorize
Instances.register(self.name,self.categorize)
Store.register(self.store,function(value,category)
if self.events.on_store_update then
self.events.on_store_update(value,category)
end
if Instances.is_registered(self.name) then
Instances.apply_to_elements(self.name,category,function(element)
callback(self,element,value)
end)
end
end)
return self
end
end
--- Used internally to create synced store adders for element defines
-- @tparam callback a callback is called when there is an update to the stored value and stould set the state of the element
-- @treturn function the function that can be used to add a sync store the the define
function Gui._sync_store_factory(callback)
--- Gui._prototype:add_sync_store(location,categorize)
--- Adds a store location for the define that will sync between games, categorize is a function that returns a string
-- @tparam string location string a unique location, unlike add_store a uid location should not be used to avoid migration problems
-- @tparam[opt] function categorize if present will be called to convert an element into a category string
-- categorize param - element LuaGuiElement - the element that needs to be converted
-- categorize return - string - a determistic string that referses to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,location,categorize)
if self.store then return end
if Store.is_registered(location) then
return error('Location for store is already registered: '..location,2)
end
self.store = location
self.categorize = categorize
Instances.register(self.name,self.categorize)
Store.register(self.store,true,function(value,category)
if self.events.on_store_update then
self.events.on_store_update(value,category)
end
if Instances.is_registered(self.name) then
Instances.apply_to_elements(self,category,function(element)
callback(self,element,value)
end)
end
end)
return self
end
end
--- Used internally to create new element defines from a class prototype
--- Used to create new element defines from a class prototype, please use the own given by the class
-- @tparam table prototype the class prototype that will be used for the element define
-- @treturn table the new element define with all functions accessed via __index metamethod
function Gui._define_factory(prototype)
local uid = Gui.uid_name()
function Gui.new_define(prototype,debug_name)
local name = Gui.uid_name()
local define = setmetatable({
name=uid,
events={},
draw_data={
name=uid
debug_name = debug_name,
name = name,
events = {},
draw_data = {
name = name
}
},{
__index=prototype,
__call=function(self,element,...)
return self:draw_to(element,...)
__index = prototype,
__call = function(self,...)
return self:draw_to(...)
end
})
Gui.defines[define.name] = define
return define
end
--- Gets the uid for the element define
-- @treturn string the uid of this element define
function Gui._prototype:uid()
return self.name
end
--- Sets a debug alias for the define
-- @tparam string name the debug name for the element define that can be used to get this element define
-- @treturn self the element define to allow chaining
function Gui._prototype:debug_name(name)
self.debug_name = name
return self
end
--- Sets the caption for the element define
-- @tparam string caption the caption that will be drawn with the element
-- @treturn self the element define to allow chaining
function Gui._prototype:set_caption(caption)
self.draw_data.caption = caption
return self
end
--- Sets the tooltip for the element define
-- @tparam string tooltip the tooltip that will be displayed for this element when drawn
-- @treturn self the element define to allow chaining
function Gui._prototype:set_tooltip(tooltip)
self.draw_data.tooltip = tooltip
return self
end
--- Sets the style for the element define
-- @tparam string style the style that will be used for this element when drawn
-- @tparam[opt] callback function function is called when element is drawn to alter its style
-- @treturn self the element define to allow chaining
function Gui._prototype:set_style(style,callback)
self.draw_data.style = style
self.events.on_style = callback
return self
end
--- Sets the element to be drawn inside a nameless flow, can be given a name using a function
-- @tparam state ?boolean|function when true a padless flow is created to contain the element
-- @treturn self the element define to allow chaining
function Gui._prototype:set_embeded_flow(state)
if state == false or type(state) == 'function' then
self.embeded_flow = state
else
self.embeded_flow = true
end
return self
end
--- Sets an authenticator that blocks the draw function if check fails
-- @tparam function callback the function that will be ran to test if the element should be drawn or not
-- callback param - player LuaPlayer - the player that the element is being drawn to
-- callback param - define_name string - the name of the define that is being drawn
-- callback return - boolean - false will stop the element from being drawn
-- @treturn self the element define to allow chaining
function Gui._prototype:set_pre_authenticator(callback)
if type(callback) ~= 'function' then
return error('Pre authenticator callback must be a function')
end
self.pre_authenticator = callback
return self
end
--- Sets an authenticator that disables the element if check fails
-- @tparam function callback the function that will be ran to test if the element should be enabled or not
-- callback param - player LuaPlayer - the player that the element is being drawn to
-- callback param - define_name string - the name of the define that is being drawn
-- callback return - boolean - false will disable the element
-- @treturn self the element define to allow chaining
function Gui._prototype:set_post_authenticator(callback)
if type(callback) ~= 'function' then
return error('Authenicater callback must be a function')
end
self.post_authenticator = callback
return self
end
--- Draws the element using what is in the draw_data table, allows use of authenticator if present, registers new instances if store present
-- the data with in the draw_data is set up through the use of all the other functions
-- @tparam LuaGuiElement element the element that the define will draw a copy of its self onto
-- @treturn LuaGuiElement the new element that was drawn so styles can be applied
function Gui._prototype:draw_to(element,...)
if element[self.name] then return end
local player = Game.get_player_by_index(element.player_index)
if self.pre_authenticator then
if not self.pre_authenticator(player,self.name) then return end
end
if self.embeded_flow then
local embeded_name
if type(self.embeded_flow) == 'function' then
embeded_name = self.embeded_flow(element,...)
end
element = element.add{type='flow',name=embeded_name}
Gui.set_padding(element)
end
local new_element = element.add(self.draw_data)
if self.events.on_style then
self.events.on_style(new_element.style)
end
if self.post_authenticator then
new_element.enabled = self.post_authenticator(player,self.name)
end
if Instances.is_registered(self.name) then
Instances.add_element(self.name,new_element)
end
if self.post_draw then self.post_draw(new_element,...) end
return new_element
end
--- Gets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @treturn any the value that is stored for this define
function Gui._prototype:get_store(category)
if not self.store then return end
return Store.get(self.store,category)
end
--- Sets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc
-- @treturn boolean true if the value was set
function Gui._prototype:set_store(category,value)
if not self.store then return end
return Store.set(self.store,category,value)
end
--- Sets the value in this elements store to nil, category needed if categorize function used
-- @tparam[opt] string category the category to get such as player name or force name
-- @treturn boolean true if the value was set
function Gui._prototype:clear_store(category)
if not self.store then return end
return Store.clear(self.store,category)
end
--- Gets an element define give the uid, debug name or a copy of the element define
-- @tparam name ?string|table the uid, debug name or define for the element define to get
-- @tparam[opt] boolean internal when true the error trace is one level higher (used internally)
@@ -463,29 +180,10 @@ function Gui.get_define(name,internal)
return define
end
--- Gets the value that is stored for a given element define, category needed if categorize function used
-- @tparam name ?string|table the uid, debug name or define for the element define to get
-- @tparam[opt] string category the category to get the value for
-- @treturn any the value that is stored for this define
function Gui.get_store(name,category)
local define = Gui.get_define(name,true)
return define:get_store(category)
end
--- Sets the value stored for a given element define, category needed if categorize function used
-- @tparam name ?string|table the uid, debug name or define for the element define to set
-- @tparam[opt] string category the category to set the value for
-- @tparam boolean any value the value to set for the define, must be valid for its type ie for a checkbox
-- @treturn boolean true if the value was set
function Gui.set_store(name,category,value)
local define = Gui.get_define(name,true)
return define:get_store(category,value)
end
--- A categorize function to be used with add_store, each player has their own value
-- @tparam LuaGuiElement element the element that will be converted to a string
-- @treturn string the player's name who owns this element
function Gui.player_store(element)
function Gui.categorize_by_player(element)
local player = Game.get_player_by_index(element.player_index)
return player.name
end
@@ -493,7 +191,7 @@ end
--- A categorize function to be used with add_store, each force has its own value
-- @tparam LuaGuiElement element the element that will be converted to a string
-- @treturn string the player's force name who owns this element
function Gui.force_store(element)
function Gui.categorize_by_force(element)
local player = Game.get_player_by_index(element.player_index)
return player.force.name
end
@@ -501,7 +199,7 @@ end
--- A categorize function to be used with add_store, each surface has its own value
-- @tparam LuaGuiElement element the element that will be converted to a string
-- @treturn string the player's surface name who owns this element
function Gui.surface_store(element)
function Gui.categorize_by_surface(element)
local player = Game.get_player_by_index(element.player_index)
return player.surface.name
end
@@ -518,7 +216,7 @@ end
--- Will toggle the enabled state of an element
-- @tparam LuaGuiElement element the gui element to toggle
-- @treturn boolean the new state that the element has
function Gui.toggle_enable(element)
function Gui.toggle_enabled(element)
if not element or not element.valid then return end
if not element.enabled then
element.enabled = true
@@ -568,20 +266,21 @@ function Gui.set_padding_style(style,up,down,left,right)
style.right_padding = right or 0
end
--- Allows the creation of a right align flow to place elements into
-- @tparam LuaGuiElement element the element to add this flow to,
-- @tparam[opt] string flow_name the name of the flow can be nil
-- @treturn LuaGuiElement the flow that was created
function Gui.create_right_align(element,flow_name)
local right_flow =
element.add{
name=flow_name,
type='flow'
}
Gui.set_padding(right_flow,1,1,2,2)
right_flow.style.horizontal_align = 'right'
right_flow.style.horizontally_stretchable = true
return right_flow
--- Allows the creation of an alignment flow to place elements into
-- @tparam LuaGuiElement element the element to add this alignment into
-- @tparam[opt] string name the name to use for the alignment
-- @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in this flow
-- @tparam[opt='center'] string vertical_align the vertical alignment of the elements in this flow
-- @treturn LuaGuiElement the new flow that was created
function Gui.create_alignment(element,name,horizontal_align,vertical_align)
local flow = element.add{name=name,type='flow'}
local style = flow.style
Gui.set_padding(flow,1,1,2,2)
style.horizontal_align = horizontal_align or 'right'
style.vertical_align = vertical_align or 'center'
style.horizontally_stretchable =style.horizontal_align ~= 'center'
style.vertically_stretchable = style.vertical_align ~= 'center'
return flow
end
--- Destroies an element but tests for it being present and valid first

View File

@@ -15,12 +15,14 @@
]]
local mod_gui = require 'mod-gui'
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Button = {
_prototype=Gui._prototype_factory{
on_click = Gui._event_factory('on_click'),
on_left_click = Gui._event_factory('on_left_click'),
on_right_click = Gui._event_factory('on_right_click'),
_prototype=Prototype.extend{
on_raw_click = Prototype.event,
on_click = Prototype.event,
on_left_click = Prototype.event,
on_right_click = Prototype.event,
}
}
@@ -29,27 +31,26 @@ local Button = {
-- @treturn table the new button element define
function Button.new_button(name)
local self = Gui._define_factory(Button._prototype)
local self = Gui.new_define(Button._prototype,name)
self.draw_data.type = 'button'
self.draw_data.style = mod_gui.button_style
if name then
self:debug_name(name)
end
Gui.on_click(self.name,function(event)
local mouse_button = event.button
local keys = {alt=event.alt,control=event.control,shift=event.shift}
local player,element = event.player,event.element
event.keys = keys
self:raise_event('on_raw_click',event)
if self.post_authenticator then
if not self.post_authenticator(event.player,self.name) then return end
end
if mouse_button == defines.mouse_button_type.left and self.events.on_left_click then
self.events.on_left_click(event.player,event.element)
if mouse_button == defines.mouse_button_type.left then
self:raise_event('on_left_click',player,element)
elseif mouse_button == defines.mouse_button_type.right and self.events.on_right_click then
self.events.on_right_click(event.player,event.element)
self:raise_event('on_right_click',player,element)
end
if self.mouse_button_filter and not self.mouse_button_filter[mouse_button] then return end
@@ -59,9 +60,7 @@ function Button.new_button(name)
end
end
if self.events.on_click then
self.events.on_click(event.player,event.element,event)
end
self:raise_event('on_click',player,element)
end)
return self

View File

@@ -10,7 +10,7 @@
local example_option_set =
Gui.new_option_set('example-option-set',function(value,category)
game.print('Example options set '..category..' is now: '..tostring(value))
end,Gui.player_store)
end,Gui.categorize_by_player)
Then you must register some radiobutton defines and include them in the option set:
@@ -46,43 +46,34 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Store = require 'expcore.store'
local Game = require 'utils.game'
--- Event call for on_checked_state_changed and store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam boolean value the new state of the checkbox
local function event_call(define,element,value)
if define.events.on_element_update then
local player = Game.get_player_by_index(element.player_index)
define.events.on_element_update(player,element,value)
end
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam boolean value the new state of the checkbox
local function store_call(define,element,value)
local function store_update(define,element,value)
element.state = value
event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
define:raise_event('on_element_update',player,element,value)
end
local Checkbox = {
option_sets={},
option_categorize={},
_prototype_checkbox=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_checkbox=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
},
_prototype_radiobutton=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_radiobutton=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -91,21 +82,17 @@ local Checkbox = {
-- @treturn table the new checkbox element define
function Checkbox.new_checkbox(name)
local self = Gui._define_factory(Checkbox._prototype_checkbox)
local self = Gui.new_define(Checkbox._prototype_checkbox,name)
self.draw_data.type = 'checkbox'
self.draw_data.state = false
if name then
self:debug_name(name)
end
self.post_draw = function(element)
self:on_draw(function(player,element)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local state = self:get_store(category,true)
if state then element.state = true end
end
end
end)
Gui.on_checked_state_changed(self.name,function(event)
local element = event.element
@@ -121,8 +108,7 @@ function Checkbox.new_checkbox(name)
self:set_store(category,value)
else
local value = element.state
event_call(self,element,value)
self:raise_event('on_element_update',event.player,element,element.state)
end
end)

View File

@@ -17,40 +17,30 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
--- Event call for on_selection_state_changed and store update
local select_value
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new option for the dropdown
local function event_call(define,element,value)
local function store_update(define,element,value)
select_value(element,value)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_element_update then
define.events.on_element_update(player,element,value)
end
define:raise_event('on_element_update',player,element,value)
if define.option_callbacks and define.option_callbacks[value] then
define.option_callbacks[value](player,element,value)
end
end
local _select_value
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new option for the dropdown
local function store_call(define,element,value)
_select_value(element,value)
event_call(define,element,value)
end
local Dropdown = {
_prototype=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -59,16 +49,11 @@ local Dropdown = {
-- @treturn table the new dropdown element define
function Dropdown.new_dropdown(name)
local self = Gui._define_factory(Dropdown._prototype)
local self = Gui.new_define(Dropdown._prototype,name)
self.draw_data.type = 'drop-down'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
self:on_draw(function(player,element)
if self.dynamic_options then
local player = Game.get_player_by_index(element.player_index)
local dynamic_options = self.dynamic_options(player,element)
local items = element.items
for _,v in pairs(dynamic_options) do
@@ -82,7 +67,7 @@ function Dropdown.new_dropdown(name)
local value = self:get_store(category)
if value then Dropdown.select_value(element,value) end
end
end
end)
Gui.on_selection_state_changed(self.name,function(event)
local element = event.element
@@ -93,7 +78,12 @@ function Dropdown.new_dropdown(name)
self:set_store(category,value)
else
event_call(self,element,value)
local player = event.player
local option_callbacks = self.option_callbacks
self:raise_event('on_element_update',player,element,value)
if option_callbacks and option_callbacks[value] then
option_callbacks[value](player,element,value)
end
end
@@ -176,7 +166,7 @@ function Dropdown.select_value(element,value)
end
end
end
_select_value = Dropdown.select_value
select_value = Dropdown.select_value
--- Returns the currently selected value rather than index
-- @tparam LuaGuiElement element the gui element that you want to get the value of

View File

@@ -12,36 +12,25 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
--- Event call for on_elem_changed and store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new value for the elem button
local function event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_element_update then
define.events.on_element_update(player,element,value)
end
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new value for the elem button
local function store_call(define,element,value)
local function store_update(define,element,value)
element.elem_value = value
event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
define:raise_event('on_element_update',player,element,value)
end
local ElemButton = {
_prototype=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -50,16 +39,10 @@ local ElemButton = {
-- @treturn table the new elem button element define
function ElemButton.new_elem_button(name)
local self = Gui._define_factory(ElemButton._prototype)
local self = Gui.new_define(ElemButton._prototype,name)
self.draw_data.type = 'choose-elem-button'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
local player = Game.get_player_by_index(element.player_index)
self:on_draw(function(player,element)
if type(self.default) == 'function' then
element.elem_value = self.default(player,element)
end
@@ -69,7 +52,7 @@ function ElemButton.new_elem_button(name)
local value = self:get_store(category)
if value then element.elem_value = value end
end
end
end)
Gui.on_elem_changed(self.name,function(event)
local element = event.element
@@ -80,7 +63,7 @@ function ElemButton.new_elem_button(name)
self:set_store(category,value)
else
event_call(self,element,value)
self:raise_event('on_element_update',event.player,element,value)
end
@@ -92,10 +75,7 @@ end
--- Sets the type of the elem button, the type is required so this must be called at least once
-- @tparam string type the type that this elem button is see factorio api
-- @treturn the element define to allow for chaining
function ElemButton._prototype:set_type(type)
self.draw_data.elem_type = type
return self
end
ElemButton._prototype.set_type = Prototype.setter('string','draw_data','elem_type')
--- Sets the default value for the elem button, this may be a function or a string
-- @tparam ?string|function value string a will be a static default and a function will be called when drawn to get the default

View File

@@ -21,6 +21,7 @@
ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggeres, can filter which elements are decremented
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Global = require 'utils.global'
local Game = require 'utils.game'
@@ -29,20 +30,17 @@ local Game = require 'utils.game'
-- @tparam LuaGuiElement element the element that triggered the event
local function event_call(define,element)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_complete then
define.events.on_complete(player,element,function()
define:add_element(element)
define:reset_element(element)
end)
end
define:raise_event('on_complete',player,element,function()
define:add_element(element)
define:reset_element(element)
end)
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam number value the new value for the progress bar
local function store_call(define,element,value)
local function store_update(define,element,value)
if value then
element.value = value
if define.count_down and value <= 0
@@ -55,14 +53,14 @@ end
local ProgressBar = {
unregistered={}, -- elements with no callbacks
independent={}, -- elements with a link to a deinfe
_prototype=Gui._prototype_factory{
-- note both events will recive a reset function that can be used to reset the progress of the element/store
on_complete = Gui._event_factory('on_complete'),
on_store_complete = Gui._event_factory('on_store_complete'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_complete = Prototype.event,
on_store_complete = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
Global.register({
unregistered = ProgressBar.unregistered,
independent = ProgressBar.independent
@@ -182,14 +180,11 @@ end
-- @tparam[opt] string name the optional debug name that can be added
-- @treturn table the new progressbar elemente define
function ProgressBar.new_progressbar(name)
local self = Gui._define_factory(ProgressBar._prototype)
local self = Gui.new_define(ProgressBar._prototype,name)
self.draw_data.type = 'progressbar'
if name then
self:debug_name(name)
end
self.post_draw = function(element,maximum)
self:on_draw(function(player,element,maximum)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
@@ -215,7 +210,7 @@ function ProgressBar.new_progressbar(name)
end
end
end)
return self
end
@@ -263,11 +258,7 @@ local function change_value_prototype(self,amount,category,filter)
if self.count_down and new_value <= 0
or not self.count_down and new_value >= 1 then
self:clear_store(category)
if self.events.on_store_complete then
self.events.on_store_complete(category,reset_store)
end
self:raise_event('on_store_complete',category,reset_store)
return
end

View File

@@ -6,7 +6,6 @@
Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates
Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates
Slider._prototype:use_notches(state) --- Adds notches to the slider
Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider
Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player
Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider
@@ -14,6 +13,7 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Instances = require 'expcore.gui.instances'
local Game = require 'utils.game'
@@ -28,9 +28,7 @@ local function event_call(define,element,value)
local delta = max-min
local percent = delta == 0 and 0 or (value-min)/delta
if define.events.on_element_update then
define.events.on_element_update(player,element,value,percent)
end
define:raise_event('on_element_update',player,element,value,percent)
local category = player.name
if define.categorize then
@@ -46,17 +44,17 @@ end
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam number value the new value for the slider
local function store_call(define,element,value)
local function store_update(define,element,value)
element.slider_value = value
event_call(define,element,value)
end
local Slider = {
_prototype=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -65,15 +63,10 @@ local Slider = {
-- @treturn table the new slider element define
function Slider.new_slider(name)
local self = Gui._define_factory(Slider._prototype)
local self = Gui.new_define(Slider._prototype,name)
self.draw_data.type = 'slider'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
local player = Game.get_player_by_index(element.player_index)
self:on_draw(function(player,element)
local min,max = element.get_slider_minimum(),element.get_slider_maximum()
if type(self.min) == 'function' then
@@ -95,7 +88,7 @@ function Slider.new_slider(name)
if self.auto_label then
self:draw_label(element.parent)
end
end
end)
Gui.on_value_changed(self.name,function(event)
local element = event.element
@@ -115,17 +108,6 @@ function Slider.new_slider(name)
return self
end
--- Adds notches to the slider
-- @tparam[opt] boolean state when true will draw notches onto the slider
function Slider._prototype:use_notches(state)
if state == false then
self.draw_data.style = nil
else
self.draw_data.style = 'notched_slider'
end
return self
end
--- Sets the range of a slider, if not used will use default values for a slider
-- @tparam[opt] number min the minimum value that the slider can take
-- @tparam[opt] number max the maximum value that the slider can take
@@ -164,7 +146,7 @@ function Slider._prototype:draw_label(element)
caption=tostring(math.round(value,2))
}
local categorise = self.categorise or Gui.player_store
local categorise = self.categorise or Gui.categorize_by_player
local category = categorise(new_element)
Instances.unregistered_add_element(name,category,new_element)

View File

@@ -15,42 +15,31 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
--- Event call for on_text_changed and store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new text for the text field
local function event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_element_update then
define.events.on_element_update(player,element,value)
end
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new text for the text field
local function store_call(define,element,value)
local function store_update(define,element,value)
element.text = value
event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
define:raise_event('on_element_update',player,element,value)
end
local Text = {
_prototype_field=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_field=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
},
_prototype_box=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_box=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -59,14 +48,10 @@ local Text = {
-- @treturn table the new text field element define
function Text.new_text_field(name)
local self = Gui._define_factory(Text._prototype_field)
local self = Gui.new_define(Text._prototype_field,name)
self.draw_data.type = 'textfield'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
self:on_draw(function(player,element)
if self.selectable then
element.selectable = true
end
@@ -84,7 +69,7 @@ function Text.new_text_field(name)
local value = self:get_store(category)
if value then element.text = value end
end
end
end)
Gui.on_text_changed(self.name,function(event)
local element = event.element
@@ -95,7 +80,7 @@ function Text.new_text_field(name)
self:set_store(category,value)
else
event_call(self,element,value)
self:raise_event('on_element_update',event.player,element,value)
end

View File

@@ -12,7 +12,7 @@
-- categorise works in the same way as store categorise
-- so the function will worl here but no value is stored only gui elements
Instances.register('score',Gui.force_store)
Instances.register('score',Gui.categorize_by_force)
Then when you draw the new element to a gui you will want to add the element to the group:
@@ -38,7 +38,7 @@
instance group would work when registered vs unregistered:
-- Registered with category
Instances.register('score',Gui.force_store) -- force_store will return the force name of an element
Instances.register('score',Gui.categorize_by_force) -- force_store will return the force name of an element
Instances.add_element('score',new_element) -- the new element is added to the category based on in force
Instances.apply_to_elements('score','player',function(element)
element.caption = '0'

303
expcore/gui/prototype.lua Normal file
View File

@@ -0,0 +1,303 @@
--- Used to create new gui prototypes see elements and concepts
--[[
>>>> Functions
Constructor.event(event_name) --- Creates a new function to add functions to an event handler
Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables
Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define
Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set
Prototype:uid() --- Gets the uid for the element define
Prototype:debug_name(value) --- Sets a debug alias for the define
Prototype:set_caption(value) --- Sets the caption for the element define
Prototype:set_tooltip(value) --- Sets the tooltip for the element define
Prototype:set_style(style,callback) --- Sets the style for the element define
Prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails
Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails
Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element
Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used
]]
local Game = require 'utils.game'
local Store = require 'expcore.store'
local Instances = require 'expcore.gui.instances'
local Constructor = {}
local Prototype = {}
--- Creates a new function to add functions to an event handler
-- @tparam string event_name the name of the event that callbacks will be added to
-- @treturn function the function used to register handlers
function Constructor.event(event_name)
--- Adds a callback as a handler for an event
-- @tparam table self the gui define being acted on
-- @tparam function callback the function that will be added as a handler for the event
-- @treturn table self returned to allowing chaining of functions
return function(self,callback)
if type(callback) ~= 'function' then
return error('Event callback for '..event_name..' must be a function',2)
end
local handlers = self.events[event_name]
if not handlers then
handlers = {}
self.events[event_name] = handlers
end
handlers[#handlers+1] = callback
return self
end
end
--- Extents a prototype with the base functions of all gui prototypes, no metatables
-- @tparam table new_prototype the prototype that you want to add the functions to
-- @treturn table the same prototype but with the new functions added
function Constructor.extend(new_prototype)
for key,value in pairs(Prototype) do
if type(value) == 'table' then
new_prototype[key] = table.deepcopy(value)
else
new_prototype[key] = value
end
end
for key,value in pairs(new_prototype) do
if value == Constructor.event then
new_prototype[key] = Constructor.event(key)
end
end
return new_prototype
end
--- Creates a new function which adds a store to a gui define
-- @tparam boolean sync if the function should create a synced store
-- @tparam function callback the function called when needing to update the value of an element
-- @treturn function the function that will add a store for this define
function Constructor.store(sync,callback)
--- Adds a store for the define that is shared between all instances of the define in the same category, categorize is a function that returns a string
-- @tparam self table the gui define being acted on
-- @tparam[opt] string location a unique location identifier, when omited a uid location will be used, use when sync is set to true
-- @tparam[opt] function categorize function used to determine the category of a LuaGuiElement, when omited all share one single category
-- categorize param - LuaGuiElement element - the element that needs to be converted
-- categorize return - string - a determistic string that referses to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,location,categorize)
if self.store then return end
if not sync then
categorize = location
location = Store.uid_location()
end
if Store.is_registered(location) then
return error('Location for store is already registered: '..location,2)
end
self.store = location
self.categorize = categorize
Instances.register(self.name,self.categorize)
Store.register(self.store,sync,function(value,category)
self:raise_event('on_store_update',value,category)
if Instances.is_registered(self.name) then
Instances.apply_to_elements(self.name,category,function(element)
callback(self,element,value)
end)
end
end)
return self
end
end
--- Creates a setter function that checks the type when a value is set
-- @tparam string value_type the type that the value should be when it is set
-- @tparam string key the key of the define that will be set
-- @tparam[opt] string second_key allows for setting of a key in a sub table
-- @treturn function the function that will check the type and set the value
function Constructor.setter(value_type,key,second_key)
local display_message = 'Gui define '..key..' must be of type '..value_type
if second_key then
display_message = 'Gui define '..second_key..' must be of type '..value_type
end
local locale = false
if value_type == 'locale-string' then
locale = true
value_type = 'table'
end
return function(self,value)
local vtype = type(value)
if vtype ~= value_type and (not locale or vtype ~= 'string') then
error(display_message,2)
end
if second_key then
self[key][second_key] = value
else
self[key] = value
end
return self
end
end
--- Gets the uid for the element define
-- @treturn string the uid of this element define
function Prototype:uid()
return self.name
end
--- Sets a debug alias for the define
-- @tparam string name the debug name for the element define that can be used to get this element define
-- @treturn self the element define to allow chaining
Prototype.debug_name = Constructor.setter('string','debug_name')
--- Sets the caption for the element define
-- @tparam string caption the caption that will be drawn with the element
-- @treturn self the element define to allow chaining
Prototype.set_caption = Constructor.setter('locale-string','draw_data','caption')
--- Sets the tooltip for the element define
-- @tparam string tooltip the tooltip that will be displayed for this element when drawn
-- @treturn self the element define to allow chaining
Prototype.set_tooltip = Constructor.setter('locale-string','draw_data','tooltip')
--- Sets an authenticator that blocks the draw function if check fails
-- @tparam function callback the function that will be ran to test if the element should be drawn or not
-- callback param - LuaPlayer player - the player that the element is being drawn to
-- callback param - string define_name - the name of the define that is being drawn
-- callback return - boolean - false will stop the element from being drawn
-- @treturn self the element define to allow chaining
Prototype.set_pre_authenticator = Constructor.setter('function','pre_authenticator')
--- Sets an authenticator that disables the element if check fails
-- @tparam function callback the function that will be ran to test if the element should be enabled or not
-- callback param - LuaPlayer player - the player that the element is being drawn to
-- callback param - string define_name - the name of the define that is being drawn
-- callback return - boolean - false will disable the element
-- @treturn self the element define to allow chaining
Prototype.set_post_authenticator = Constructor.setter('function','post_authenticator')
--- Registers a callback to the on_draw event
-- @tparam function callback
-- callback param - LuaPlayer player - the player that the element was drawn to
-- callback param - LuaGuiElement element - the element that was drawn
-- callback param - any ... - any other params passed by the draw_to function
Prototype.on_draw = Constructor.event('on_draw')
--- Registers a callback to the on_style_update event
-- @tparam function callback
-- callback param - LuaStyle style - the style that was changed and/or needs changing
Prototype.on_style_update = Constructor.event('on_style_update')
--- Sets the style for the element define
-- @tparam string style the style that will be used for this element when drawn
-- @tparam[opt] callback function function is called when element is drawn to alter its style
-- @treturn self the element define to allow chaining
function Prototype:set_style(style,callback)
self.draw_data.style = style
if callback then
self:on_style_update(callback)
end
return self
end
--- Sets the element to be drawn inside a nameless flow, can be given a name using a function
-- @tparam state ?boolean|function when true a padless flow is created to contain the element
-- @treturn self the element define to allow chaining
function Prototype:set_embeded_flow(state)
if state == false or type(state) == 'function' then
self.embeded_flow = state
else
self.embeded_flow = true
end
return self
end
--- Raises a custom event for this define, any number of params can be given
-- @tparam string event_name the name of the event that you want to raise
-- @tparam any ... any params that you want to pass to the event
-- @treturn number the number of handlers that were registered
function Prototype:raise_event(event_name,...)
local handlers = self.events[event_name]
if handlers then
for _,handler in pairs(handlers) do
handler(...)
end
end
return handlers and #handlers or 0
end
--- The main function for defines, when called will draw an instance of this define to the given element
-- what is drawn is based on the data in draw_data which is set using other functions
-- @tparam LuaGuiElement element the element that the define will draw a instance of its self onto
-- @treturn LuaGuiElement the new element that was drawn
function Prototype:draw_to(element,...)
local name = self.name
if element[name] then return end
local player = Game.get_player_by_index(element.player_index)
if self.pre_authenticator then
if not self.pre_authenticator(player,self.name) then return end
end
if self.embeded_flow then
local embeded_name
if type(self.embeded_flow) == 'function' then
embeded_name = self.embeded_flow(element,...)
end
element = element.add{type='flow',name=embeded_name}
element.style.padding = 0
end
local new_element = element.add(self.draw_data)
self:raise_event('on_style_update',new_element.style)
if self.post_authenticator then
new_element.enabled = self.post_authenticator(player,self.name)
end
if Instances.is_registered(self.name) then
Instances.add_element(self.name,new_element)
end
self:raise_event('on_draw',player,new_element)
return new_element
end
--- Gets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @treturn any the value that is stored for this define
function Prototype:get_store(category)
if not self.store then return end
return Store.get(self.store,category)
end
--- Sets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc
-- @treturn boolean true if the value was set
function Prototype:set_store(category,value)
if not self.store then return end
return Store.set(self.store,category,value)
end
--- Sets the value in this elements store to nil, category needed if categorize function used
-- @tparam[opt] string category the category to get such as player name or force name
-- @treturn boolean true if the value was set
function Prototype:clear_store(category)
if not self.store then return end
return Store.clear(self.store,category)
end
return Constructor

View File

@@ -55,7 +55,7 @@ Gui.new_center_frame('gui-test-open')
return global.show_test_gui
end)
:on_draw(function(player,frame)
:on_creation(function(player,frame)
for test_group_name,test_group in pairs(tests) do
player.print('Starting tests for: '..format_chat_colour(test_group_name,Colors.cyan))
@@ -106,7 +106,7 @@ Gui.new_left_frame('test-left-frame')
end)
:set_open_by_default()
:on_draw(function(_player,frame)
:on_creation(function(_player,frame)
for _,player in pairs(game.connected_players) do
frame.add{
type='label',
@@ -125,7 +125,7 @@ Event.add(defines.events.on_player_left_game,left_frame 'update_all')
local test_popup =
Gui.new_popup('test-popup')
:on_draw(function(player,frame)
:on_creation(function(player,frame)
frame.add{
type='label',
caption=player.name
@@ -225,7 +225,7 @@ local checkbox_force =
Gui.new_checkbox('test-checkbox-store-force')
:set_tooltip('Checkboc store force')
:set_caption('Checkbox Store Force')
:add_store(Gui.force_store)
:add_store(Gui.categorize_by_force)
:on_element_update(function(player,element,state)
player.print('Checkbox store force: '..tostring(state))
end)
@@ -234,7 +234,7 @@ local checkbox_player =
Gui.new_checkbox('test-checkbox-store-player')
:set_tooltip('Checkbox store player')
:set_caption('Checkbox Store Player')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,state)
player.print('Checkbox store player: '..tostring(state))
end)
@@ -265,7 +265,7 @@ local radiobutton_player =
Gui.new_radiobutton('test-radiobutton-store')
:set_tooltip('Radiobutton store')
:set_caption('Radiobutton Store')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,state)
player.print('Radiobutton store: '..tostring(state))
end)
@@ -273,7 +273,7 @@ end)
local radiobutton_option_set =
Gui.new_radiobutton_option_set('gui.test.share',function(value,category)
game.print('Radiobutton option set for: '..category..' is now: '..tostring(value))
end,Gui.player_store)
end,Gui.categorize_by_player)
local radiobutton_option_one =
Gui.new_radiobutton('test-radiobutton-option-one')
@@ -332,7 +332,7 @@ local dropdown_player_static_general =
Gui.new_dropdown('test-dropdown-store-static-general')
:set_tooltip('Dropdown store static general')
:add_options('One','Two','Three','Four')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Dropdown store static general: '..tostring(value))
end)
@@ -360,7 +360,7 @@ end
local dropdown_player_static_case =
Gui.new_dropdown('test-dropdown-store-static-case')
:set_tooltip('Dropdown store static case')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:add_options('One','Two')
:add_option_callback('One',print_option_selected_2)
:add_option_callback('Two',print_option_selected_2)
@@ -388,7 +388,7 @@ Gui.new_dropdown('test-dropdown-store-dynamic')
:add_dynamic(function(player,element)
return table_keys(Colors)
end)
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Dropdown store dynamic: '..tostring(value))
end)
@@ -420,7 +420,7 @@ local list_box_player =
Gui.new_list_box('test-list-box-store')
:set_tooltip('List box store')
:add_options('One','Two','Three','Four')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Dropdown store: '..tostring(value))
end)
@@ -433,7 +433,6 @@ tests["List Boxs"] = {
--[[
Slider Tests
> Local default -- Simple slider with default range
> Local notched -- Simple slider with notches
> Store default -- Slider with default range that stores value between re-draws
> Static range -- Simple slider with a static range
> Dynamic range -- Slider with a dynamic range
@@ -448,18 +447,11 @@ Gui.new_slider('test-slider-local-default')
player.print('Slider local default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
local slider_notched_default =
Gui.new_slider('test-slider-notched-default')
:set_tooltip('Silder notched default')
:use_notches()
:on_element_update(function(player,element,value,percent)
player.print('Slider notched default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
local slider_player_default =
Gui.new_slider('test-slider-store-default')
:set_tooltip('Silder store default')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value,percent)
player.print('Slider store default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
@@ -496,14 +488,13 @@ local label_slider_player =
Gui.new_slider('test-slider-store-label')
:set_tooltip('Silder store label')
:enable_auto_draw_label()
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value,percent)
player.print('Slider store label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
tests.Sliders = {
['Local default']=slider_local_default,
['Local notched']=slider_notched_default,
['Player default']=slider_player_default,
['Static range']=slider_static,
['Dynamic range']=slider_dynamic,
@@ -535,7 +526,7 @@ end)
local text_filed_store =
Gui.new_text_filed('test-text-field-store')
:set_tooltip('Text field store')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Text field store: '..value)
end)
@@ -603,7 +594,7 @@ local elem_store =
Gui.new_elem_button('test-elem-store')
:set_tooltip('Elem store')
:set_type('item')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Elem store: '..value)
end)
@@ -632,7 +623,7 @@ end)
local progressbar_two =
Gui.new_progressbar('test-prog-one')
:set_default_maximum(300)
:add_store(Gui.force_store)
:add_store(Gui.categorize_by_force)
:on_complete(function(player,element,reset_element)
reset_element()
end)

View File

@@ -258,7 +258,7 @@ local function add_player(list_table,player,role_name)
player_name.style.font_color = player.chat_color
-- flow which allows right align for the play time
local time_flow = Gui.create_right_align(list_table,'player-time-'..player.index)
local time_flow = Gui.create_alignment(list_table,'player-time-'..player.index)
-- time given in Xh Ym and is right aligned
local tick = game.tick > 0 and game.tick or 1
@@ -295,7 +295,7 @@ Gui.new_left_frame('gui/player-list')
:set_tooltip{'player-list.main-tooltip'}
:set_open_by_default()
:set_direction('vertical')
:on_draw(function(player,element)
:on_creation(function(player,element)
local list_table,action_bar = generate_container(player,element)
generate_action_bar(player,action_bar)

View File

@@ -163,7 +163,7 @@ local function create_section(container,section_name,table_size)
}
--- Right aligned button to toggle the section
local expand_flow = Gui.create_right_align(header,section_name)
local expand_flow = Gui.create_alignment(header,section_name)
toggle_section(expand_flow)
--- The area which contains the section content
@@ -272,7 +272,7 @@ local function create_label_value_pair(element,data_name,value,tooltip,extra)
tooltip={'rocket-info.data-tooltip-'..data_name,extra}
}
--- Right aligned label to store the data
local right_flow = Gui.create_right_align(element,data_name_extra)
local right_flow = Gui.create_alignment(element,data_name_extra)
right_flow.add{
type='label',
name='label',
@@ -470,7 +470,7 @@ local function generate_progress(player,frame)
}
--- Creates the progress value which is right aligned
local right_flow = Gui.create_right_align(element,silo_name)
local right_flow = Gui.create_alignment(element,silo_name)
right_flow.add{
type='label',
name='label',
@@ -517,7 +517,7 @@ end)
return player.force.rockets_launched > 0
end)
:set_direction('vertical')
:on_draw(function(player,element)
:on_creation(function(player,element)
generate_container(player,element)
generate_stats(player,element)
generate_milestones(player,element)

View File

@@ -142,7 +142,7 @@ local function generate_container(player,element)
}
-- data for the footer
local right_align = Gui.create_right_align(footer,'eta')
local right_align = Gui.create_alignment(footer,'eta')
eta =
right_align.add{
name='label',
@@ -191,7 +191,7 @@ local function add_data_label(element,name,value,secondary,tooltip)
else
-- right aligned number
local right_align = Gui.create_right_align(element,name)
local right_align = Gui.create_alignment(element,name)
local data =
right_align.add{
name='label',
@@ -341,7 +341,7 @@ Gui.new_left_frame('gui/science-info')
:set_sprites('entity/lab')
:set_direction('vertical')
:set_tooltip{'science-info.main-tooltip'}
:on_draw(function(player,element)
:on_creation(function(player,element)
local table, eta = generate_container(player,element)
for _,science_pack in ipairs(config) do

View File

@@ -211,7 +211,7 @@ function generate_task(player,element,task_id)
Gui.set_padding(task_area)
-- if the player can edit then it adds the edit and delete button
local flow = Gui.create_right_align(element,'edit-'..task_id)
local flow = Gui.create_alignment(element,'edit-'..task_id)
local sub_flow = flow.add{type='flow',name=task_id}
edit_task(sub_flow)
@@ -330,7 +330,7 @@ local function generate_container(player,element)
--- Right aligned button to toggle the section
if player_allowed_edit(player) then
local right_align = Gui.create_right_align(header)
local right_align = Gui.create_alignment(header)
add_new_task(right_align)
end
@@ -381,7 +381,7 @@ Gui.new_left_frame('gui/task-list')
:set_direction('vertical')
:set_tooltip{'task-list.main-tooltip'}
:set_open_by_default()
:on_draw(function(player,element)
:on_creation(function(player,element)
local data_table = generate_container(player,element)
local force_name = player.force.name

View File

@@ -254,7 +254,7 @@ local warp_timer =
Gui.new_progressbar()
:set_tooltip{'warp-list.timer-tooltip',config.recharge_time}
:set_default_maximum(math.floor(config.recharge_time*config.update_smothing))
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:set_style(nil,function(style)
style.horizontally_stretchable = true
style.color = Colors.light_blue
@@ -449,7 +449,7 @@ function generate_warp(player,element,warp_id)
Gui.set_padding(warp_area)
-- if the player can edit then it adds the edit and delete button
local flow = Gui.create_right_align(element,'edit-'..warp_id)
local flow = Gui.create_alignment(element,'edit-'..warp_id)
local sub_flow = flow.add{type='flow',name=warp_id}
edit_warp(sub_flow)
@@ -597,7 +597,7 @@ local function generate_container(player,element)
--- Right aligned button to toggle the section
if player_allowed_edit(player) then
local right_align = Gui.create_right_align(header)
local right_align = Gui.create_alignment(header)
add_new_warp(right_align)
end
@@ -637,7 +637,7 @@ Gui.new_left_frame('gui/warp-list')
:set_sprites('item/'..config.default_icon)
:set_tooltip{'warp-list.main-tooltip',config.activation_range}
:set_direction('vertical')
:on_draw(function(player,element)
:on_creation(function(player,element)
local data_table = generate_container(player,element)
local force_name = player.force.name
@@ -655,7 +655,6 @@ end)
local warps = force_warps[force_name] or {}
for _,warp_id in pairs(warps) do
generate_warp(player,data_table,warp_id)
make_warp_tag(warp_id)
end
end)
:on_player_toggle(function(player,element,visible)
@@ -790,4 +789,24 @@ Event.add(defines.events.on_player_created,function(event)
end
end)
local function maintain_tag(event)
local tag = event.tag
local force = event.force
local warps = force_warps[force.name]
if warps then
for _,warp_id in pairs(warps) do
local warp = warp_details[warp_id]
if not warp.tag or not warp.tag.valid or warp.tag == tag then
if event.name == defines.events.on_chart_tag_removed then
warp.tag = nil
end
make_warp_tag(warp_id)
end
end
end
end
Event.add(defines.events.on_chart_tag_modified,maintain_tag)
Event.add(defines.events.on_chart_tag_removed,maintain_tag)
return warp_list