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.

1999 lines
68 KiB

if not WeakAuras.IsLibsOK() then return end
---@type string
local AddonName = ...
---@class OptionsPrivate
local OptionsPrivate = select(2, ...)
local tinsert, tremove = table.insert, table.remove
local select, pairs, type, unpack = select, pairs, type, unpack
local error = error
local Type, Version = "WeakAurasDisplayButton", 60
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
local LibDD = LibStub:GetLibrary("LibUIDropDownMenu-4.0")
local L = WeakAuras.L;
local fullName;
local clipboard = {};
local function IsRegionAGroup(data)
return data and (data.regionType == "group" or data.regionType == "dynamicgroup");
end
local ignoreForCopyingDisplay = {
triggers = true,
conditions = true,
load = true,
actions = true,
animation = true,
id = true,
parent = true,
controlledChildren = true,
uid = true,
authorOptions = true,
config = true,
url = true,
semver = true,
version = true,
internalVersion = true,
tocversion = true
}
local function copyAuraPart(source, destination, part)
local all = (part == "all");
if (part == "display" or all) then
for k, v in pairs(source) do
if (not ignoreForCopyingDisplay[k]) then
if (type(v) == "table") then
destination[k] = CopyTable(v);
else
destination[k] = v;
end
end
end
end
if (part == "trigger" or all) and not IsRegionAGroup(source) then
destination.triggers = CopyTable(source.triggers);
end
if (part == "condition" or all) and not IsRegionAGroup(source) then
destination.conditions = CopyTable(source.conditions);
end
if (part == "load" or all) and not IsRegionAGroup(source) then
destination.load = CopyTable(source.load);
end
if (part == "action" or all) and not IsRegionAGroup(source) then
destination.actions = CopyTable(source.actions);
end
if (part == "animation" or all) and not IsRegionAGroup(source) then
destination.animation = CopyTable(source.animation);
end
if (part == "authorOptions" or all) and not IsRegionAGroup(source) then
destination.authorOptions = CopyTable(source.authorOptions);
end
if (part == "config" or all) and not IsRegionAGroup(source) then
destination.config = CopyTable(source.config);
end
end
local function CopyToClipboard(part, description)
clipboard.part = part;
clipboard.pasteText = description;
clipboard.source = CopyTable(clipboard.current);
end
clipboard.pasteMenuEntry = {
text = nil, -- Hidden by default
notCheckable = true,
func = function()
if (not IsRegionAGroup(clipboard.source) and IsRegionAGroup(clipboard.current)) then
-- Copy from a single aura to a group => paste it to each individual aura
for child in OptionsPrivate.Private.TraverseLeafs(clipboard.current) do
copyAuraPart(clipboard.source, child, clipboard.part);
WeakAuras.Add(child)
WeakAuras.ClearAndUpdateOptions(child.id)
end
else
copyAuraPart(clipboard.source, clipboard.current, clipboard.part);
WeakAuras.Add(clipboard.current)
WeakAuras.ClearAndUpdateOptions(clipboard.current.id)
end
WeakAuras.FillOptions()
OptionsPrivate.Private.ScanForLoads({[clipboard.current.id] = true});
OptionsPrivate.SortDisplayButtons(nil, true);
WeakAuras.PickDisplay(clipboard.current.id);
WeakAuras.UpdateThumbnail(clipboard.current.id);
WeakAuras.ClearAndUpdateOptions(clipboard.current.id);
end
}
clipboard.copyEverythingEntry = {
text = L["Everything"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("all", L["Paste Settings"])
end
};
clipboard.copyGroupEntry = {
text = L["Group"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("display", L["Paste Group Settings"])
end
};
clipboard.copyDisplayEntry = {
text = L["Display"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("display", L["Paste Display Settings"])
end
};
clipboard.copyTriggerEntry = {
text = L["Trigger"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("trigger", L["Paste Trigger Settings"])
end
};
clipboard.copyConditionsEntry = {
text = L["Conditions"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("condition", L["Paste Condition Settings"])
end
};
clipboard.copyLoadEntry = {
text = L["Load"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("load", L["Paste Load Settings"])
end
};
clipboard.copyActionsEntry = {
text = L["Actions"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("action", L["Paste Action Settings"])
end
};
clipboard.copyAnimationsEntry = {
text = L["Animations"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("animation", L["Paste Animations Settings"])
end
};
clipboard.copyAuthorOptionsEntry = {
text = L["Author Options"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("authorOptions", L["Paste Author Options Settings"])
end
};
clipboard.copyUserConfigEntry = {
text = L["Custom Configuration"],
notCheckable = true,
func = function()
LibDD:CloseDropDownMenus()
CopyToClipboard("config", L["Paste Custom Configuration"])
end
};
local function UpdateClipboardMenuEntry(data)
clipboard.current = data;
if (IsRegionAGroup(clipboard.source) and not IsRegionAGroup(clipboard.current)) then
-- Don't copy from a group to a non group
clipboard.pasteMenuEntry.text = nil;
else
clipboard.pasteMenuEntry.text = clipboard.pasteText;
end
if (IsRegionAGroup(clipboard.current)) then
clipboard.copyEverythingEntry.text = nil;
clipboard.copyDisplayEntry.text = nil;
clipboard.copyTriggerEntry.text = nil;
clipboard.copyConditionsEntry.text = nil;
clipboard.copyLoadEntry.text = nil;
clipboard.copyActionsEntry.text = nil;
clipboard.copyAnimationsEntry.text = nil;
clipboard.copyAuthorOptionsEntry = nil;
clipboard.copyUserConfigEntry = nil;
clipboard.copyGroupEntry.text = L["Group"];
else
clipboard.copyEverythingEntry.text = L["Everything"];
clipboard.copyDisplayEntry.text = L["Display"];
clipboard.copyTriggerEntry.text = L["Trigger"];
clipboard.copyConditionsEntry.text = L["Conditions"];
clipboard.copyLoadEntry.text = L["Load"];
clipboard.copyActionsEntry.text = L["Actions"];
clipboard.copyAnimationsEntry.text = L["Animations"];
clipboard.copyAuthorOptionsEntry = L["Author Options"];
clipboard.copyUserConfigEntry = L["Custom Configuration"];
clipboard.copyGroupEntry.text = nil;
end
end
local function Hide_Tooltip()
GameTooltip:Hide();
end
local function Show_Tooltip(owner, line1, line2)
GameTooltip:SetOwner(owner, "ANCHOR_NONE");
GameTooltip:ClearAllPoints()
GameTooltip:SetPoint("LEFT", owner, "RIGHT");
GameTooltip:ClearLines();
GameTooltip:AddLine(line1);
GameTooltip:AddLine(line2, 1, 1, 1, 1);
GameTooltip:Show();
end
local function Show_Long_Tooltip(owner, description)
GameTooltip:SetOwner(owner, "ANCHOR_NONE");
GameTooltip:ClearAllPoints()
GameTooltip:SetPoint("LEFT", owner, "RIGHT");
GameTooltip:ClearLines();
local line = 1;
for i,v in pairs(description) do
if(type(v) == "string") then
if(line > 1) then
GameTooltip:AddLine(v, 1, 1, 1, 1);
else
GameTooltip:AddLine(v);
end
elseif(type(v) == "table") then
if(i == 1) then
GameTooltip:AddDoubleLine(v[1], v[2]..(v[3] and (" |T"..v[3]..":12:12:0:0:64:64:4:60:4:60|t") or ""));
else
GameTooltip:AddDoubleLine(v[1], v[2]..(v[3] and (" |T"..v[3]..":12:12:0:0:64:64:4:60:4:60|t") or ""),
1, 1, 1, 1, 1, 1, 1, 1);
end
end
line = line + 1;
end
GameTooltip:Show();
end
local function ensure(t, k, v)
return t and k and v and t[k] == v
end
local statusIconPool = CreateFramePool("Button")
--[[ Actions ]]--
local Actions = {
-- move source into group or top-level list / optionally place it before or after target
["Group"] = function(source, groupId, target, before)
if source and not source.data.parent then
if groupId then
local group = OptionsPrivate.GetDisplayButton(groupId)
if group and group:IsGroup() then
local children = group.data.controlledChildren
if target then
local index = target:GetGroupOrder()
if ensure(children, index, target.data.id) then
-- account for insert position
index = before and index or index+1
tinsert(children, index, source.data.id)
else
error("Calling 'Group' with invalid target. Reload your UI to fix the display list.")
end
else
-- move source into group as the first child
tinsert(children, 1, source.data.id)
end
source:SetGroup(groupId)
source.data.parent = groupId
WeakAuras.Add(source.data)
WeakAuras.Add(group.data)
OptionsPrivate.Private.AddParents(group.data)
WeakAuras.UpdateGroupOrders(group.data)
WeakAuras.ClearAndUpdateOptions(group.data.id)
WeakAuras.ClearAndUpdateOptions(source.data.id)
group.callbacks.UpdateExpandButton();
group:UpdateParentWarning()
group:ReloadTooltip()
else
WeakAuras.Add(source.data)
WeakAuras.ClearAndUpdateOptions(source.data.id)
end
else
-- move source into the top-level list
WeakAuras.Add(source.data)
WeakAuras.ClearAndUpdateOptions(source.data.id)
end
else
error("Calling 'Group' with invalid source. Reload your UI to fix the display list.")
end
end,
-- remove source from its group or top-level list
["Ungroup"] = function(source)
if source and source.data.parent then
local parent = WeakAuras.GetData(source.data.parent)
local children = parent.controlledChildren
local index = source:GetGroupOrder()
if ensure(children, index, source.data.id) then
tremove(children, index)
source:SetGroup()
source.data.parent = nil
WeakAuras.Add(parent);
OptionsPrivate.Private.AddParents(parent)
WeakAuras.UpdateGroupOrders(parent);
WeakAuras.ClearAndUpdateOptions(parent.id);
local group = OptionsPrivate.GetDisplayButton(parent.id)
group.callbacks.UpdateExpandButton();
group:UpdateParentWarning()
group:ReloadTooltip()
else
error("Display thinks it is a member of a group which does not control it")
end
else
error("Calling 'Ungroup' with invalid source. Reload your UI to fix the display list.")
end
end
}
local function GetAction(target, area)
if target and area then
if area == "GROUP" then
return function(_source, _target)
if _source.data.parent then
Actions["Ungroup"](_source)
end
Actions["Group"](_source, _target.data.id)
end
else -- BEFORE or AFTER
-- Insert into target's parent, at the right position
if target.data.parent then
return function(_source, _target)
if _source.data.parent then
Actions["Ungroup"](_source)
end
Actions["Group"](_source, _target.data.parent, _target, area == "BEFORE")
end
end
end
end
end
-------------------------
local function GetDropTarget()
local buttonList = OptionsPrivate.displayButtons
for id, button in pairs(buttonList) do
if not button.dragging and button:IsEnabled() and button:IsShown() then
local halfHeight = button.frame:GetHeight() / 2
local height = button.frame:GetHeight()
if button.data.controlledChildren then
if button.data.parent == nil and button.frame:IsMouseOver(1, -1) then
-- Top level group, always group into
return id, button, "GROUP"
end
-- For sub groups, middle third is for grouping
if button.frame:IsMouseOver(-height / 3, height / 3) then
return id, button, "GROUP"
end
end
if button.frame:IsMouseOver(1, height / 2) then
return id, button, "BEFORE"
elseif button.frame:IsMouseOver(-height / 2, -1) then
return id, button, "AFTER"
end
end
end
end
local function Show_DropIndicator(id)
local indicator = OptionsPrivate.DropIndicator()
local source = OptionsPrivate.GetDisplayButton(id)
local target, pos
if source then
target, pos = select(2, GetDropTarget())
end
local action = GetAction(target, pos)
if action then
indicator:ShowAction(target, pos)
else
indicator:Hide()
end
end
-- WORKAROUND
-- Blizzard in its infinite wisdom did:
-- * Force enable the profanity filter for the chinese region
-- * Add a realm name's part to the profanity filter
local function ObfuscateName(name)
if (GetCurrentRegion() == 5) then
local result = ""
for i = 1, #name do
local b = name:byte(i)
if (b >= 196 and i ~= 1) then
-- UTF8 Start byte
result = result .. string.char(46, b)
else
result = result .. string.char(b)
end
end
return result
else
return name
end
end
local function IsParentRecursive(needle, parent)
if needle.id == parent.id then
return true
end
if needle.parent then
local needleParent = WeakAuras.GetData(needle.parent)
return IsParentRecursive(needleParent, parent)
end
end
local tabsForWarning = {
tts_condition = "conditions",
sound_condition = "conditions",
tts_action = "action",
sound_action = "action",
spammy_event_warning = "trigger"
}
--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
["OnAcquire"] = function(self)
self:SetWidth(1000);
self:SetHeight(32);
self.hasThumbnail = false
self.first = false
self.last = false
end,
["Initialize"] = function(self)
self.callbacks = {};
function self.callbacks.OnClickNormal(_, mouseButton)
if(IsControlKeyDown() and not self.data.controlledChildren) then
if (OptionsPrivate.IsDisplayPicked(self.data.id)) then
OptionsPrivate.ClearPick(self.data.id);
else
OptionsPrivate.PickDisplayMultiple(self.data.id);
end
self:ReloadTooltip();
elseif(IsShiftKeyDown()) then
local editbox = GetCurrentKeyBoardFocus();
if(editbox) then
if (not fullName) then
local name, realm = UnitFullName("player")
if realm then
fullName = name.."-".. ObfuscateName(realm)
else
fullName = name
end
end
if not (GetCurrentRegion() == 5 or GetLocale() == "zhCN") then -- China region (5), and chinese locale profanity filter doesn't allow links in chat
local url = ""
if self.data.url then
url = " ".. self.data.url
end
editbox:Insert("[WeakAuras: "..fullName.." - "..self.data.id.."]"..url)
else
editbox:Insert("[WeakAuras: "..fullName.." - "..self.data.id.."]")
end
OptionsPrivate.Private.linked = OptionsPrivate.Private.linked or {}
OptionsPrivate.Private.linked[self.data.id] = GetTime()
elseif not self.data.controlledChildren then
-- select all buttons between 1st select and current
OptionsPrivate.PickDisplayMultipleShift(self.data.id)
end
else
if(mouseButton == "RightButton") then
Hide_Tooltip();
if(OptionsPrivate.IsDisplayPicked(self.data.id) and OptionsPrivate.IsPickedMultiple()) then
LibDD:EasyMenu(OptionsPrivate.MultipleDisplayTooltipMenu(), WeakAuras_DropDownMenu, self.frame, 0, 0, "MENU");
else
UpdateClipboardMenuEntry(self.data);
LibDD:EasyMenu(self.menu, WeakAuras_DropDownMenu, self.frame, 0, 0, "MENU");
if not(OptionsPrivate.IsDisplayPicked(self.data.id)) then
if self.data.controlledChildren then
WeakAuras.PickDisplay(self.data.id, "group")
else
WeakAuras.PickDisplay(self.data.id);
end
end
end
else
if (OptionsPrivate.IsDisplayPicked(self.data.id)) then
OptionsPrivate.ClearPicks();
else
if self.data.controlledChildren then
WeakAuras.PickDisplay(self.data.id, "group")
else
WeakAuras.PickDisplay(self.data.id);
end
end
self:ReloadTooltip();
end
end
end
function self.callbacks.UpdateExpandButton()
if(not self.data.controlledChildren or #self.data.controlledChildren == 0) then
self:DisableExpand();
else
self:EnableExpand();
end
end
function self.callbacks.OnClickGrouping()
if (WeakAuras.IsImporting()) then return end;
for index, selectedId in ipairs(self.grouping) do
local selectedData = WeakAuras.GetData(selectedId);
tinsert(self.data.controlledChildren, selectedId);
local selectedButton = OptionsPrivate.GetDisplayButton(selectedId);
while selectedData.parent do
selectedButton:Ungroup();
end
selectedButton:SetGroup(self.data.id, self.data.regionType == "dynamicgroup");
selectedButton:SetGroupOrder(#self.data.controlledChildren, #self.data.controlledChildren);
selectedData.parent = self.data.id;
if (self.data.regionType == "dynamicgroup") then
selectedData.xOffset = 0
selectedData.yOffset = 0
end
WeakAuras.Add(selectedData);
OptionsPrivate.ClearOptions(selectedId)
if (selectedData.controlledChildren) then
for child in OptionsPrivate.Private.TraverseAllChildren(selectedData) do
local childButton = OptionsPrivate.GetDisplayButton(child.id)
childButton:UpdateOffset()
end
end
end
WeakAuras.Add(self.data);
OptionsPrivate.Private.AddParents(self.data)
self.callbacks.UpdateExpandButton();
self:UpdateParentWarning();
OptionsPrivate.StopGrouping();
OptionsPrivate.ClearOptions(self.data.id);
WeakAuras.FillOptions();
WeakAuras.UpdateGroupOrders(self.data);
OptionsPrivate.SortDisplayButtons();
self:ReloadTooltip();
self:Expand()
OptionsPrivate.ResetMoverSizer();
end
function self.callbacks.OnClickGroupingSelf()
OptionsPrivate.StopGrouping();
self:ReloadTooltip();
end
function self.callbacks.OnGroupClick()
OptionsPrivate.StartGrouping(self.data);
end
local function addParents(hash, data)
local parent = data.parent
if parent then
hash[parent] = true
local parentData = WeakAuras.GetData(parent)
if parentData then
addParents(hash, parentData)
end
end
end
function self.callbacks.OnDeleteClick()
if (WeakAuras.IsImporting()) then return end;
local toDelete = {self.data}
local parents = {}
addParents(parents, self.data)
OptionsPrivate.ConfirmDelete(toDelete, parents)
end
local function DuplicateGroups(sourceParent, targetParent, mapping)
for index, childId in pairs(sourceParent.controlledChildren) do
local childData = WeakAuras.GetData(childId)
if childData.controlledChildren then
local newChildGroup = OptionsPrivate.DuplicateAura(childData, targetParent.id)
mapping[childData] = newChildGroup
DuplicateGroups(childData, newChildGroup, mapping)
end
end
end
local function DuplicateAuras(sourceParent, targetParent, mapping)
for index, childId in pairs(sourceParent.controlledChildren) do
local childData = WeakAuras.GetData(childId)
if childData.controlledChildren then
DuplicateAuras(childData, mapping[childData], mapping)
else
OptionsPrivate.DuplicateAura(childData, targetParent.id, true, index)
end
end
end
function self.callbacks.OnDuplicateClick()
if (WeakAuras.IsImporting()) then return end;
if self.data.controlledChildren then
local newGroup = OptionsPrivate.DuplicateAura(self.data)
local mapping = {}
-- This builds the group skeleton
DuplicateGroups(self.data, newGroup, mapping)
-- Do this after duplicating all groups
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
-- And this fills in the leafs
DuplicateAuras(self.data, newGroup, mapping)
local button = OptionsPrivate.GetDisplayButton(newGroup.id)
button.callbacks.UpdateExpandButton()
button:UpdateParentWarning()
for old, new in pairs(mapping) do
local button = OptionsPrivate.GetDisplayButton(new.id)
button.callbacks.UpdateExpandButton()
button:UpdateParentWarning()
end
OptionsPrivate.SortDisplayButtons(nil, true)
OptionsPrivate.PickAndEditDisplay(newGroup.id)
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
else
local new = OptionsPrivate.DuplicateAura(self.data)
OptionsPrivate.SortDisplayButtons(nil, true)
OptionsPrivate.PickAndEditDisplay(new.id)
end
end
function self.callbacks.OnDeleteAllClick()
if (WeakAuras.IsImporting()) then return end;
local toDelete = {}
if(self.data.controlledChildren) then
for child in OptionsPrivate.Private.TraverseAllChildren(self.data) do
tinsert(toDelete, child);
end
end
tinsert(toDelete, self.data)
local parents = {}
addParents(parents, self.data)
OptionsPrivate.ConfirmDelete(toDelete, parents);
end
function self.callbacks.OnUngroupClick()
OptionsPrivate.Ungroup(self.data);
end
function self.callbacks.OnUpGroupClick()
if (WeakAuras.IsImporting()) then return end;
if(self.data.parent) then
local id = self.data.id;
local parentData = WeakAuras.GetData(self.data.parent);
local index;
for childIndex, childId in pairs(parentData.controlledChildren) do
if(childId == id) then
index = childIndex;
break;
end
end
if(index) then
if(index <= 1) then
error("Attempt to move up the first element in a group");
else
tremove(parentData.controlledChildren, index);
tinsert(parentData.controlledChildren, index - 1, id);
WeakAuras.Add(parentData);
OptionsPrivate.Private.AddParents(parentData)
WeakAuras.ClearAndUpdateOptions(parentData.id)
self:SetGroupOrder(index - 1, #parentData.controlledChildren);
local otherbutton = OptionsPrivate.GetDisplayButton(parentData.controlledChildren[index]);
otherbutton:SetGroupOrder(index, #parentData.controlledChildren);
OptionsPrivate.SortDisplayButtons();
local updata = {duration = 0.15, type = "custom", use_translate = true, x = 0, y = -32};
local downdata = {duration = 0.15, type = "custom", use_translate = true, x = 0, y = 32};
OptionsPrivate.Private.Animate("button", WeakAuras.GetData(parentData.controlledChildren[index-1]).uid, "main", updata, self.frame, true, function() OptionsPrivate.SortDisplayButtons() end);
OptionsPrivate.Private.Animate("button", WeakAuras.GetData(parentData.controlledChildren[index]).uid, "main", downdata, otherbutton.frame, true, function() OptionsPrivate.SortDisplayButtons() end);
WeakAuras.FillOptions()
end
else
error("Display thinks it is a member of a group which does not control it");
end
else
error("This display is not in a group. You should not have been able to click this button");
end
end
function self.callbacks.OnDownGroupClick()
if (WeakAuras.IsImporting()) then return end;
if(self.data.parent) then
local id = self.data.id;
local parentData = WeakAuras.GetData(self.data.parent);
local index;
for childIndex, childId in pairs(parentData.controlledChildren) do
if(childId == id) then
index = childIndex;
break;
end
end
if(index) then
if(index >= #parentData.controlledChildren) then
error("Attempt to move down the last element in a group");
else
tremove(parentData.controlledChildren, index);
tinsert(parentData.controlledChildren, index + 1, id);
WeakAuras.Add(parentData);
OptionsPrivate.Private.AddParents(parentData)
WeakAuras.ClearAndUpdateOptions(parentData.id)
self:SetGroupOrder(index + 1, #parentData.controlledChildren);
local otherbutton = OptionsPrivate.GetDisplayButton(parentData.controlledChildren[index]);
otherbutton:SetGroupOrder(index, #parentData.controlledChildren);
OptionsPrivate.SortDisplayButtons()
local updata = {duration = 0.15, type = "custom", use_translate = true, x = 0, y = -32};
local downdata = {duration = 0.15, type = "custom", use_translate = true, x = 0, y = 32};
OptionsPrivate.Private.Animate("button", WeakAuras.GetData(parentData.controlledChildren[index+1]).uid, "main", downdata, self.frame, true, function() OptionsPrivate.SortDisplayButtons() end);
OptionsPrivate.Private.Animate("button", WeakAuras.GetData(parentData.controlledChildren[index]).uid, "main", updata, otherbutton.frame, true, function() OptionsPrivate.SortDisplayButtons() end);
WeakAuras.FillOptions()
end
else
error("Display thinks it is a member of a group which does not control it");
end
else
error("This display is not in a group. You should not have been able to click this button");
end
end
function self.callbacks.OnViewClick()
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
if(self.view.visibility == 2) then
for child in OptionsPrivate.Private.TraverseAllChildren(self.data) do
OptionsPrivate.GetDisplayButton(child.id):PriorityHide(2);
end
self:PriorityHide(2)
else
for child in OptionsPrivate.Private.TraverseAllChildren(self.data) do
OptionsPrivate.GetDisplayButton(child.id):PriorityShow(2);
end
self:PriorityShow(2)
end
self:RecheckParentVisibility()
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
end
function self.callbacks.OnRenameClick()
if (WeakAuras.IsImporting()) then return end;
if(self.title:IsVisible()) then
self.title:Hide();
self.renamebox:SetText(self.title:GetText());
self.renamebox:Show();
else
self.title:Show();
self.renamebox:Hide();
end
end
function self.callbacks.OnRenameAction(newid)
if (WeakAuras.IsImporting()) then return end;
local oldid = self.data.id;
if not(newid == oldid) then
WeakAuras.Rename(self.data, newid);
end
self:UpdateParentWarning()
end
function self.callbacks.OnDragStart()
if WeakAuras.IsImporting() then return end;
if not OptionsPrivate.IsDisplayPicked(self.data.id) then
WeakAuras.PickDisplay(self.data.id)
end
OptionsPrivate.StartDrag(self.data);
end
function self.callbacks.OnDragStop()
if not self.dragging then return end
local target, area = select(2, GetDropTarget())
local action = GetAction(target, area)
OptionsPrivate.Drop(self.data, target, action, area)
end
function self.callbacks.OnKeyDown(self, key)
if (key == "ESCAPE") then
OptionsPrivate.DragReset()
end
end
self.frame:SetScript("OnEnter", function()
if(OptionsPrivate.IsPickedMultiple() and OptionsPrivate.IsDisplayPicked(self.frame.id)) then
Show_Long_Tooltip(self.frame, OptionsPrivate.MultipleDisplayTooltipDesc());
else
if not self.grouping then
self:SetNormalTooltip();
end
Show_Long_Tooltip(self.frame, self.frame.description);
end
end);
self.frame:SetScript("OnLeave", Hide_Tooltip);
local copyEntries = {};
tinsert(copyEntries, clipboard.copyEverythingEntry);
tinsert(copyEntries, clipboard.copyGroupEntry);
tinsert(copyEntries, clipboard.copyDisplayEntry);
tinsert(copyEntries, clipboard.copyTriggerEntry);
tinsert(copyEntries, clipboard.copyConditionsEntry);
tinsert(copyEntries, clipboard.copyLoadEntry);
tinsert(copyEntries, clipboard.copyActionsEntry);
tinsert(copyEntries, clipboard.copyAnimationsEntry);
tinsert(copyEntries, clipboard.copyAuthorOptionsEntry);
tinsert(copyEntries, clipboard.copyUserConfigEntry);
self:SetTitle(self.data.id);
self.menu = {
{
text = L["Rename"],
notCheckable = true,
func = self.callbacks.OnRenameClick
},
{
text = L["Copy settings..."],
notCheckable = true,
hasArrow = true,
menuList = copyEntries;
},
};
tinsert(self.menu, clipboard.pasteMenuEntry);
if (not self.data.controlledChildren) then
local convertMenu = {};
for regionType, regionData in pairs(OptionsPrivate.Private.regionOptions) do
if(regionType ~= "group" and regionType ~= "dynamicgroup" and regionType ~= self.data.regionType) then
tinsert(convertMenu, {
text = regionData.displayName,
notCheckable = true,
func = function()
OptionsPrivate.ConvertDisplay(self.data, regionType);
LibDD:CloseDropDownMenus()
end
});
end
end
tinsert(self.menu, {
text = L["Convert to..."],
notCheckable = true,
hasArrow = true,
menuList = convertMenu
});
end
tinsert(self.menu, {
text = L["Duplicate"],
notCheckable = true,
func = self.callbacks.OnDuplicateClick
});
tinsert(self.menu, {
text = L["Export..."],
notCheckable = true,
func = function() OptionsPrivate.ExportToString(self.data.id) end
});
tinsert(self.menu, {
text = L["Export debug table..."],
notCheckable = true,
func = function() OptionsPrivate.ExportToTable(self.data.id) end
});
tinsert(self.menu, {
text = " ",
notClickable = true,
notCheckable = true,
});
if not self.data.controlledChildren then
tinsert(self.menu, {
text = L["Delete"],
notCheckable = true,
func = self.callbacks.OnDeleteClick
});
end
if (self.data.controlledChildren) then
tinsert(self.menu, {
text = L["Delete children and group"],
notCheckable = true,
func = self.callbacks.OnDeleteAllClick
});
end
tinsert(self.menu, {
text = " ",
notClickable = true,
notCheckable = true,
});
tinsert(self.menu, {
text = L["Close"],
notCheckable = true,
func = function() LibDD:CloseDropDownMenus() end
});
if(self.data.controlledChildren) then
self.expand:Show();
self.callbacks.UpdateExpandButton();
self:SetOnExpandCollapse(function() OptionsPrivate.SortDisplayButtons(nil, true) end);
else
self.expand:Hide();
end
self.group:Show();
self:SetNormalTooltip();
self.frame:SetScript("OnClick", self.callbacks.OnClickNormal);
self.frame:SetScript("OnKeyDown", self.callbacks.OnKeyDown);
self.frame:EnableKeyboard(false);
self.frame:SetMovable(true);
self.frame:RegisterForDrag("LeftButton");
self.frame:SetScript("OnDragStart", self.callbacks.OnDragStart);
self.frame:SetScript("OnDragStop", self.callbacks.OnDragStop);
self:Enable();
self:SetRenameAction(self.callbacks.OnRenameAction);
self.group:SetScript("OnClick", self.callbacks.OnGroupClick);
self.ungroup:SetScript("OnClick", self.callbacks.OnUngroupClick);
self.upgroup:SetScript("OnClick", self.callbacks.OnUpGroupClick);
self.downgroup:SetScript("OnClick", self.callbacks.OnDownGroupClick);
self.view:SetScript("OnClick", self.callbacks.OnViewClick);
if self.data.parent then
local parentData = WeakAuras.GetData(self.data.parent);
local index;
for childIndex, childId in pairs(parentData.controlledChildren) do
if(childId == self.data.id) then
index = childIndex;
break;
end
end
if(index) then
self:SetGroup(self.data.parent);
self:SetGroupOrder(index, #parentData.controlledChildren);
else
error("Display \""..self.data.id.."\" thinks it is a member of group \""..self.data.parent.."\" which does not control it");
end
end
self.frame:Hide()
end,
["SetNormalTooltip"] = function(self)
local data = self.data;
local namestable = {};
if(data.controlledChildren) then
namestable[1] = "";
local function addChildrenNames(data, indent)
for index, childId in pairs(data.controlledChildren) do
tinsert(namestable, indent .. childId);
local childData = WeakAuras.GetData(childId)
if not childData then
return
end
if (childData.controlledChildren) then
addChildrenNames(childData, indent .. " ")
end
end
end
addChildrenNames(data, " ")
if (#namestable > 30) then
local size = #namestable;
namestable[26] = {" ", "[...]"};
namestable[27] = {L[string.format(L["%s total auras"], #namestable)], " " }
for i = 28, size do
namestable[i] = nil;
end
end
if(#namestable > 1) then
namestable[1] = L["Children:"];
else
namestable[1] = L["No Children"];
end
else
OptionsPrivate.Private.GetTriggerDescription(data, -1, namestable)
end
local hasDescription = data.desc and data.desc ~= "";
local hasUrl = data.url and data.url ~= "";
local hasVersion = (data.semver and data.semver ~= "") or (data.version and data.version ~= "");
if(hasDescription or hasUrl or hasVersion) then
tinsert(namestable, " ");
end
if(hasDescription) then
tinsert(namestable, "|cFFFFD100\""..data.desc.."\"");
end
if (hasUrl) then
tinsert(namestable, "|cFFFFD100" .. data.url .. "|r");
end
if (hasVersion) then
tinsert(namestable, "|cFFFFD100" .. L["Version: "] .. (data.semver or data.version) .. "|r");
end
tinsert(namestable, " ");
tinsert(namestable, {" ", "|cFF00FFFF"..L["Right-click for more options"]});
tinsert(namestable, {" ", "|cFF00FFFF"..L["Drag to move"]});
if not(data.controlledChildren) then
tinsert(namestable, {" ", "|cFF00FFFF"..L["Control-click to select multiple displays"]});
end
tinsert(namestable, {" ", "|cFF00FFFF"..L["Shift-click to create chat link"]});
local regionData = OptionsPrivate.Private.regionOptions[data.regionType or ""]
local displayName = regionData and regionData.displayName or "";
self:SetDescription({data.id, displayName}, unpack(namestable));
end,
["ReloadTooltip"] = function(self)
if(OptionsPrivate.IsPickedMultiple() and OptionsPrivate.IsDisplayPicked(self.data.id)) then
Show_Long_Tooltip(self.frame, OptionsPrivate.MultipleDisplayTooltipDesc());
else
Show_Long_Tooltip(self.frame, self.frame.description);
end
end,
["StartGrouping"] = function(self, groupingData, selected, groupingGroup, childOfGrouping)
self.grouping = groupingData;
self:UpdateIconsVisible()
if(selected) then
self.frame:SetScript("OnClick", self.callbacks.OnClickGroupingSelf);
self:SetDescription(L["Cancel"], L["Do not group this display"]);
elseif (childOfGrouping) then
self:Disable();
else
if(self.data.regionType == "dynamicgroup" and groupingGroup) then
self:Disable();
elseif (self.data.regionType == "group" or self.data.regionType == "dynamicgroup") then
self.frame:SetScript("OnClick", self.callbacks.OnClickGrouping);
self:SetDescription(self.data.id, L["Add to group %s"]:format(self.data.id));
else
self:Disable();
end
end
end,
["StopGrouping"] = function(self)
if self.grouping then
self.grouping = nil
self:UpdateIconsVisible()
self:SetNormalTooltip()
self.frame:SetScript("OnClick", self.callbacks.OnClickNormal)
self:Enable()
end
end,
["Ungroup"] = function(self)
if (WeakAuras.IsImporting()) then return end;
local parentData = WeakAuras.GetData(self.data.parent);
if not parentData then return end;
local index = tIndexOf(parentData.controlledChildren, self.data.id);
if(index) then
tremove(parentData.controlledChildren, index);
WeakAuras.Add(parentData);
OptionsPrivate.Private.AddParents(parentData)
WeakAuras.ClearAndUpdateOptions(parentData.id);
else
error("Display thinks it is a member of a group which does not control it");
end
local newParent = parentData.parent and WeakAuras.GetData(parentData.parent)
if newParent then
local insertIndex = tIndexOf(newParent.controlledChildren, parentData.id)
if not insertIndex then
error("Parent Display thinks it is a member of a group which does not control it");
end
insertIndex = insertIndex + 1
tinsert(newParent.controlledChildren, insertIndex, self.data.id)
end
self:SetGroup(newParent and newParent.id);
self.data.parent = newParent and newParent.id;
WeakAuras.Add(self.data);
self:UpdateIconsVisible()
if newParent then
WeakAuras.Add(newParent)
OptionsPrivate.Private.AddParents(newParent)
WeakAuras.ClearAndUpdateOptions(newParent.id)
WeakAuras.UpdateGroupOrders(newParent)
end
WeakAuras.ClearAndUpdateOptions(self.data.id);
WeakAuras.UpdateGroupOrders(parentData);
local parentButton = OptionsPrivate.GetDisplayButton(parentData.id)
if(#parentData.controlledChildren == 0) then
parentButton:DisableExpand()
end
parentButton:UpdateParentWarning()
for child in OptionsPrivate.Private.TraverseAllChildren(self.data) do
local button = OptionsPrivate.GetDisplayButton(child.id)
button:UpdateOffset()
end
OptionsPrivate.SortDisplayButtons();
end,
["UpdateIconsVisible"] = function(self)
if self.dragging or self.grouping then
self.downgroup:Hide()
self.group:Hide()
self.ungroup:Hide()
self.upgroup:Hide()
else
self.group:Show()
if self.data.parent then
self.downgroup:Show()
self.ungroup:Show()
self.upgroup:Show()
else
self.downgroup:Hide()
self.ungroup:Hide()
self.upgroup:Hide()
end
end
end,
["DragStart"] = function(self, mode, picked, mainAura, size)
self.frame:SetScript("OnClick", nil)
self.view:Hide()
self.expand:Hide()
self.statusIcons:Hide()
Hide_Tooltip()
if picked then
self.frame:EnableKeyboard(true)
local uiscale, scale = UIParent:GetScale(), self.frame:GetEffectiveScale()
local x, w = self.frame:GetLeft(), self.frame:GetWidth()
local _, y = GetCursorPosition()
-- mark as being dragged, attach to mouse and raise frame strata
self.dragging = true
self.frame:StartMoving()
self.frame:ClearAllPoints()
self.frame.temp = {
parent = self.frame:GetParent(),
strata = self.frame:GetFrameStrata(),
}
self.frame:SetParent(UIParent)
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
if self.data.id == mainAura.id then
self.frame:SetPoint("Center", UIParent, "BOTTOMLEFT", (x+w/2)*scale/uiscale, y/uiscale)
if mode == "MULTI" then
-- change label & icon
self.frame:SetPoint("Center", UIParent, "BOTTOMLEFT", (x+w/2)*scale/uiscale, y/uiscale)
self.frame.temp.title = self.title:GetText()
self.title:SetText((L["%i auras selected"]):format(size))
self:OverrideIcon();
end
else
-- Hide frames
self.frame:StopMovingOrSizing()
self.frame:Hide()
end
-- attach OnUpdate event to update drop indicator
if self.data.id == mainAura.id then
local id = self.data.id
self.frame:SetScript("OnUpdate", function(self,elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed > 0.1 then
Show_DropIndicator(id)
self.elapsed = 0
end
end)
Show_DropIndicator(id)
end
self:UpdateIconsVisible()
else
-- Are we a valid target?
-- Top level auras that aren't groups aren't
if not self.data.parent and not self:IsGroup() then
self:Disable()
end
-- If we are dragging a group, dynamic groups aren't valid targets
if mode == "GROUP" then
if self.data.regionType == "dynamicgroup" then
self:Disable()
else
local parentData = self.data.parent and WeakAuras.GetData(self.data.parent)
if (parentData and parentData.regionType == "dynamicgroup") then
self:Disable()
end
end
end
end
end,
["Drop"] = function(self, mode, mainAura, target, func)
if mode == "MULTI" or mode == "SINGLE" then
if self.dragging then
if func and target then
func(self, target)
end
end
elseif mode == "GROUP" then
if mainAura.id == self.data.id then
if func and target then
func(self, target)
end
end
end
self:DropEnd()
end,
["IsDragging"] = function(self)
return self.dragging
end,
["DragReset"] = function(self)
self:DropEnd()
end,
["DropEnd"] = function(self)
Show_DropIndicator()
self.frame:SetScript("OnClick", self.callbacks.OnClickNormal)
self.frame:EnableKeyboard(false); -- disables self.callbacks.OnKeyDown
self.view:Show()
self.statusIcons:Show()
if self.data.controlledChildren then
self.expand:Show()
end
self:Enable()
-- get action and execute it
self.frame:StopMovingOrSizing()
self.frame:SetScript("OnUpdate", nil)
if self.dragging then
if self.frame.temp.title then
-- restore title and icon
self.title:SetText(self.frame.temp.title)
self:RestoreIcon();
end
self.frame:SetParent(self.frame.temp.parent)
self.frame:SetFrameStrata(self.frame.temp.strata)
self.frame.temp = nil
end
self.dragging = false
self:UpdateIconsVisible()
end,
["ShowTooltip"] = function(self)
end,
["UpdateOffset"] = function(self)
local group = self.frame.dgroup
if group then
local depth = 0
while(group) do
depth = depth + 1
group = WeakAuras.GetData(group).parent
end
self.offset:SetWidth(depth * 8 + 1)
else
self.offset:SetWidth(1)
end
end,
["GetOffset"] = function(self)
return self.offset:GetWidth()
end,
["GetGroupOrCopying"] = function(self)
return self.group;
end,
["SetTitle"] = function(self, title)
self.titletext = title;
self.title:SetText(title);
end,
["GetTitle"] = function(self)
return self.titletext;
end,
["SetDescription"] = function(self, ...)
self.frame.description = {...};
end,
["SetRenameAction"] = function(self, func)
self.renamebox.func = function()
func(self.renamebox:GetText());
end
end,
["EnableGroup"] = function(self)
end,
["SetIds"] = function(self, ids)
self.renamebox.ids = ids;
end,
["SetGroup"] = function(self, group)
self.frame.dgroup = group;
if(group) then
self.icon:SetPoint("LEFT", self.ungroup, "RIGHT");
self.background:SetPoint("LEFT", self.offset, "RIGHT");
else
self.icon:SetPoint("LEFT", self.frame, "LEFT");
self.background:SetPoint("LEFT", self.frame, "LEFT");
end
self:UpdateIconsVisible()
self:UpdateOffset()
end,
["GetGroup"] = function(self)
return self.frame.dgroup;
end,
["IsGroup"] = function(self)
return self.data.regionType == "group" or self.data.regionType == "dynamicgroup"
end,
["SetData"] = function(self, data)
self.data = data;
self.frame.id = data.id;
end,
["GetData"] = function(self)
return self.data;
end,
["Expand"] = function(self, reloadTooltip)
self.expand:Enable();
OptionsPrivate.SetCollapsed(self.data.id, "displayButton", "", false)
self.expand:SetNormalTexture("Interface\\BUTTONS\\UI-MinusButton-Up.blp");
self.expand:SetPushedTexture("Interface\\BUTTONS\\UI-MinusButton-Down.blp");
self.expand.title = L["Collapse"];
self.expand.desc = L["Hide this group's children"];
self.expand:SetScript("OnClick", function() self:Collapse(true) end);
self.expand.func();
if(reloadTooltip) then
Hide_Tooltip();
Show_Tooltip(self.frame, self.expand.title, self.expand.desc);
end
end,
["Collapse"] = function(self, reloadTooltip)
self.expand:Enable();
OptionsPrivate.SetCollapsed(self.data.id, "displayButton", "", true)
self.expand:SetNormalTexture("Interface\\BUTTONS\\UI-PlusButton-Up.blp");
self.expand:SetPushedTexture("Interface\\BUTTONS\\UI-PlusButton-Down.blp");
self.expand.title = L["Expand"];
self.expand.desc = L["Show this group's children"];
self.expand:SetScript("OnClick", function() self:Expand(true) end);
self.expand.func();
if(reloadTooltip) then
Hide_Tooltip();
Show_Tooltip(self.frame, self.expand.title, self.expand.desc);
end
end,
["SetOnExpandCollapse"] = function(self, func)
self.expand.func = func;
end,
["GetExpanded"] = function(self)
return not OptionsPrivate.IsCollapsed(self.data.id, "displayButton", "", true)
end,
["DisableExpand"] = function(self)
if self.expand.disabled then
return
end
self.expand:Disable();
self.expand.disabled = true;
self.expand.expanded = false;
self.expand:SetNormalTexture("Interface\\BUTTONS\\UI-PlusButton-Disabled.blp");
end,
["EnableExpand"] = function(self)
if not self.expand.disabled then
return
end
self.expand.disabled = false;
if(self:GetExpanded()) then
self:Expand();
else
self:Collapse();
end
end,
["UpdateStatusIcon"] = function(self, key, prio, icon, title, tooltip, onClick)
local iconButton
for _, button in ipairs(self.statusIcons.buttons) do
if button.key == key then
iconButton = button
break
end
end
if not iconButton then
iconButton = statusIconPool:Acquire()
iconButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
tinsert(self.statusIcons.buttons, iconButton)
iconButton:SetParent(self.statusIcons)
iconButton.key = key
iconButton:SetSize(16, 16)
end
iconButton.prio = prio
if C_Texture.GetAtlasInfo(icon) then
iconButton:SetNormalAtlas(icon)
else
iconButton:SetNormalTexture(icon)
end
if title then
iconButton:SetScript("OnEnter", function()
Show_Tooltip(
self.frame,
title,
tooltip
)
end)
iconButton:SetScript("OnLeave", Hide_Tooltip)
else
iconButton:SetScript("OnEnter", nil)
end
iconButton:SetScript("OnClick", onClick)
iconButton:Show()
end,
["ClearStatusIcon"] = function(self, key)
for index, button in ipairs(self.statusIcons.buttons) do
if button.key == key then
statusIconPool:Release(button)
table.remove(self.statusIcons.buttons, index)
return
end
end
end,
["SortStatusIcons"] = function(self)
table.sort(self.statusIcons.buttons, function(a, b)
return a.prio < b.prio
end)
local lastAnchor = self.statusIcons
if self:IsGroup() then
self.statusIcons:SetWidth(17)
else
self.statusIcons:SetWidth(1)
end
for _, button in ipairs(self.statusIcons.buttons) do
button:ClearAllPoints()
button:SetPoint("BOTTOMLEFT", lastAnchor, "BOTTOMRIGHT", 4, 0)
lastAnchor = button
end
end,
["UpdateWarning"] = function(self)
local warnings = OptionsPrivate.Private.AuraWarnings.GetAllWarnings(self.data.uid)
local warningTypes = {"info", "sound", "tts", "warning", "error"}
for _, key in ipairs(warningTypes) do
self:ClearStatusIcon(key)
end
if warnings then
for severity, warning in pairs(warnings) do
local onClick
if severity == "sound" or severity == "tts" then
local soundText = L["Show Sound Setting"]
local removeText = L["Remove All Sounds"]
if severity == "tts" then
soundText = L["Show Text To Speech Setting"]
removeText = L["Remove All Text To Speech"]
end
onClick = function()
MenuUtil.CreateContextMenu(UIParent, function(ownerRegion, root)
root:CreateButton(soundText, function()
WeakAuras.PickDisplay(warning.auraId, tabsForWarning[warning.key] or "information")
end)
root:CreateButton(removeText, function()
OptionsPrivate.Private.ClearSounds(self.data.uid, severity)
end)
end)
end
else
onClick = function()
WeakAuras.PickDisplay(warning.auraId, tabsForWarning[warning.key] or "information")
end
end
self:UpdateStatusIcon(severity, warning.prio, warning.icon, warning.title, warning.message, onClick)
end
end
self:SortStatusIcons()
end,
["UpdateParentWarning"] = function(self)
self:UpdateWarning()
for parent in OptionsPrivate.Private.TraverseParents(self.data) do
local parentButton = OptionsPrivate.GetDisplayButton(parent.id)
if parentButton then
parentButton:UpdateWarning()
end
end
end,
["SetGroupOrder"] = function(self, order, max)
self.first = (order == 1)
self.last = (order == max)
self.frame.dgrouporder = order;
self:UpdateUpDownButtons()
end,
["UpdateUpDownButtons"] = function(self)
if self.first or not self:IsEnabled() then
self.upgroup:Disable();
self.upgroup.texture:SetVertexColor(0.3, 0.3, 0.3);
else
self.upgroup:Enable();
self.upgroup.texture:SetVertexColor(1, 1, 1);
end
if self.last or not self:IsEnabled() then
self.downgroup:Disable();
self.downgroup.texture:SetVertexColor(0.3, 0.3, 0.3);
else
self.downgroup:Enable();
self.downgroup.texture:SetVertexColor(1, 1, 1);
end
end,
["GetGroupOrder"] = function(self)
return self.frame.dgrouporder;
end,
["ClearLoaded"] = function(self)
self:ClearStatusIcon("load")
self:SortStatusIcons()
end,
["SetLoaded"] = function(self, prio, file, title, description)
self:UpdateStatusIcon("load", prio, "Interface\\AddOns\\WeakAuras\\Media\\Textures\\" .. file, title, description, nil)
self:SortStatusIcons()
end,
["IsLoaded"] = function(self)
return OptionsPrivate.Private.loaded[self.data.id] == true
end,
["IsStandby"] = function(self)
return OptionsPrivate.Private.loaded[self.data.id] == false
end,
["IsUnloaded"] = function(self)
return OptionsPrivate.Private.loaded[self.data.id] == nil
end,
["Pick"] = function(self)
self.frame:LockHighlight();
self:PriorityShow(1);
self:RecheckParentVisibility()
end,
["ClearPick"] = function(self, noHide)
self.frame:UnlockHighlight();
if not noHide then
self:PriorityHide(1);
self:RecheckParentVisibility()
end
end,
["SyncVisibility"] = function(self)
if (not WeakAuras.IsOptionsOpen()) then
return;
end
if self.view.visibility >= 1 then
if not OptionsPrivate.Private.IsGroupType(self.data) then
OptionsPrivate.Private.FakeStatesFor(self.data.id, true)
end
if (OptionsPrivate.Private.personalRessourceDisplayFrame) then
OptionsPrivate.Private.personalRessourceDisplayFrame:expand(self.data.id);
end
if (OptionsPrivate.Private.mouseFrame) then
OptionsPrivate.Private.mouseFrame:expand(self.data.id);
end
else
if not OptionsPrivate.Private.IsGroupType(self.data) then
OptionsPrivate.Private.FakeStatesFor(self.data.id, false)
end
if (OptionsPrivate.Private.personalRessourceDisplayFrame) then
OptionsPrivate.Private.personalRessourceDisplayFrame:collapse(self.data.id);
end
if (OptionsPrivate.Private.mouseFrame) then
OptionsPrivate.Private.mouseFrame:collapse(self.data.id);
end
end
end,
["PriorityShow"] = function(self, priority)
if (not WeakAuras.IsOptionsOpen()) then
return;
end
if(priority >= self.view.visibility and self.view.visibility ~= priority) then
self.view.visibility = priority;
self:SyncVisibility()
self:UpdateViewTexture()
end
local region = OptionsPrivate.Private.EnsureRegion(self.data.id)
if region and region.ClickToPick then
region:ClickToPick();
end
end,
["PriorityHide"] = function(self, priority)
if (not WeakAuras.IsOptionsOpen()) then
return;
end
if(priority >= self.view.visibility and self.view.visibility ~= 0) then
self.view.visibility = 0;
self:SyncVisibility()
self:UpdateViewTexture()
end
end,
["RecheckParentVisibility"] = function(self)
if self.data.parent then
local parentButton = OptionsPrivate.GetDisplayButton(self.data.parent)
parentButton:RecheckVisibility()
else
OptionsPrivate.Private.OptionsFrame().loadedButton:RecheckVisibility()
OptionsPrivate.Private.OptionsFrame().unloadedButton:RecheckVisibility()
end
end,
["RecheckVisibility"] = function(self)
local none, all = true, true;
for child in OptionsPrivate.Private.TraverseAllChildren(self.data) do
local childButton = OptionsPrivate.GetDisplayButton(child.id);
if(childButton) then
if(childButton:GetVisibility() ~= 2) then
all = false;
end
if(childButton:GetVisibility() ~= 0) then
none = false;
end
end
end
local newVisibility
if(all) then
newVisibility = 2;
elseif(none) then
newVisibility = 0;
else
newVisibility = 1;
end
if newVisibility ~= self.view.visibility then
self.view.visibility = newVisibility
self:UpdateViewTexture()
self:RecheckParentVisibility()
end
end,
["UpdateViewTexture"] = function(self)
local visibility = self.view.visibility
if(visibility == 2) then
self.view.texture:SetTexture("Interface\\LFGFrame\\BattlenetWorking0.blp");
elseif(visibility == 1) then
self.view.texture:SetTexture("Interface\\LFGFrame\\BattlenetWorking2.blp");
else
self.view.texture:SetTexture("Interface\\LFGFrame\\BattlenetWorking4.blp");
end
end,
["GetVisibility"] = function(self)
return self.view.visibility;
end,
["Disable"] = function(self)
self.background:Hide();
self.frame:Disable();
self.view:Disable();
self.group:Disable();
self.ungroup:Disable();
self.expand:Disable();
for _, button in ipairs(self.statusIcons.buttons) do
button:Disable();
end
self:UpdateUpDownButtons()
end,
["Enable"] = function(self)
self.background:Show();
self.frame:Enable();
self.view:Enable();
self.group:Enable();
self.ungroup:Enable();
for _, button in ipairs(self.statusIcons.buttons) do
button:Enable();
end
self:UpdateUpDownButtons()
if not(self.expand.disabled) then
self.expand:Enable();
end
end,
["IsEnabled"] = function(self)
return self.frame:IsEnabled();
end,
["OnRelease"] = function(self)
self:ReleaseThumbnail()
self:Enable();
self:SetGroup();
self.renamebox:Hide();
self.title:Show();
local id = self.data.id;
self.frame:SetScript("OnEnter", nil);
self.frame:SetScript("OnLeave", nil);
self.frame:SetScript("OnClick", nil);
self.frame:SetScript("OnDragStart", nil);
self.frame:SetScript("OnDragStop", nil);
--self.frame:EnableMouse(false);
self.frame:ClearAllPoints();
self.frame:Hide();
for _, button in ipairs(self.statusIcons.buttons) do
statusIconPool:Release(button)
end
wipe(self.statusIcons.buttons)
self.frame = nil;
self.data = nil;
end,
["UpdateThumbnail"] = function(self)
if not self.hasThumbnail then
return
end
if self.data.regionType ~= self.thumbnailType then
self:ReleaseThumbnail()
self:AcquireThumbnail()
else
local option = OptionsPrivate.Private.regionOptions[self.thumbnailType]
if option and option.modifyThumbnail then
option.modifyThumbnail(self.frame, self.thumbnail, self.data)
end
end
end,
["ReleaseThumbnail"] = function(self)
if not self.hasThumbnail then
return
end
self.hasThumbnail = false
if self.thumbnail then
local regionType = self.thumbnailType
local option = OptionsPrivate.Private.regionOptions[regionType]
option.releaseThumbnail(self.thumbnail)
self.thumbnail = nil
end
end,
["AcquireThumbnail"] = function(self)
if self.hasThumbnail then
return
end
if not self.data then
return
end
self.hasThumbnail = true
local button = self.frame
local regionType = self.data.regionType
self.thumbnailType = regionType
local option = OptionsPrivate.Private.regionOptions[regionType]
if option and option.acquireThumbnail then
self.thumbnail = option.acquireThumbnail(button, self.data)
self:SetIcon(self.thumbnail)
else
self:SetIcon("Interface\\Icons\\INV_Misc_QuestionMark")
end
end,
["SetIcon"] = function(self, icon)
self.orgIcon = icon;
if(type(icon) == "string" or type(icon) == "number") then
self.icon:SetTexture(icon);
self.icon:Show();
if(self.iconRegion and self.iconRegion.Hide) then
self.iconRegion:Hide();
end
else
self.iconRegion = icon;
icon:SetAllPoints(self.icon);
icon:SetParent(self.frame);
icon:Show()
self.iconRegion:Show();
self.icon:Hide();
end
end,
["OverrideIcon"] = function(self)
self.icon:SetTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\icon.blp")
self.icon:Show()
if(self.iconRegion and self.iconRegion.Hide) then
self.iconRegion:Hide();
end
end,
["RestoreIcon"] = function(self)
self:SetIcon(self.orgIcon);
end,
}
--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local function Constructor()
local name = "WeakAurasDisplayButton"..AceGUI:GetNextWidgetNum(Type);
---@class Button
local button = CreateFrame("Button", name, UIParent, "OptionsListButtonTemplate");
button:SetHeight(32);
button:SetWidth(1000);
button.dgroup = nil;
button.data = {};
local offset = CreateFrame("Frame", nil, button)
button.offset = offset
offset:SetPoint("TOP", button, "TOP");
offset:SetPoint("BOTTOM", button, "BOTTOM");
offset:SetPoint("LEFT", button, "LEFT");
offset:SetWidth(1)
local background = button:CreateTexture(nil, "BACKGROUND");
button.background = background;
background:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight2.blp");
background:SetBlendMode("ADD");
background:SetVertexColor(0.5, 0.5, 0.5, 0.25);
background:SetPoint("TOP", button, "TOP");
background:SetPoint("BOTTOM", button, "BOTTOM");
background:SetPoint("LEFT", button, "LEFT")
background:SetPoint("RIGHT", button, "RIGHT");
local icon = button:CreateTexture(nil, "OVERLAY");
button.icon = icon;
icon:SetWidth(32);
icon:SetHeight(32);
icon:SetPoint("LEFT", offset, "RIGHT");
local title = button:CreateFontString(nil, "OVERLAY", "GameFontNormal");
button.title = title;
title:SetHeight(14);
title:SetJustifyH("LEFT");
title:SetPoint("TOP", button, "TOP", 0, -2);
title:SetPoint("LEFT", icon, "RIGHT", 2, 0);
title:SetPoint("RIGHT", button, "RIGHT");
button.description = {};
---@class Button
local view = CreateFrame("Button", nil, button);
button.view = view;
view:SetWidth(16);
view:SetHeight(16);
view:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 0);
local viewTexture = view:CreateTexture()
view.texture = viewTexture;
viewTexture:SetTexture("Interface\\LFGFrame\\BattlenetWorking4.blp");
viewTexture:SetTexCoord(0.1, 0.9, 0.1, 0.9);
viewTexture:SetAllPoints(view);
view:SetNormalTexture(viewTexture);
view:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight.blp");
view:SetScript("OnEnter", function() Show_Tooltip(button, L["View"], L["Toggle the visibility of this display"]) end);
view:SetScript("OnLeave", Hide_Tooltip);
view.visibility = 0;
local renamebox = CreateFrame("EditBox", nil, button, "InputBoxTemplate");
renamebox:SetHeight(14);
renamebox:SetPoint("TOP", button, "TOP");
renamebox:SetPoint("LEFT", icon, "RIGHT", 6, 0);
renamebox:SetPoint("RIGHT", button, "RIGHT", -4, 0);
renamebox:SetFont(STANDARD_TEXT_FONT, 10, "");
renamebox:Hide();
renamebox.func = function() --[[By default, do nothing!]] end;
renamebox:SetScript("OnEnterPressed", function()
local oldid = button.title:GetText();
local newid = renamebox:GetText();
if(newid == "" or (newid ~= oldid and WeakAuras.GetData(newid))) then
renamebox:SetText(button.title:GetText());
else
renamebox.func();
title:SetText(renamebox:GetText());
title:Show();
renamebox:Hide();
end
end);
renamebox:SetScript("OnEscapePressed", function()
title:Show();
renamebox:Hide();
end);
local group = CreateFrame("Button", nil, button);
button.group = group;
group:SetWidth(16);
group:SetHeight(16);
group:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -18, 0);
local grouptexture = group:CreateTexture(nil, "OVERLAY");
group.texture = grouptexture;
grouptexture:SetTexture("Interface\\GLUES\\CharacterCreate\\UI-RotationRight-Big-Up.blp");
grouptexture:SetTexCoord(0.15, 0.85, 0.15, 0.85);
grouptexture:SetAllPoints(group);
group:SetNormalTexture(grouptexture);
group:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight.blp");
group:SetScript("OnEnter", function() Show_Tooltip(button, L["Group (verb)"], L["Put this display in a group"]) end);
group:SetScript("OnLeave", Hide_Tooltip);
local ungroup = CreateFrame("Button", nil, button);
button.ungroup = ungroup;
ungroup:SetWidth(11);
ungroup:SetHeight(11);
ungroup:SetPoint("LEFT", offset, "RIGHT", 0, 0);
local ungrouptexture = group:CreateTexture(nil, "OVERLAY");
ungrouptexture:SetTexture("Interface\\MoneyFrame\\Arrow-Left-Down.blp");
ungrouptexture:SetTexCoord(0.5, 0, 0.5, 1, 1, 0, 1, 1);
ungrouptexture:SetAllPoints(ungroup);
ungroup:SetNormalTexture(ungrouptexture);
ungroup:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight.blp");
ungroup:SetScript("OnEnter", function() Show_Tooltip(button, L["Ungroup"], L["Remove this display from its group"]) end);
ungroup:SetScript("OnLeave", Hide_Tooltip);
ungroup:Hide();
local upgroup = CreateFrame("Button", nil, button);
button.upgroup = upgroup;
upgroup:SetWidth(11);
upgroup:SetHeight(11);
upgroup:SetPoint("TOPLEFT", offset, "TOPRIGHT", 0, 0);
local upgrouptexture = group:CreateTexture(nil, "OVERLAY");
upgroup.texture = upgrouptexture;
upgrouptexture:SetTexture("Interface\\MoneyFrame\\Arrow-Left-Down.blp");
upgrouptexture:SetTexCoord(0.5, 1, 1, 1, 0.5, 0, 1, 0);
upgrouptexture:SetVertexColor(1, 1, 1);
upgrouptexture:SetAllPoints(upgroup);
upgroup:SetNormalTexture(upgrouptexture);
upgroup:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight.blp");
upgroup:SetScript("OnEnter", function() Show_Tooltip(button, L["Move Up"], L["Move this display up in its group's order"]) end);
upgroup:SetScript("OnLeave", Hide_Tooltip);
upgroup:Hide();
local downgroup = CreateFrame("Button", nil, button);
button.downgroup = downgroup;
downgroup:SetWidth(11);
downgroup:SetHeight(11);
downgroup:SetPoint("BOTTOMLEFT", offset, "BOTTOMRIGHT", 0, 0);
local downgrouptexture = group:CreateTexture(nil, "OVERLAY");
downgroup.texture = downgrouptexture;
downgrouptexture:SetTexture("Interface\\MoneyFrame\\Arrow-Left-Down.blp");
downgrouptexture:SetTexCoord(1, 0, 0.5, 0, 1, 1, 0.5, 1);
downgrouptexture:SetAllPoints(downgroup);
downgroup:SetNormalTexture(downgrouptexture);
downgroup:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight.blp");
downgroup:SetScript("OnEnter", function()
Show_Tooltip(button, L["Move Down"], L["Move this display down in its group's order"])
end)
downgroup:SetScript("OnLeave", Hide_Tooltip);
downgroup:Hide();
---@class Button
local expand = CreateFrame("Button", nil, button);
button.expand = expand;
expand.expanded = true;
expand.disabled = true;
expand.func = function() end;
expand:SetNormalTexture("Interface\\BUTTONS\\UI-PlusButton-Disabled.blp");
expand:Disable();
expand:SetWidth(16);
expand:SetHeight(16);
expand:SetPoint("BOTTOM", button, "BOTTOM");
expand:SetPoint("LEFT", icon, "RIGHT", 0, 0);
expand:SetHighlightTexture("Interface\\BUTTONS\\UI-Panel-MinimizeButton-Highlight.blp");
expand.title = L["Disabled"];
expand.desc = L["Expansion is disabled because this group has no children"];
expand:SetScript("OnEnter", function() Show_Tooltip(button, expand.title, expand.desc) end);
expand:SetScript("OnLeave", Hide_Tooltip);
local statusIcons = CreateFrame("Frame", nil, button);
button.statusIcons = statusIcons
statusIcons:SetPoint("BOTTOM", button, "BOTTOM", 0, 1);
statusIcons:SetPoint("LEFT", icon, "RIGHT");
statusIcons:SetSize(1,1)
statusIcons.buttons = {}
local widget = {
frame = button,
title = title,
icon = icon,
view = view,
renamebox = renamebox,
group = group,
ungroup = ungroup,
upgroup = upgroup,
downgroup = downgroup,
background = background,
expand = expand,
statusIcons = statusIcons,
type = Type,
offset = offset
}
for method, func in pairs(methods) do
widget[method] = func
end
return AceGUI:RegisterAsWidget(widget);
end
AceGUI:RegisterWidgetType(Type, Constructor, Version)