1
0
Fork 0
AccountWideRaidProfiles/AccountWideRaidProfiles.lua

599 lines
19 KiB
Lua

local addonName = "AccountWideRaidProfiles"
local dbName = "AccountWideRaidProfilesDB"
local addon = LibStub("AceAddon-3.0"):NewAddon(addonName,"AceHook-3.0", "AceEvent-3.0", "AceConsole-3.0")
local AceGUI = LibStub("AceGUI-3.0")
local CVAR_FRAME_STYLE = "useCompactPartyFrames"
local DEFAULT_CUF_PROFILE_NAME = "Primary"
local RAID_CONTAINER_WIDTH = 300
local MINIMUM_RAID_CONTAINER_HEIGHT = 86
local MINIMUM_RAID_BLOCK_WIDTH = 72
local MAXIMUM_RAID_BLOCK_WIDTH = 144
local MINIMUM_RAID_BLOCK_HEIGHT = 36
local MAXIMUM_RAID_BLOCK_HEIGHT = 72
local ADDON_INACTIVE_PROFILE = "ADDON_INACTIVE"
local ADDON_RELOAD_DIALOG = "ACCOUNT_WIDE_RAID_PROFILES_RELOAD_DIALOG"
local function ShallowCopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
StaticPopupDialogs[ADDON_RELOAD_DIALOG] = {
text = "Account Wide Raid Profiles has applied changes to the raid profile settings. Reloading the user interface is required to avoid tainting the raid frame. Do you want to reload now?",
button1 = YES,
button2 = NO,
OnAccept = function(self)
ReloadUI()
end,
OnCancel = function(self)
addon:Print("The user interface is not reloaded. The addon has applied new raid profile settings, but has tainted the raid frame that may cause it not responding to user input. To fix it, enter \"\/reload\" in chat.")
end,
timeout = 0,
hideOnEscape = 1,
}
function addon:OnInitialize()
addon:RegisterEvent("COMPACT_UNIT_FRAME_PROFILES_LOADED")
self.needReload = false
self.disableOptionPanelUpdate = false
self.inCombat = false
self.isOptionOpen = false
self.db = LibStub("AceDB-3.0"):New(dbName)
self.initialized = false
local addonOption = addon:SetUpOptionsPanel(addonOption)
LibStub("AceConfig-3.0"):RegisterOptionsTable(addonName, addonOption, {"awrp"})
self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions(addonName, addonName)
addon:HookAll()
end
function addon:COMPACT_UNIT_FRAME_PROFILES_LOADED(...)
if (not self.db.profile.profiles) then
addon:StoreAll()
self.initialized = true
else
if (addon:IsAddonActive()) then
local tempProfile = {}
addon:StoreAllToProfile(tempProfile)
if not addon:isProfilesEqual(self.db.profile, tempProfile) then
addon:LoadAll()
addon:ReloadDialog()
else
self.initialized = true
end
else
addon:StoreAll()
self.initialized = true
end
self.initialized = true
end
addon:HookAll()
end
function addon:ShowRaidFrameWhenSolo()
if ((not self.inCombat) and (not IsInGroup()) and GetCVar(CVAR_FRAME_STYLE) == '1' ) then
CompactRaidFrameContainer:Show()
CompactRaidFrameManager:Show()
end
end
function addon:HideRaidFrameWhenSolo()
if ((not self.inCombat) and (not IsInGroup()) and GetCVar(CVAR_FRAME_STYLE) == '1' ) then
CompactRaidFrameContainer:Hide()
CompactRaidFrameManager:Hide()
end
end
function addon:OnOptionShow()
self.isOptionOpen = true
end
function addon:OnOptionHide()
self.isOptionOpen = false
if (self.needReload) then
self.needReload = false
addon:HideRaidFrameWhenSolo()
addon:ReloadDialog()
end
end
function addon:HookAll()
addon:UnhookAll()
self.db.RegisterCallback(self, "OnProfileReset", "ResetProfiles")
self.db.RegisterCallback(self, "OnProfileChanged", "RefreshProfiles")
self.db.RegisterCallback(self, "OnProfileCopied", "RefreshProfiles")
addon:RegisterEvent("PLAYER_REGEN_DISABLED")
addon:RegisterEvent("PLAYER_REGEN_ENABLED")
addon:SecureHookScript(self.optionsFrame, "OnShow", "OnOptionShow")
addon:SecureHookScript(self.optionsFrame, "OnHide", "OnOptionHide")
if (addon:IsAddonActive() and self.initialized) then
addon:SecureHook("SetRaidProfileSavedPosition","StorePosition")
addon:SecureHook("CompactUnitFrameProfiles_ApplyProfile", "StoreAll")
addon:SecureHook("SetCVar", "StoreFrameStyleChanges")
end
end
function addon:GetActiveRaidProfileId()
for i=1, GetNumRaidProfiles() do
if self.db.profile.lastProfile == self.db.profile.profiles[i] then
return i
end
end
return 1
end
function addon:PLAYER_REGEN_DISABLED()
self.inCombat = true
end
function addon:PLAYER_REGEN_ENABLED()
self.inCombat = false
end
-- Unsecure function. Need reload somewhere after calling this function.
function addon:UnlockFrame()
if (not self.inCombat) then
CompactRaidFrameManagerDisplayFrameLockedModeToggle:SetText(UNLOCK)
CompactRaidFrameManagerDisplayFrameLockedModeToggle.lockMode = false
CompactRaidFrameManager_UpdateContainerLockVisibility(CompactRaidFrameManager)
CompactRaidFrameContainer_UpdateDisplayedUnits(CompactRaidFrameContainer)
CompactRaidFrameContainer_TryUpdate(CompactRaidFrameContainer)
RaidOptionsFrame_UpdatePartyFrames()
CompactRaidFrameManager_UpdateShown(CompactRaidFrameManager)
if (self.isOptionOpen) then
addon:ShowRaidFrameWhenSolo()
end
end
end
function addon:RefreshProfiles()
self.needReload = true
addon:UnhookAll()
if (not self.db.profile.profiles) then
addon:ResetProfiles()
else
addon:LoadAll()
end
if (self.isOptionOpen) then
addon:ShowRaidFrameWhenSolo()
end
addon:HookAll()
end
function addon:ResetProfiles()
self.needReload = true
addon:UnhookAll()
local profiles = {}
for i=1, GetNumRaidProfiles() do
tinsert(profiles, GetRaidProfileName(i))
end
for i=1, #profiles do
DeleteRaidProfile(profiles[i])
end
CreateNewRaidProfile(DEFAULT_CUF_PROFILE_NAME)
SetActiveRaidProfile(DEFAULT_CUF_PROFILE_NAME)
SetCVar(CVAR_FRAME_STYLE, false)
addon:StoreAll()
addon:HookAll()
if (self.isOptionOpen) then
addon:ShowRaidFrameWhenSolo()
end
end
function addon:IsAddonActive()
return true -- Change this in the future
end
----------------------- Load and store raid prorfiles ---------------------------
function addon:LoadAll(...)
if (addon:IsAddonActive()) then
addon:UnhookAll()
local profiles = {}
for i=1, GetNumRaidProfiles() do
tinsert(profiles, GetRaidProfileName(i))
end
for i=1, #profiles do
DeleteRaidProfile(profiles[i])
end
SetCVar(CVAR_FRAME_STYLE, self.db.profile.frameStyle)
profiles = self.db.profile.profiles
local options = self.db.profile.options
local positions = self.db.profile.positions
for i=1, #profiles do
local profile = profiles[i]
CreateNewRaidProfile(profile)
for option, value in pairs(options[i]) do
SetRaidProfileOption(profile, option, value)
end
SetRaidProfileSavedPosition(profile, unpack(positions[i]))
end
SetActiveRaidProfile(self.db.profile.lastProfile)
CompactUnitFrameProfiles_ValidateProfilesLoaded(CompactUnitFrameProfiles)
addon:UpdateOptionsPanel()
end
end
function addon:StoreFrameStyleChanges(glStr, value)
if glStr == CVAR_FRAME_STYLE and not self.isOptionOpen then
self.db.profile.frameStyle = value
end
end
function addon:StorePosition(...)
args = {...}
for i=1, #self.db.profile.positions do
if self.db.profile.profiles[i] == args[1] then
self.db.profile.positions[i] = {select(2,unpack(args))}
end
end
if (not self.disableOptionPanelUpdate) then
addon:UpdateOptionsPanel()
end
end
function addon:StoreAllToProfile(db)
local profiles = {}
for i=1, GetNumRaidProfiles() do
tinsert(profiles, GetRaidProfileName(i))
end
db.frameStyle = GetCVar(CVAR_FRAME_STYLE)
db.profiles = profiles
db.options = {}
db.positions = {}
db.lastProfile = GetActiveRaidProfile()
for i=1, #profiles do
local profile = profiles[i]
db.options[i] = GetRaidProfileFlattenedOptions(profile)
db.positions[i] = {GetRaidProfileSavedPosition(profile)}
end
if (not self.disableOptionPanelUpdate) then
addon:UpdateOptionsPanel()
end
end
function addon:StoreAll()
addon:StoreAllToProfile(self.db.profile)
end
function addon:isProfilesEqual(p1, p2)
if ((not p1) or (not p2)) then return false end
if (p1.frameStyle ~= p2.frameStyle) then return false end
if (#p1.profiles ~= #p2.profiles) then return false end
if (#p1.options ~= #p2.options) then return false end
if (#p1.positions ~= #p2.positions) then return false end
for i=1, #p1.profiles do
if (p1.profiles[i] ~= p2.profiles[i]) then return false end
if (#p1.options[i] ~= #p2.options[i]) then return false end
if (#p1.positions[i] ~= #p2.positions[i]) then return false end
for j,_ in pairs(p1.options[i]) do
if (p1.options[i][j] ~= p2.options[i][j]) then
return false
end end
for j=1,#p1.positions[i] do
a = p1.positions[i][j]
b = p2.positions[i][j]
na = tonumber(a)
nb = tonumber(b)
if ((not na) and (not nb) and (a ~= b)) then
return false
end
if (na and nb and math.abs(na-nb) > 1) then
return false
end end
end
return true
end
function addon:ReloadDialog()
StaticPopup_Show(ADDON_RELOAD_DIALOG)
end
---------------------------- Option panel ----------------------------------------------
function addon:UpdateOptionsPanel()
local addonOption = addon:SetUpOptionsPanel(addonOption)
LibStub("AceConfig-3.0"):RegisterOptionsTable(addonName, addonOption, {"awrp", addonName})
LibStub("AceConfigRegistry-3.0"):NotifyChange(addonName)
end
function addon:SetUpOptionsPanel()
local option = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
option = ShallowCopy(option)
option.name = "Account Wide Raid Profiles"
option.desc = "Manage Profiles and extra options of Account Wide Raid Profiles"
option.args = ShallowCopy(option.args)
option.args.rp = {
type = "execute",
name = "rp",
desc = "Open blizzard raid profile settings.",
guiHidden = true,
func = function()
InterfaceOptionsFrame_OpenToCategory(_G["CompactUnitFrameProfiles"])
end
}
option.args.config = {
type = "execute",
name = "config",
desc = "Open addon config panel.",
guiHidden = true,
func = function()
InterfaceOptionsFrame_OpenToCategory(addonName)
InterfaceOptionsFrame_OpenToCategory(addonName)
end
}
option.args.space0 = {
name = "",
type = 'description',
width = 'full',
cmdHidden = true,
order = 100,
}
option.args.configButton = {
order = 110,
type = "execute",
name = "Open Raid Profile Option",
desc = "Open Blizzard raid profile option.",
width = "double",
cmdHidden = true,
func = function()
InterfaceOptionsFrame_OpenToCategory(_G["CompactUnitFrameProfiles"])
end
}
option.args.descChange = {
name = "The raid frame is always shown when you adjust it in this panel.\n",
type = 'description',
width = 'full',
cmdHidden = true,
order = 111,
}
option.args.currentProfile = {
order = 112,
type = "description",
name = function(info) return "Current Raid Profile: " .. " "
.. NORMAL_FONT_COLOR_CODE
.. GetActiveRaidProfile()
.. FONT_COLOR_CODE_CLOSE .."\n" end,
width = "double",
}
option.args.frameStyle = {
order = 113,
type = "toggle",
name = "Use Raid-Style Party Frames",
desc = "Use Party Frames in the same style as the Raid Frames. These frames obey your Raid Frame options.",
get = function(info) return GetCVar(CVAR_FRAME_STYLE) == "1" end,
set = function(info, val)
if val then
SetCVar(CVAR_FRAME_STYLE, "1")
if CompactUnitFrameProfilesRaidStylePartyFrames then
CompactUnitFrameProfilesRaidStylePartyFrames:SetChecked(true)
end
else
SetCVar(CVAR_FRAME_STYLE, "0")
if CompactUnitFrameProfilesRaidStylePartyFrames then
CompactUnitFrameProfilesRaidStylePartyFrames:SetChecked(false)
end
end
end,
width = "double",
}
option.args.isAttached =
{
order = 114,
type = "toggle",
name = "Attach frame",
desc = "If Raid frame attaches to the raid panel on the left edge of the screen.",
get = function(info) return addon:GetOption(info[#info]) end,
set = function(info, val) addon:SetOption(info[#info], val) end,
width = "normal"
}
option.args.xOffset = {
order = 115,
name = "x Offset",
desc = "Pixels between the left of the screen and the topleft corner of the frame container.",
type = "range",
min = 0,
step = 1,
disabled = function(...) return addon:GetOption("isAttached") end,
max = math.floor(GetScreenWidth()-RAID_CONTAINER_WIDTH),
width = "normal",
get = function(info) return addon:GetOption(info[#info]) end,
set = function(info, val) addon:SetOption(info[#info], val) end
}
option.args.yOffset = {
order = 120,
name = "y Offset",
desc = "Pixels between the bottom of the screen and the topleft corner of the frame container.",
type = "range",
min = MINIMUM_RAID_CONTAINER_HEIGHT,
step = 1,
disabled = function(...) return addon:GetOption("isAttached") end,
max = math.floor(GetScreenHeight()),
get = function(info) return addon:GetOption(info[#info]) end,
set = function(info, val) addon:SetOption(info[#info], val) end
}
option.args.spacer3 = {
name = "",
type = 'description',
width = 'full',
cmdHidden = true,
order = 125,
}
option.args.frameHeight = {
order = 130,
name = "Frame Height",
desc = "Height of the frame block.",
type = "range",
min = MINIMUM_RAID_BLOCK_HEIGHT,
step = 1,
max = MAXIMUM_RAID_BLOCK_HEIGHT,
get = function(info) return addon:GetOption(info[#info]) end,
set = function(info, val) addon:SetOption(info[#info], val) end
}
option.args.frameWidth = {
order = 135,
name = "Frame Width",
desc = "Width of the frame block.",
type = "range",
min = MINIMUM_RAID_BLOCK_WIDTH,
step = 1,
max = MAXIMUM_RAID_BLOCK_WIDTH,
get = function(info) return addon:GetOption(info[#info]) end,
set = function(info, val) addon:SetOption(info[#info], val) end
}
option.args.containerHeight = {
order = 140,
name = "Container Height",
desc = "Pixels of the height of the frame container.",
type = "range",
min = MINIMUM_RAID_CONTAINER_HEIGHT,
step = 1,
max = math.floor(math.min(GetScreenHeight()-90,addon:GetOption("yOffset"))),
get = function(info) return addon:GetOption(info[#info]) end,
set = function(info, val) addon:SetOption(info[#info], val) end
}
return option
end
function addon:GetOption(optionName)
local manager = CompactRaidFrameManager
local top = manager.containerResizeFrame:GetTop()
local bottom = manager.containerResizeFrame:GetBottom()
local isAttached = (select(2, manager.containerResizeFrame:GetPoint(1)) == manager)
local left = manager.containerResizeFrame:GetLeft()
if (optionName == "isAttached") then
return isAttached
elseif (optionName == "xOffset") then
return math.floor(left)
elseif (optionName == "yOffset") then
return math.floor(top)
elseif (optionName == "containerHeight") then
return math.floor(top-bottom)
elseif (optionName == "frameWidth") then
return self.db.profile.options[addon:GetActiveRaidProfileId()]["frameWidth"]
elseif (optionName == "frameHeight") then
return self.db.profile.options[addon:GetActiveRaidProfileId()]["frameHeight"]
end
end
function addon:SetOption(optionName, value)
if not self.inCombat then
self.disableOptionPanelUpdate = true
self.needReload = true
if (optionName == "frameWidth") then
SetRaidProfileOption(GetActiveRaidProfile(), "frameWidth", value)
CompactUnitFrameProfiles_ApplyCurrentSettings()
elseif (optionName == "frameHeight") then
SetRaidProfileOption(GetActiveRaidProfile(), "frameHeight", value)
CompactUnitFrameProfiles_ApplyCurrentSettings()
else
local manager = CompactRaidFrameManager
if (optionName == "isAttached") then
manager.dynamicContainerPosition = value
end
if ( manager.dynamicContainerPosition ) then
SetRaidProfileSavedPosition(GetActiveRaidProfile(), true)
else
local topPoint, topOffset
local bottomPoint, bottomOffset
local leftPoint, leftOffset
local screenHeight = GetScreenHeight()
local top = manager.containerResizeFrame:GetTop()
local topDifference = 0
if (optionName == "yOffset") then
topDifference = value - top
top = value
end
if ( top > screenHeight / 2 ) then
topPoint = "TOP"
topOffset = screenHeight - top
else
topPoint = "BOTTOM"
topOffset = top
end
local bottom = manager.containerResizeFrame:GetBottom()
if (optionName == "yOffset") then
bottom = bottom + topDifference
if (bottom < 0) then
bottom = 0
end
elseif (optionName == "containerHeight") then
bottom = top - value
end
if ( bottom > screenHeight / 2 ) then
bottomPoint = "TOP"
bottomOffset = screenHeight - bottom
else
bottomPoint = "BOTTOM"
bottomOffset = bottom
end
local isAttached = (select(2, manager.containerResizeFrame:GetPoint(1)) == manager)
if (optionName == "isAttached") then
isAttached = value
end
if ( isAttached ) then
leftPoint = "ATTACHED"
leftOffset = 0
else
local screenWidth = GetScreenWidth()
local left = manager.containerResizeFrame:GetLeft()
if (optionName == "xOffset") then
left = value
end
if ( left > screenWidth / 2 ) then
leftPoint = "RIGHT"
leftOffset = screenWidth - left
else
leftPoint = "LEFT"
leftOffset = left
end
end
SetRaidProfileSavedPosition(GetActiveRaidProfile(), false
, topPoint, topOffset, bottomPoint, bottomOffset, leftPoint, leftOffset)
end
CompactRaidFrameManager_ResizeFrame_LoadPosition(CompactRaidFrameManager)
end
self.disableOptionPanelUpdate = false
addon:UnlockFrame()
addon:UpdateOptionsPanel()
else
addon:Print("Cannot change options in combat.")
end
end