mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
244 lines
10 KiB
Lua
244 lines
10 KiB
Lua
--- Gui class define for checkbox and radiobuttons
|
|
--[[
|
|
>>>> 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 |