Skip to content

Instantly share code, notes, and snippets.

@callumbrieske
Last active April 28, 2020 06:44
Show Gist options
  • Save callumbrieske/4d0ccec0625ec65bbf0f0730f0abd927 to your computer and use it in GitHub Desktop.
Save callumbrieske/4d0ccec0625ec65bbf0f0730f0abd927 to your computer and use it in GitHub Desktop.
-- 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