mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-28 20:05:22 +09:00
Added progress bar
This commit is contained in:
336
expcore/Gui/progress-bar.lua
Normal file
336
expcore/Gui/progress-bar.lua
Normal file
@@ -0,0 +1,336 @@
|
||||
--- Gui element define for progess bars
|
||||
--[[
|
||||
>>>> Functions
|
||||
ProgressBar.set_maximum(element,amount,start_full) --- 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 are incremented
|
||||
ProgressBar.decrement(element,amount) --- Decreases the value of the progressbar, if a define is given all of its instances are decresed
|
||||
|
||||
ProgressBar.new_progressbar(name) --- Creates a new progressbar element define
|
||||
ProgressBar._prototype:set_maximum(amount,start_full) --- Sets the maximum value that represents the end value of the progress bar
|
||||
ProgressBar._prototype:increment(amount,category) --- Increases the value of the progressbar
|
||||
ProgressBar._prototype:decrement(amount,category) --- Decreases the value of the progressbar
|
||||
ProgressBar._prototype:add_element(element) --- 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() --- Triggers when a progress bar element compeltes (hits 0 or 1)
|
||||
ProgressBar._prototype:on_complete() --- Triggers when a store value completes (hits 0 or 1)
|
||||
ProgressBar._prototype:event_counter() --- Event handler factory that counts up by 1 every time the event triggeres
|
||||
ProgressBar._prototype:event_countdown() --- Event handler factory that counts down by 1 every time the event triggeres
|
||||
]]
|
||||
local Gui = require 'expcore.gui.core'
|
||||
local Global = require 'utils.global'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
--- Event call for when the value is outside the range 0-1
|
||||
-- @tparam define table the define that this is acting on
|
||||
-- @tparam element LuaGuiElement 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
|
||||
end
|
||||
|
||||
--- Store call for store update
|
||||
-- @tparam define table the define that this is acting on
|
||||
-- @tparam element LuaGuiElement the element that triggered the event
|
||||
local function store_call(define,element,value)
|
||||
element.value = value
|
||||
if define.start_full and value <= 0 or not define.start_full and value >= 1 then
|
||||
event_call(define,element)
|
||||
end
|
||||
end
|
||||
|
||||
local ProgressBar = {
|
||||
unregistered={},
|
||||
independent={},
|
||||
_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)
|
||||
}
|
||||
}
|
||||
Global.register({
|
||||
ProgressBar.unregistered,
|
||||
ProgressBar.independent
|
||||
},function(tbl)
|
||||
ProgressBar.unregistered = tbl[1]
|
||||
ProgressBar.independent = tbl[2]
|
||||
end)
|
||||
|
||||
--- Gets the define data, cant use Gui.get_define as it would error
|
||||
-- @tparam define ?table|string 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 element LuaGuiElement
|
||||
-- @treturn table the element data simialr 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]
|
||||
|
||||
else
|
||||
ProgressBar.unregistered[name] = {
|
||||
element=element,
|
||||
maximum=1
|
||||
}
|
||||
return ProgressBar.unregistered[name]
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets the maximum value that represents the end value of the progress bar
|
||||
-- @tparam element ?LuaGuiElement|string either a gui element or a registered define
|
||||
-- @tparam amount number the amount to have set as the maximum
|
||||
-- @tparam[opt=false] start_full boolean when true the bar will start filled, to be used with decrease
|
||||
function ProgressBar.set_maximum(element,amount,start_full)
|
||||
amount = amount > 0 and amount or error('amount must be greater than 0')
|
||||
|
||||
local define = get_define(element)
|
||||
if define then
|
||||
define:set_maximum(amount,start_full)
|
||||
|
||||
else
|
||||
local element_data = get_element(element)
|
||||
|
||||
if element_data then
|
||||
element_data.maximum = amount
|
||||
if start_full then
|
||||
element.value = 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Increases the value of the progressbar, if a define is given all of its instances are incremented
|
||||
-- @tapram element ?LuaGuiElement|string either a gui element or a registered define
|
||||
-- @tparam[opt=1] amount number 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 max = element_data.maximum > 0 and element_data.maximum or 1
|
||||
local real_amount = amount/max
|
||||
element.value = element.value + real_amount
|
||||
|
||||
if element.value >= 1 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Decreases the value of the progressbar, if a define is given all of its instances are decresed
|
||||
-- @tapram element ?LuaGuiElement|string either a gui element or a registered define
|
||||
-- @tparam[opt=1] amount number 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 max = element_data.maximum > 0 and element_data.maximum or 1
|
||||
local real_amount = amount/max
|
||||
element.value = element.value - real_amount
|
||||
|
||||
if element.value <= 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a new progressbar element define
|
||||
-- @tparam[opt] name string 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)
|
||||
self.draw_data.type = 'progressbar'
|
||||
|
||||
if name then
|
||||
self:debug_name(name)
|
||||
end
|
||||
|
||||
self.post_draw = function(element)
|
||||
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.start_full and 1 or 0
|
||||
self:set_store(category,value)
|
||||
end
|
||||
element.value = value
|
||||
|
||||
else
|
||||
if self.start_full then
|
||||
self.value = 1
|
||||
end
|
||||
|
||||
if not ProgressBar.independent[self.name] then
|
||||
ProgressBar.independent[self.name] = {}
|
||||
end
|
||||
|
||||
table.insert(ProgressBar.independent[self.name],element)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the maximum value that represents the end value of the progress bar
|
||||
-- @tparam amount number the amount to have set as the maximum
|
||||
-- @tparam[opt=false] start_full boolean when true the bar will start filled, to be used with decrease
|
||||
function ProgressBar._prototype:set_maximum(amount,start_full)
|
||||
amount = amount > 0 and amount or error('amount must be greater than 0')
|
||||
self.maximum = amount
|
||||
if start_full then
|
||||
self.start_full = true
|
||||
else
|
||||
self.start_full = false
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Main logic for changing the value of a progress bar, this only applies when its a registered define
|
||||
-- @tparam self table the define that is being changed
|
||||
-- @tparam amount number the amount which it is being changed by, may be negative
|
||||
-- @tparam[opt] category string the category to use with store
|
||||
local function change_value_prototype(self,amount,category)
|
||||
|
||||
local function reset_store()
|
||||
local value = self.start_full and 1 or 0
|
||||
local _category = category or value
|
||||
self:set_store(_category,value)
|
||||
end
|
||||
|
||||
if self.store then
|
||||
local value = self:get_store(category) or self.start_full and 1 or 0
|
||||
local new_value = value + amount
|
||||
|
||||
if self.start_full and value <= 0 or not self.start_full and value >= 1 then
|
||||
self:set_store(category)
|
||||
if self.events.on_store_complete then
|
||||
category = category or reset_store
|
||||
self.events.on_store_complete(category,reset_store)
|
||||
end
|
||||
end
|
||||
|
||||
category = category or new_value
|
||||
self:set_store(category,new_value)
|
||||
end
|
||||
|
||||
if ProgressBar.independent[self.name] then
|
||||
for key,element in pairs(ProgressBar.independent[self.name]) do
|
||||
if not element or not element.valid then
|
||||
ProgressBar.independent[self.name][key] = nil
|
||||
else
|
||||
element.value = element.value + amount
|
||||
|
||||
if self.start_full and element.value <= 0 or not self.start_full and element.value >= 1 then
|
||||
ProgressBar.independent[self.name][key] = nil
|
||||
event_call(self,element)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Increases the value of the progressbar
|
||||
-- @tparam[opt=1] amount number the amount to increase the progressbar by
|
||||
-- @tparam[opt] category string the category that is used with a store
|
||||
function ProgressBar._prototype:increment(amount,category)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
local max = self.maximum > 0 and self.maximum or 1
|
||||
local real_amount = amount/max
|
||||
|
||||
change_value_prototype(self,real_amount,category)
|
||||
end
|
||||
|
||||
--- Decreases the value of the progressbar
|
||||
-- @tparam[opt=1] amount number the amount to decrease the progressbar by
|
||||
-- @tparam[opt] category string the category that is used with a store
|
||||
function ProgressBar._prototype:decrement(amount,category)
|
||||
amount = type(amount) == 'number' and amount or 1
|
||||
local max = self.maximum > 0 and self.maximum or 1
|
||||
local real_amount = amount/max
|
||||
|
||||
change_value_prototype(self,-real_amount,category)
|
||||
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 element LuaGuiElement the element that you want to add into the waiting to complete list
|
||||
function ProgressBar._prototype:add_element(element)
|
||||
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)
|
||||
end
|
||||
|
||||
--- Resets an element, or its store, to be back at the start, either 1 or 0
|
||||
-- @tparam element LuaGuiElement 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.start_full 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 triggeres
|
||||
-- @treturn function the event handler
|
||||
function ProgressBar._prototype:event_counter()
|
||||
return function()
|
||||
self:increment()
|
||||
end
|
||||
end
|
||||
|
||||
--- Event handler factory that counts down by 1 every time the event triggeres
|
||||
-- @treturn function the event handler
|
||||
function ProgressBar._prototype:event_countdown()
|
||||
return function()
|
||||
self:decrement()
|
||||
end
|
||||
end
|
||||
|
||||
return ProgressBar
|
||||
Reference in New Issue
Block a user