mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-29 20:16:38 +09:00
Revert
This commit is contained in:
128
expcore/gui/elements/buttons.lua
Normal file
128
expcore/gui/elements/buttons.lua
Normal file
@@ -0,0 +1,128 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Buttons.
|
||||
-- Gui class define for buttons and sprite buttons
|
||||
-- @section Buttons
|
||||
|
||||
--[[
|
||||
>>>> Functions
|
||||
Button.new_button(name) --- Creates a new button element define
|
||||
|
||||
Button._prototype:on_click(player,element) --- Registers a handler for when the button is clicked
|
||||
Button._prototype:on_left_click(player,element) --- Registers a handler for when the button is clicked with the left mouse button
|
||||
Button._prototype:on_right_click(player,element) --- Registers a handler for when the button is clicked with the right mouse button
|
||||
|
||||
Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite) --- Adds sprites to a button making it a sprite button
|
||||
Button._prototype:set_click_filter(filter,...) --- Adds a click / mouse button filter to the button
|
||||
Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button
|
||||
|
||||
Other functions present from expcore.gui.core
|
||||
]]
|
||||
local mod_gui = require 'mod-gui' --- @dep mod-gui
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
|
||||
local Button = {
|
||||
_prototype=Prototype.extend{
|
||||
on_raw_click = Prototype.event,
|
||||
on_click = Prototype.event,
|
||||
on_left_click = Prototype.event,
|
||||
on_right_click = Prototype.event,
|
||||
}
|
||||
}
|
||||
|
||||
--- Creates a new button element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new button element define
|
||||
function Button.new_button(name)
|
||||
|
||||
local self = Gui.new_define(Button._prototype,name)
|
||||
self.draw_data.type = 'button'
|
||||
self.draw_data.style = mod_gui.button_style
|
||||
|
||||
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 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:raise_event('on_right_click',player,element)
|
||||
end
|
||||
|
||||
if self.mouse_button_filter and not self.mouse_button_filter[mouse_button] then return end
|
||||
if self.key_button_filter then
|
||||
for key,state in pairs(self.key_button_filter) do
|
||||
if state and not keys[key] then return end
|
||||
end
|
||||
end
|
||||
|
||||
self:raise_event('on_click',player,element)
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds sprites to a button making it a sprite button
|
||||
-- @tparam SpritePath sprite the sprite path for the default sprite for the button
|
||||
-- @tparam[opt] SpritePath hovered_sprite the sprite path for the sprite when the player hovers over the button
|
||||
-- @tparam[opt] SpritePath clicked_sprite the sprite path for the sprite when the player clicks the button
|
||||
-- @treturn self returns the button define to allow chaining
|
||||
function Button._prototype:set_sprites(sprite,hovered_sprite,clicked_sprite)
|
||||
self.draw_data.type = 'sprite-button'
|
||||
self.draw_data.sprite = sprite
|
||||
self.draw_data.hovered_sprite = hovered_sprite
|
||||
self.draw_data.clicked_sprite = clicked_sprite
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a click / mouse button filter to the button
|
||||
-- @tparam table filter ?string|table either a of mouse buttons or the first mouse button to filter, with a table true means allowed
|
||||
-- @tparam[opt] table ... when filter is not a you can add the mouse buttons one after each other
|
||||
-- @treturn self returns the button define to allow chaining
|
||||
function Button._prototype:set_click_filter(filter,...)
|
||||
if type(filter) == 'string' then
|
||||
filter = {[filter]=true}
|
||||
for _,v in pairs({...}) do
|
||||
filter[v] = true
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(filter) do
|
||||
if type(v) == 'string' then
|
||||
filter[k] = defines.mouse_button_type[v]
|
||||
end
|
||||
end
|
||||
|
||||
self.mouse_button_filter = filter
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a control key filter to the button
|
||||
-- @tparam table filter ?string|table either a of control keys or the first control keys to filter, with a table true means allowed
|
||||
-- @tparam[opt] table ... when filter is not a you can add the control keys one after each other
|
||||
-- @treturn self returns the button define to allow chaining
|
||||
function Button._prototype:set_key_filter(filter,...)
|
||||
if type(filter) == 'string' then
|
||||
filter = {[filter]=true}
|
||||
for _,v in pairs({...}) do
|
||||
filter[v] = true
|
||||
end
|
||||
end
|
||||
|
||||
self.key_button_filter = filter
|
||||
return self
|
||||
end
|
||||
|
||||
return Button
|
||||
252
expcore/gui/elements/checkbox.lua
Normal file
252
expcore/gui/elements/checkbox.lua
Normal file
@@ -0,0 +1,252 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Checkboxs.
|
||||
-- Gui class define for checkbox and radiobuttons
|
||||
-- @section checkboxs
|
||||
|
||||
--[[
|
||||
>>>> Using an option set
|
||||
An option set is a set of radio buttons where only one of them can be active at a time, this means that when one
|
||||
is clicked all the other ones are set to false, an option set must be defined before hand and will always store
|
||||
its state but is not limited by how it can categorize the store.
|
||||
|
||||
First you must register the store with a name and a update callback, and an optional function for categorize:
|
||||
|
||||
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.categorize_by_player)
|
||||
|
||||
Then you must register some radiobutton defines and include them in the option set:
|
||||
|
||||
local example_option_one =
|
||||
Gui.new_radiobutton()
|
||||
:set_caption('Option One')
|
||||
:add_as_option(example_option_set,'One')
|
||||
|
||||
local example_option_two =
|
||||
Gui.new_radiobutton()
|
||||
:set_caption('Option Two')
|
||||
:add_as_option(example_option_set,'Two')
|
||||
|
||||
Note that these radiobuttons can still have on_element_update events but this may result in a double trigger of events as
|
||||
the option set update is always triggered; also add_store cant be used as the option set acts as the store however get
|
||||
and set store will still work but will effect the option set rather than the individual radiobuttons.
|
||||
|
||||
>>>> Functions
|
||||
Checkbox.new_checkbox(name) --- Creates a new checkbox element define
|
||||
Checkbox._prototype_checkbox:on_element_update(callback) --- Registers a handler for when an element instance updates
|
||||
Checkbox._prototype_checkbox:on_store_update(callback) --- Registers a handler for when the stored value updates
|
||||
|
||||
Checkbox.new_radiobutton(name) --- Creates a new radiobutton element define
|
||||
Checkbox._prototype_radiobutton:on_element_update(callback) --- Registers a handler for when an element instance updates
|
||||
Checkbox._prototype_radiobutton:on_store_update(callback) --- Registers a handler for when the stored value updates
|
||||
Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) --- Adds this radiobutton to be an option in the given option set (only one can be true at a time)
|
||||
|
||||
Checkbox.new_option_set(name,callback,categorize) --- Registers a new option set that can be linked to radiobutton (only one can be true at a time)
|
||||
Checkbox.draw_option_set(name,element) --- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)
|
||||
|
||||
Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobutton in a element to false (unless excluded) and can act recursively
|
||||
|
||||
Other functions present from expcore.gui.core
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
local Store = require 'expcore.store' --- @dep expcore.store
|
||||
local Game = require 'utils.game' --- @dep utils.game
|
||||
|
||||
--- 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_update(define,element,value)
|
||||
element.state = 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=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=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)
|
||||
}
|
||||
}
|
||||
|
||||
--- Creates a new checkbox element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new checkbox element define
|
||||
function Checkbox.new_checkbox(name)
|
||||
|
||||
local self = Gui.new_define(Checkbox._prototype_checkbox,name)
|
||||
self.draw_data.type = 'checkbox'
|
||||
self.draw_data.state = false
|
||||
|
||||
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)
|
||||
|
||||
Gui.on_checked_state_changed(self.name,function(event)
|
||||
local element = event.element
|
||||
|
||||
if self.option_set then
|
||||
local value = Checkbox.option_sets[self.option_set][element.name]
|
||||
local category = self.categorize and self.categorize(element)
|
||||
self:set_store(category,value)
|
||||
|
||||
elseif self.store then
|
||||
local value = element.state
|
||||
local category = self.categorize and self.categorize(element)
|
||||
self:set_store(category,value)
|
||||
|
||||
else
|
||||
self:raise_event('on_element_update',event.player,element,element.state)
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Creates a new radiobutton element define, has all functions checkbox has
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new button element define
|
||||
function Checkbox.new_radiobutton(name)
|
||||
local self = Checkbox.new_checkbox(name)
|
||||
self.draw_data.type = 'radiobutton'
|
||||
|
||||
local mt = getmetatable(self)
|
||||
mt.__index = Checkbox._prototype_radiobutton
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds this radiobutton to be an option in the given option set (only one can be true at a time)
|
||||
-- @tparam string option_set the name of the option set to add this element to
|
||||
-- @tparam string option_name the name of this option that will be used to identify it
|
||||
-- @treturn self the define to allow chaining
|
||||
function Checkbox._prototype_radiobutton:add_as_option(option_set,option_name)
|
||||
self.option_set = option_set
|
||||
self.option_name = option_name or self.name
|
||||
|
||||
Checkbox.option_sets[option_set][self.option_name] = self.name
|
||||
Checkbox.option_sets[option_set][self.name] = self.option_name
|
||||
|
||||
self:add_store(Checkbox.option_categorize[option_set])
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the stored value of the radiobutton or the option set if present
|
||||
-- @tparam string category[opt] the category to get such as player name or force name
|
||||
-- @tparam boolean internal used to prevent stackover flow
|
||||
-- @treturn any the value that is stored for this define
|
||||
function Checkbox._prototype_radiobutton:get_store(category,internal)
|
||||
if not self.store then return end
|
||||
local location = not internal and self.option_set or self.store
|
||||
return Store.get(location,category)
|
||||
end
|
||||
|
||||
--- Sets the stored value of the radiobutton or the option set if present
|
||||
-- @tparam string category[opt] the category to get such as player name or force name
|
||||
-- @tparam boolean value the value to set for this define, must be valid for its type ie for checkbox etc
|
||||
-- @tparam boolean internal used to prevent stackover flow
|
||||
-- @treturn boolean true if the value was set
|
||||
function Checkbox._prototype_radiobutton:set_store(category,value,internal)
|
||||
if not self.store then return end
|
||||
local location = not internal and self.option_set or self.store
|
||||
return Store.set(location,category,value)
|
||||
end
|
||||
|
||||
--- Registers a new option set that can be linked to radiobuttons (only one can be true at a time)
|
||||
-- @tparam string name the name of the option set, must be unique
|
||||
-- @tparam function callback the update callback when the value of the option set changes
|
||||
-- callback param - value string - the new selected option for this option set
|
||||
-- callback param - category string - the category that updated if categorize was used
|
||||
-- @tparam function categorize the function used to convert an element into a string
|
||||
-- @treturn string the name of this option set to be passed to add_as_option
|
||||
function Checkbox.new_option_set(name,callback,categorize)
|
||||
|
||||
Store.register(name,function(value,category)
|
||||
local options = Checkbox.option_sets[name]
|
||||
for opt_name,define_name in pairs(options) do
|
||||
if Gui.defines[define_name] then
|
||||
local define = Gui.get_define(define_name)
|
||||
local state = opt_name == value
|
||||
define:set_store(category,state,true)
|
||||
end
|
||||
end
|
||||
callback(value,category)
|
||||
end)
|
||||
|
||||
Checkbox.option_categorize[name] = categorize
|
||||
Checkbox.option_sets[name] = {}
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
--- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)
|
||||
-- @tparam string name the name of the option set to draw the radiobuttons of
|
||||
-- @tparam LuaGuiElement element the parent element that the radiobuttons will be drawn to
|
||||
function Checkbox.draw_option_set(name,element)
|
||||
if not Checkbox.option_sets[name] then return end
|
||||
local options = Checkbox.option_sets[name]
|
||||
|
||||
for _,option in pairs(options) do
|
||||
if Gui.defines[option] then
|
||||
Gui.defines[option]:draw_to(element)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Sets all radiobutton in a element to false (unless excluded) and can act recursively
|
||||
-- @tparam LuaGuiElement element the root gui element to start setting radio buttons from
|
||||
-- @tparam[opt] table exclude ?string|table the name of the radiobutton to exclude or a of radiobuttons where true will set the state true
|
||||
-- @tparam[opt=false] ?number|boolean recursive if true will recur as much as possible, if a will recur that number of times
|
||||
-- @treturn boolean true if successful
|
||||
function Checkbox.reset_radiobuttons(element,exclude,recursive)
|
||||
if not element or not element.valid then return end
|
||||
exclude = type(exclude) == 'table' and exclude or exclude ~= nil and {[exclude]=true} or {}
|
||||
recursive = type(recursive) == 'number' and recursive-1 or recursive
|
||||
|
||||
for _,child in pairs(element.children) do
|
||||
if child and child.valid and child.type == 'radiobutton' then
|
||||
local state = exclude[child.name] or false
|
||||
local define = Gui.defines[child.name]
|
||||
|
||||
if define then
|
||||
local category = define.categorize and define.categorize(child) or state
|
||||
define:set_store(category,state)
|
||||
|
||||
else
|
||||
child.state = state
|
||||
|
||||
end
|
||||
|
||||
elseif child.children and (type(recursive) == 'number' and recursive >= 0 or recursive == true) then
|
||||
Checkbox.reset_radiobutton(child,exclude,recursive)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return Checkbox
|
||||
187
expcore/gui/elements/dropdown.lua
Normal file
187
expcore/gui/elements/dropdown.lua
Normal file
@@ -0,0 +1,187 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Dropdowns.
|
||||
-- Gui class define for dropdowns and list box
|
||||
-- @section dropdowns
|
||||
|
||||
--[[
|
||||
>>>> Functions
|
||||
Dropdown.new_dropdown(name) --- Creates a new dropdown element define
|
||||
Dropdown.new_list_box(name) --- Creates a new list box element define
|
||||
|
||||
Dropdown._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates
|
||||
Dropdown._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates
|
||||
|
||||
Dropdown._prototype:new_static_options(options,...) --- Adds new static options to the dropdown which will trigger the general callback
|
||||
Dropdown._prototype:new_dynamic_options(callback) --- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options)
|
||||
Dropdown._prototype:add_option_callback(option,callback) --- Adds a case specific callback which will only run when that option is selected (general case still triggered)
|
||||
|
||||
Dropdown.select_value(element,value) --- Selects the option from a dropdown or list box given the value rather than key
|
||||
Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index
|
||||
|
||||
Other functions present from expcore.gui.core
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
local Game = require 'utils.game' --- @dep utils.game
|
||||
|
||||
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_update(define,element,value)
|
||||
select_value(element,value)
|
||||
local player = Game.get_player_by_index(element.player_index)
|
||||
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 Dropdown = {
|
||||
_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)
|
||||
}
|
||||
}
|
||||
|
||||
--- Creates a new dropdown element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new dropdown element define
|
||||
function Dropdown.new_dropdown(name)
|
||||
|
||||
local self = Gui.new_define(Dropdown._prototype,name)
|
||||
self.draw_data.type = 'drop-down'
|
||||
|
||||
self:on_draw(function(player,element)
|
||||
if self.dynamic_options then
|
||||
local dynamic_options = self.dynamic_options(player,element)
|
||||
local items = element.items
|
||||
for _,v in pairs(dynamic_options) do
|
||||
table.insert(items,v)
|
||||
end
|
||||
element.items = items
|
||||
end
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or nil
|
||||
local value = self:get_store(category)
|
||||
if value then Dropdown.select_value(element,value) end
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.on_selection_state_changed(self.name,function(event)
|
||||
local element = event.element
|
||||
local value = Dropdown.get_selected_value(element)
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or value
|
||||
self:set_store(category,value)
|
||||
|
||||
else
|
||||
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
|
||||
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Creates a new list box element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new list box element define
|
||||
function Dropdown.new_list_box(name)
|
||||
local self = Dropdown.new_dropdown(name)
|
||||
self.draw_data.type = 'list-box'
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds new static options to the dropdown which will trigger the general callback
|
||||
-- @tparam table options ?string|table either a of option strings or the first option string, with a table values are the options
|
||||
-- @tparam[opt] table ... when options is not a you can add the options one after each other
|
||||
-- @tparam self the define to allow chaining
|
||||
function Dropdown._prototype:new_static_options(options,...)
|
||||
if type(options) == 'string' then
|
||||
options = {options}
|
||||
for _,v in pairs({...}) do
|
||||
table.insert(options,v)
|
||||
end
|
||||
end
|
||||
|
||||
self.options = options
|
||||
self.draw_data.items = options
|
||||
return self
|
||||
end
|
||||
Dropdown._prototype.add_options = Dropdown._prototype.new_static_options
|
||||
|
||||
--- Adds a callback which should return a table of values to be added as options for the dropdown (appended after static options)
|
||||
-- @tparam function callback the function that will run to get the options for the dropdown
|
||||
-- callback param - player LuaPlayer - the player that the element is being drawn to
|
||||
-- callback param - element LuaGuiElement - the element that is being drawn
|
||||
-- callback return - table - the values of this table will be appended to the static options of the dropdown
|
||||
-- @treturn self the define to allow chaining
|
||||
function Dropdown._prototype:new_dynamic_options(callback)
|
||||
if type(callback) ~= 'function' then
|
||||
return error('Dynamic options callback must be a function',2)
|
||||
end
|
||||
self.dynamic_options = callback
|
||||
return self
|
||||
end
|
||||
Dropdown._prototype.add_dynamic = Dropdown._prototype.new_dynamic_options
|
||||
|
||||
--- Adds a case specific callback which will only run when that option is selected (general case still triggered)
|
||||
-- @tparam string option the name of the option to trigger the callback on; if not already added then will be added as an option
|
||||
-- @tparam function callback the function that will be called when that option is selected
|
||||
-- callback param - player LuaPlayer - the player who owns the gui element
|
||||
-- callback param - element LuaGuiElement - the element which is being effected
|
||||
-- callback param - value string - the new option that has been selected
|
||||
-- @treturn self the define to allow chaining
|
||||
function Dropdown._prototype:add_option_callback(option,callback)
|
||||
if not self.option_callbacks then self.option_callbacks = {} end
|
||||
if not self.options then self.options = {} end
|
||||
|
||||
self.option_callbacks[option] = callback
|
||||
if not table.contains(self.options,option) then
|
||||
table.insert(self.options,option)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Selects the option from a dropdown or list box given the value rather than key
|
||||
-- @tparam LuaGuiElement element the element that contains the option
|
||||
-- @tparam string value the option to select from the dropdown
|
||||
-- @treturn number the key where the value was
|
||||
function Dropdown.select_value(element,value)
|
||||
for k,item in pairs(element.items) do
|
||||
if item == value then
|
||||
element.selected_index = k
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
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
|
||||
-- @treturn string the value that is currently selected
|
||||
function Dropdown.get_selected_value(element)
|
||||
local index = element.selected_index
|
||||
return element.items[index]
|
||||
end
|
||||
|
||||
return Dropdown
|
||||
99
expcore/gui/elements/elem-button.lua
Normal file
99
expcore/gui/elements/elem-button.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Elem Buttons.
|
||||
-- Gui class defines for elem buttons
|
||||
-- @section elem-buttons
|
||||
|
||||
--[[
|
||||
>>>> Functions
|
||||
ElemButton.new_elem_button(name) --- Creates a new elem button element define
|
||||
|
||||
ElemButton._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates
|
||||
ElemButton._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates
|
||||
|
||||
ElemButton._prototype:set_type(type) --- Sets the type of the elem button, the type is required so this must be called at least once
|
||||
ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string
|
||||
|
||||
Other functions present from expcore.gui.core
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
local Game = require 'utils.game' --- @dep utils.game
|
||||
|
||||
--- 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_update(define,element,value)
|
||||
element.elem_value = value
|
||||
local player = Game.get_player_by_index(element.player_index)
|
||||
define:raise_event('on_element_update',player,element,value)
|
||||
end
|
||||
|
||||
local ElemButton = {
|
||||
_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)
|
||||
}
|
||||
}
|
||||
|
||||
--- Creates a new elem button element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new elem button element define
|
||||
function ElemButton.new_elem_button(name)
|
||||
|
||||
local self = Gui.new_define(ElemButton._prototype,name)
|
||||
self.draw_data.type = 'choose-elem-button'
|
||||
|
||||
self:on_draw(function(player,element)
|
||||
if type(self.default) == 'function' then
|
||||
element.elem_value = self.default(player,element)
|
||||
end
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or nil
|
||||
local value = self:get_store(category)
|
||||
if value then element.elem_value = value end
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.on_elem_changed(self.name,function(event)
|
||||
local element = event.element
|
||||
local value = element.elem_value
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or value
|
||||
self:set_store(category,value)
|
||||
|
||||
else
|
||||
self:raise_event('on_element_update',event.player,element,value)
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
return self
|
||||
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
|
||||
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
|
||||
-- @treturn the element define to allow for chaining
|
||||
function ElemButton._prototype:set_default(value)
|
||||
self.default = value
|
||||
if type(value) ~= 'function' then
|
||||
self.draw_data[self.draw_data.elem_type] = value
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
return ElemButton
|
||||
390
expcore/gui/elements/progress-bar.lua
Normal file
390
expcore/gui/elements/progress-bar.lua
Normal file
@@ -0,0 +1,390 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Progress Bars.
|
||||
-- Gui element define for progress bars
|
||||
-- @section progress-bars
|
||||
|
||||
--[[
|
||||
>>>> Functions
|
||||
ProgressBar.set_maximum(element,amount,count_down) --- Sets the maximum value that represents the end value of the progress bar
|
||||
ProgressBar.increment(element,amount) --- Increases the value of the progressbar, if a define is given all of its instances have incremented
|
||||
ProgressBar.decrement(element,amount) --- Decreases the value of the progressbar, if a define is given all of its instances have decremented
|
||||
|
||||
ProgressBar.new_progressbar(name) --- Creates a new progressbar element define
|
||||
ProgressBar._prototype:set_maximum(amount,count_down) --- Sets the maximum value that represents the end value of the progress bar
|
||||
ProgressBar._prototype:use_count_down(state) --- Will set the progress bar to start at 1 and trigger when it hits 0
|
||||
ProgressBar._prototype:increment(amount,category) --- Increases the value of the progressbar
|
||||
ProgressBar._prototype:increment_filtered(amount,filter) --- Increases the value of the progressbar, if the filter condition is met, does not work with store
|
||||
ProgressBar._prototype:decrement(amount,category) --- Decreases the value of the progressbar
|
||||
ProgressBar._prototype:decrement_filtered(amount,filter) --- Decreases the value of the progressbar, if the filter condition is met, does not work with store
|
||||
ProgressBar._prototype:add_element(element,maximum) --- Adds an element into the list of instances that will are waiting to complete, does not work with store
|
||||
ProgressBar._prototype:reset_element(element) --- Resets an element, or its store, to be back at the start, either 1 or 0
|
||||
|
||||
ProgressBar._prototype:on_complete(callback) --- Triggers when a progress bar element completes (hits 0 or 1)
|
||||
ProgressBar._prototype:on_complete(callback) --- Triggers when a store value completes (hits 0 or 1)
|
||||
ProgressBar._prototype:event_counter(filter) --- Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented
|
||||
ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
local Global = require 'utils.global' --- @dep utils.global
|
||||
local Game = require 'utils.game' --- @dep utils.game
|
||||
|
||||
--- Event call for when the value is outside the range 0-1
|
||||
-- @tparam table define the define that this is acting on
|
||||
-- @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)
|
||||
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_update(define,element,value)
|
||||
if value then
|
||||
element.value = value
|
||||
if define.count_down and value <= 0
|
||||
or not define.count_down and value >= 1 then
|
||||
event_call(define,element)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local ProgressBar = {
|
||||
unregistered={}, -- elements with no callbacks
|
||||
independent={}, -- elements with a link to a define
|
||||
_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
|
||||
},function(tbl)
|
||||
ProgressBar.unregistered = tbl.unregistered
|
||||
ProgressBar.independent = tbl.independent
|
||||
end)
|
||||
|
||||
--- Gets the define data, cant use Gui.get_define as it would error
|
||||
-- @tparam ?table|string define the define to get
|
||||
-- @treturn table the define or nil
|
||||
local function get_define(define)
|
||||
if type(define) == 'table' then
|
||||
if define.name and Gui.defines[define.name] then
|
||||
return Gui.defines[define.name]
|
||||
end
|
||||
end
|
||||
|
||||
return Gui.defines[define]
|
||||
end
|
||||
|
||||
--- Gets the element data, used when there is no define
|
||||
-- @tparam LuaGuiElement element the element to get the data of
|
||||
-- @treturn table the element data similar to define
|
||||
local function get_element(element)
|
||||
if not element.valid then return end
|
||||
local name = element.player_index..':'..element.index
|
||||
|
||||
if ProgressBar.unregistered[name] then
|
||||
return ProgressBar.unregistered[name]
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets the maximum value that represents the end value of the progress bar
|
||||
-- @tparam ?LuaGuiElement|string element either a gui element or a registered define
|
||||
-- @tparam number amount the amount to have set as the maximum
|
||||
function ProgressBar.set_maximum(element,amount)
|
||||
amount = amount > 0 and amount or error('amount must be greater than 0')
|
||||
|
||||
local define = get_define(element)
|
||||
if define then
|
||||
define:set_default_maximum(amount)
|
||||
|
||||
else
|
||||
local element_data = get_element(element)
|
||||
|
||||
if element_data then
|
||||
element_data.maximum = amount
|
||||
|
||||
else
|
||||
local name = element.player_index..':'..element.index
|
||||
ProgressBar.unregistered[name] = {
|
||||
element=element,
|
||||
maximum=amount or 1
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Increases the value of the progressbar, if a define is given all of its instances have incremented
|
||||
-- @tparam ?LuaGuiElement|string element either a gui element or a registered define
|
||||
-- @tparam[opt=1] number amount the amount to increase the progressbar by
|
||||
function ProgressBar.increment(element,amount)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
|
||||
local define = get_define(element)
|
||||
if define then
|
||||
define:increment(amount)
|
||||
|
||||
else
|
||||
local element_data = get_element(element)
|
||||
|
||||
if element_data then
|
||||
local real_amount = amount/element_data.maximum
|
||||
element.value = element.value + real_amount
|
||||
|
||||
if element.value >= 1 then
|
||||
local name = element.player_index..':'..element.index
|
||||
ProgressBar.unregistered[name] = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Decreases the value of the progressbar, if a define is given all of its instances have decremented
|
||||
-- @tparam ?LuaGuiElement|string element either a gui element or a registered define
|
||||
-- @tparam[opt=1] number amount the amount to decrease the progressbar by
|
||||
function ProgressBar.decrement(element,amount)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
|
||||
local define = get_define(element)
|
||||
if define then
|
||||
define:decrement(amount)
|
||||
|
||||
else
|
||||
local element_data = get_element(element)
|
||||
|
||||
if element_data then
|
||||
local real_amount = amount/element_data.maximum
|
||||
element.value = element.value - real_amount
|
||||
|
||||
if element.value <= 0 then
|
||||
local name = element.player_index..':'..element.index
|
||||
ProgressBar.unregistered[name] = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a new progressbar element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new progressbar element define
|
||||
function ProgressBar.new_progressbar(name)
|
||||
|
||||
local self = Gui.new_define(ProgressBar._prototype,name)
|
||||
self.draw_data.type = 'progressbar'
|
||||
|
||||
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)
|
||||
if not value then
|
||||
value = self.count_down and 1 or 0
|
||||
self:set_store(category,value)
|
||||
end
|
||||
element.value = value
|
||||
|
||||
else
|
||||
if self.count_down then
|
||||
element.value = 1
|
||||
end
|
||||
|
||||
if not ProgressBar.independent[self.name] then
|
||||
ProgressBar.independent[self.name] = {}
|
||||
end
|
||||
|
||||
table.insert(ProgressBar.independent[self.name],{
|
||||
element = element,
|
||||
maximum = maximum
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the maximum value that represents the end value of the progress bar
|
||||
-- @tparam number amount the amount to have set as the maximum
|
||||
-- @treturn table the define to allow chaining
|
||||
function ProgressBar._prototype:set_default_maximum(amount)
|
||||
amount = amount > 0 and amount or error('amount must be greater than 0')
|
||||
self.default_maximum = amount
|
||||
return self
|
||||
end
|
||||
|
||||
--- Will set the progress bar to start at 1 and trigger when it hits 0
|
||||
-- @tparam[opt=true] boolean state when true the bar will start filled, to be used with decrease
|
||||
-- @treturn table the define to allow chaining
|
||||
function ProgressBar._prototype:use_count_down(state)
|
||||
if state == false then
|
||||
self.count_down = false
|
||||
else
|
||||
self.count_down = true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Main logic for changing the value of a progress bar, this only applies when its a registered define
|
||||
-- @tparam table self the define that is being changed
|
||||
-- @tparam number amount the amount which it is being changed by, may be negative
|
||||
-- @tparam[opt] string category the category to use with store
|
||||
-- @tparam[opt] function filter when given the filter must return true for the value of the element to be changed
|
||||
local function change_value_prototype(self,amount,category,filter)
|
||||
|
||||
local function reset_store()
|
||||
local value = self.count_down and 1 or 0
|
||||
self:set_store(category,value)
|
||||
end
|
||||
|
||||
if self.store then
|
||||
local value = self:get_store(category) or self.count_down and 1 or 0
|
||||
local maximum = self.default_maximum or 1
|
||||
local new_value = value + (amount/maximum)
|
||||
|
||||
self:set_store(category,new_value)
|
||||
|
||||
if self.count_down and new_value <= 0
|
||||
or not self.count_down and new_value >= 1 then
|
||||
self:clear_store(category)
|
||||
self:raise_event('on_store_complete',category,reset_store)
|
||||
return
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if ProgressBar.independent[self.name] then
|
||||
for key,element_data in pairs(ProgressBar.independent[self.name]) do
|
||||
local element = element_data.element
|
||||
if not element or not element.valid then
|
||||
ProgressBar.independent[self.name][key] = nil
|
||||
|
||||
else
|
||||
if not filter or filter(element) then
|
||||
local maximum = element_data.maximum or self.default_maximum or 1
|
||||
element.value = element.value + (amount/maximum)
|
||||
|
||||
if self.count_down and element.value <= 0
|
||||
or not self.count_down and element.value >= 1 then
|
||||
ProgressBar.independent[self.name][key] = nil
|
||||
event_call(self,element)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Increases the value of the progressbar
|
||||
-- @tparam[opt=1] number amount the amount to increase the progressbar by
|
||||
-- @tparam[opt] string category the category that is used with a store
|
||||
function ProgressBar._prototype:increment(amount,category)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
change_value_prototype(self,amount,category)
|
||||
end
|
||||
|
||||
--- Increases the value of the progressbar, if the filter condition is met, does not work with store
|
||||
-- @tparam[opt=1] number amount the amount to increase the progressbar by
|
||||
-- @tparam function filter the filter to be used
|
||||
function ProgressBar._prototype:increment_filtered(amount,filter)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
change_value_prototype(self,amount,nil,filter)
|
||||
end
|
||||
|
||||
--- Decreases the value of the progressbar
|
||||
-- @tparam[opt=1] number amount the amount to decrease the progressbar by
|
||||
-- @tparam[opt] string category the category that is used with a store
|
||||
function ProgressBar._prototype:decrement(amount,category)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
change_value_prototype(self,-amount,category)
|
||||
end
|
||||
|
||||
--- Decreases the value of the progressbar, if the filter condition is met, does not work with store
|
||||
-- @tparam[opt=1] number amount the amount to decrease the progressbar by
|
||||
-- @tparam function filter the filter to be used
|
||||
function ProgressBar._prototype:decrement_filtered(amount,filter)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
change_value_prototype(self,-amount,nil,filter)
|
||||
end
|
||||
|
||||
--- Adds an element into the list of instances that will are waiting to complete, does not work with store
|
||||
-- note use store if you want persistent data, this only stores the elements not the values which they have
|
||||
-- @tparam LuaGuiElement element the element that you want to add into the waiting to complete list
|
||||
-- @tparam[opt] number maximum the maximum for this element if not given the default for this define is used
|
||||
function ProgressBar._prototype:add_element(element,maximum)
|
||||
if self.store then return end
|
||||
if not ProgressBar.independent[self.name] then
|
||||
ProgressBar.independent[self.name] = {}
|
||||
end
|
||||
table.insert(ProgressBar.independent[self.name],{
|
||||
element = element,
|
||||
maximum = maximum
|
||||
})
|
||||
end
|
||||
|
||||
--- Resets an element, or its store, to be back at the start, either 1 or 0
|
||||
-- @tparam LuaGuiElement element the element that you want to reset the progress of
|
||||
function ProgressBar._prototype:reset_element(element)
|
||||
if not element or not element.valid then return end
|
||||
local value = self.count_down and 1 or 0
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or value
|
||||
self:set_store(category,value)
|
||||
else
|
||||
element.value = value
|
||||
end
|
||||
end
|
||||
|
||||
--- Event handler factory that counts up by 1 every time the event triggers, can filter which elements have incremented
|
||||
-- @tparam[opt] function filter when given will use filtered increment
|
||||
-- @treturn function the event handler
|
||||
function ProgressBar._prototype:event_counter(filter)
|
||||
if type(filter) == 'function' then
|
||||
return function()
|
||||
self:increment_filtered(1,filter)
|
||||
end
|
||||
else
|
||||
return function()
|
||||
self:increment()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Event handler factory that counts down by 1 every time the event triggers, can filter which elements have decremented
|
||||
-- @tparam[opt] function filter when given will use filtered decrement
|
||||
-- @treturn function the event handler
|
||||
function ProgressBar._prototype:event_countdown(filter)
|
||||
if type(filter) == 'function' then
|
||||
return function()
|
||||
self:decrement_filtered(1,filter)
|
||||
end
|
||||
else
|
||||
return function()
|
||||
self:decrement()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ProgressBar
|
||||
177
expcore/gui/elements/slider.lua
Normal file
177
expcore/gui/elements/slider.lua
Normal file
@@ -0,0 +1,177 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Sliders.
|
||||
-- Gui class define for sliders
|
||||
-- @section sliders
|
||||
|
||||
--[[
|
||||
>>>> Functions
|
||||
Slider.new_slider(name) --- Creates a new slider element define
|
||||
|
||||
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: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
|
||||
|
||||
Other functions present from expcore.gui.core
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
local Instances = require 'expcore.gui.instances' --- @dep expcore.gui.instances
|
||||
local Game = require 'utils.game' --- @dep utils.game
|
||||
|
||||
--- Event call for on_value_changed and 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 slider
|
||||
local function event_call(define,element,value)
|
||||
local player = Game.get_player_by_index(element.player_index)
|
||||
|
||||
local min,max = element.get_slider_minimum(),element.get_slider_maximum()
|
||||
local delta = max-min
|
||||
local percent = delta == 0 and 0 or (value-min)/delta
|
||||
|
||||
define:raise_event('on_element_update',player,element,value,percent)
|
||||
|
||||
local category = player.name
|
||||
if define.categorize then
|
||||
category = define.categorize(element)
|
||||
end
|
||||
|
||||
Instances.unregistered_get_elements(define.name..'-label',category,function(label)
|
||||
label.caption = tostring(math.round(value,2))
|
||||
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 slider
|
||||
local function store_update(define,element,value)
|
||||
element.slider_value = value
|
||||
event_call(define,element,value)
|
||||
end
|
||||
|
||||
local Slider = {
|
||||
_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)
|
||||
}
|
||||
}
|
||||
|
||||
--- Creates a new slider element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new slider element define
|
||||
function Slider.new_slider(name)
|
||||
|
||||
local self = Gui.new_define(Slider._prototype,name)
|
||||
self.draw_data.type = 'slider'
|
||||
|
||||
self:on_draw(function(player,element)
|
||||
local min,max = element.get_slider_minimum(),element.get_slider_maximum()
|
||||
|
||||
if type(self.min) == 'function' then
|
||||
min = self.min(player,element)
|
||||
end
|
||||
|
||||
if type(self.max) == 'function' then
|
||||
max = self.max(player,element)
|
||||
end
|
||||
|
||||
element.set_slider_minimum_maximum(min,max)
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or nil
|
||||
local value = self:get_store(category)
|
||||
if value then element.slider_value = value end
|
||||
end
|
||||
|
||||
if self.auto_label then
|
||||
self:draw_label(element.parent)
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.on_value_changed(self.name,function(event)
|
||||
local element = event.element
|
||||
local value = element.slider_value
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or value
|
||||
self:set_store(category,value)
|
||||
|
||||
else
|
||||
event_call(self,element,value)
|
||||
|
||||
end
|
||||
|
||||
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
|
||||
-- @treturn self the define to allow chaining
|
||||
function Slider._prototype:set_range(min,max)
|
||||
self.min = min
|
||||
self.max = max
|
||||
|
||||
if type(min) == 'number' then
|
||||
self.draw_data.minimum_value = min
|
||||
end
|
||||
|
||||
if type(max) == 'number' then
|
||||
self.draw_data.maximum_value = max
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- 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
|
||||
-- @tparam LuaGuiElement element the parent element that the label will be drawn to
|
||||
-- @treturn LuaGuiElement the new label element so that styles can be applied
|
||||
function Slider._prototype:draw_label(element)
|
||||
local name = self.name..'-label'
|
||||
if element[name] then return end
|
||||
|
||||
local value = 0
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or value
|
||||
value = self:get_store(category) or 0
|
||||
end
|
||||
|
||||
local new_element = element.add{
|
||||
name=name,
|
||||
type='label',
|
||||
caption=tostring(math.round(value,2))
|
||||
}
|
||||
|
||||
local categorise = self.categorise or Gui.categorize_by_player
|
||||
local category = categorise(new_element)
|
||||
|
||||
Instances.unregistered_add_element(name,category,new_element)
|
||||
|
||||
return new_element
|
||||
end
|
||||
|
||||
--- Enables auto draw of the label, the label will share the same parent element as the slider
|
||||
-- @tparam[opt=true] boolean state when false will disable the auto draw of the label
|
||||
-- @treturn self the define to allow chaining
|
||||
function Slider._prototype:enable_auto_draw_label(state)
|
||||
if state == false then
|
||||
self.auto_label = false
|
||||
else
|
||||
self.auto_label = true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
return Slider
|
||||
149
expcore/gui/elements/text.lua
Normal file
149
expcore/gui/elements/text.lua
Normal file
@@ -0,0 +1,149 @@
|
||||
--[[-- Core Module - Gui
|
||||
@module Gui
|
||||
@alias Prototype
|
||||
]]
|
||||
|
||||
--- Text.
|
||||
-- Gui class define for text fields and text boxes
|
||||
-- @section text
|
||||
|
||||
--[[
|
||||
>>>> Functions
|
||||
Text.new_text_field(name) --- Creates a new text field element define
|
||||
Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates
|
||||
Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates
|
||||
|
||||
Text.new_text_box(name) --- Creates a new text box element define
|
||||
Text._prototype_field:on_element_update(callback) --- Registers a handler for when an element instance updates
|
||||
Text._prototype_field:on_store_update(callback) --- Registers a handler for when the stored value updates
|
||||
Text._prototype_box:set_selectable(state) --- Sets the text box to be selectable
|
||||
Text._prototype_box:set_word_wrap(state) --- Sets the text box to have word wrap
|
||||
Text._prototype_box:set_read_only(state) --- Sets the text box to be read only
|
||||
|
||||
Other functions present from expcore.gui.core
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core' --- @dep expcore.gui.core
|
||||
local Prototype = require 'expcore.gui.prototype' --- @dep expcore.gui.prototype
|
||||
local Game = require 'utils.game' --- @dep utils.game
|
||||
|
||||
--- 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_update(define,element,value)
|
||||
element.text = 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=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=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)
|
||||
}
|
||||
}
|
||||
|
||||
--- Creates a new text field element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new text field element define
|
||||
function Text.new_text_field(name)
|
||||
|
||||
local self = Gui.new_define(Text._prototype_field,name)
|
||||
self.draw_data.type = 'textfield'
|
||||
|
||||
self:on_draw(function(player,element)
|
||||
if self.selectable then
|
||||
element.selectable = true
|
||||
end
|
||||
|
||||
if self.word_wrap then
|
||||
element.word_wrap = true
|
||||
end
|
||||
|
||||
if self.read_only then
|
||||
element.read_only = true
|
||||
end
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or nil
|
||||
local value = self:get_store(category)
|
||||
if value then element.text = value end
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.on_text_changed(self.name,function(event)
|
||||
local element = event.element
|
||||
local value = element.text
|
||||
|
||||
if self.store then
|
||||
local category = self.categorize and self.categorize(element) or value
|
||||
self:set_store(category,value)
|
||||
|
||||
else
|
||||
self:raise_event('on_element_update',event.player,element,value)
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Creates a new text box element define
|
||||
-- @tparam[opt] string name the optional debug name that can be added
|
||||
-- @treturn table the new text box element define
|
||||
function Text.new_text_box(name)
|
||||
local self = Text.new_text_field(name)
|
||||
self.draw_data.type = 'text-box'
|
||||
|
||||
local mt = getmetatable(self)
|
||||
mt.__index = Text._prototype_box
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the text box to be selectable
|
||||
-- @tparam[opt=true] boolean state when false will set the state to false
|
||||
-- @treturn self table the define to allow for chaining
|
||||
function Text._prototype_box:set_selectable(state)
|
||||
if state == false then
|
||||
self.selectable = false
|
||||
else
|
||||
self.selectable = true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the text box to have word wrap
|
||||
-- @tparam[opt=true] boolean state when false will set the state to false
|
||||
-- @treturn self table the define to allow for chaining
|
||||
function Text._prototype_box:set_word_wrap(state)
|
||||
if state == false then
|
||||
self.word_wrap = false
|
||||
else
|
||||
self.word_wrap = true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the text box to be read only
|
||||
-- @tparam[opt=true] boolean state when false will set the state to false
|
||||
-- @treturn self table the define to allow for chaining
|
||||
function Text._prototype_box:set_read_only(state)
|
||||
if state == false then
|
||||
self.read_only = false
|
||||
else
|
||||
self.read_only = true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
return Text
|
||||
Reference in New Issue
Block a user