--[[ Copyright (C) 2006-2007 Nymbia Copyright (C) 2010 Hendrik "Nevcairiel" Leppkes < h.leppkes@gmail.com > This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ]] local Quartz3 = LibStub("AceAddon-3.0"):GetAddon("Quartz3") local L = LibStub("AceLocale-3.0"):GetLocale("Quartz3") local MODNAME = "Mirror" local Mirror = Quartz3:NewModule(MODNAME, "AceHook-3.0", "AceEvent-3.0", "AceTimer-3.0") local Player = Quartz3:GetModule("Player") local Focus = Quartz3:GetModule("Focus") local Target = Quartz3:GetModule("Target") local TimeFmt = Quartz3.Util.TimeFormat local media = LibStub("LibSharedMedia-3.0") local lsmlist = AceGUIWidgetLSMlists ---------------------------- -- Upvalues -- GLOBALS: MIRRORTIMER_NUMTIMERS local _G = _G local CreateFrame, GetTime, UIParent, StaticPopupDialogs = CreateFrame, GetTime, UIParent, StaticPopupDialogs local GetMirrorTimerProgress, GetMirrorTimerInfo, GetCorpseRecoveryDelay = GetMirrorTimerProgress, GetMirrorTimerInfo, GetCorpseRecoveryDelay local UnitHealth = UnitHealth local pairs, unpack, next, wipe, error = pairs, unpack, next, wipe, error local table_sort = table.sort local gametimebase, gametimetostart local lfgshowbase, readycheckshowbase, readycheckshowduration local locked = true local db, getOptions local new, del local defaults = { profile = { mirroricons = true, mirroriconside = "left", mirroranchor = "player",--L["Free"], L["Target"], L["Focus"] mirrorx = 500, mirrory = 700, mirrorgrowdirection = "up", --L["Down"] mirrorposition = "topleft", mirrorgap = 1, mirrorspacing = 1, mirroroffset = 3, mirrornametext = true, mirrortimetext = true, mirrortexture = "LiteStep", mirrorwidth = 120, mirrorheight = 12, mirrorfont = "Friz Quadrata TT", mirrorfontsize = 9, mirroralpha = 1, mirrortextcolor = {1, 1, 1}, BREATH = {0, 0.5, 1}, EXHAUSTION = {1.00, 0.9, 0}, FEIGNDEATH = {1, 0.7, 0}, CAMP = {1, 0.7, 0}, DEATH = {1, 0.1, 0.1}, QUIT = {1, 0.7, 0}, DUEL_OUTOFBOUNDS = {0.2, 0.8, 0.2}, INSTANCE_BOOT = {1, 0, 0}, CONFIRM_SUMMON = {1, 0.3, 1}, AREA_SPIRIT_HEAL = {0, 0.22, 1}, REZTIMER = {1, 0, 0.5}, RESURRECT_NO_SICKNESS = {0.47, 1, 0}, RESURRECT_NO_TIMER = {0.47, 1, 0}, PARTY_INVITE = {1, 0.9, 0}, DUEL_REQUESTED = {1, 0.13, 0}, GAMESTART = {0,1,0}, READYCHECK = {0,1,0}, hideblizzmirrors = true, showmirror = true, showstatic = true, showpvp = true, showreadycheck = true, } } local icons = { BREATH = "Interface\\Icons\\Spell_Shadow_DemonBreath", EXHAUSTION = "Interface\\Icons\\Ability_Suffocate", FEIGNDEATH = "Interface\\Icons\\Ability_Rogue_FeignDeath", CAMP = "Interface\\Icons\\INV_Misc_GroupLooking", DEATH = "Interface\\Icons\\Ability_Vanish", QUIT = "Interface\\Icons\\INV_Misc_GroupLooking", DUEL_OUTOFBOUNDS = "Interface\\Icons\\Ability_Rogue_Sprint", INSTANCE_BOOT = "Interface\\Icons\\INV_Misc_Rune_01", CONFIRM_SUMMON = "Interface\\Icons\\Spell_Shadow_Twilight", AREA_SPIRIT_HEAL = "Interface\\Icons\\Spell_Holy_Resurrection", REZTIMER = "", RESURRECT_NO_SICKNESS = "", PARTY_INVITE = "", DUEL_REQUESTED = "", GAMESTART = "", READYCHECK = "", } local popups = { CAMP = L["Logout"], DEATH = L["Release"], QUIT = L["Quit"], DUEL_OUTOFBOUNDS = L["Forfeit Duel"], INSTANCE_BOOT = L["Instance Boot"], CONFIRM_SUMMON = L["Summon"], AREA_SPIRIT_HEAL = L["AOE Rez"], REZTIMER = L["Resurrect Timer"], --GetCorpseRecoveryDelay RESURRECT_NO_SICKNESS = L["Resurrect"], --only show if timeleft < delay RESURRECT_NO_TIMER = L["Resurrect"], PARTY_INVITE = L["Party Invite"], DUEL_REQUESTED = L["Duel Request"], GAMESTART = L["Game Start"], READYCHECK = READY_CHECK, } local timeoutoverrides = { DEATH = 360, AREA_SPIRIT_HEAL = 30, INSTANCE_BOOT = 60, CONFIRM_SUMMON = 120, GAMESTART = 60, READYCHECK = 40, } Mirror.ExternalTimers = setmetatable({}, {__index = function(t,k) local v = new() t[k] = v return v --[[ startTime endTime icon color ]] end}) local mirrorOnUpdate, fakeOnUpdate do function mirrorOnUpdate(frame) local progress = GetMirrorTimerProgress(frame.mode) / 1000 progress = progress > frame.duration and frame.duration or progress frame:SetValue(progress) frame.TimeText:SetFormattedText(TimeFmt(progress)) end function fakeOnUpdate(frame) local currentTime = GetTime() local endTime = frame.endTime if frame.framenum > 0 then local popup = _G["StaticPopup"..frame.framenum] -- hate to do this, but I can"t think of a better way. if popup.which ~= frame.which or not popup:IsVisible() then return Mirror:UpdateBars() end end if currentTime > endTime then Mirror:UpdateBars() else local remaining = currentTime - frame.startTime frame:SetValue(endTime - remaining) frame.TimeText:SetFormattedText(TimeFmt(endTime - currentTime)) end end end local function OnHide(frame) frame:SetScript("OnUpdate", nil) end local mirrorbars = setmetatable({}, { __index = function(t,k) local bar = CreateFrame("StatusBar", nil, UIParent) t[k] = bar bar:SetFrameStrata("MEDIUM") bar:Hide() bar:SetScript("OnHide", OnHide) bar:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16}) bar:SetBackdropColor(0,0,0) bar.Text = bar:CreateFontString(nil, "OVERLAY") bar.TimeText = bar:CreateFontString(nil, "OVERLAY") bar.Icon = bar:CreateTexture(nil, "DIALOG") if k == 1 then bar:SetMovable(true) bar:RegisterForDrag("LeftButton") bar:SetClampedToScreen(true) end Mirror:ApplySettings() return bar end }) function Mirror:OnInitialize() self.db = Quartz3.db:RegisterNamespace(MODNAME, defaults) db = self.db.profile self:SetEnabledState(Quartz3:GetModuleEnabled(MODNAME)) Quartz3:RegisterModuleOptions(MODNAME, getOptions, L["Mirror"]) end function Mirror:OnEnable() self:RegisterEvent("MIRROR_TIMER_PAUSE", "UpdateBars") self:RegisterEvent("MIRROR_TIMER_START", "UpdateBars") self:RegisterEvent("MIRROR_TIMER_STOP", "UpdateBars") self:RegisterEvent("PLAYER_UNGHOST", "UpdateBars") self:RegisterEvent("PLAYER_ALIVE", "UpdateBars") self:RegisterMessage("Quartz3Mirror_UpdateCustom", "UpdateBars") self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") self:RegisterEvent("LFG_PROPOSAL_SHOW") self:RegisterEvent("READY_CHECK") self:RegisterEvent("READY_CHECK_FINISHED") self:RegisterEvent("LFG_PROPOSAL_FAILED", "LFG_PROPOSAL_End") self:RegisterEvent("LFG_PROPOSAL_SUCCEEDED", "LFG_PROPOSAL_End") self:SecureHook("StaticPopup_Show", "UpdateBars") media.RegisterCallback(self, "LibSharedMedia_SetGlobal", function(mtype, override) if mtype == "statusbar" then for i, v in pairs(mirrorbars) do v:SetStatusBarTexture(media:Fetch("statusbar", override)) end end end) media.RegisterCallback(self, "LibSharedMedia_Registered", function(mtype, key) if mtype == "statusbar" and key == self.config.mirrortexture then for i, v in pairs(mirrorbars) do v:SetStatusBarTexture(media:Fetch("statusbar", self.config.mirrortexture)) end end end) self:ApplySettings() end function Mirror:OnDisable() mirrorbars[1].Hide = nil mirrorbars[1]:EnableMouse(false) mirrorbars[1]:SetScript("OnDragStart", nil) mirrorbars[1]:SetScript("OnDragStop", nil) for _, v in pairs(mirrorbars) do v:Hide() end for i = 1, 3 do _G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_PAUSE") _G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_STOP") end UIParent:RegisterEvent("MIRROR_TIMER_START") media.UnregisterCallback(self, "LibSharedMedia_SetGlobal") media.UnregisterCallback(self, "LibSharedMedia_Registered") end do local tblCache = setmetatable({}, {__mode="k"}) function new() local entry = next(tblCache) if entry then tblCache[entry] = nil else entry = {} end return entry end function del(tbl) wipe(tbl) tblCache[tbl] = true end local function sort(a,b) return a.name < b.name end local tmp = {} local reztimermax = 0 local function update() Mirror.updateMirrorBar = nil local currentTime = GetTime() for k in pairs(tmp) do tmp[k] = del(tmp[k]) end if db.showpvp then if gametimebase then local endTime = gametimebase + gametimetostart if endTime > currentTime then local which = "GAMESTART" local t = new() tmp[#tmp+1] = t t.name = popups[which] t.texture = icons[which] t.mode = which t.startTime = endTime - timeoutoverrides[which] t.endTime = endTime t.isfake = true t.framenum = 0 else gametimebase = nil gametimetostart = nil end end end if db.showreadycheck then if lfgshowbase or readycheckshowbase then local which = "READYCHECK" local endTime if readycheckshowbase then endTime = readycheckshowbase + readycheckshowduration else endTime = lfgshowbase + timeoutoverrides[which] end if endTime > currentTime then local t = new() tmp[#tmp+1] = t t.name = popups[which] t.texture = icons[which] t.mode = which t.startTime = lfgshowbase or readycheckshowbase t.endTime = endTime t.isfake = true t.framenum = 0 else lfgshowbase = nil readycheckshowbase = nil readycheckshowduration = nil end end end if db.showmirror then for i = 1, MIRRORTIMER_NUMTIMERS do local timer, value, maxvalue, scale, paused, label = GetMirrorTimerInfo(i) if timer ~= "UNKNOWN" then local t = new() tmp[#tmp+1] = t t.name = label t.texture = icons[timer] t.mode = timer t.duration = maxvalue / 1000 t.isfake = false end end end if db.showstatic then local recoverydelay = GetCorpseRecoveryDelay() if recoverydelay > 0 and UnitHealth("player") < 2 then if reztimermax == 0 then reztimermax = recoverydelay end local which = "REZTIMER" local t = new() tmp[#tmp+1] = t t.name = popups[which] t.texture = icons[which] t.mode = which t.startTime = currentTime - (reztimermax - recoverydelay) t.endTime = currentTime + recoverydelay t.isfake = true t.framenum = 0 else reztimermax = 0 end for i = 1, 4 do local popup = _G["StaticPopup"..i] local which = popup.which local timeleft = popup.timeleft local name = popups[which] --special case for a timered rez if which == "RESURRECT_NO_SICKNESS" then if timeleft > 60 then name = nil end end if popup:IsVisible() and name and timeleft and timeleft > 0 then local t = new() tmp[#tmp+1] = t t.name = name t.texture = icons[which] t.mode = which local timeout = StaticPopupDialogs[which].timeout if not timeout or timeout == 0 then timeout = timeoutoverrides[which] end t.startTime = currentTime - (timeout - timeleft) t.endTime = currentTime + timeleft t.isfake = true t.framenum = i end end end local external = Mirror.ExternalTimers for name, v in pairs(external) do local endTime = v.endTime if not v.startTime or not endTime then error("bad custom table") end if endTime > currentTime then local t = new() tmp[#tmp+1] = t t.name = name t.texture = v.icon or icons[name] t.startTime = v.startTime t.endTime = v.endTime t.isfake = true t.framenum = 0 if v.color then t.color = v.color end else external[name] = del(v) end end table_sort(tmp, sort) local maxindex = 0 for k=1,#tmp do local v = tmp[k] maxindex = k local bar = mirrorbars[k] bar.Text:SetText(v.name) bar.Icon:SetTexture(v.texture) bar.mode = v.mode if v.isfake then local startTime, endTime = v.startTime, v.endTime bar:SetMinMaxValues(startTime, endTime) bar.startTime = startTime bar.endTime = endTime bar.framenum = v.framenum bar.which = v.mode bar:Show() bar:SetScript("OnUpdate", fakeOnUpdate) if v.mode then bar:SetStatusBarColor(unpack(db[v.mode])) elseif v.color then bar:SetStatusBarColor(unpack(v.color)) else bar:SetStatusBarColor(1,1,1) --!! add option end else local duration = v.duration bar:SetMinMaxValues(0, duration) bar.duration = duration bar:Show() bar:SetScript("OnUpdate", mirrorOnUpdate) bar:SetStatusBarColor(unpack(db[v.mode])) end end for i = maxindex+1, #mirrorbars do mirrorbars[i]:Hide() end end function Mirror:UpdateBars() if not self.updateMirrorBar then self.updateMirrorBar = self:ScheduleTimer(update, 0) -- API funcs dont return helpful crap until after the event. end end end function Mirror:CHAT_MSG_BG_SYSTEM_NEUTRAL(event, msg) if msg:match(L["1 minute"]) or msg:match(L["One minute until"]) then gametimebase = GetTime() gametimetostart = 60 elseif msg:match(L["30 seconds"]) or msg:match(L["Thirty seconds until"]) then gametimebase = GetTime() gametimetostart = 30 elseif msg:match(L["15 seconds"]) or msg:match(L["Fifteen seconds until"]) then gametimebase = GetTime() gametimetostart = 15 end self:UpdateBars() end function Mirror:LFG_PROPOSAL_SHOW(event, msg) lfgshowbase = GetTime() self:UpdateBars() end function Mirror:LFG_PROPOSAL_End(event, msg) lfgshowbase = nil self:UpdateBars() end function Mirror:READY_CHECK(event, msg, duration) readycheckshowbase = GetTime() readycheckshowduration = duration self:UpdateBars() end function Mirror:READY_CHECK_FINISHED(event, msg) readycheckshowbase = nil self:UpdateBars() end do local function apply(i, bar, db, direction) local position, showicons, iconside, gap, spacing, offset local qpdb = Player.db.profile position = db.mirrorposition showicons = db.mirroricons iconside = db.mirroriconside gap = db.mirrorgap spacing = db.mirrorspacing offset = db.mirroroffset bar:ClearAllPoints() bar:SetStatusBarTexture(media:Fetch("statusbar", db.mirrortexture)) bar:GetStatusBarTexture():SetHorizTile(false) bar:GetStatusBarTexture():SetVertTile(false) bar:SetWidth(db.mirrorwidth) bar:SetHeight(db.mirrorheight) bar:SetScale(qpdb.scale) bar:SetAlpha(db.mirroralpha) if db.mirroranchor == "free" then if i == 1 then bar:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", db.mirrorx, db.mirrory) if db.mirrorgrowdirection == "up" then direction = 1 else --L["Down"] direction = -1 end else if direction == 1 then bar:SetPoint("BOTTOMRIGHT", mirrorbars[i-1], "TOPRIGHT", 0, spacing) else -- -1 bar:SetPoint("TOPRIGHT", mirrorbars[i-1], "BOTTOMRIGHT", 0, -1 * spacing) end end else if i == 1 then local anchorframe local anchor = db.mirroranchor if anchor == "focus" and Focus.Bar then anchorframe = Focus.Bar elseif anchor == "target" and Target.Bar then anchorframe = Target.Bar else -- L["Player"] anchorframe = Player.Bar end if position == "top" then direction = 1 bar:SetPoint("BOTTOM", anchorframe, "TOP", 0, gap) elseif position == "bottom" then direction = -1 bar:SetPoint("TOP", anchorframe, "BOTTOM", 0, -1 * gap) elseif position == "topright" then direction = 1 bar:SetPoint("BOTTOMRIGHT", anchorframe, "TOPRIGHT", -1 * offset, gap) elseif position == "bottomright" then direction = -1 bar:SetPoint("TOPRIGHT", anchorframe, "BOTTOMRIGHT", -1 * offset, -1 * gap) elseif position == "topleft" then direction = 1 bar:SetPoint("BOTTOMLEFT", anchorframe, "TOPLEFT", offset, gap) elseif position == "bottomleft" then direction = -1 bar:SetPoint("TOPLEFT", anchorframe, "BOTTOMLEFT", offset, -1 * gap) elseif position == "leftup" then if iconside == "right" and showicons then offset = offset + db.mirrorheight end if qpdb.iconposition == "left" and not qpdb.hideicon then offset = offset + qpdb.h end direction = 1 bar:SetPoint("BOTTOMRIGHT", anchorframe, "BOTTOMLEFT", -1 * offset, gap) elseif position == "leftdown" then if iconside == "right" and showicons then offset = offset + db.mirrorheight end if qpdb.iconposition == "left" and not qpdb.hideicon then offset = offset + qpdb.h end direction = -1 bar:SetPoint("TOPRIGHT", anchorframe, "TOPLEFT", -3 * offset, -1 * gap) elseif position == "rightup" then if iconside == "left" and showicons then offset = offset + db.mirrorheight end if qpdb.iconposition == "right" and not qpdb.hideicon then offset = offset + qpdb.h end direction = 1 bar:SetPoint("BOTTOMLEFT", anchorframe, "BOTTOMRIGHT", offset, gap) elseif position == "rightdown" then if iconside == "left" and showicons then offset = offset + db.mirrorheight end if qpdb.iconposition == "right" and not qpdb.hideicon then offset = offset + qpdb.h end direction = -1 bar:SetPoint("TOPLEFT", anchorframe, "TOPRIGHT", offset, -1 * gap) end else if direction == 1 then bar:SetPoint("BOTTOMRIGHT", mirrorbars[i-1], "TOPRIGHT", 0, spacing) else -- -1 bar:SetPoint("TOPRIGHT", mirrorbars[i-1], "BOTTOMRIGHT", 0, -1 * spacing) end end end local timetext = bar.TimeText if db.mirrortimetext then timetext:Show() timetext:ClearAllPoints() timetext:SetWidth(db.mirrorwidth) timetext:SetPoint("RIGHT", bar, "RIGHT", -2, 0) timetext:SetJustifyH("RIGHT") else timetext:Hide() end timetext:SetFont(media:Fetch("font", db.mirrorfont), db.mirrorfontsize) timetext:SetShadowColor( 0, 0, 0, 1) timetext:SetShadowOffset( 0.8, -0.8 ) timetext:SetTextColor(unpack(db.mirrortextcolor)) timetext:SetNonSpaceWrap(false) timetext:SetHeight(db.mirrorheight) local temptext = timetext:GetText() timetext:SetText("10.0") local normaltimewidth = timetext:GetStringWidth() timetext:SetText(temptext) local text = bar.Text if db.mirrornametext then text:Show() text:ClearAllPoints() text:SetPoint("LEFT", bar, "LEFT", 2, 0) text:SetJustifyH("LEFT") if db.mirrortimetext then text:SetWidth(db.mirrorwidth - normaltimewidth) else text:SetWidth(db.mirrorwidth) end else text:Hide() end text:SetFont(media:Fetch("font", db.mirrorfont), db.mirrorfontsize) text:SetShadowColor( 0, 0, 0, 1) text:SetShadowOffset( 0.8, -0.8 ) text:SetTextColor(unpack(db.mirrortextcolor)) text:SetNonSpaceWrap(false) text:SetHeight(db.mirrorheight) local icon = bar.Icon if showicons then icon:Show() icon:SetWidth(db.mirrorheight-1) icon:SetHeight(db.mirrorheight-1) icon:SetTexCoord(0.07, 0.93, 0.07, 0.93) icon:ClearAllPoints() if iconside == "left" then icon:SetPoint("RIGHT", bar, "LEFT", -1, 0) else icon:SetPoint("LEFT", bar, "RIGHT", 1, 0) end else icon:Hide() end return direction end function Mirror:ApplySettings() db = self.db.profile if self:IsEnabled() then local direction if db.mirroranchor ~= "free" then mirrorbars[1].Hide = nil mirrorbars[1]:EnableMouse(false) mirrorbars[1]:SetScript("OnDragStart", nil) mirrorbars[1]:SetScript("OnDragStop", nil) end for i, v in pairs(mirrorbars) do direction = apply(i, v, db, direction) end if db.hideblizzmirrors then for i = 1, 3 do _G["MirrorTimer"..i]:UnregisterAllEvents() _G["MirrorTimer"..i]:Hide() end UIParent:UnregisterEvent("MIRROR_TIMER_START") else for i = 1, 3 do _G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_PAUSE") _G["MirrorTimer"..i]:RegisterEvent("MIRROR_TIMER_STOP") end UIParent:RegisterEvent("MIRROR_TIMER_START") end db.RESURRECT_NO_TIMER = db.RESURRECT_NO_SICKNESS self:UpdateBars() end end end do local function getmirrorhidden() return not db.showmirror end local function getstatichidden() return not db.showstatic end local function getpvphidden() return not db.showpvp end local function getreadycheckhidden() return not db.showreadycheck end local function getfreeoptionshidden() return db.mirroranchor ~= "free" end local function getnotfreeoptionshidden() return db.mirroranchor == "free" end local function dragstart() mirrorbars[1]:StartMoving() end local function dragstop() db.mirrorx = mirrorbars[1]:GetLeft() db.mirrory = mirrorbars[1]:GetBottom() mirrorbars[1]:StopMovingOrSizing() end local function nothing() mirrorbars[1]:SetAlpha(db.mirroralpha) end local positions = { ["bottom"] = L["Bottom"], ["top"] = L["Top"], ["topleft"] = L["Top Left"], ["topright"] = L["Top Right"], ["bottomleft"] = L["Bottom Left"], ["bottomright"] = L["Bottom Right"], ["leftup"] = L["Left (grow up)"], ["leftdown"] = L["Left (grow down)"], ["rightup"] = L["Right (grow up)"], ["rightdown"] = L["Right (grow down)"], } local function setOpt(info, value) db[info[#info]] = value Mirror:ApplySettings() end local function getOpt(info) return db[info[#info]] end local function getColor(info) return unpack(getOpt(info)) end local function setColor(info, r, g, b, a) setOpt(info, {r, g, b, a}) end local options function getOptions() if not options then options = { type = "group", name = L["Mirror"], order = 600, set = setOpt, get = getOpt, childGroups = "tab", args = { toggle = { type = "toggle", name = L["Enable"], desc = L["Enable"], get = function() return Quartz3:GetModuleEnabled(MODNAME) end, set = function(info, v) Quartz3:SetModuleEnabled(MODNAME, v) end, order = 96, width = "full", }, settings = { type = "group", name = L["Settings"], args = { mirroranchor = { type = "select", name = L["Anchor Frame"], desc = L["Select where to anchor the mirror bars"], values = {["player"] = L["Player"], ["free"] = L["Free"], ["target"] = L["Target"], ["focus"] = L["Focus"]}, }, -- free mirrorlock = { type = "toggle", name = L["Lock"], desc = L["Toggle mirror bar lock"], get = function() return locked end, set = function(info, v) if v then mirrorbars[1].Hide = nil mirrorbars[1]:EnableMouse(false) mirrorbars[1]:SetScript("OnDragStart", nil) mirrorbars[1]:SetScript("OnDragStop", nil) Mirror:UpdateBars() else mirrorbars[1]:Show() mirrorbars[1]:EnableMouse(true) mirrorbars[1]:SetScript("OnDragStart", dragstart) mirrorbars[1]:SetScript("OnDragStop", dragstop) mirrorbars[1]:SetAlpha(1) mirrorbars[1].Hide = nothing end locked = v end, hidden = getfreeoptionshidden, order = 98, }, mirrorgrowdirection = { type = "select", name = L["Grow Direction"], desc = L["Set the grow direction of the mirror bars"], values = {["up"] = L["Up"], ["down"] = L["Down"]}, hidden = getfreeoptionshidden, order = 102, }, mirrorx = { type = "range", name = L["X"], desc = L["Set an exact X value for this bar's position."], min = 0, max = 2560, bigStep = 1, order = 103, hidden = getfreeoptionshidden, }, mirrory = { type = "range", name = L["Y"], desc = L["Set an exact Y value for this bar's position."], min = 0, max = 1600, bigStep = 1, order = 103, hidden = getfreeoptionshidden, }, -- anchored to a cast bar mirrorposition = { type = "select", name = L["Position"], desc = L["Position the mirror bars"], values = positions, hidden = getnotfreeoptionshidden, order = 101, }, mirrorgap = { type = "range", name = L["Gap"], desc = L["Tweak the vertical position of the mirror bars"], min = -35, max = 35, step = 1, hidden = getnotfreeoptionshidden, order = 102, }, mirroroffset = { type = "range", name = L["Offset"], desc = L["Tweak the horizontal position of the mirror bars"], min = -35, max = 35, step = 1, hidden = getnotfreeoptionshidden, order = 103, }, mirrorspacing = { type = "range", name = L["Spacing"], desc = L["Tweak the space between mirror bars"], min = -35, max = 35, step = 1, order = 104, }, nl4 = { type = "description", name = "", order = 109, }, mirroricons = { type = "toggle", name = L["Show Icons"], desc = L["Show icons on mirror bars"], order = 110, }, mirroriconside = { type = "select", name = L["Icon Position"], desc = L["Set the side of the mirror bar that the icon appears on"], values = {["left"] = L["Left"], ["right"] = L["Right"]}, order = 111, }, mirrortexture = { type = "select", dialogControl = "LSM30_Statusbar", name = L["Texture"], desc = L["Set the mirror bar Texture"], values = lsmlist.statusbar, order = 112, }, nl5 = { type = "description", name = "", order = 113, }, mirrorwidth = { type = "range", name = L["Mirror Bar Width"], desc = L["Set the width of the mirror bars"], min = 50, max = 300, step = 1, order = 114, }, mirrorheight = { type = "range", name = L["Mirror Bar Height"], desc = L["Set the height of the mirror bars"], min = 4, max = 25, step = 1, order = 115, }, mirroralpha = { type = "range", name = L["Alpha"], desc = L["Set the alpha of the mirror bars"], min = 0.05, max = 1, bigStep = 0.05, isPercent = true, order = 116, }, nl6 = { type = "description", name = "", order = 119, }, mirrornametext = { type = "toggle", name = L["Mirror Name Text"], desc = L["Display the names of Mirror Bar Types on their bars"], order = 120, }, mirrortimetext = { type = "toggle", name = L["Mirror Time Text"], desc = L["Display the time remaining on mirror bars"], order = 121, }, mirrorfont = { type = "select", dialogControl = "LSM30_Font", name = L["Font"], desc = L["Set the font used in the mirror bars"], values = lsmlist.font, order = 122, }, mirrorfontsize = { type = "range", name = L["Font Size"], desc = L["Set the font size for the mirror bars"], min = 3, max = 15, step = 1, order = 123, }, mirrortextcolor = { type = "color", name = L["Text Color"], desc = L["Set the color of the text for the mirror bars"], get = getColor, set = setColor, order = 124, }, hideblizzmirrors = { type = "toggle", name = L["Hide Blizz Mirror Bars"], desc = L["Hide Blizzard's mirror bars"], order = 130, }, } }, bars = { type = "group", name = L["Bars and Colors"], order = -1, args = { -- mirror showmirror = { type = "toggle", name = L["Show Mirror"], desc = L["Show mirror bars such as breath and feign death"], order = 97, width = "full", }, BREATH = { type = "color", name = L["%s Color"]:format(L["Breath"]), desc = L["Set the color of the bars for %s"]:format(L["Breath"]), get = getColor, set = setColor, disabled = getmirrorhidden, order = 101, }, EXHAUSTION = { type = "color", name = L["%s Color"]:format(L["Exhaustion"]), desc = L["Set the color of the bars for %s"]:format(L["Exhaustion"]), get = getColor, set = setColor, disabled = getmirrorhidden, order = 101, }, FEIGNDEATH = { type = "color", name = L["%s Color"]:format(L["Feign Death"]), desc = L["Set the color of the bars for %s"]:format(L["Feign Death"]), get = getColor, set = setColor, disabled = getmirrorhidden, order = 101, }, -- static showstatic = { type = "toggle", name = L["Show Static"], desc = L["Show bars for static popup items such as rez and summon timers"], order = 200, width = "full", }, CAMP = { type = "color", name = L["%s Color"]:format(L["Logout"]), desc = L["Set the color of the bars for %s"]:format(L["Logout"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, DEATH = { type = "color", name = L["%s Color"]:format(L["Release"]), desc = L["Set the color of the bars for %s"]:format(L["Release"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, QUIT = { type = "color", name = L["%s Color"]:format(L["Quit"]), desc = L["Set the color of the bars for %s"]:format(L["Quit"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, DUEL_OUTOFBOUNDS = { type = "color", name = L["%s Color"]:format(L["Forfeit Duel"]), desc = L["Set the color of the bars for %s"]:format(L["Forfeit Duel"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, INSTANCE_BOOT = { type = "color", name = L["%s Color"]:format(L["Instance Boot"]), desc = L["Set the color of the bars for %s"]:format(L["Instance Boot"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, CONFIRM_SUMMON = { type = "color", name = L["%s Color"]:format(L["Summon"]), desc = L["Set the color of the bars for %s"]:format(L["Summon"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, AREA_SPIRIT_HEAL = { type = "color", name = L["%s Color"]:format(L["AOE Rez"]), desc = L["Set the color of the bars for %s"]:format(L["AOE Rez"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, REZTIMER = { type = "color", name = L["%s Color"]:format(L["Resurrect Timer"]), desc = L["Set the color of the bars for %s"]:format(L["Resurrect Timer"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, RESURRECT_NO_SICKNESS = { type = "color", name = L["%s Color"]:format(L["Resurrect"]), desc = L["Set the color of the bars for %s"]:format(L["Resurrect"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, PARTY_INVITE = { type = "color", name = L["%s Color"]:format(L["Party Invite"]), desc = L["Set the color of the bars for %s"]:format(L["Party Invite"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, DUEL_REQUESTED = { type = "color", name = L["%s Color"]:format(L["Duel Request"]), desc = L["Set the color of the bars for %s"]:format(L["Duel Request"]), get = getColor, set = setColor, disabled = getstatichidden, order = 201, }, --pvp showpvp = { type = "toggle", name = L["Show PvP"], desc = L["Show bar for start of arena and battleground games"], order = 300, width = "full", }, GAMESTART = { type = "color", name = L["%s Color"]:format(L["Game Start"]), desc = L["Set the color of the bars for %s"]:format(L["Game Start"]), get = getColor, set = setColor, disabled = getpvphidden, order = 301, }, --ready check showreadycheck = { type = "toggle", name = L["Show Ready Check"], desc = L["Show bar for Ready Checks"], order = 500, width = "full", }, READYCHECK = { type = "color", name = L["%s Color"]:format(READY_CHECK), desc = L["Set the color of the bars for %s"]:format(READY_CHECK), get = getColor, set = setColor, disabled = getreadycheckhidden, order = 501, }, }, }, }, } end return options end end