Added progress bar

This commit is contained in:
Cooldude2606
2019-05-23 22:13:07 +01:00
parent 37cc34b392
commit bda4750871
6 changed files with 413 additions and 1 deletions

View File

@@ -17,7 +17,6 @@ local mod_gui = require 'mod-gui'
local Gui = require 'expcore.gui.core'
local Button = {
config={},
_prototype=Gui._prototype_factory{
on_click = Gui._event_factory('on_click'),
on_left_click = Gui._event_factory('on_left_click'),

View File

@@ -8,6 +8,7 @@
CenterFrames.toggle_frame(player,name,state) --- Toggles if the frame is currently open or not, will open if closed and close if open
CenterFrames.new_frame(permision_name) --- Sets the frame to be the current active gui when opened and closes all other frames
CenterFrames._prototype:on_draw(player,frame) --- Use to draw your elements onto the new frame
CenterFrames._prototype:set_auto_focus(state) --- Sets the frame to be the current active gui when opened and closes all other frames
CenterFrames._prototype:draw_frame(player) --- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame)
CenterFrames._prototype:redraw_frame(player) --- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame)

View File

@@ -42,6 +42,8 @@
LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame
LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw
LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame
LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it
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'

View 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

View File

@@ -5,6 +5,7 @@ local Gui = require 'expcore.gui'
local format_chat_colour,table_keys = ext_require('expcore.common','format_chat_colour','table_keys')
local Colors = require 'resources.color_presets'
local Event = require 'utils.event'
local Store = require 'expcore.store'
local tests = {}
@@ -572,4 +573,51 @@ tests["Elem Buttons"] = {
['Default']=elem_default,
['Function']=elem_function,
['Store']=elem_store
}
--[[
Progress bar tests
> Simple -- Progress bar that fills every 2 seconds
> Store -- Progress bar that fills every 5 seconds with synced value
> Reverce -- Progress bar that decreases every 2 seconds
]]
local progressbar_one =
Gui.new_progressbar('test-prog-one')
:set_maximum(120)
:on_complete(function(player,element,reset_element)
reset_element()
end)
local progressbar_two =
Gui.new_progressbar('test-prog-one')
:set_maximum(300)
:add_store(Gui.force_store)
:on_complete(function(player,element,reset_element)
reset_element()
end)
:on_store_complete(function(category,reset_store)
reset_store()
end)
local progressbar_three =
Gui.new_progressbar('test-prog-one')
:set_maximum(120,true)
:on_complete(function(player,element,reset_element)
reset_element()
end)
Event.add(defines.events.on_tick,function()
progressbar_one:increment()
progressbar_three:decrement()
local categories = Store.get_children(progressbar_two.store)
for category,_ in pairs(categories) do
progressbar_two:increment(1,category)
end
end)
tests["Progress Bars"] = {
['Simple']=progressbar_one,
['Store']=progressbar_two,
['Reverce']=progressbar_three
}

View File

@@ -143,6 +143,29 @@ 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'
Gui.new_progressbar = ProgressBar.new_progressbar
Gui.set_progressbar_maximum = ProgressBar.set_maximum
Gui.increment_progressbar = ProgressBar.increment
Gui.decrement_progressbar = ProgressBar.decrement
--[[
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 Toolbar = require 'expcore.gui.toolbar'
Gui.new_toolbar_button = Toolbar.new_button
Gui.add_button_to_toolbar = Toolbar.add_button
@@ -176,6 +199,8 @@ Gui.classes.left_frames = LeftFrames
LeftFrames._prototype:redraw(player) --- Redraws the frame by calling on_draw, will always clear the frame
LeftFrames._prototype:redraw_all(update_offline) --- Redraws the frame for all players, see redraw
LeftFrames._prototype:on_draw(player,frame) --- Use to draw your elements to the new frame
LeftFrames._prototype:on_update(player,frame) --- Use to edit your frame when there is no need to redraw it
LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
@@ -194,6 +219,7 @@ Gui.classes.center_frames = CenterFrames
CenterFrames.toggle_frame(player,name,state) --- Toggles if the frame is currently open or not, will open if closed and close if open
CenterFrames.new_frame(permision_name) --- Sets the frame to be the current active gui when opened and closes all other frames
CenterFrames._prototype:on_draw(player,frame) --- Use to draw your elements onto the new frame
CenterFrames._prototype:set_auto_focus(state) --- Sets the frame to be the current active gui when opened and closes all other frames
CenterFrames._prototype:draw_frame(player) --- Draws this frame to the player, if already open does nothing (will call on_draw to draw to the frame)
CenterFrames._prototype:redraw_frame(player) --- Draws this frame to the player, if already open it will remove it and redraw it (will call on_draw to draw to the frame)