Compare with Previous | Blame | View Log
local _, class = UnitClass("player") if class ~= "DEATHKNIGHT" then return end local plugin = mRunes:NewModule("Timers", "AceEvent-3.0") plugin.mRunesPlugin = true local AceGUI = LibStub("AceGUI-3.0") local LSM = LibStub("LibSharedMedia-3.0") local BD = LibStub("LibBackdrop-1.0") local FA = LibStub("LibFrameAnchorRegistry-1.0") local UIF local db local LUnitDebuff = UnitDebuff local LUnitBuff = UnitBuff local InCombat = false local ConfigMode = false local Bars = { } local Spells = { { id = "FrostFever", spell = 59921 }, { id = "BloodPlague", spell = 59879 }, { id = "ScarletFever", spell = 81130, talent = { tab = 1, index = 6, }, }, { id = "UnholyBlight", spell = 50536, talent = { tab = 3, index = 13, }, }, { id = "EbonPlague", spell = 65142, talent = { tab = 3, index = 17, } }, { id = "ShadowInfustion", spell = 91342, talent = { tab = 3, index = 10, }, unit = "pet", type = "buff", showStacks = true, }, { id = "DarkTransformation", spell = 93426, talent = { tab = 3, index = 16, }, unit = "pet", type = "buff", }, { id = "FreezingFog", spell = 59052, talent = { tab = 2, index = 11, }, type = "buff", unit = "player", }, { id = "KillingMachine", spell = 51124, talent = { tab = 2, index = 10, }, type = "buff", unit = "player", }, { id = "SuddenDoom", spell = 81340, talent = { tab = 3, index = 18, }, type = "buff", unit = "player", }, { id = "BloodSwarm", spell = 81141, talent = { tab = 1, index = 19, }, type = "buff", unit = "player", }, { id = "RunicCorruption", spell = 51460, talent = { tab = 3, index = 7, }, type = "buff", unit = "player", } } -- local name, icon, tier, column, currentRank, maxRank = GetTalentInfo(tab, i, isnotplayer) local backdrop = { tile = true, tileSize = 16, insets = {}, } plugin.DisplayName = "Timers" plugin.DisplayIcon = [[Interface\Icons\spell_deathknight_bloodplague]] plugin.DisplayOrder = 3 function plugin:OnInitialize() local defaults = { profile = { Enabled = true, Bar = { ["**"] = { Attached = { f = nil, x = 0, y = 0, OffSetY = 0, Point = "TOP", RelPoint = "BOTTOM", StretchToParent = true, }, Enabled = true, DisableOnMissingTalent = true, NotCountMissing = true, RelativeHeight = 1, Color = {1, 1, 1, 1}, Order = 1, ShowName = true, ShowTime = true, Width = 330, Height = 25, BarSpacing = 2, AlphaIncCombat = 1, AlphaOutCombat = 0.0, ShowIcon = true, Texture = "HalD", BorderTexture = "None", BorderWidth = 5, BorderInsets = 0, BorderPadding = 0, BorderColor = {0, 0, 0, 1}, BackgroundColor = {0, 0, 0, 0.5}, Font = "accid", FontSize = 16, FontFlags = "OUTLINE", FontColor = {1, 1, 1, 1}, HorAlign = "LEFT", InternalSpacing = 2, UseGlobals = true, }, ["Global"] = { }, ["FrostFever"] = { Color = {12/255, 146/255, 237/255, 1}, }, ["BloodPlague"] = { Color = {255/255, 0/255, 228/255, 1}, }, ["ScarletFever"] = { Color = {208/255, 77/255, 0/255, 1}, }, ["EbonPlague"] = { Color = {169/255, 0/255, 255/255, 1}, }, ["ShadowInfustion"] = { Color = {8/255, 153/255, 32/255, 1}, }, ["DarkTransformation"] = { Color = {8/255, 153/255, 32/255, 1}, }, ["SuddenDoom"] = { Color = {255/255, 0/255, 69/255, 1}, }, ["UnholyBlight"] = { Color = {115/255, 255/255, 59/255, 1}, }, ["KillingMachine"] = { Color = {54/255, 255/255, 232/255, 1}, }, ["FreezingFog"] = { Color = {0/255, 145/255, 255/255, 1}, }, ["RunicCorruption"] = { Color = {253/255, 36/255, 255/255, 1}, }, ["BloodSwarm"] = { Color = {255/255, 219/255, 0/255, 1}, }, }, } } for i, data in pairs(Spells) do defaults.profile.Bar[data.id] = defaults.profile.Bar[data.id] or {} defaults.profile.Bar[data.id].NotCountMissing = data.NotCountMissing end self.db = mRunes.db:RegisterNamespace(self:GetName(), defaults) self.db.RegisterCallback(self, "OnProfileChanged", "ProfileChanged") self.db.RegisterCallback(self, "OnProfileCopied", "ProfileChanged") self.db.RegisterCallback(self, "OnProfileReset", "ProfileChanged") db = self.db.profile self:SetEnabledState(db.Enabled) UIF = LibStub("LibGUIFactory-1.0"):GetFactory("mRunes") if not self.DiseaseFrame then self:CreateDiseaseFrame() end end function plugin:OnEnable() self:RegisterEvent("UNIT_AURA") self:RegisterEvent("PLAYER_TARGET_CHANGED") self:RegisterEvent("PLAYER_TALENT_UPDATE", "ApplySettings") mRunes.RegisterCallback(self, "EnteringCombat") mRunes.RegisterCallback(self, "LeavingCombat") mRunes.RegisterCallback(self, "ToggleConfigMode") FA.RegisterCallback(self, "FrameUnregistered", "ApplySettings") self:ApplySettings() mRunes:RegisterOnUpdate(self, self.Update) self:UNIT_AURA("UNIT_AURA", "target") self:UNIT_AURA("UNIT_AURA", "pet") end function plugin:OnDisable() mRunes:UnregisterOnUpdate(self, self.Update) mRunes.UnregisterAllCallbacks(self) end function plugin:ProfileChanged(event) db = self.db.profile for i, bar in pairs(Bars) do bar.db = db.Bar[bar.id] end self:ApplySettings() end -- ~~~~~~~~~~~~~~~~~~~~ -- Callbacks ~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~ function plugin:EnteringCombat(event) if UnitExists("target") and UnitReaction("player", "target") < 5 then end InCombat = true end function plugin:LeavingCombat(event) InCombat = false end function plugin:ToggleConfigMode(event, enable) ConfigMode = enable self:ApplySettings() end function plugin:Update() local t = GetTime() for name, bar in pairs(Bars) do local bdb = bar.db if bdb.Enabled then if bar.duration then local dur = bar.expires - t if dur < 0 then bar.expires = nil bar.duration = nil bar.stacks = nil bar:SetValue(0) bar.text:SetText() if not self:ShouldShow(bar) and bar.background:IsShown() then bar.background:Hide() bar.background:SetHeight(0.01) plugin:ReAnchor() end else bar:SetValue(dur / bar.duration) if bdb.UseGlobals then bdb = db.Bar.Global end if bdb.ShowTime and bdb.ShowName then bar.text:SetFormattedText("%s %s: %.1f", bar.SpellName, bar.ShowStacks and ("(%d)"):format(bar.stacks) or "", dur) elseif bdb.ShowTime then bar.text:SetFormattedText("%s %.1f ", bar.ShowStacks and ("(%d)"):format(bar.stacks) or "", dur) elseif bdb.ShowName then bar.text:SetFormattedText("%s %s", bar.SpellName, bar.ShowStacks and ("(%d)"):format(bar.stacks) or "") else bar.text:SetText() end end end end end end -- ~~~~~~~~~~~~~~~~~~~~ -- Events ~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~ function plugin:UNIT_AURA(event, unit) if ConfigMode then return end if unit == "target" or unit == "pet" or unit == "player" then for i, bar in pairs(Bars) do if unit == bar.Unit then local bdb = bar.db local BuffFunc = bar.Type == "debuff" and LUnitDebuff or LUnitBuff local name, rank, icon, count, atype, duration, expires, caster, stealable, shouldConsolidate, spellId = BuffFunc(unit, bar.SpellName) if name and caster == "player" then bar.expires = expires bar.duration = duration bar.stacks = count if self:ShouldShow(bar) and not bar.background:IsShown() then bar.background:Show() bar.background:SetHeight(bdb.Height) self:ReAnchor() end else bar.expires = nil bar.duration = nil bar.stacks = nil bar:SetValue(0) bar.text:SetText() if not self:ShouldShow(bar) and bar.background:IsShown() then bar.background:Hide() bar.background:SetHeight(0.01) self:ReAnchor() end end end end end end function plugin:PLAYER_TARGET_CHANGED(event) self:UNIT_AURA("UNIT_AURA", "target") end -- ~~~~~~~~~~~~~~~~~~~~ -- Settings ~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~ local SortedBars = {} local function SortBars(a, b) return a.db.Order < b.db.Order end function plugin:ApplySettings() for i, b in pairs(Spells) do local bar = Bars[i] local bdb = bar.db local frame = bar.background -- Cannot be global bar:SetStatusBarColor(unpack(bdb.Color)) -- Can be globla if bdb.UseGlobals then bdb = db.Bar.Global end backdrop.insets.left = bdb.BorderInsets backdrop.insets.right = bdb.BorderInsets backdrop.insets.top = bdb.BorderInsets backdrop.insets.bottom = bdb.BorderInsets backdrop.edgeFile = LSM:Fetch("border", bdb.BorderTexture) backdrop.edgeSize = bdb.BorderWidth backdrop.bgFile = LSM:Fetch("background", "Solid") frame:SetBackdrop(backdrop) frame:SetBackdropColor(unpack(bdb.BackgroundColor)) frame:SetBackdropBorderColor(unpack(bdb.BorderColor)) bar:SetStatusBarTexture(LSM:Fetch("statusbar", bdb.Texture)) local leftinset, rightinset = 0, 0 if bdb.HorAlign == "LEFT" then leftinset = bdb.InternalSpacing elseif bdb.HorAlign == "RIGHT" then rightinset = -bdb.InternalSpacing end bar.text:SetPoint("TOPLEFT", leftinset, 0) bar.text:SetPoint("BOTTOMRIGHT", rightinset, 0) bar.text:SetFont(LSM:Fetch("font", bdb.Font), bdb.FontSize, bdb.FontFlags) bar.text:SetTextColor(unpack(bdb.FontColor)) bar.text:SetJustifyH(bdb.HorAlign) bar.text:SetJustifyV("MIDDLE") if ConfigMode then for _, bar in pairs(Bars) do local min, max = bar:GetMinMaxValues() bar.background:SetHeight(bar.db.Height) bar.background:Show() bar:SetValue(math.random(50, 70) / 100) bar.text:SetFormattedText("%s "..(bdb.ShowTime and "%.1f" or ""), bdb.ShowName and bar.SpellName or "", math.random(10, 40 * 100) / 100) end else for _, bar in pairs(Bars) do bar:SetValue(0) end end end self:ReAnchor() if not db.Enabled and self:IsEnabled() then self:Disable() elseif db.Enabled and not self:IsEnabled() then self:Enable() end end function plugin:ReAnchor() for i, b in pairs(Spells) do local bar = Bars[i] local bdb = bar.db local anchor if bdb.Attached.f then anchor = FA:GetAnchor(bdb.Attached.f) end if not anchor then anchor = i == 1 and FA:GetAnchor("mRunesRunicPower") or Bars[i-1].background end local frame = bar.background frame:ClearAllPoints() local offset = (bdb.UseGlobals and db.Bar.Global.Attached.OffSetY or bdb.Attached.OffSetY) if bdb.Attached.Point == "TOPLEFT" or bdb.Attached.Point == "TOPRIGHT" or bdb.Attached.Point == "TOP" then offset = -offset end frame:SetPoint(bdb.Attached.Point, anchor, bdb.Attached.RelPoint, bdb.Attached.x, bdb.Attached.y + offset) if bdb.Attached.StretchToParent then frame:SetPoint("LEFT", anchor) frame:SetPoint("RIGHT", anchor) else frame:SetWidth(bdb.UseGlobals and db.Bar.Globa.Width or bdb.Width) end if bdb.UseGlobals then bdb = db.Bar.Global end if self:ShouldShow(bar) and not bar.background:IsShown() then frame:Show() frame:SetHeight(bdb.Height) elseif not self:ShouldShow(bar) and bar.background:IsShown() then frame:Hide() frame:SetHeight(0.01) elseif self:ShouldShow(bar) then frame:SetHeight(bdb.Height) end bar:ClearAllPoints() if bdb.ShowIcon then bar.icon:ClearAllPoints() bar.icon:SetPoint("TOPLEFT", frame, "TOPLEFT", bdb.BorderPadding, -bdb.BorderPadding) bar.icon:SetHeight(frame:GetHeight() - bdb.BorderPadding * 2) bar.icon:SetWidth(frame:GetHeight() - bdb.BorderPadding * 2) bar.icon:SetTexture(bar.SpellIcon) bar.icon:Show() bar:SetPoint("TOPLEFT", bar.icon, "TOPRIGHT", 2, 0) bar:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -bdb.BorderPadding, bdb.BorderPadding) else bar.icon:Hide() bar:SetPoint("TOPLEFT", frame, bdb.BorderPadding, -bdb.BorderPadding) bar:SetPoint("BOTTOMRIGHT", frame, -bdb.BorderPadding, bdb.BorderPadding) end bar:SetMinMaxValues(0, 1) end end function plugin:ShouldShow(bar) local bdb = bar.db if not bdb.Enabled then return false end if ConfigMode then return true end if bar.Restriction and bdb.DisableOnMissingTalent then if bar.Restriction.type == "TALENT" then local name, icon, tier, column, currentRank, maxRank = GetTalentInfo(bar.Restriction.tab, bar.Restriction.index, false) if not name or currentRank == 0 then return false end end end if bdb.NotCountMissing and not bar.duration then return false end if bar.Unit == "target" and (not InCombat or not UnitExists("target") or UnitReaction("player", "target") > 4)then return false end return true end -- ~~~~~~~~~~~~~~~~~~~~ -- Create Frames ~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~ function plugin:CreateDiseaseFrame() for s, data in pairs(Spells) do local spellID = (type(data.spell) == "table") and data.spell[1] or data.spell local spellName, _, spellIcon = GetSpellInfo(spellID) if spellName then local bar = self:CreateBar(UIParent, data.id, spellName) bar.Spell = spellID bar.SpellName = spellName bar.SpellIcon = spellIcon bar.Unit = data.unit or "target" bar.Type = data.type or "debuff" bar.ShowStacks = data.showStacks bar.NotCountMissing = data.NotCountMissing bar.db = db.Bar[data.id] bar.id = data.id if data.talent then bar.Restriction = { type = "TALENT", tab = data.talent.tab, index = data.talent.index, } end Bars[s] = bar end end end function plugin:CreateBar(parent, BarName, SpellName) local frame = CreateFrame("Frame", "mRunes"..BarName.."Background", parent) local bar = CreateFrame("StatusBar", "mRunes"..BarName.."Bar", frame) --BD:EnhanceBackdrop(frame) bar.background = frame FA:RegisterAnchor("mRunes\001Timers", SpellName, "mRunesTimer"..BarName, frame) local text = bar:CreateFontString(nil, nil, "GameFontNormal") bar.text = text local icon = frame:CreateTexture(nil, "ARTOWORK") icon:SetTexCoord(0.08, 0.92, 0.08, 0.92) bar.icon = icon bar:SetFrameLevel(bar.background:GetFrameLevel() + 1) return bar end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Options ~~~~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ function plugin:GetOptions() return plugin.GetGUI end do local function Callback() plugin:ApplySettings() end local FontFlagList = { ["NONE"] = "None", ["OUTLINE"] = "Outline", ["THICKOUTLINE"] = "Thick Outline", ["MONOCHROME"] = "Monochrome", } local VerticalAlignList = { ["TOP"] = "Top", ["MIDDLE"] = "Middle", ["BOTTOM"] = "Bottom", } local HorizontalAlignList = { ["LEFT"] = "Left", ["CENTER"] = "Center", ["RIGHT"] = "Right", } local TabSelected local LastTabSelected local BarSelected local LastBarSelected local GlobalSettings local BarTabs = {} function plugin:GetGUI() self = plugin local returnGroup = AceGUI:Create("SimpleGroup") returnGroup:SetFullWidth(true) returnGroup:SetLayout("Flow") returnGroup:AddChild(UIF:NewLine(10)) returnGroup:AddChild(UIF:CheckBox("Enabled", db, "Enabled", Callback, nil, 0.33)) wipe(BarTabs) for name, bar in pairs(Bars) do BarTabs[bar.id] = {text = bar.SpellName, value = bar.id, icon = bar.SpellIcon} if not bar.db.UseGlobals then BarTabs[bar.id].text = "** "..bar.SpellName end end BarTabs["1"] = {text = "Global", value = "1"} table.sort(BarTabs, function(a, b) return a.text < b.text end) local tgroup = UIF:DropdownGroup("Spells") tgroup:SetLayout("Flow") returnGroup:AddChild(tgroup) tgroup:SetGroupList(BarTabs) tgroup:SetCallback("OnGroupSelected", BarSelected) tgroup:SetGroup(LastBarSelected or "1") return returnGroup end BarSelected = function(self, event, tab) self:ReleaseChildren() LastBarSelected = tab if tab == "1" then GlobalSettings(self) else local bar for _, b in pairs(Bars) do if b.id == tab then bar = b break end end local title = UIF:Title2(bar.SpellName) title:SetImageSize(30, 30) title:SetImage(bar.SpellIcon) self:AddChild(title) self:AddChild(UIF:CheckBox("Enabled", bar.db, "Enabled", Callback, nil, 0.3)) self:AddChild(UIF:ColorSelect("Color", bar.db, "Color", Callback, true, 0.2)) self:AddChild(UIF:CheckBox("Use globals", bar.db, "UseGlobals", Callback, "Overrides font, texture, name and time settings.", 0.5)) local tgroup = UIF:TabGroup() tgroup:SetTabs( { {text = "Anchoring and Size", value = "anchor"}, {text = "Font", value = "font"}, {text = "Texture and Colors", value = "tex"}, } ) self:AddChild(tgroup) tgroup.userdata.bar = bar tgroup:SetCallback("OnGroupSelected", TabSelected) tgroup:SelectTab(LastSelectedTab or "anchor") end end TabSelected = function(self, event, tab) self:ReleaseChildren() LastSelectedTab = tab local bar = self.userdata.bar local bdb = self.userdata.bar.db if tab == "anchor" then self:AddChild(UIF:Text1("Select a frame to attach to. You can then adjust the relative positioning to that frame via X and Y as well as the anchor points.")) self:AddChild(UIF:CheckBox("Spell Icon", bdb, "ShowIcon", Callback, "Show the icon for the spell on the left side of the bar", 0.5)) local t = AceGUI:Create("FrameAnchorDropdown") t:SetRelativeWidth(0.5) t:SetList(FA:GetAnchors(bar.background)) t:SetLabel("Anchor") t:SetValue(bdb.Attached.f) t:SetCallback("OnValueChanged", function(self, event, cat, name, frame) bdb.Attached.f = cat Callback() end) self:AddChild(t) self:AddChild(UIF:NewLine()) self:AddChild(UIF:Dropdown("Point", bdb.Attached, "Point", Callback, mRunes:GetAnchorList(), 0.5, true)) self:AddChild(UIF:Dropdown("Relative Point", bdb.Attached, "RelPoint", Callback, mRunes:GetAnchorList(), 0.5, true)) self:AddChild(UIF:CheckBox("Stretch to anchor", bdb.Attached, "StretchToParent", function() plugin:ApplySettings() TabSelected(self, event, tab) end, "Will override X-postion and width, and instead stretch the timer to whatever it is anchored to", 1)) local sliderx = UIF:Slider("X", bdb.Attached, "x", -1500, 1500, 0.1, Callback, 0.5) sliderx:SetDisabled(bdb.Attached.StretchToParent) self:AddChild(sliderx) local sliderw = UIF:Slider("Width", bdb, "Width", 5, 1000, 0.1, Callback, 0.5) sliderw:SetDisabled(bdb.Attached.StretchToParent) self:AddChild(sliderw) self:AddChild(UIF:Slider("Y", bdb.Attached, "y", -1500, 1500, 0.1, Callback, 0.5)) self:AddChild(UIF:Slider("Height", bdb, "Height", 5, 200, 0.1, Callback, 0.5)) self:AddChild(UIF:CheckBox("Name", bdb, "ShowName", Callback, "Toggle display of spellname on the bar", 0.5)) self:AddChild(UIF:CheckBox("Time", bdb, "ShowTime", Callback, "Toggle display of remaining time", 0.5)) self:AddChild(UIF:CheckBox("Collapse when missing", bdb, "NotCountMissing", Callback, "Toggle if the bars should collapse and take up no space when the the spell is missing", 0.5)) if bar.Restriction then if bar.Restriction.type == "TALENT" then self:AddChild(UIF:CheckBox("Disable when missing talent", bdb, "DisableOnMissingTalent", Callback, "This will disable this bar if the talent for it is missing", 0.8)) end self:AddChild(UIF:NewLine()) end elseif tab == "font" then self:AddChild(UIF:LSMDropdown("font", "Font", bdb, "Font", Callback, 0.5)) self:AddChild(UIF:Dropdown("Font Flags", bdb, "FontFlags", Callback, FontFlagList, 0.5)) self:AddChild(UIF:ColorSelect("Color", bdb, "FontColor", Callback, false, 0.2)) self:AddChild(UIF:Slider("Size", bdb, "FontSize", 2, 50, 1, Callback, 0.4)) self:AddChild(UIF:Slider("Margin", bdb, "InternalSpacing", 0, 50, 0.1, Callback, 0.4)) self:AddChild(UIF:Dropdown("Horizontal Align", bdb, "HorAlign", Callback, HorizontalAlignList, 0.5)) elseif tab == "tex" then group = UIF:InlineGroup2("Border and Background") self:AddChild(group) group:AddChild(UIF:LSMDropdown("border", "Border texture", bdb, "BorderTexture", Callback, 0.5)) group:AddChild(UIF:LSMDropdown("statusbar", "Bar Texture", bdb, "Texture", Callback, 0.5)) group:AddChild(UIF:ColorSelect("Background Color", bdb, "BackgroundColor", Callback, true, 0.5)) group:AddChild(UIF:ColorSelect("Border color", bdb, "BorderColor", Callback, true, 0.5)) group:AddChild(UIF:Slider("Border Width", bdb, "BorderWidth", 1, 50, 1, Callback, 0.33)) group:AddChild(UIF:Slider("Border Padding", bdb, "BorderPadding", 0, 100, 0.1, Callback, 0.33)) group:AddChild(UIF:Slider("Border Insets", bdb, "BorderInsets", 0, 50, 1, Callback, 0.33)) end self.parent.parent.parent:DoLayout() self.parent.parent.parent:FixScroll() end GlobalSettings = function(self) local bdb = db.Bar.Global self:AddChild(UIF:CheckBox("Name", bdb, "ShowName", Callback, "Toggle display of spellname on the bar", 0.33)) self:AddChild(UIF:CheckBox("Time", bdb, "ShowTime", Callback, "Toggle display of remaining time", 0.32)) self:AddChild(UIF:CheckBox("Spell Icon", bdb, "ShowIcon", Callback, "Show the icon for the spell on the left side of the bar", 0.33)) self:AddChild(UIF:Slider("Height", bdb, "Height", 5, 200, 0.1, Callback, 0.5)) self:AddChild(UIF:Slider("Offset Y", bdb.Attached, "OffSetY", -200, 200, 0.1, Callback, 0.5)) local group = UIF:InlineGroup("Font") self:AddChild(group) group:AddChild(UIF:ColorSelect("Color", bdb, "FontColor", Callback, false, 0.2)) group:AddChild(UIF:Slider("Size", bdb, "FontSize", 2, 50, 1, Callback, 0.8)) group:AddChild(UIF:LSMDropdown("font", "Font", bdb, "Font", Callback, 0.5)) group:AddChild(UIF:Dropdown("Font Flags", bdb, "FontFlags", Callback, FontFlagList, 0.5)) group:AddChild(UIF:Dropdown("Horizontal Align", bdb, "HorAlign", Callback, HorizontalAlignList, 0.5)) group:AddChild(UIF:Slider("Margin", bdb, "InternalSpacing", 0, 50, 0.1, Callback, 0.5)) local group = UIF:InlineGroup("Texture") self:AddChild(group) group:AddChild(UIF:LSMDropdown("border", "Border texture", bdb, "BorderTexture", Callback, 0.5)) group:AddChild(UIF:LSMDropdown("statusbar", "Bar Texture", bdb, "Texture", Callback, 0.5)) group:AddChild(UIF:ColorSelect("Background Color", bdb, "BackgroundColor", Callback, true, 0.5)) group:AddChild(UIF:ColorSelect("Border color", bdb, "BorderColor", Callback, true, 0.5)) group:AddChild(UIF:Slider("Border Width", bdb, "BorderWidth", 1, 50, 1, Callback, 0.33)) group:AddChild(UIF:Slider("Border Padding", bdb, "BorderPadding", 0, 100, 0.1, Callback, 0.33)) group:AddChild(UIF:Slider("Border Insets", bdb, "BorderInsets", 0, 50, 1, Callback, 0.33)) self.parent.parent:DoLayout() self.parent.parent:FixScroll() end end