You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
787 lines
31 KiB
787 lines
31 KiB
local PA = _G.ProjectAzilroka
|
|
local stAM = PA:NewModule('stAddonManager', 'AceEvent-3.0')
|
|
PA.stAM, _G.stAddonManager = stAM, stAM
|
|
|
|
_G.stAddonManagerProfilesDB = {}
|
|
_G.stAddonManagerServerDB = {}
|
|
|
|
stAM.Title = PA.ACL['|cFF16C3F2st|r|cFFFFFFFFAddonManager|r']
|
|
stAM.Description = PA.ACL['A simple and minimalistic addon to disable/enabled addons without logging out.']
|
|
stAM.Authors = 'Azilroka Safturento'
|
|
stAM.isEnabled = false
|
|
|
|
local _G = _G
|
|
local unpack = unpack
|
|
local tinsert = tinsert
|
|
local wipe = wipe
|
|
local pairs = pairs
|
|
local sort = sort
|
|
local format = format
|
|
local strlen = strlen
|
|
local strlower = strlower
|
|
local strfind = strfind
|
|
local min = min
|
|
local max = max
|
|
local concat = table.concat
|
|
local select = select
|
|
local gsub = gsub
|
|
|
|
local GetNumAddOns = GetNumAddOns
|
|
local GetAddOnInfo = GetAddOnInfo
|
|
local GetAddOnDependencies = GetAddOnDependencies
|
|
local GetAddOnOptionalDependencies = GetAddOnOptionalDependencies
|
|
local DisableAddOn = DisableAddOn
|
|
local EnableAddOn = EnableAddOn
|
|
local GetAddOnMetadata = GetAddOnMetadata
|
|
local DisableAllAddOns = DisableAllAddOns
|
|
local EnableAllAddOns = EnableAllAddOns
|
|
|
|
local CreateFrame = CreateFrame
|
|
local UIParent = UIParent
|
|
local GameTooltip = GameTooltip
|
|
|
|
local IsShiftKeyDown = IsShiftKeyDown
|
|
|
|
_G.StaticPopupDialogs.STADDONMANAGER_OVERWRITEPROFILE = {
|
|
button1 = PA.ACL['Overwrite'],
|
|
button2 = PA.ACL['Cancel'],
|
|
timeout = 0,
|
|
whileDead = 1,
|
|
enterClicksFirstButton = 1,
|
|
hideOnEscape = 1,
|
|
}
|
|
|
|
_G.StaticPopupDialogs.STADDONMANAGER_NEWPROFILE = {
|
|
text = PA.ACL['Enter a name for your new Addon Profile:'],
|
|
button1 = PA.ACL['Create'],
|
|
button2 = PA.ACL['Cancel'],
|
|
timeout = 0,
|
|
hasEditBox = 1,
|
|
whileDead = 1,
|
|
OnAccept = function(self) stAM:NewAddOnProfile(self.editBox:GetText()) end,
|
|
EditBoxOnEnterPressed = function(self) stAM:NewAddOnProfile(self:GetText()) self:GetParent():Hide() end,
|
|
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end,
|
|
}
|
|
|
|
_G.StaticPopupDialogs.STADDONMANAGER_RENAMEPROFILE = {
|
|
text = PA.ACL['Enter a name for your AddOn Profile:'],
|
|
button1 = PA.ACL['Update'],
|
|
button2 = PA.ACL['Cancel'],
|
|
timeout = 0,
|
|
hasEditBox = 1,
|
|
whileDead = 1,
|
|
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end,
|
|
}
|
|
|
|
_G.StaticPopupDialogs.STADDONMANAGER_DELETECONFIRMATION = {
|
|
button1 = PA.ACL['Delete'],
|
|
button2 = PA.ACL['Cancel'],
|
|
timeout = 0,
|
|
whileDead = 1,
|
|
enterClicksFirstButton = 1,
|
|
hideOnEscape = 1,
|
|
}
|
|
|
|
local function strtrim(str)
|
|
return gsub(str, '^%s*(.-)%s*$', '%1')
|
|
end
|
|
|
|
function stAM:BuildFrame()
|
|
local Frame = CreateFrame('Frame', 'stAMFrame', UIParent)
|
|
local Close = CreateFrame('Button', 'stAMCloseButton', Frame)
|
|
local Search = CreateFrame('EditBox', 'stAMSearchBox', Frame, 'SearchBoxTemplate')
|
|
|
|
local Profiles = CreateFrame('Button', 'stAMProfiles', Frame)
|
|
local AddOns = CreateFrame('Frame', 'stAMAddOns', Frame)
|
|
local Slider = CreateFrame('Slider', nil, AddOns)
|
|
|
|
local Reload = CreateFrame('Button', 'stAMReload', Frame)
|
|
local RequiredAddons = CreateFrame('CheckButton', nil, Frame)
|
|
local OptionalAddons = CreateFrame('CheckButton', nil, Frame)
|
|
local CharacterSelect = CreateFrame('Button', nil, Frame)
|
|
|
|
local Title = Frame:CreateFontString(nil, 'OVERLAY')
|
|
|
|
-- Defines
|
|
local font, fontSize, fontFlag = PA.LSM:Fetch('font', stAM.db.Font), stAM.db.FontSize, stAM.db.FontFlag
|
|
local Texture = PA.LSM:Fetch('statusbar', stAM.db.CheckTexture)
|
|
local FrameWidth = stAM.db.FrameWidth
|
|
local NumAddOns = stAM.db.NumAddOns
|
|
local Color = stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor
|
|
local Width, Height = stAM.db.ButtonWidth, stAM.db.ButtonHeight
|
|
|
|
Frame:SetSize(FrameWidth, 10 + NumAddOns * 25 + 40)
|
|
Frame:SetPoint('CENTER', UIParent, 'CENTER', 0, 0)
|
|
PA:SetTemplate(Frame)
|
|
Frame:Hide()
|
|
Frame:SetFrameStrata('HIGH')
|
|
Frame:SetClampedToScreen(true)
|
|
Frame:SetMovable(true)
|
|
Frame:EnableMouse(true)
|
|
Frame:SetScript('OnMouseDown', Frame.StartMoving)
|
|
Frame:SetScript('OnMouseUp', Frame.StopMovingOrSizing)
|
|
|
|
Title:SetPoint('TOPLEFT', 0, -5)
|
|
Title:SetPoint('TOPRIGHT', 0, -5)
|
|
Title:SetFont(font, 14, fontFlag)
|
|
Title:SetText(stAM.Title)
|
|
Title:SetJustifyH('CENTER')
|
|
Title:SetJustifyV('MIDDLE')
|
|
|
|
PA:SetTemplate(Close)
|
|
Close:SetPoint('TOPRIGHT', -3, -3)
|
|
Close:SetSize(16, 16)
|
|
Close:SetScript('OnEnter', function() Close:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor)) end)
|
|
Close:SetScript('OnLeave', function() PA:SetTemplate(Close) end)
|
|
Close:SetScript('OnClick', function() Frame:Hide() end)
|
|
|
|
local Mask = Close:CreateMaskTexture()
|
|
Mask:SetTexture('Interface/AddOns/ProjectAzilroka/Media/Textures/Close', 'CLAMPTOBLACKADDITIVE', 'CLAMPTOBLACKADDITIVE')
|
|
Mask:SetSize(10, 10)
|
|
Mask:SetPoint('CENTER')
|
|
|
|
Close.Mask = Mask
|
|
|
|
Close:SetNormalTexture(Texture)
|
|
Close:SetPushedTexture(Texture)
|
|
|
|
local Normal, Pushed = Close:GetNormalTexture(), Close:GetPushedTexture()
|
|
|
|
PA:SetInside(Normal, Close)
|
|
Normal:SetVertexColor(1, 1, 1)
|
|
Normal:AddMaskTexture(Mask)
|
|
|
|
PA:SetInside(Pushed, Close)
|
|
Pushed:SetVertexColor(1, .2, .2)
|
|
Pushed:AddMaskTexture(Mask)
|
|
|
|
Search:SetPoint('TOPLEFT', Title, 'BOTTOMLEFT', 10, -10)
|
|
Search:SetPoint('BOTTOMRIGHT', Profiles, 'BOTTOMLEFT', -5, 0)
|
|
Search:SetSize(1, 20)
|
|
Search.Left:SetTexture()
|
|
Search.Middle:SetTexture()
|
|
Search.Right:SetTexture()
|
|
PA:SetTemplate(Search)
|
|
Search.AddOns = {}
|
|
Search:HookScript('OnEscapePressed', function() stAM:UpdateAddonList() end)
|
|
Search:HookScript('OnTextChanged', function(_, userInput) stAM.scrollOffset = 0 stAM.searchQuery = userInput stAM:UpdateAddonList() end)
|
|
Search:HookScript('OnEditFocusGained', function() Search:SetBackdropBorderColor(unpack(stAM.db.CheckColor)) Search:HighlightText() end)
|
|
Search:HookScript('OnEditFocusLost', function() PA:SetTemplate(Search) Search:HighlightText(0, 0) PA:SetTemplate(Search) end)
|
|
Search.clearButton:HookScript('OnClick', stAM.UpdateAddonList)
|
|
|
|
PA:SetTemplate(Reload)
|
|
Reload:SetSize(70, 20)
|
|
Reload:SetScript('OnEnter', function() Reload:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor)) end)
|
|
Reload:SetScript('OnLeave', function() PA:SetTemplate(Reload) end)
|
|
Reload:SetScript('OnClick', _G.ReloadUI)
|
|
Reload.Text = Reload:CreateFontString(nil, 'OVERLAY')
|
|
Reload.Text:SetFont(font, 12, fontFlag)
|
|
Reload.Text:SetText(PA.ACL['Reload'])
|
|
Reload.Text:SetPoint('CENTER', 0, 0)
|
|
Reload.Text:SetJustifyH('CENTER')
|
|
Reload:SetPoint('TOPLEFT', AddOns, 'BOTTOMLEFT', 0, -10)
|
|
|
|
RequiredAddons:SetPoint('LEFT', Reload, 'RIGHT', 50, 0)
|
|
PA:SetTemplate(RequiredAddons)
|
|
RequiredAddons:SetSize(20, 20)
|
|
RequiredAddons:SetScript('OnClick', function()
|
|
stAM.db.EnableRequiredAddons = not stAM.db.EnableRequiredAddons
|
|
end)
|
|
RequiredAddons:SetScript('OnEnter', function()
|
|
GameTooltip:SetOwner(RequiredAddons, 'ANCHOR_TOPRIGHT', 0, 4)
|
|
GameTooltip:ClearLines()
|
|
GameTooltip:AddLine(PA.ACL['Enable Required AddOns'], 1, 1, 1)
|
|
GameTooltip:AddLine(PA.ACL['This will attempt to enable all the "Required" AddOns for the selected AddOn.'], 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end)
|
|
RequiredAddons:SetScript('OnLeave', function() PA:SetTemplate(RequiredAddons) GameTooltip:Hide() end)
|
|
|
|
RequiredAddons.CheckTexture = RequiredAddons:CreateTexture(nil, 'OVERLAY', nil, 1)
|
|
RequiredAddons.CheckTexture:SetTexture(Texture)
|
|
RequiredAddons.CheckTexture:SetVertexColor(unpack(Color))
|
|
PA:SetInside(RequiredAddons.CheckTexture, RequiredAddons)
|
|
|
|
RequiredAddons:SetCheckedTexture(RequiredAddons.CheckTexture)
|
|
RequiredAddons:SetHighlightTexture('')
|
|
|
|
RequiredAddons.Text = RequiredAddons:CreateFontString(nil, 'OVERLAY')
|
|
RequiredAddons.Text:SetPoint('LEFT', RequiredAddons, 'RIGHT', 5, 0)
|
|
RequiredAddons.Text:SetFont(font, 12, fontFlag)
|
|
RequiredAddons.Text:SetText(PA.ACL['Required'])
|
|
|
|
RequiredAddons:SetChecked(stAM.db.EnableRequiredAddons)
|
|
|
|
CharacterSelect:SetPoint('TOPRIGHT', AddOns, 'BOTTOMRIGHT', 0, -10)
|
|
CharacterSelect.DropDown = CreateFrame('Frame', 'stAMCharacterSelectDropDown', CharacterSelect, 'UIDropDownMenuTemplate')
|
|
CharacterSelect:SetSize(150, 20)
|
|
PA:SetTemplate(CharacterSelect)
|
|
CharacterSelect:SetScript('OnEnter', function() CharacterSelect:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor)) end)
|
|
CharacterSelect:SetScript('OnLeave', function() PA:SetTemplate(CharacterSelect) end)
|
|
CharacterSelect:SetScript('OnClick', function() _G.EasyMenu(stAM.Menu, CharacterSelect.DropDown, CharacterSelect, 0, 38 + (stAM.MenuOffset * 16), 'MENU', 5) end)
|
|
CharacterSelect.Text = CharacterSelect:CreateFontString(nil, 'OVERLAY')
|
|
CharacterSelect.Text:SetFont(font, 12, fontFlag)
|
|
CharacterSelect.Text:SetText(PA.ACL['Character Select'])
|
|
CharacterSelect.Text:SetPoint('CENTER', 0, 0)
|
|
CharacterSelect.Text:SetJustifyH('CENTER')
|
|
|
|
Profiles:SetPoint('TOPRIGHT', Title, 'BOTTOMRIGHT', -10, -10)
|
|
PA:SetTemplate(Profiles)
|
|
Profiles:SetSize(70, 20)
|
|
Profiles:SetScript('OnEnter', function() Profiles:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor)) end)
|
|
Profiles:SetScript('OnLeave', function() PA:SetTemplate(Profiles) end)
|
|
Profiles:SetScript('OnClick', function() stAM:ToggleProfiles() end)
|
|
|
|
Profiles.Text = Profiles:CreateFontString(nil, 'OVERLAY')
|
|
Profiles.Text:SetFont(font, 12, fontFlag)
|
|
Profiles.Text:SetText(PA.ACL['Profiles'])
|
|
Profiles.Text:SetPoint('CENTER', 0, 0)
|
|
Profiles.Text:SetJustifyH('CENTER')
|
|
|
|
AddOns:SetPoint('TOPLEFT', Search, 'BOTTOMLEFT', 0, -5)
|
|
AddOns:SetPoint('TOPRIGHT', Profiles, 'BOTTOMRIGHT', 0, -5)
|
|
AddOns:SetHeight(NumAddOns * (Height + 5) + 15)
|
|
PA:SetTemplate(AddOns)
|
|
AddOns.Buttons = {}
|
|
AddOns:EnableMouse(true)
|
|
AddOns:EnableMouseWheel(true)
|
|
|
|
Slider:SetPoint('RIGHT', -2, 0)
|
|
Slider:SetWidth(12)
|
|
Slider:SetHeight(NumAddOns * (Height + 5) + 11)
|
|
Slider:SetThumbTexture(PA.LSM:Fetch('background', 'Solid'))
|
|
Slider:SetOrientation('VERTICAL')
|
|
Slider:SetValueStep(1)
|
|
PA:SetTemplate(Slider)
|
|
Slider:SetMinMaxValues(0, 1)
|
|
Slider:SetValue(0)
|
|
Slider:EnableMouse(true)
|
|
Slider:EnableMouseWheel(true)
|
|
|
|
local Thumb = Slider:GetThumbTexture()
|
|
Thumb:SetSize(8, 16)
|
|
Thumb:SetVertexColor(unpack(Color))
|
|
|
|
AddOns.ScrollBar = Slider
|
|
|
|
local OnScroll = function(_, delta)
|
|
local numAddons = stAM.searchQuery and #Search.AddOns or #stAM.AddOnInfo
|
|
if numAddons < stAM.db.NumAddOns then return end
|
|
|
|
if IsShiftKeyDown() then
|
|
if delta == 1 then
|
|
stAM.scrollOffset = max(0, stAM.scrollOffset - stAM.db.NumAddOns)
|
|
elseif delta == -1 then
|
|
stAM.scrollOffset = min(numAddons - stAM.db.NumAddOns, stAM.scrollOffset + stAM.db.NumAddOns)
|
|
end
|
|
else
|
|
if delta == 1 and stAM.scrollOffset > 0 then
|
|
stAM.scrollOffset = stAM.scrollOffset - 1
|
|
elseif delta == -1 then
|
|
if stAM.scrollOffset < numAddons - stAM.db.NumAddOns then
|
|
stAM.scrollOffset = stAM.scrollOffset + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
Slider:SetMinMaxValues(0, (numAddons - stAM.db.NumAddOns))
|
|
Slider:SetValue(stAM.scrollOffset)
|
|
stAM:UpdateAddonList()
|
|
end
|
|
|
|
AddOns:SetScript('OnMouseWheel', OnScroll)
|
|
Slider:SetScript('OnMouseWheel', OnScroll)
|
|
Slider:SetScript('OnValueChanged', function(_, value)
|
|
stAM.scrollOffset = value
|
|
OnScroll()
|
|
end)
|
|
|
|
for i = 1, 30 do
|
|
local CheckButton = CreateFrame('CheckButton', 'stAMCheckButton_'..i, AddOns)
|
|
CheckButton:Hide()
|
|
PA:SetTemplate(CheckButton)
|
|
CheckButton:SetSize(Width, Height)
|
|
CheckButton:SetPoint(unpack(i == 1 and {'TOPLEFT', AddOns, 'TOPLEFT', 10, -10} or {'TOP', AddOns.Buttons[i-1], 'BOTTOM', 0, -5}))
|
|
CheckButton:SetScript('OnClick', function()
|
|
if CheckButton.name then
|
|
if PA:IsAddOnEnabled(CheckButton.name, stAM.SelectedCharacter) then
|
|
DisableAddOn(CheckButton.name, stAM.SelectedCharacter)
|
|
else
|
|
EnableAddOn(CheckButton.name, stAM.SelectedCharacter)
|
|
if stAM.db.EnableRequiredAddons and CheckButton.required then
|
|
for _, AddOn in pairs(CheckButton.required) do
|
|
EnableAddOn(AddOn)
|
|
end
|
|
end
|
|
end
|
|
stAM:UpdateAddonList()
|
|
end
|
|
end)
|
|
CheckButton:SetScript('OnEnter', function()
|
|
GameTooltip:SetOwner(CheckButton, 'ANCHOR_TOPRIGHT', 0, 4)
|
|
GameTooltip:ClearLines()
|
|
GameTooltip:AddDoubleLine('AddOn:', CheckButton.title, 1, 1, 1, 1, 1, 1)
|
|
GameTooltip:AddDoubleLine(PA.ACL['Authors:'], CheckButton.authors, 1, 1, 1, 1, 1, 1)
|
|
GameTooltip:AddDoubleLine(PA.ACL['Version:'], CheckButton.version, 1, 1, 1, 1, 1, 1)
|
|
if CheckButton.notes ~= nil then
|
|
GameTooltip:AddDoubleLine('Notes:', CheckButton.notes, 1, 1, 1, 1, 1, 1)
|
|
end
|
|
if CheckButton.required or CheckButton.optional then
|
|
GameTooltip:AddLine(' ')
|
|
end
|
|
if CheckButton.required then
|
|
GameTooltip:AddDoubleLine('Required Dependencies:', concat(CheckButton.required, ', '), 1, 1, 1, 1, 1, 1)
|
|
end
|
|
if CheckButton.optional then
|
|
GameTooltip:AddDoubleLine('Optional Dependencies:', concat(CheckButton.optional, ', '), 1, 1, 1, 1, 1, 1)
|
|
end
|
|
GameTooltip:Show()
|
|
CheckButton:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor))
|
|
end)
|
|
CheckButton:SetScript('OnLeave', function() PA:SetTemplate(CheckButton) GameTooltip:Hide() end)
|
|
|
|
local Checked = CheckButton:CreateTexture(nil, 'OVERLAY', nil, 1)
|
|
Checked:SetTexture(Texture)
|
|
Checked:SetVertexColor(unpack(Color))
|
|
PA:SetInside(Checked, CheckButton)
|
|
|
|
CheckButton.CheckTexture = Checked
|
|
CheckButton:SetCheckedTexture(Checked)
|
|
|
|
CheckButton:SetHighlightTexture('')
|
|
|
|
local Text = CheckButton:CreateFontString(nil, 'OVERLAY')
|
|
Text:SetFont(font, fontSize, fontFlag)
|
|
Text:SetText('')
|
|
Text:SetJustifyH('CENTER')
|
|
Text:ClearAllPoints()
|
|
Text:SetPoint('LEFT', CheckButton, 'RIGHT', 10, 0)
|
|
Text:SetPoint('TOP', CheckButton, 'TOP')
|
|
Text:SetPoint('BOTTOM', CheckButton, 'BOTTOM')
|
|
Text:SetPoint('RIGHT', AddOns, 'CENTER', 0, 0)
|
|
Text:SetJustifyH('LEFT')
|
|
|
|
CheckButton.Text = Text
|
|
|
|
local StatusText = CheckButton:CreateFontString(nil, 'OVERLAY')
|
|
StatusText:SetFont(font, fontSize, fontFlag)
|
|
StatusText:SetText('')
|
|
StatusText:SetJustifyH('CENTER')
|
|
StatusText:ClearAllPoints()
|
|
StatusText:SetPoint('LEFT', Text, 'RIGHT', 0, 0)
|
|
StatusText:SetPoint('TOP', CheckButton, 'TOP')
|
|
StatusText:SetPoint('BOTTOM', CheckButton, 'BOTTOM')
|
|
StatusText:SetPoint('RIGHT', AddOns, 'RIGHT', -10, 0)
|
|
StatusText:SetJustifyH('LEFT')
|
|
|
|
CheckButton.StatusText = StatusText
|
|
|
|
local Icon = CheckButton:CreateTexture(nil, 'OVERLAY')
|
|
Icon:SetTexture('Interface/AddOns/ProjectAzilroka/Media/Textures/QuestBang')
|
|
Icon:SetPoint('CENTER', CheckButton, 'RIGHT', 10, 0)
|
|
Icon:SetSize(32, 32)
|
|
|
|
CheckButton.Icon = Icon
|
|
|
|
AddOns.Buttons[i] = CheckButton
|
|
end
|
|
|
|
Frame.Title = Title
|
|
Frame.Close = Close
|
|
Frame.Reload = Reload
|
|
Frame.RequiredAddons = RequiredAddons
|
|
Frame.OptionalAddons = OptionalAddons
|
|
Frame.Search = Search
|
|
Frame.CharacterSelect = CharacterSelect
|
|
Frame.Profiles = Profiles
|
|
Frame.AddOns = AddOns
|
|
|
|
Frame.AddOns:SetHeight(stAM.db.NumAddOns * (stAM.db.ButtonHeight + 5) + 15)
|
|
Frame:SetSize(stAM.db.FrameWidth, Frame.Title:GetHeight() + Frame.Search:GetHeight() + Frame.AddOns:GetHeight() + Frame.Profiles:GetHeight() + 40)
|
|
|
|
stAM.Frame = Frame
|
|
|
|
tinsert(_G.UISpecialFrames, stAM.Frame:GetName())
|
|
|
|
_G.GameMenuButtonAddons:SetScript('OnClick', function() stAM.Frame:Show() _G.HideUIPanel(_G.GameMenuFrame) end)
|
|
end
|
|
|
|
function stAM:NewAddOnProfile(name, overwrite)
|
|
if _G.stAddonManagerProfilesDB[name] and (not overwrite) then
|
|
_G.StaticPopupDialogs['STADDONMANAGER_OVERWRITEPROFILE'].text = format(PA.ACL['There is already a profile named %s. Do you want to overwrite it?'], name)
|
|
_G.StaticPopupDialogs['STADDONMANAGER_OVERWRITEPROFILE'].OnAccept = function() stAM:NewAddOnProfile(name, true) end
|
|
_G.StaticPopup_Show('STADDONMANAGER_OVERWRITEPROFILE')
|
|
return
|
|
end
|
|
|
|
_G.stAddonManagerProfilesDB[name] = {}
|
|
|
|
for i = 1, #stAM.AddOnInfo do
|
|
local AddOn, isEnabled = stAM.AddOnInfo[i].Name, PA:IsAddOnEnabled(i, stAM.SelectedCharacter)
|
|
if isEnabled then
|
|
tinsert(_G.stAddonManagerProfilesDB[name], AddOn)
|
|
end
|
|
end
|
|
|
|
stAM:UpdateProfiles()
|
|
end
|
|
|
|
function stAM:InitProfiles()
|
|
local ProfileMenu = CreateFrame('Frame', 'stAMProfileMenu', stAM.Frame)
|
|
ProfileMenu:SetPoint('TOPLEFT', stAM.Frame, 'TOPRIGHT', 3, 0)
|
|
ProfileMenu:SetSize(250, 50)
|
|
PA:SetTemplate(ProfileMenu)
|
|
ProfileMenu:Hide()
|
|
|
|
for _, name in pairs({'EnableAll', 'DisableAll', 'NewButton'}) do
|
|
local Button = CreateFrame('Button', nil, ProfileMenu)
|
|
PA:SetTemplate(Button)
|
|
Button:SetSize(stAM.db.ButtonWidth, stAM.db.ButtonHeight)
|
|
Button:SetScript('OnEnter', function() Button:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor)) end)
|
|
Button:SetScript('OnLeave', function() PA:SetTemplate(Button) end)
|
|
|
|
Button.Text = Button:CreateFontString(nil, 'OVERLAY')
|
|
Button.Text:SetFont(PA.LSM:Fetch('font', stAM.db.Font), 12, 'OUTLINE')
|
|
Button.Text:SetPoint('CENTER', 0, 0)
|
|
Button.Text:SetJustifyH('CENTER')
|
|
|
|
ProfileMenu[name] = Button
|
|
end
|
|
|
|
ProfileMenu.EnableAll.Text:SetText(PA.ACL['Enable All'])
|
|
ProfileMenu.EnableAll:SetPoint('TOPLEFT', ProfileMenu, 'TOPLEFT', 10, -10)
|
|
ProfileMenu.EnableAll:SetPoint('TOPRIGHT', ProfileMenu, 'TOP', -3, -10)
|
|
ProfileMenu.EnableAll:SetScript('OnClick', function() EnableAllAddOns(stAM.SelectedCharacter) stAM:UpdateAddonList() end)
|
|
|
|
ProfileMenu.DisableAll.Text:SetText(PA.ACL['Disable All'])
|
|
ProfileMenu.DisableAll:SetPoint('TOPRIGHT', ProfileMenu, 'TOPRIGHT', -10, -10)
|
|
ProfileMenu.DisableAll:SetPoint('TOPLEFT', ProfileMenu, 'TOP', 2, -10)
|
|
ProfileMenu.DisableAll:SetScript('OnClick', function() DisableAllAddOns(stAM.SelectedCharacter) stAM:UpdateAddonList() end)
|
|
|
|
ProfileMenu.NewButton.Text:SetText(PA.ACL['New Profile'])
|
|
ProfileMenu.NewButton:SetPoint('TOPLEFT', ProfileMenu.EnableAll, 'BOTTOMLEFT', 0, -5)
|
|
ProfileMenu.NewButton:SetPoint('TOPRIGHT', ProfileMenu.DisableAll, 'BOTTOMRIGHT', 0, -5)
|
|
ProfileMenu.NewButton:SetScript('OnClick', function() _G.StaticPopup_Show('STADDONMANAGER_NEWPROFILE') end)
|
|
|
|
ProfileMenu.Buttons = {}
|
|
|
|
for i = 1, 30 do
|
|
local Pullout = CreateFrame('Frame', nil, ProfileMenu)
|
|
Pullout:SetWidth(210)
|
|
Pullout:SetHeight(stAM.db.ButtonHeight)
|
|
Pullout:Hide()
|
|
|
|
for _, Frame in pairs({'Load', 'Delete', 'Update'}) do
|
|
local Button = CreateFrame('Button', nil, Pullout)
|
|
PA:SetTemplate(Button)
|
|
Button:SetSize(73, stAM.db.ButtonHeight)
|
|
Button:RegisterForClicks('AnyDown')
|
|
Button:SetScript('OnEnter', function() Button:SetBackdropBorderColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor)) end)
|
|
Button:SetScript('OnLeave', function() PA:SetTemplate(Button) end)
|
|
|
|
Button.Text = Button:CreateFontString(nil, 'OVERLAY')
|
|
Button.Text:SetFont(PA.LSM:Fetch('font', stAM.db.Font), 12, 'OUTLINE')
|
|
Button.Text:SetPoint('CENTER', 0, 0)
|
|
Button.Text:SetJustifyH('CENTER')
|
|
|
|
Pullout[Frame] = Button
|
|
end
|
|
|
|
Pullout.Load:SetPoint('LEFT', Pullout, 0, 0)
|
|
Pullout.Load.Text:SetText('Load')
|
|
Pullout.Load:SetScript('OnClick', function(_, btn)
|
|
if btn == 'RightButton' then
|
|
local Dialog = _G.StaticPopupDialogs.STADDONMANAGER_RENAMEPROFILE
|
|
Dialog.OnAccept = function(dialog)
|
|
_G.stAddonManagerProfilesDB[Pullout.Name] = nil
|
|
stAM:NewAddOnProfile(dialog.editBox:GetText())
|
|
stAM:UpdateProfiles()
|
|
end
|
|
Dialog.EditBoxOnEnterPressed = function(editBox)
|
|
_G.stAddonManagerProfilesDB[Pullout.Name] = nil
|
|
stAM:NewAddOnProfile(editBox:GetText())
|
|
stAM:UpdateProfiles()
|
|
editBox:GetParent():Hide()
|
|
end
|
|
_G.StaticPopup_Show('STADDONMANAGER_RENAMEPROFILE')
|
|
else
|
|
if not IsShiftKeyDown() then
|
|
DisableAllAddOns(stAM.SelectedCharacter)
|
|
end
|
|
for _, AddOn in pairs(_G.stAddonManagerProfilesDB[Pullout.Name]) do
|
|
EnableAddOn(AddOn, stAM.SelectedCharacter)
|
|
end
|
|
|
|
stAM:UpdateAddonList()
|
|
end
|
|
end)
|
|
|
|
Pullout.Update:SetPoint('LEFT', Pullout.Load, 'RIGHT', 5, 0)
|
|
Pullout.Update.Text:SetText(PA.ACL['Update'])
|
|
Pullout.Update:SetScript('OnClick', function() stAM:NewAddOnProfile(Pullout.Name, true) end)
|
|
|
|
Pullout.Delete:SetPoint('LEFT', Pullout.Update, 'RIGHT', 5, 0)
|
|
Pullout.Delete.Text:SetText(PA.ACL['Delete'])
|
|
Pullout.Delete:SetScript('OnClick', function()
|
|
local dialog = _G.StaticPopupDialogs['STADDONMANAGER_DELETECONFIRMATION']
|
|
|
|
dialog.text = format(PA.ACL['Are you sure you want to delete %s?'], Pullout.Name)
|
|
dialog.OnAccept = function() _G.stAddonManagerProfilesDB[Pullout.Name] = nil stAM:UpdateProfiles() end
|
|
|
|
_G.StaticPopup_Show('STADDONMANAGER_DELETECONFIRMATION')
|
|
end)
|
|
|
|
ProfileMenu.Buttons[i] = Pullout
|
|
end
|
|
|
|
stAM.ProfileMenu = ProfileMenu
|
|
end
|
|
|
|
function stAM:UpdateProfiles()
|
|
local ProfileMenu = stAM.ProfileMenu
|
|
|
|
wipe(stAM.Profiles)
|
|
for name, _ in pairs(_G.stAddonManagerProfilesDB) do tinsert(stAM.Profiles, name) end
|
|
sort(stAM.Profiles)
|
|
|
|
local PreviousButton
|
|
for i, Button in ipairs(ProfileMenu.Buttons) do
|
|
local isShown = i <= min(#stAM.Profiles, 30)
|
|
if isShown then
|
|
Button.Load.Text:SetText(stAM.Profiles[i])
|
|
end
|
|
|
|
Button.Name = isShown and stAM.Profiles[i] or nil
|
|
Button:SetShown(isShown)
|
|
|
|
if i == 1 then
|
|
Button:SetPoint('TOPLEFT', ProfileMenu.NewButton, 'BOTTOMLEFT', 0, -5)
|
|
else
|
|
Button:SetPoint('TOP', PreviousButton, 'BOTTOM', 0, -5)
|
|
end
|
|
|
|
PreviousButton = Button
|
|
end
|
|
|
|
ProfileMenu:SetHeight((min(#stAM.Profiles, 30) + 2) * (stAM.db.ButtonHeight + 5) + 15)
|
|
end
|
|
|
|
function stAM:ToggleProfiles()
|
|
_G.ToggleFrame(stAM.ProfileMenu)
|
|
stAM:UpdateProfiles()
|
|
end
|
|
|
|
function stAM:UpdateAddonList()
|
|
wipe(stAM.Frame.Search.AddOns)
|
|
|
|
if stAM.searchQuery then
|
|
local query = strlower(strtrim(stAM.Frame.Search:GetText()))
|
|
|
|
if (strlen(query) == 0) then
|
|
stAM.searchQuery = false
|
|
end
|
|
|
|
for i, AddOn in ipairs(stAM.AddOnInfo) do
|
|
local name, title, authors = AddOn.Name, AddOn.Title, AddOn.Authors
|
|
|
|
if strfind(strlower(name), query) or strfind(strlower(title), query) or (authors and strfind(strlower(authors), query)) then
|
|
tinsert(stAM.Frame.Search.AddOns, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
for i, button in ipairs(stAM.Frame.AddOns.Buttons) do
|
|
local addonIndex = (not stAM.searchQuery and (stAM.scrollOffset + i)) or stAM.Frame.Search.AddOns[stAM.scrollOffset + i]
|
|
local info = stAM.AddOnInfo[addonIndex]
|
|
|
|
if addonIndex and addonIndex <= #stAM.AddOnInfo then
|
|
button.name, button.title, button.authors, button.version, button.notes, button.required, button.optional = info.Name, info.Title, info.Authors, info.Version, info.Notes, info.Required, info.Optional
|
|
button.Text:SetText(button.title)
|
|
button.Icon:SetShown(info.Missing or info.Disabled)
|
|
button.StatusText:SetShown(info.Missing or info.Disabled)
|
|
|
|
if info.Missing or info.Disabled then
|
|
if info.Missing then
|
|
button.Icon:SetVertexColor(.77, .12, .24)
|
|
button.StatusText:SetVertexColor(.77, .12, .24)
|
|
button.StatusText:SetText(PA.ACL['Missing: ']..concat(info.Missing, ', '))
|
|
else
|
|
button.Icon:SetVertexColor(1, .8, .1)
|
|
button.StatusText:SetVertexColor(1, .8, .1)
|
|
button.StatusText:SetText(PA.ACL['Disabled: ']..concat(info.Disabled, ', '))
|
|
end
|
|
|
|
button.Text:SetPoint('LEFT', button.Icon, 'CENTER', 5, 0)
|
|
button.Text:SetPoint('RIGHT', stAM.Frame.AddOns, 'CENTER', 0, 0)
|
|
else
|
|
button.Text:SetPoint('LEFT', button, 'RIGHT', 5, 0)
|
|
button.Text:SetPoint('RIGHT', stAM.Frame.AddOns, 'RIGHT', -10, 0)
|
|
end
|
|
|
|
button:SetChecked(PA:IsAddOnPartiallyEnabled(addonIndex, stAM.SelectedCharacter) or PA:IsAddOnEnabled(addonIndex, stAM.SelectedCharacter))
|
|
button.CheckTexture:SetVertexColor(unpack(PA:IsAddOnPartiallyEnabled(addonIndex, stAM.SelectedCharacter) and {.6, .6, .6} or stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor))
|
|
button:SetShown(i <= min(#stAM.Frame.Search.AddOns > 0 and #stAM.Frame.Search.AddOns or stAM.db.NumAddOns, stAM.db.NumAddOns))
|
|
else
|
|
button:SetShown(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
function stAM:Update()
|
|
if not stAM.Frame then return end
|
|
|
|
stAM.Frame:SetSize(stAM.db.FrameWidth, stAM.Frame.Title:GetHeight() + 5 + stAM.Frame.Search:GetHeight() + 5 + stAM.Frame.AddOns:GetHeight() + 10 + stAM.Frame.Profiles:GetHeight() + 20)
|
|
stAM.Frame.AddOns:SetHeight(stAM.db.NumAddOns * (stAM.db.ButtonHeight + 5) + 15)
|
|
stAM.Frame.AddOns.ScrollBar:SetHeight(stAM.db.NumAddOns * (stAM.db.ButtonHeight + 5) + 11)
|
|
|
|
local font, fontSize, fontFlag = PA.LSM:Fetch('font', stAM.db.Font), stAM.db.FontSize, stAM.db.FontFlag
|
|
|
|
for _, CheckButton in ipairs(stAM.Frame.AddOns.Buttons) do
|
|
CheckButton:SetSize(stAM.db.ButtonWidth, stAM.db.ButtonHeight)
|
|
CheckButton.Text:SetFont(font, fontSize, fontFlag)
|
|
CheckButton.StatusText:SetFont(font, fontSize, fontFlag)
|
|
CheckButton.CheckTexture:SetTexture(PA.LSM:Fetch('statusbar', stAM.db.CheckTexture))
|
|
CheckButton.CheckTexture:SetVertexColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor))
|
|
CheckButton:SetCheckedTexture(CheckButton.CheckTexture)
|
|
end
|
|
|
|
stAM.Frame.AddOns.ScrollBar:GetThumbTexture():SetVertexColor(unpack(stAM.db.ClassColor and PA.ClassColor or stAM.db.CheckColor))
|
|
stAM.Frame.Title:SetFont(font, 14, fontFlag)
|
|
stAM.Frame.Search:SetFont(font, 12, fontFlag)
|
|
stAM.Frame.Reload.Text:SetFont(font, 12, fontFlag)
|
|
stAM.Frame.Profiles.Text:SetFont(font, 12, fontFlag)
|
|
stAM.Frame.CharacterSelect.Text:SetFont(font, 12, fontFlag)
|
|
stAM.Frame.RequiredAddons.Text:SetFont(font, 12, fontFlag)
|
|
|
|
stAM.Frame.RequiredAddons:SetChecked(stAM.db.EnableRequiredAddons)
|
|
stAM.Frame.OptionalAddons:SetChecked(stAM.db.EnableOptionalAddons)
|
|
|
|
stAM.ProfileMenu.EnableAll.Text:SetFont(font, 12, fontFlag)
|
|
stAM.ProfileMenu.DisableAll.Text:SetFont(font, 12, fontFlag)
|
|
stAM.ProfileMenu.NewButton.Text:SetFont(font, 12, fontFlag)
|
|
|
|
for _, Button in ipairs(stAM.ProfileMenu.Buttons) do
|
|
Button.Load.Text:SetFont(font, 12, fontFlag)
|
|
Button.Update.Text:SetFont(font, 12, fontFlag)
|
|
Button.Delete.Text:SetFont(font, 12, fontFlag)
|
|
end
|
|
|
|
stAM:UpdateAddonList()
|
|
end
|
|
|
|
function stAM:GetOptions()
|
|
local stAddonManager = PA.ACH:Group(stAM.Title, stAM.Description, nil, nil, function(info) return stAM.db[info[#info]] end, function(info, value) stAM.db[info[#info]] = value stAM:Update() end)
|
|
PA.Options.args.stAddonManager = stAddonManager
|
|
|
|
stAddonManager.args.Description = PA.ACH:Description(stAM.Description, 0)
|
|
stAddonManager.args.Enable = PA.ACH:Toggle(PA.ACL['Enable'], nil, 1, nil, nil, nil, nil, function(info, value) stAM.db[info[#info]] = value if not stAM.isEnabled then stAM:Initialize() else _G.StaticPopup_Show('PROJECTAZILROKA_RL') end end)
|
|
|
|
stAddonManager.args.General = PA.ACH:Group(PA.ACL['General'], nil, 2)
|
|
stAddonManager.args.General.inline = true
|
|
|
|
stAddonManager.args.General.args.NumAddOns = PA.ACH:Range(PA.ACL['# Shown AddOns'], nil, 1, { min = 3, max = 30, step = 1 })
|
|
stAddonManager.args.General.args.FrameWidth = PA.ACH:Range(PA.ACL['Frame Width'], nil, 2, { min = 250, max = 2048, step = 2 })
|
|
stAddonManager.args.General.args.ButtonHeight = PA.ACH:Range(PA.ACL['Button Height'], nil, 3, { min = 3, max = 30, step = 1 })
|
|
stAddonManager.args.General.args.ButtonWidth = PA.ACH:Range(PA.ACL['Button Width'], nil, 4, { min = 3, max = 30, step = 1 })
|
|
stAddonManager.args.General.args.EnableRequiredAddons = PA.ACH:Toggle(PA.ACL['Enable Required AddOns'], PA.ACL['This will attempt to enable all the "Required" AddOns for the selected AddOn.'], 5)
|
|
stAddonManager.args.General.args.CheckTexture = PA.ACH:SharedMediaStatusbar(PA.ACL['Texture'], nil, 6)
|
|
stAddonManager.args.General.args.CheckColor = PA.ACH:Color(COLOR_PICKER, nil, 2, true, nil, function(info) return unpack(stAM.db[info[#info]]) end, function(info, r, g, b, a) stAM.db[info[#info]] = { r, g, b, a} stAM:Update() end, function() return stAM.db.ClassColor end)
|
|
stAddonManager.args.General.args.ClassColor = PA.ACH:Toggle(PA.ACL['Class Color Check Texture'], nil, 8)
|
|
|
|
stAddonManager.args.General.args.FontSettings = PA.ACH:Group(PA.ACL['Font Settings'], nil, -1)
|
|
stAddonManager.args.General.args.FontSettings.inline = true
|
|
stAddonManager.args.General.args.FontSettings.args.Font = PA.ACH:SharedMediaFont(PA.ACL['Font'], nil, 1)
|
|
stAddonManager.args.General.args.FontSettings.args.FontSize = PA.ACH:Range(FONT_SIZE, nil, 2, { min = 6, max = 22, step = 1 })
|
|
stAddonManager.args.General.args.FontSettings.args.FontFlag = PA.ACH:FontFlags(PA.ACL['Font Outline'], nil, 3)
|
|
|
|
stAddonManager.args.AuthorHeader = PA.ACH:Header(PA.ACL['Authors:'], -2)
|
|
stAddonManager.args.Authors = PA.ACH:Description(stAM.Authors, -1, 'large')
|
|
end
|
|
|
|
function stAM:BuildProfile()
|
|
PA.Defaults.profile.stAddonManager = {
|
|
Enable = true,
|
|
NumAddOns = 30,
|
|
FrameWidth = 550,
|
|
Font = 'PT Sans Narrow Bold',
|
|
FontSize = 16,
|
|
FontFlag = 'OUTLINE',
|
|
ButtonHeight = 18,
|
|
ButtonWidth = 22,
|
|
CheckColor = { 0, .66, 1},
|
|
ClassColor = false,
|
|
CheckTexture = 'Solid',
|
|
EnableRequiredAddons = true,
|
|
EnableOptionalAddons = false,
|
|
}
|
|
end
|
|
|
|
function stAM:UpdateSettings()
|
|
stAM.db = PA.db.stAddonManager
|
|
end
|
|
|
|
function stAM:Initialize()
|
|
stAM:UpdateSettings()
|
|
|
|
if stAM.db.Enable ~= true then
|
|
return
|
|
end
|
|
|
|
stAM.isEnabled = true
|
|
|
|
stAM.AddOnInfo = {}
|
|
stAM.Profiles = {}
|
|
|
|
for i = 1, GetNumAddOns() do
|
|
local Name, Title, Notes = GetAddOnInfo(i)
|
|
local Required, Optional = nil, nil
|
|
local MissingAddons, DisabledAddons
|
|
|
|
local HasRequired, HasOptional = GetAddOnDependencies(i), GetAddOnOptionalDependencies(i)
|
|
|
|
if HasRequired then
|
|
Required = { HasRequired }
|
|
for _, addon in pairs(Required) do
|
|
local Reason = select(5, GetAddOnInfo(addon))
|
|
if Reason == 'MISSING' then
|
|
MissingAddons = MissingAddons or {}
|
|
tinsert(MissingAddons, addon)
|
|
elseif Reason == 'DISABLED' then
|
|
DisabledAddons = DisabledAddons or {}
|
|
tinsert(DisabledAddons, addon)
|
|
end
|
|
end
|
|
end
|
|
|
|
if HasOptional then
|
|
Optional = { HasOptional }
|
|
end
|
|
|
|
local Authors = GetAddOnMetadata(i, 'Author')
|
|
local Version = GetAddOnMetadata(i, 'Version')
|
|
|
|
stAM.AddOnInfo[i] = { Name = Name, Title = Title, Authors = Authors, Version = Version, Notes = Notes, Required = Required, Optional = Optional, Missing = MissingAddons, Disabled = DisabledAddons }
|
|
end
|
|
|
|
stAM.SelectedCharacter = PA.MyName
|
|
|
|
stAM.Menu = {
|
|
{ text = 'All', checked = function() return stAM.SelectedCharacter == true end, func = function() stAM.SelectedCharacter = true stAM:UpdateAddonList() end}
|
|
}
|
|
|
|
_G.stAddonManagerServerDB[PA.MyRealm] = _G.stAddonManagerServerDB[PA.MyRealm] or {}
|
|
_G.stAddonManagerServerDB[PA.MyRealm][PA.MyName] = true
|
|
|
|
local index = 2
|
|
for Character in PA:PairsByKeys(_G.stAddonManagerServerDB[PA.MyRealm]) do
|
|
stAM.Menu[index] = { text = Character, checked = function() return stAM.SelectedCharacter == Character end, func = function() stAM.SelectedCharacter = Character stAM:UpdateAddonList() end }
|
|
index = index + 1
|
|
end
|
|
|
|
stAM.MenuOffset = index
|
|
|
|
stAM.scrollOffset = 0
|
|
|
|
stAM:BuildFrame()
|
|
stAM:InitProfiles()
|
|
stAM:Update()
|
|
end
|
|
|