Last active
April 28, 2020 06:44
-
-
Save callumbrieske/4d0ccec0625ec65bbf0f0730f0abd927 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Generic Radio Group Constructor. | |
local function radio(controls, allowOff) | |
local handlers = {} | |
-- Radio logic function. | |
local function doRadio(control) | |
local currentIdx = 0 | |
for i, v in ipairs(controls) do | |
local initialValue = v.Boolean | |
v.Boolean = v == control and (not allowOff and true or control.Boolean) | |
currentIdx = v == control and i or currentIdx | |
if handlers[i] and (initialValue ~= v.Boolean or v == control) then | |
handlers[i](v, i) | |
end | |
end | |
if handlers["groupHandler"] then | |
handlers["groupHandler"](controls[currentIdx], currentIdx) | |
end | |
end | |
-- Setup control EventHandlers. | |
local currentIdx = false | |
for i, v in ipairs(controls) do | |
v.EventHandler = doRadio | |
currentIdx = (not currentIdx) and v.Boolean and v or currentIdx | |
end | |
doRadio(currentIdx) -- Run logic when initialised. | |
-- Return 'RadioControl' object. | |
return setmetatable({}, { | |
__index = function(t, k) | |
if controls[k] then | |
return setmetatable({}, { | |
__index = function(_, cK) | |
return controls[k][cK] | |
end, | |
__newindex = function(_, cK, cV) | |
if cK == "EventHandler" then | |
if type(cV) == "function" then | |
handlers[k] = cV | |
else | |
error("EventHandler must be a function.", 2) | |
end | |
else | |
controls[k][cK] = cV | |
doRadio(controls[k]) | |
end | |
end | |
}) | |
end | |
end, | |
__newindex = function(_, cK, cV) | |
if cK == "EventHandler" then | |
if type(cV) == "function" then | |
handlers["groupHandler"] = cV | |
else | |
error("EventHandler must be a function.", 2) | |
end | |
else | |
error("Cannot write to radiogroup.", 2) | |
end | |
end, | |
__pairs = ipairs -- Pass a valid iterator back. | |
}) | |
end | |
-- To create a radio group, simply call radio(controls, allowOff). | |
-- 'controls' is a table of controls. This can either be an entire control table, or a table of discrete controls. | |
-- 'allowOff' is a boolean that determines whether clicking an active control will turn it off. | |
-- radio will return a 'RadioGroup' object that contains all the logic for the radio group. | |
-- You can set an 'EventHandler' for the group that will be called when any group member is triggered. | |
-- The group handler signature is (control, index), where 'control' is the control that triggered the event, and 'index' | |
-- is the numerical index within the radio group. | |
-- You can also set individual handlers for each member control that will be called whenever their boolean state changes. | |
-- The signatue for individual handlers is (self, index), self it the control the handler is registered to, and 'index' | |
-- is the numerical index within the radio group. | |
-- This example creates a radio group using all the controls in the 'Radio Controls' control group. | |
MyRadioGroup = radio(Controls["Radio Controls"]) | |
-- We can create an 'EventHandler' for the entire group. This gets called when any control in the group is triggered. | |
MyRadioGroup.EventHandler = function(ctl, index) | |
print("The group is now set to index " .. index, ctl.Boolean) | |
end | |
-- We can also register an individual handler that calls whenever control 3 changes state. | |
MyRadioGroup[3].EventHandler = function(ctl, index) | |
print("You triggered control number 3! Its special!") | |
end | |
-- Once we have created a radio group, it is possible to interact with it as follows: | |
-- It is possible to 'iterate' through the members of a control group. | |
for i, v in ipairs(MyRadioGroup) do | |
print("Control " .. i .. " is in the " .. (v.Boolean and "'on' state." or "'off' state.")) | |
end | |
-- It is also possible to set the state of a control in the radio group. | |
-- Calling this method invokes all register 'EventHandlers' as if the control had been pressed. | |
MyRadioGroup[2].Boolean = true | |
-- If you want to set a control state without invoking the handlers, set the value directly on the control. | |
-- We can also supply a discrete table of controls, instead of an entire control group. | |
-- Additionally, by passing 'true' as the second argument, we enable the 'off' state for the radio group. | |
NewRadioGroup = radio({Controls["Radio 1"], Controls["Radio B"], Controls["Radio three"]}, true) | |
-- We can now attach an handler as before. | |
NewRadioGroup.EventHandler = function(ctl, index) | |
print("The new group is now set to index " .. index, ctl.Boolean) | |
end | |
-- It is also possible to create a radio group, and attach the handler in a single call. | |
-- Note that with this method we dont receive a 'handle', so we are unable to interact with the radio group further. | |
radio(Controls["Inline Radio"]).EventHandler = function(ctl, index) | |
print("The inline group is now set to index " .. index, ctl.Boolean) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment