--[[-- 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