--- @type StdUi local StdUi = LibStub and LibStub('StdUi', true); if not StdUi then return end local module, version = 'Checkbox', 5; if not StdUi:UpgradeNeeded(module, version) then return end ---------------------------------------------------- --- Checkbox ---------------------------------------------------- local CheckboxMethods = { --- Set checkbox state --- --- @param flag boolean --- @param internal boolean - indicates to not run OnValueChanged SetChecked = function(self, flag, internal) self.isChecked = flag; if not internal and self.OnValueChanged then self:OnValueChanged(flag, self.value); end if not flag then self.checkedTexture:Hide(); self.disabledCheckedTexture:Hide(); return end if self.isDisabled then self.checkedTexture:Hide(); self.disabledCheckedTexture:Show(); else self.checkedTexture:Show(); self.disabledCheckedTexture:Hide(); end end, GetChecked = function(self) return self.isChecked; end, SetText = function(self, t) self.text:SetText(t); end, SetValue = function(self, value) self.value = value; end, GetValue = function(self) if self:GetChecked() then return self.value; else return nil; end end, Disable = function(self) self.isDisabled = true; self:SetChecked(self.isChecked); end, Enable = function(self) self.isDisabled = false; self:SetChecked(self.isChecked); end, AutoWidth = function(self) self:SetWidth(self.target:GetWidth() + 15 + self.text:GetWidth()); end }; local CheckboxEvents = { OnClick = function(self) if not self.isDisabled then self:SetChecked(not self:GetChecked()); end end } ---@return CheckButton function StdUi:Checkbox(parent, text, width, height) local checkbox = CreateFrame('Button', nil, parent); checkbox.stdUi = self; checkbox:EnableMouse(true); self:SetObjSize(checkbox, width, height or 20); self:InitWidget(checkbox); checkbox.target = self:Panel(checkbox, 16, 16); checkbox.target.stdUi = self; checkbox.target:SetPoint('LEFT', 0, 0); checkbox.value = true; checkbox.isChecked = false; checkbox.text = self:Label(checkbox, text); checkbox.text:SetPoint('LEFT', checkbox.target, 'RIGHT', 5, 0); checkbox.text:SetPoint('RIGHT', checkbox, 'RIGHT', -5, 0); checkbox.target.text = checkbox.text; -- reference for disabled checkbox.checkedTexture = self:Texture(checkbox.target, nil, nil, [[Interface\Buttons\UI-CheckBox-Check]]); checkbox.checkedTexture:SetAllPoints(); checkbox.checkedTexture:Hide(); checkbox.disabledCheckedTexture = self:Texture(checkbox.target, nil, nil, [[Interface\Buttons\UI-CheckBox-Check-Disabled]]); checkbox.disabledCheckedTexture:SetAllPoints(); checkbox.disabledCheckedTexture:Hide(); for k, v in pairs(CheckboxMethods) do checkbox[k] = v; end self:ApplyBackdrop(checkbox.target); self:HookDisabledBackdrop(checkbox); self:HookHoverBorder(checkbox); if width == nil then checkbox:AutoWidth(); end for k, v in pairs(CheckboxEvents) do checkbox:SetScript(k, v); end return checkbox; end ---------------------------------------------------- --- IconCheckbox ---------------------------------------------------- function StdUi:IconCheckbox(parent, icon, text, width, height, iconSize) iconSize = iconSize or 16 local checkbox = self:Checkbox(parent, text, width, height); checkbox.icon = self:Texture(checkbox, iconSize, iconSize, icon); checkbox.icon:SetPoint('LEFT', checkbox.target, 'RIGHT', 5, 0); checkbox.text:ClearAllPoints(); checkbox.text:SetPoint('LEFT', checkbox.target, 'RIGHT', iconSize + 5, 0); checkbox.text:SetPoint('RIGHT', checkbox, 'RIGHT', -5, 0); return checkbox; end ---------------------------------------------------- --- Radio ---------------------------------------------------- local RadioEvents = { OnClick = function(self) if not self.isDisabled then self:SetChecked(true); end end }; ---@return CheckButton function StdUi:Radio(parent, text, groupName, width, height) local radio = self:Checkbox(parent, text, width, height); radio.checkedTexture = self:Texture(radio.target, nil, nil, [[Interface\Buttons\UI-RadioButton]]); radio.checkedTexture:SetAllPoints(radio.target); radio.checkedTexture:Hide(); radio.checkedTexture:SetTexCoord(0.25, 0.5, 0, 1); radio.disabledCheckedTexture = self:Texture(radio.target, nil, nil, [[Interface\Buttons\UI-RadioButton]]); radio.disabledCheckedTexture:SetAllPoints(radio.target); radio.disabledCheckedTexture:Hide(); radio.disabledCheckedTexture:SetTexCoord(0.75, 1, 0, 1); for k, v in pairs(RadioEvents) do radio:SetScript(k, v); end if groupName then self:AddToRadioGroup(radio, groupName); end return radio; end StdUi.radioGroups = {}; StdUi.radioGroupValues = {}; ---@return CheckButton[] function StdUi:RadioGroup(groupName) if not self.radioGroups[groupName] then self.radioGroups[groupName] = {}; end if not self.radioGroupValues[groupName] then self.radioGroupValues[groupName] = {}; end return self.radioGroups[groupName]; end function StdUi:GetRadioGroupValue(groupName) local group = self:RadioGroup(groupName); for i = 1, #group do local radio = group[i]; if radio:GetChecked() then return radio:GetValue(); end end return nil; end function StdUi:SetRadioGroupValue(groupName, value) local group = self:RadioGroup(groupName); for i = 1, #group do local radio = group[i]; radio:SetChecked(radio.value == value) end return nil; end local radioGroupOnValueChanged = function(radio) radio.notified = true; local group = radio.radioGroup; local groupName = radio.radioGroupName; -- We must get all notifications from group for i = 1, #group do if not group[i].notified then return end end local newValue = radio.stdUi:GetRadioGroupValue(groupName); if radio.stdUi.radioGroupValues[groupName] ~= newValue then radio.OnValueChangedCallback(newValue, groupName); end radio.stdUi.radioGroupValues[groupName] = newValue; for i = 1, #group do group[i].notified = false; end end function StdUi:OnRadioGroupValueChanged(groupName, callback) local group = self:RadioGroup(groupName); for i = 1, #group do local radio = group[i]; radio.OnValueChangedCallback = callback; radio.OnValueChanged = radioGroupOnValueChanged; end return nil; end local RadioGroupEvents = { OnClick = function(radio) for i = 1, #radio.radioGroup do local otherRadio = radio.radioGroup[i]; if otherRadio ~= radio then otherRadio:SetChecked(false); end end end }; function StdUi:AddToRadioGroup(radio, groupName) local group = self:RadioGroup(groupName); tinsert(group, radio); radio.radioGroup = group; radio.radioGroupName = groupName; for k, v in pairs(RadioGroupEvents) do radio:HookScript(k, v); end end StdUi:RegisterModule(module, version);