Go to most recent revision | Compare with Previous | Blame | View Log
mNameplates = LibStub("AceAddon-3.0"):NewAddon("mNameplates", "AceEvent-3.0", "AceConsole-3.0", "AceHook-3.0") local mNameplates = mNameplates MDB_MN = mNameplates mNameplates.DisplayIcon = [[Interface\Icons\inv_shield_09]] local UIF local LSM = LibStub("LibSharedMedia-3.0") local AceGUI = LibStub("AceGUI-3.0") local Nameplates = LibStub("LibNameplate-1.0") LSM:Register("font", "accid", [[Interface\AddOns\mRunes\accid.ttf]]) LSM:Register("statusbar", "HalD", [[Interface\AddOns\mRunes\HalD.tga]]) LSM:Register("border", "Glowing", [[Interface\AddOns\mRunes\Glowing.tga]]) local db local Cache = {} local bossIconTexture = [[Interface\TargetingFrame\UI-TargetingFrame-Skull]] local ResetTextures = { ThreatGlow = [[Interface\TargetingFrame\UI-TargetingFrame-Flash]], Highlight = [[Interface\Tooltips\Nameplate-Glow]], BossIcon = [[Interface\TargetingFrame\UI-TargetingFrame-Skull]], ElitIcon = [[Interface\Tooltips\EliteNameplateIcon]], CastBorder = [[Interface\Tooltips\Nameplate-Border]], RaidIcon = [[nterface\TargetingFrame\UI-RaidTargetingIcons]], } local DefaultWidth, DefaultHeight, DefaultIconSize local InCombat = false -- Combat Wrappers local StateScriptSet = {} local ApplyPlateSet = {} local PlateReset = {} mNameplates.Levels = { Bars = 2, Text = 3, Icon = 4, } local StateHeader = CreateFrame("Frame", nil, nil, "SecureHandlerBaseTemplate") StateHeader:RegisterEvent("PLAYER_REGEN_ENABLED") StateHeader:SetScript("OnEvent", function(self, event, ...) for plate in pairs(PlateReset) do mNameplates:ResetLockedAttributes(plate) end wipe(PlateReset) end) local backdrop = { tile = true, tileSize = 16, insets = {}, } function mNameplates:OnInitialize() local defaults = { profile = { Enabled = true, Width = 125, Height = 25, BorderWidth = 5, BorderPadding = 5, BorderColor = {0, 0, 0, 0.5}, BackgroundColor = {0, 0, 0, 0.5}, BorderInsets = 4, BorderTexture = "Glowing", } } self.db = LibStub("AceDB-3.0"):New("mNameplatesDB", defaults, "Default") db = self.db.profile self.db.RegisterCallback(self, "OnProfileChanged", "ProfileChanged") self.db.RegisterCallback(self, "OnProfileCopied", "ProfileChanged") self.db.RegisterCallback(self, "OnProfileReset", "ProfileChanged") self:SetupLDB() self:SetEnabledState(db.Enabled) self.Callbacks = LibStub("CallbackHandler-1.0"):New(self) self.Plates = {} UIF = LibStub("LibGUIFactory-1.0"):GetFactory("mNameplates", {font = LibStub("LibSharedMedia-3.0"):Fetch("font", "accid"), fontSize = 16}) UIF:SetValuesChangedCallback(function() mNameplates:ToggleConfig(true) end) self:RegisterChatCommand("mn", "ToggleConfig") end function mNameplates:OnEnable() if UnitAffectingCombat("plater") then InCombat = true end Nameplates.RegisterCallback(self, "LibNameplate_FoundGUID") Nameplates.RegisterCallback(self, "LibNameplate_NewNameplate") Nameplates.RegisterCallback(self, "LibNameplate_MouseoverNameplate") Nameplates.RegisterCallback(self, "LibNameplate_HealthChange") Nameplates.RegisterCallback(self, "LibNameplate_RecycleNameplate") self:RegisterEvent("UPDATE_MOUSEOVER_UNIT") self:RegisterEvent("PLAYER_REGEN_DISABLED") self:RegisterEvent("PLAYER_REGEN_ENABLED") for i, plate in pairs({select(2, Nameplates:GetAllNameplates())}) do self:LibNameplate_NewNameplate("LibNameplate_NewNameplate", plate) end wipe(PlateReset) end function mNameplates:OnDisable() for moduleName, module in self:IterateModules() do LibStub("AceAddon-3.0"):DisableAddon(module) end for i, plate in pairs(self.Plates) do plate.DefaultItems.ThreatGlow:SetTexture(ResetTextures.ThreatGlow) plate.DefaultItems.Highlight:SetTexture(ResetTextures.Highlight) plate.DefaultItems.BossIcon:SetTexture(ResetTextures.BossIcon) plate.DefaultItems.ElitIcon:SetTexture(ResetTextures.ElitIcon) plate.DefaultItems.CastBorder:SetTexture(ResetTextures.CastBorder) plate.DefaultItems.RaidIcon:SetTexture(ResetTextures.RaidIcon) plate.DefaultItems.Icon:SetHeight(DefaultIconSize) plate.DefaultItems.Icon:SetWidth(DefaultIconSize) plate.DefaultItems.Name:Show() plate.DefaultItems.HealthBorder:Show() plate.DefaultItems.Level:Show() plate.DefaultItems.HealthBar:Show() plate.DefaultItems.CastBar:Show() self:Unhook(plate.DefaultItems.CastBar, "OnShow") local data = mNameplates:GetExtra(plate) data.Background:ClearAllPoints() data.Background:Hide() tinsert(Cache, data.Background) data.Background = nil plate.DefaultItems = nil plate.mn = nil self:CombatWrapperResetPlate(plate) end wipe(self.Plates) Nameplates.UnregisterAllCallbacks(self) end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Callbacks ~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ function mNameplates:LibNameplate_NewNameplate(event, plate) self:PrepPlate(plate) plate.DefaultItems.Level:Hide() local filtered = false for i, filter in pairs(self.Filters) do local result = filter:RunFilter(plate) if result then filtered = result end end local data = mNameplates:GetExtra(plate) if not filtered then data.Background:SetParent(plate) data.Background:Show() data.Background.backdrop:Show() self:ApplyOnPlate(plate, data) self.Callbacks:Fire("PlateShow", plate, data) else data.Background:SetParent(plate) data.Background:Show() data.Background.backdrop:Hide() self:ApplyOnPlate(plate, data) self.Callbacks:Fire("PlateShowFiltered", plate, data) end end function mNameplates:LibNameplate_FoundGUID(event, plate, gUID, unit) local data = self:GetExtra(plate) if data then self.Callbacks:Fire("PlateGUID", gUID, unit, self:GetExtra(plate)) end end function mNameplates:LibNameplate_MouseoverNameplate(event, plate) if self.CurrentMouseOver and self.CurrentMouseOver == plate then return end self:MouseOverUpdate() self.CurrentMouseOver = plate local data = mNameplates:GetExtra(plate) self.Callbacks:Fire("PlateMouseover", plate, data) self:RegisterOnUpdate(self, self.MouseOverUpdate) if data then for i, frame in pairs(data) do frame:SetFrameLevel(frame:GetFrameLevel() + 100) end end end function mNameplates:LibNameplate_HealthChange(event, plate) local data = self:GetExtra(plate) if data then self.Callbacks:Fire("PlateHPChanged", plate, data) end end function mNameplates:LibNameplate_RecycleNameplate(event, plate) local data = self:GetExtra(plate) if data then self.Callbacks:Fire("PlateHide", plate, data) end end function mNameplates:ProfileChanged(event) db = self.db.profile end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Events ~~~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ function mNameplates:UPDATE_MOUSEOVER_UNIT(...) local plate = Nameplates:GetNameplateByUnit("mouseover") if self.CurrentMouseOver and self.CurrentMouseOver == plate then return end if plate then self:MouseOverUpdate() self.CurrentMouseOver = plate local data = mNameplates:GetExtra(plate) self.Callbacks:Fire("PlateMouseover", plate, data) self:RegisterOnUpdate(self, self.MouseOverUpdate) if data then for i, frame in pairs(data) do frame:SetFrameLevel(frame:GetFrameLevel() + 100) end end end end function mNameplates:PLAYER_REGEN_DISABLED() InCombat = true end function mNameplates:PLAYER_REGEN_ENABLED() InCombat = false for plate in pairs(StateScriptSet) do self:SetStateScript(plate) end for plate in pairs(ApplyPlateSet) do self:SetLockedAttributes(plate) end wipe(StateScriptSet) wipe(ApplyPlateSet) wipe(PlateReset) end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Creation ~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ do local function CastBarShow(self) self:Hide() local plate = self:GetParent() plate.DefaultItems.Icon:SetTexture(nil) end local regions = {} function mNameplates:PrepPlate(plate) if plate.mn then return end local healthBar, castBar = plate:GetChildren() local threatGlow, healthBorder, castbarBorder, castNoInterupt, castIcon, highlight, name, level, bossIcon, raidIcon, eliteIcon = plate:GetRegions() healthBar:Hide() castBar:Hide() self:HookScript(castBar, "OnShow", CastBarShow) DefaultIconSize = DefaultIconSize or castIcon:GetHeight() threatGlow:SetTexture(nil) highlight:SetTexture(nil) bossIcon:SetTexture(nil) eliteIcon:SetTexture(nil) castbarBorder:SetTexture(nil) castNoInterupt:SetTexture(nil) raidIcon:SetTexture(nil) castIcon:SetWidth(0.01) castIcon:SetHeight(0.01) name:Hide() healthBorder:Hide() plate.mn = {} plate.DefaultItems = { HealthBar = healthBar, CastBar = castBar, ThreatGlow = threatGlow, HealthBorder = healthBorder, CastBorder = castbarBorder, CastNoInterupt = castNoInterupt, Icon = castIcon, Highlight = highlight, Name = name, Level = level, BossIcon = bossIcon, RaidIcon = raidIcon, ElitIcon = eliteIcon, } tinsert(self.Plates, plate) DefaultHeight = DefaultHeight or plate:GetHeight() DefaultWidth = DefaultWidth or plate:GetWidth() self:CombatWrapperSetStateScript(plate) local Background = tremove(Cache) if not Background then Background = CreateFrame("Frame", nil, plate) Background:SetFrameLevel(plate:GetFrameLevel()) Background:SetPoint("CENTER") local back = CreateFrame("Frame", nil, Background) LibStub("LibBackdrop-1.0"):EnhanceBackdrop(back) back:SetFrameLevel(Background:GetFrameLevel() - 1 ) Background.backdrop = back end Background:ClearAllPoints() Background:SetParent(plate) Background:SetPoint("CENTER") plate.mn.Background = Background self.Callbacks:Fire("PlateNew", plate, self:GetExtra(plate)) end end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Settings ~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ function mNameplates:ApplyOnPlate(plate, data) self:CombatWrapperApplyPlate(plate) self:CombatWrapperSetStateScript(plate) data.Background:SetWidth(db.Width) data.Background:SetHeight(db.Height) backdrop.insets.left = db.BorderInsets backdrop.insets.right = db.BorderInsets backdrop.insets.top = db.BorderInsets backdrop.insets.bottom = db.BorderInsets backdrop.edgeFile = LSM:Fetch("border", db.BorderTexture) backdrop.edgeSize = db.BorderWidth backdrop.bgFile = LSM:Fetch("background", "Solid") data.Background.backdrop:SetBackdrop(backdrop) data.Background.backdrop:SetBackdropColor(unpack(db.BackgroundColor)) data.Background.backdrop:SetBackdropBorderColor(unpack(db.BorderColor)) data.Background.backdrop:ClearAllPoints() data.Background.backdrop:SetPoint("TOPLEFT", -db.BorderPadding, db.BorderPadding) data.Background.backdrop:SetPoint("BOTTOMRIGHT", db.BorderPadding, -db.BorderPadding) end function mNameplates:Applyettings() for i, plate in self:IteratePlates() do self:ApplyOnPlate(plate, self:GetExtra(plate)) end end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Misc ~~~~~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ function mNameplates:IteratePlates() return pairs(self.Plates) end function mNameplates:GetExtra(plate) assert(plate, "No plates passed to get extra") return plate.mn end do local AttachList = {} local AnchorList = {} function mNameplates:GetAttachList(callingModule) wipe(AttachList) for moduleName, module in self:IterateModules() do if module ~= callingModule then AttachList[moduleName] = {text = module.DisplayName or moduleName, value = moduleName, disabled = (not module:IsEnabled()) or (callingModule:GetName() == module.db.profile.AttachedFrame), icon = module.DisplayIcon} end end AttachList["NAMEPLATE"] = {text = "Nameplate", value = "NAMEPLATE", icon = [[Interface\Icons\inv_shield_09]]} return AttachList end function mNameplates:GetAttachFrame(moduleName, plate) local module = self:GetModule(moduleName, "true") if module then return module:GetAttachFrame(plate) end end function mNameplates:GetAnchorList() AnchorList = AnchorList or {} AnchorList["TOPLEFT"] = "Top left" AnchorList["TOP"] = "Top" AnchorList["TOPRIGHT"] = "Top Right" AnchorList["RIGHT"] = "Right" AnchorList["BOTTOMRIGHT"] = "Bottom right" AnchorList["BOTTOM"] = "Bottom" AnchorList["BOTTOMLEFT"] = "Bottom left" AnchorList["LEFT"] = "Left" AnchorList["CENTER"] = "Center" return AnchorList end end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Combat Wrappers ~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ function mNameplates:CombatWrapperSetStateScript(plate) if InCombat then StateScriptSet[plate] = true else self:SetStateScript(plate) end end function mNameplates:CombatWrapperApplyPlate(plate) if InCombat then ApplyPlateSet[plate] = true else self:SetLockedAttributes(plate) end end function mNameplates:CombatWrapperResetPlate(plate) if InCombat then PlateReset[plate] = true else self:ResetLockedAttributes(plate) end end function mNameplates:SetStateScript(plate) StateHeader:UnwrapScript(plate, "OnShow") StateHeader:WrapScript(plate, "OnShow", [[ self:SetWidth(]]..db.Width..[[) self:SetHeight(]]..db.Height..[[) ]]) end function mNameplates:SetLockedAttributes(plate) plate:SetWidth(db.Width) plate:SetHeight(db.Height) end function mNameplates:ResetLockedAttributes(plate) plate:SetWidth(DefaultWidth) plate:SetHeight(DefaultHeight) StateHeader:UnwrapScript(plate, "OnShow") end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Config ~~~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~ do local function Callback() mNameplates:Applyettings() end local OptionsFrame local SelectedOption local OptionsStatus = {} function mNameplates:ToggleConfig(reOpen) if not OptionsFrame then OptionsFrame = UIF:Frame("mNameplates") OptionsFrame:SetLayout("Fill") OptionsFrame:SetWidth(813) OptionsFrame:SetHeight(630) OptionsFrame:Hide() OptionsFrame:SetCallback("OnClose", function(widget) OptionsFrame:ReleaseChildren() OptionsFrame.frame:Hide() end) end if OptionsFrame.frame:IsShown() then OptionsFrame:Hide() if not reOpen then return end end m = UIF:TreeGroup() m:SetLayout("Fill") m:SetCallback("OnGroupSelected", function(self, event, group) SelectedOption = group end) OptionsFrame:AddChild(m) m:AddGroup({{text = "Main", value = "Main", order = 0}}, function() local g = UIF:InlineGroup1() g:AddChild(UIF:CheckBox("Enabled", db, "Enabled", function() if db.Enabled and not mNameplates:IsEnabled() then mNameplates:Enable() elseif not db.Enabled and mNameplates:IsEnabled() then mNameplates:Disable() end end)) g:AddChild(UIF:Slider("Width", db, "Width", 0, 300, 0.1, Callback, 0.5)) g:AddChild(UIF:Slider("Height", db, "Height", 0, 300, 0.1, Callback, 0.5)) local g2 = UIF:InlineGroup1("Border and Color") g2:AddChild(UIF:ColorSelect("Border Color", db, "BorderColor", Callback, true, 0.5)) g2:AddChild(UIF:ColorSelect("Background Color", db, "BackgroundColor", Callback, true, 0.5)) g2:AddChild(UIF:LSMDropdown("border", "Border texture", db, "BorderTexture", Callback, 0.5)) g2:AddChild(UIF:Slider("Border Width", db, "BorderWidth", 0, 50, 0.1, Callback, 0.5)) g2:AddChild(UIF:Slider("Padding", db, "BorderPadding", 0, 50, 0.1, Callback, 0.5)) g2:AddChild(UIF:Slider("Insets", db, "BorderInsets", 0, 50, 0.1, Callback, 0.5)) return g, g2 end, self.DisplayIcon) for moduleName, module in self:IterateModules() do if module.GetOptions then local options = module:GetOptions() if options and type(options) == "table" then for i, option in pairs(options) do m:AddGroup(option.data, option.func, option.icon) end end end end m:AddGroup({{text = "Profile", value = "Profile"}}, function() return UIF:AceProfileOption(mNameplates.db) end) m:SetSelected(SelectedOption or "Main") m:SetStatusTable(OptionsStatus) OptionsFrame:Show() end function mNameplates:SetupLDB() local LDB = LibStub("LibDataBroker-1.1") if not LDB then return end local l = LDB:NewDataObject("mNameplates") l.type = "launcher" l.icon = [[Interface\Icons\Spell_DeathKnight_RuneTap]] l.tocname = "mNameplates" l.label = "mNameplates" l.OnClick = function(self, button) mNameplates:ToggleConfig() end l.OnTooltipShow = function(tt) tt:AddLine("mNameplates") tt:AddLine("Click to toggle configuration") end self.ldbojb = l end end