This commit is contained in:
Bunny67
2020-06-02 23:40:06 +03:00
commit f2e1a0928d
516 changed files with 185320 additions and 0 deletions
@@ -0,0 +1,123 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local CreateFrame = CreateFrame
local AceGUI = LibStub("AceGUI-3.0")
local SharedMedia = LibStub("LibSharedMedia-3.0")
local IndentationLib = IndentationLib
local WeakAuras = WeakAuras
local L = WeakAuras.L
local codeReview
local tableColor = "|c00ff3333"
local arithmeticColor = "|c00ff3333"
local relationColor = "|c00ff3333"
local logicColor = "|c004444ff"
local colorScheme = {
[IndentationLib.tokens.TOKEN_SPECIAL] = "|c00ff3333",
[IndentationLib.tokens.TOKEN_KEYWORD] = "|c004444ff",
[IndentationLib.tokens.TOKEN_COMMENT_SHORT] = "|c0000aa00",
[IndentationLib.tokens.TOKEN_COMMENT_LONG] = "|c0000aa00",
[IndentationLib.tokens.TOKEN_NUMBER] = "|c00ff9900",
[IndentationLib.tokens.TOKEN_STRING] = "|c00999999",
-- ellipsis, curly braces, table acces
["..."] = tableColor,
["{"] = tableColor,
["}"] = tableColor,
["["] = tableColor,
["]"] = tableColor,
-- arithmetic operators
["+"] = arithmeticColor,
["-"] = arithmeticColor,
["/"] = arithmeticColor,
["*"] = arithmeticColor,
[".."] = arithmeticColor,
-- relational operators
["=="] = relationColor,
["<"] = relationColor,
["<="] = relationColor,
[">"] = relationColor,
[">="] = relationColor,
["~="] = relationColor,
-- logical operators
["and"] = logicColor,
["or"] = logicColor,
["not"] = logicColor,
-- misc
[0] = "|r",
}
local function ConstructCodeReview(frame)
local group = AceGUI:Create("InlineGroup");
group.frame:SetParent(frame);
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 30);
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -10);
group.frame:Hide();
group:SetLayout("flow");
local codeTree = AceGUI:Create("TreeGroup");
group.codeTree = codeTree;
group:SetLayout("fill");
group:AddChild(codeTree);
local codebox = AceGUI:Create("MultiLineEditBox");
codebox.frame:SetAllPoints(codeTree.content);
codebox.frame:SetFrameStrata("FULLSCREEN");
codebox:SetLabel("");
group:AddChild(codebox);
codebox.button:Hide();
IndentationLib.enable(codebox.editBox, colorScheme, 4);
local fontPath = SharedMedia:Fetch("font", "Fira Mono Medium");
if(fontPath) then
codebox.editBox:SetFont(fontPath, 12);
end
group.codebox = codebox;
codeTree:SetCallback("OnGroupSelected", function(self, event, value)
for _, v in pairs(group.data) do
if (v.value == value) then
codebox:SetText(v.code);
end
end
end);
local cancel = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate");
cancel:SetScript("OnClick", function() group:Close() end);
cancel:SetPoint("bottomright", frame, "bottomright", -27, 11);
cancel:SetHeight(20);
cancel:SetWidth(100);
cancel:SetText(L["Okay"]);
function group.Open(self, data)
if frame.window == "codereview" then
return
end
self.data = data;
self.codeTree:SetTree(data);
WeakAuras.ShowOptions();
frame.window = "codereview";
frame:UpdateFrameVisible()
end
function group.Close()
frame.window = "default";
frame:UpdateFrameVisible()
end
return group
end
function WeakAuras.CodeReview(frame)
codeReview = codeReview or ConstructCodeReview(frame)
return codeReview
end
@@ -0,0 +1,99 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local CreateFrame, IsMouseButtonDown, SetCursor, GetMouseFocus, MouseIsOver, ResetCursor
= CreateFrame, IsMouseButtonDown, SetCursor, GetMouseFocus, MouseIsOver, ResetCursor
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local WeakAuras = WeakAuras
local L = WeakAuras.L
local valueFromPath = WeakAuras.ValueFromPath
local valueToPath = WeakAuras.ValueToPath
local frameChooserFrame
local frameChooserBox
local oldFocus
local oldFocusName
function WeakAuras.StartFrameChooser(data, path)
local frame = WeakAuras.OptionsFrame();
if not(frameChooserFrame) then
frameChooserFrame = CreateFrame("frame");
frameChooserBox = CreateFrame("frame", nil, frameChooserFrame);
frameChooserBox:SetFrameStrata("TOOLTIP");
frameChooserBox:SetBackdrop({
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
edgeSize = 12,
insets = {left = 0, right = 0, top = 0, bottom = 0}
});
frameChooserBox:SetBackdropBorderColor(0, 1, 0);
frameChooserBox:Hide();
end
local givenValue = valueFromPath(data, path);
frameChooserFrame:SetScript("OnUpdate", function()
if(IsMouseButtonDown("RightButton")) then
valueToPath(data, path, givenValue);
AceConfigDialog:Open("WeakAuras", frame.container);
WeakAuras.StopFrameChooser(data);
elseif(IsMouseButtonDown("LeftButton") and oldFocusName) then
WeakAuras.StopFrameChooser(data);
else
SetCursor("CAST_CURSOR");
local focus = GetMouseFocus();
local focusName;
if(focus) then
focusName = focus:GetName();
if(focusName == "WorldFrame" or not focusName) then
focusName = nil;
local focusIsGroup = false;
for id, regionData in pairs(WeakAuras.regions) do
if(regionData.region:IsVisible() and MouseIsOver(regionData.region)) then
local isGroup = regionData.regionType == "group" or regionData.regionType == "dynamicgroup";
if (not focusName or (not isGroup and focusIsGroup)) then
focus = regionData.region;
focusName = "WeakAuras:"..id;
focusIsGroup = focusIsGroup;
end
end
end
end
if(focus ~= oldFocus) then
if(focusName) then
frameChooserBox:SetPoint("bottomleft", focus, "bottomleft", -4, -4);
frameChooserBox:SetPoint("topright", focus, "topright", 4, 4);
frameChooserBox:Show();
end
if(focusName ~= oldFocusName) then
valueToPath(data, path, focusName);
oldFocusName = focusName;
AceConfigDialog:Open("WeakAuras", frame.container);
end
oldFocus = focus;
end
end
if not(focusName) then
frameChooserBox:Hide();
end
end
end);
end
function WeakAuras.StopFrameChooser(data)
if(frameChooserFrame) then
frameChooserFrame:SetScript("OnUpdate", nil);
frameChooserBox:Hide();
end
ResetCursor();
WeakAuras.Add(data);
end
@@ -0,0 +1,199 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local CreateFrame, GetSpellInfo = CreateFrame, GetSpellInfo
local AceGUI = LibStub("AceGUI-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local WeakAuras = WeakAuras
local L = WeakAuras.L
local iconPicker
local spellCache = WeakAuras.spellCache
local function ConstructIconPicker(frame)
local group = AceGUI:Create("InlineGroup");
group.frame:SetParent(frame);
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 30); -- 12
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -50);
group.frame:Hide();
group:SetLayout("flow");
local scroll = AceGUI:Create("ScrollFrame");
scroll:SetLayout("flow");
--scroll.frame:SetClipsChildren(true);
group:AddChild(scroll);
local function iconPickerFill(subname, doSort)
scroll:ReleaseChildren();
local distances = {};
local names = {};
-- Work around special numbers such as inf and nan
if (tonumber(subname)) then
local spellId = tonumber(subname);
if (abs(spellId) < math.huge and tostring(spellId) ~= "nan") then
subname = GetSpellInfo(spellId or 0)
end
end
if subname then
subname = subname:lower();
end
local usedIcons = {};
local num = 0;
if(subname and subname ~= "") then
for name, icons in pairs(spellCache.Get()) do
local bestDistance = math.huge;
local bestName;
if(name:lower():find(subname, 1, true)) then
for spellId, icon in pairs(icons) do
if (not usedIcons[icon]) then
local button = AceGUI:Create("WeakAurasIconButton");
button:SetName(name);
button:SetTexture(icon);
button:SetClick(function()
group:Pick(icon);
end);
scroll:AddChild(button);
usedIcons[icon] = true;
num = num + 1;
if(num >= 500) then
break;
end
end
end
end
if(num >= 500) then
break;
end
end
end
end
local input = CreateFrame("EDITBOX", nil, group.frame, "InputBoxTemplate");
input:SetScript("OnTextChanged", function(...) iconPickerFill(input:GetText(), false); end);
input:SetScript("OnEnterPressed", function(...) iconPickerFill(input:GetText(), true); end);
input:SetScript("OnEscapePressed", function(...) input:SetText(""); iconPickerFill(input:GetText(), true); end);
input:SetWidth(170);
input:SetHeight(15);
input:SetPoint("BOTTOMRIGHT", group.frame, "TOPRIGHT", -12, -5);
WeakAuras.input = input;
local inputLabel = input:CreateFontString(nil, "OVERLAY", "GameFontNormal");
inputLabel:SetText(L["Search"]);
inputLabel:SetJustifyH("RIGHT");
inputLabel:SetPoint("BOTTOMLEFT", input, "TOPLEFT", 0, 5);
local icon = AceGUI:Create("WeakAurasIconButton");
icon.frame:Disable();
icon.frame:SetParent(group.frame);
icon.frame:SetPoint("BOTTOMLEFT", group.frame, "TOPLEFT", 15, -15);
local iconLabel = input:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge");
iconLabel:SetNonSpaceWrap("true");
iconLabel:SetJustifyH("LEFT");
iconLabel:SetPoint("LEFT", icon.frame, "RIGHT", 5, 0);
iconLabel:SetPoint("RIGHT", input, "LEFT", -50, 0);
function group.Pick(self, texturePath)
if(not self.groupIcon and self.data.controlledChildren) then
for index, childId in pairs(self.data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
childData[self.field] = texturePath;
WeakAuras.Add(childData);
WeakAuras.UpdateThumbnail(childData);
WeakAuras.SetIconNames(childData);
end
end
else
self.data[self.field] = texturePath;
WeakAuras.Add(self.data);
WeakAuras.UpdateThumbnail(self.data);
WeakAuras.SetIconNames(self.data);
end
local success = icon:SetTexture(texturePath) and texturePath;
if(success) then
iconLabel:SetText(texturePath);
else
iconLabel:SetText();
end
end
function group.Open(self, data, field, groupIcon)
self.data = data;
self.field = field;
self.groupIcon = groupIcon
if(not groupIcon and data.controlledChildren) then
self.givenPath = {};
for index, childId in pairs(data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
self.givenPath[childId] = childData[field];
end
end
else
self.givenPath = self.data[self.field];
end
-- group:Pick(self.givenPath);
frame.window = "icon";
frame:UpdateFrameVisible()
input:SetText("");
end
function group.Close()
frame.window = "default";
frame:UpdateFrameVisible()
AceConfigDialog:Open("WeakAuras", frame.container);
end
function group.CancelClose()
if(not group.groupIcon and group.data.controlledChildren) then
for index, childId in pairs(group.data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
childData[group.field] = group.givenPath[childId] or childData[group.field];
WeakAuras.Add(childData);
WeakAuras.UpdateThumbnail(childData);
WeakAuras.SetIconNames(childData);
end
end
else
group:Pick(group.givenPath);
end
group.Close();
end
local cancel = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate");
cancel:SetScript("OnClick", group.CancelClose);
cancel:SetPoint("bottomright", frame, "bottomright", -27, 11);
cancel:SetHeight(20);
cancel:SetWidth(100);
cancel:SetText(L["Cancel"]);
local close = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate");
close:SetScript("OnClick", group.Close);
close:SetPoint("RIGHT", cancel, "LEFT", -10, 0);
close:SetHeight(20);
close:SetWidth(100);
close:SetText(L["Okay"]);
scroll.frame:SetPoint("BOTTOM", close, "TOP", 0, 10);
return group
end
function WeakAuras.IconPicker(frame)
iconPicker = iconPicker or ConstructIconPicker(frame)
return iconPicker
end
@@ -0,0 +1,96 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local strtrim, strsub = strtrim, strsub
-- WoW APIs
local GetTime, CreateFrame = GetTime, CreateFrame
local AceGUI = LibStub("AceGUI-3.0")
local WeakAuras = WeakAuras
local L = WeakAuras.L
local importexport
local function ConstructImportExport(frame)
local group = AceGUI:Create("InlineGroup");
group.frame:SetParent(frame);
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 12);
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -10);
group.frame:Hide();
group:SetLayout("fill");
local input = AceGUI:Create("MultiLineEditBox");
input:SetWidth(400);
input.button:Hide();
--input.frame:SetClipsChildren(true);
group:AddChild(input);
local close = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate");
close:SetScript("OnClick", function() group:Close() end);
close:SetPoint("BOTTOMRIGHT", -27, 13);
close:SetFrameLevel(close:GetFrameLevel() + 1)
close:SetHeight(20);
close:SetWidth(100);
close:SetText(L["Done"])
function group.Open(self, mode, id)
if(frame.window == "texture") then
frame.texturePicker:CancelClose();
elseif(frame.window == "icon") then
frame.iconPicker:CancelClose();
elseif(frame.window == "model") then
frame.modelPicker:CancelClose();
end
frame.window = "importexport";
frame:UpdateFrameVisible()
if(mode == "export" or mode == "table") then
if(id) then
local displayStr;
if(mode == "export") then
displayStr = WeakAuras.DisplayToString(id, true);
elseif(mode == "table") then
displayStr = WeakAuras.DataToString(id);
end
input.editBox:SetMaxBytes(nil);
input.editBox:SetScript("OnEscapePressed", function() group:Close(); end);
input.editBox:SetScript("OnChar", function() input:SetText(displayStr); input.editBox:HighlightText(); end);
input.editBox:SetScript("OnMouseUp", function() input.editBox:HighlightText(); end);
input:SetLabel(id.." - "..#displayStr);
input.button:Hide();
input:SetText(displayStr);
input.editBox:HighlightText();
input:SetFocus();
end
elseif(mode == "import") then
input.editBox:SetScript("OnEscapePressed", function()
importexport:Close()
end)
input.editBox:SetScript("OnChar", nil)
input.editBox:SetScript("OnMouseUp", nil)
input.editBox:SetScript("OnTextChanged", function()
local str = input:GetText()
input:SetLabel(""..#str)
if #str > 20 then
WeakAuras.Import(str)
end
end)
input:SetText("")
input:SetFocus();
end
end
function group.Close(self)
input:ClearFocus();
frame.window = "default";
frame:UpdateFrameVisible()
end
return group
end
function WeakAuras.ImportExport(frame)
importexport = importexport or ConstructImportExport(frame)
return importexport
end
@@ -0,0 +1,212 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local pairs, rad = pairs, rad
-- WoW APIs
local CreateFrame = CreateFrame
local AceGUI = LibStub("AceGUI-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local WeakAuras = WeakAuras
local L = WeakAuras.L
local modelPicker
local function ConstructModelPicker(frame)
local group = AceGUI:Create("InlineGroup");
group.frame:SetParent(frame);
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 87);
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -10);
group.frame:Hide();
group:SetLayout("flow");
local modelPickerZ = AceGUI:Create("Slider");
modelPickerZ:SetSliderValues(-20, 20, 0.05);
modelPickerZ:SetLabel(L["Z Offset"]);
modelPickerZ.frame:SetParent(group.frame);
modelPickerZ:SetCallback("OnValueChanged", function()
group:Pick(nil, modelPickerZ:GetValue());
end);
local modelPickerX = AceGUI:Create("Slider");
modelPickerX:SetSliderValues(-20, 20, 0.05);
modelPickerX:SetLabel(L["X Offset"]);
modelPickerX.frame:SetParent(group.frame);
modelPickerX:SetCallback("OnValueChanged", function()
group:Pick(nil, nil, modelPickerX:GetValue());
end);
local modelPickerY = AceGUI:Create("Slider");
modelPickerY:SetSliderValues(-20, 20, 0.05);
modelPickerY:SetLabel(L["Y Offset"]);
modelPickerY.frame:SetParent(group.frame);
modelPickerY:SetCallback("OnValueChanged", function()
group:Pick(nil, nil, nil, modelPickerY:GetValue());
end);
local modelTree = AceGUI:Create("WeakAurasTreeGroup");
group.modelTree = modelTree;
group.frame:SetScript("OnUpdate", function()
local frameWidth = frame:GetWidth();
local sliderWidth = (frameWidth - 50) / 3;
local narrowSliderWidth = (frameWidth - 50) / 7;
modelTree:SetTreeWidth(frameWidth - 370);
modelPickerZ.frame:SetPoint("bottomleft", frame, "bottomleft", 15, 43);
modelPickerZ.frame:SetPoint("bottomright", frame, "bottomleft", 15 + sliderWidth, 43);
modelPickerX.frame:SetPoint("bottomleft", frame, "bottomleft", 25 + sliderWidth, 43);
modelPickerX.frame:SetPoint("bottomright", frame, "bottomleft", 25 + (2 * sliderWidth), 43);
modelPickerY.frame:SetPoint("bottomleft", frame, "bottomleft", 35 + (2 * sliderWidth), 43);
modelPickerY.frame:SetPoint("bottomright", frame, "bottomleft", 35 + (3 * sliderWidth), 43);
end);
group:SetLayout("fill");
modelTree:SetTree(WeakAuras.ModelPaths);
modelTree:SetCallback("OnGroupSelected", function(self, event, value, fileId)
local path = string.gsub(value, "\001", "/");
if(string.lower(string.sub(path, -3, -1)) == ".m2") then
group:Pick(path, fileId);
end
end);
group:AddChild(modelTree);
local model = CreateFrame("PlayerModel", nil, group.content);
model:SetAllPoints(modelTree.content);
model:SetFrameStrata("FULLSCREEN");
group.model = model;
function group.Pick(self, model_path, model_z, model_x, model_y)
model_path = model_path or self.data.model_path;
model_z = model_z or self.data.model_z;
model_x = model_x or self.data.model_x;
model_y = model_y or self.data.model_y;
WeakAuras.SetModel(self.model, model_path)
self.model:SetPosition(model_z, model_x, model_y);
self.model:SetFacing(rad(self.data.rotation));
if(not self.parentData and self.data.controlledChildren) then
for index, childId in pairs(self.data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
childData.model_path = model_path;
childData.model_z = model_z;
childData.model_x = model_x;
childData.model_y = model_y;
WeakAuras.Add(childData);
WeakAuras.UpdateThumbnail(childData);
WeakAuras.SetIconNames(childData);
end
end
else
self.data.model_path = model_path;
self.data.model_z = model_z;
self.data.model_x = model_x;
self.data.model_y = model_y;
if self.parentData then
WeakAuras.Add(self.parentData)
else
WeakAuras.Add(self.data);
WeakAuras.UpdateThumbnail(self.data);
WeakAuras.SetIconNames(self.data);
end
end
end
function group.Open(self, data, parentData)
self.data = data;
self.parentData = parentData
WeakAuras.SetModel(self.model, data.model_path)
self.model:SetPosition(data.model_z, data.model_x, data.model_y);
self.model:SetFacing(rad(data.rotation));
modelPickerZ:SetValue(data.model_z);
modelPickerZ.editbox:SetText(("%.2f"):format(data.model_z));
modelPickerX:SetValue(data.model_x);
modelPickerX.editbox:SetText(("%.2f"):format(data.model_x));
modelPickerY:SetValue(data.model_y);
modelPickerY.editbox:SetText(("%.2f"):format(data.model_y));
modelPickerZ.frame:Show();
modelPickerY.frame:Show();
modelPickerX.frame:Show();
if(not parentData and data.controlledChildren) then
self.givenModel = {};
self.givenZ = {};
self.givenX = {};
self.givenY = {};
for index, childId in pairs(data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
self.givenModel[childId] = childData.model_path;
self.givenZ[childId] = childData.model_z;
self.givenX[childId] = childData.model_x;
self.givenY[childId] = childData.model_y;
end
end
else
self.givenModel = data.model_path;
self.givenZ = data.model_z;
self.givenX = data.model_x;
self.givenY = data.model_y;
end
frame.window = "model";
frame:UpdateFrameVisible()
end
function group.Close()
frame.window = "default"
frame:UpdateFrameVisible()
AceConfigDialog:Open("WeakAuras", frame.container);
end
function group.CancelClose(self)
if(not group.parentData and group.data.controlledChildren) then
for index, childId in pairs(group.data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
childData.model_path = group.givenModel[childId];
childData.model_z = group.givenZ[childId];
childData.model_x = group.givenX[childId];
childData.model_y = group.givenY[childId];
WeakAuras.Add(childData);
WeakAuras.UpdateThumbnail(childData);
WeakAuras.SetIconNames(childData);
end
end
else
group:Pick(group.givenPath, group.givenZ, group.givenX, group.givenY);
end
group.Close();
end
local cancel = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate");
cancel:SetScript("OnClick", group.CancelClose);
cancel:SetPoint("bottomright", frame, "bottomright", -27, 16);
cancel:SetHeight(20);
cancel:SetWidth(100);
cancel:SetText(L["Cancel"]);
local close = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate");
close:SetScript("OnClick", group.Close);
close:SetPoint("RIGHT", cancel, "LEFT", -10, 0);
close:SetHeight(20);
close:SetWidth(100);
close:SetText(L["Okay"]);
return group
end
function WeakAuras.ModelPicker(frame)
modelPicker = modelPicker or ConstructModelPicker(frame)
return modelPicker
end
@@ -0,0 +1,975 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local pairs = pairs
-- WoW APIs
local IsShiftKeyDown, CreateFrame = IsShiftKeyDown, CreateFrame
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local WeakAuras = WeakAuras
local moversizer
local mover
local savedVars = WeakAuras.savedVars
local function EnsureTexture(self, texture)
if texture then
return texture
else
local ret = self:CreateTexture()
ret:SetTexture("Interface\\GLUES\\CharacterSelect\\Glues-AddOn-Icons.blp")
ret:SetWidth(16)
ret:SetHeight(16)
ret:SetTexCoord(0, 0.25, 0, 1)
ret:SetVertexColor(1, 1, 1, 0.25)
return ret
end
end
local function moveOnePxl(direction)
if mover and mover.moving then
local data = mover.moving.data
if data then
if direction == "top" then
data.yOffset = data.yOffset + 1
elseif direction == "bottom" then
data.yOffset = data.yOffset - 1
elseif direction == "left" then
data.xOffset = data.xOffset - 1
elseif direction == "right" then
data.xOffset = data.xOffset + 1
end
WeakAuras.Add(data, nil, true)
WeakAuras.UpdateThumbnail(data)
WeakAuras.ResetMoverSizer()
if data.parent then
local parentData = WeakAuras.GetData(data.parent)
if parentData then
WeakAuras.Add(parentData)
end
end
WeakAuras.ReloadOptions(data.id)
end
end
end
local function ConstructMover(frame)
local topAndBottom = CreateFrame("Frame", nil, frame)
topAndBottom:SetClampedToScreen(true)
topAndBottom:SetSize(25, 45)
topAndBottom:SetPoint("LEFT", frame, "RIGHT", 1, 0)
local top = CreateFrame("BUTTON", nil, topAndBottom)
top:SetSize(25, 25)
top:SetPoint("TOP", topAndBottom)
local bottom = CreateFrame("BUTTON", nil, topAndBottom)
bottom:SetSize(25, 25)
bottom:SetPoint("BOTTOM", topAndBottom)
local leftAndRight = CreateFrame("Frame", nil, frame)
leftAndRight:SetClampedToScreen(true)
leftAndRight:SetSize(45, 25)
leftAndRight:SetPoint("TOP", frame, "BOTTOM", 0, 1)
local left = CreateFrame("BUTTON", nil, leftAndRight)
left:SetSize(25, 25)
left:SetPoint("LEFT", leftAndRight)
local right = CreateFrame("BUTTON", nil, leftAndRight)
right:SetSize(25, 25)
right:SetPoint("RIGHT", leftAndRight)
top:SetNormalTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-up.blp")
top:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp")
top:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp")
top:SetScript("OnClick", function() moveOnePxl("top") end)
bottom:SetNormalTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-up.blp")
bottom:GetNormalTexture():SetTexCoord(0, 1, 1, 0)
bottom:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp")
bottom:GetHighlightTexture():SetTexCoord(0, 1, 1, 0)
bottom:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp")
bottom:GetPushedTexture():SetTexCoord(0, 1, 1, 0)
bottom:SetScript("OnClick", function() moveOnePxl("bottom") end)
left:SetNormalTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-up.blp")
left:GetNormalTexture():SetRotation(math.pi/2)
left:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp")
left:GetHighlightTexture():SetRotation(math.pi/2)
left:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp")
left:GetPushedTexture():SetRotation(math.pi/2)
left:SetScript("OnClick", function() moveOnePxl("left") end)
right:SetNormalTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-up.blp")
right:GetNormalTexture():SetRotation(-math.pi/2)
right:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp")
right:GetHighlightTexture():SetRotation(-math.pi/2)
right:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp")
right:GetPushedTexture():SetRotation(-math.pi/2)
right:SetScript("OnClick", function() moveOnePxl("right") end)
--local lineX = frame:CreateLine(nil, "OVERLAY", 7)
local lineX = frame:CreateTexture(nil, "OVERLAY", 7)
lineX:SetSize(2, 2)
lineX:SetTexture(1,1,0)
lineX:SetPoint("BOTTOMLEFT", UIParent)
lineX:SetPoint("BOTTOMRIGHT", UIParent)
lineX:Hide()
--local lineY = frame:CreateLine(nil, "OVERLAY", 7)
local lineY = frame:CreateTexture(nil, "OVERLAY", 7)
lineY:SetSize(2, 2)
lineY:SetTexture(1,1,0)
lineY:SetPoint("TOPLEFT", UIParent)
lineY:SetPoint("BOTTOMLEFT", UIParent)
lineY:Hide()
return lineX, lineY
end
local function ConstructSizer(frame)
-- topright, bottomright, bottomleft, topleft
local topright = CreateFrame("FRAME", nil, frame)
topright:EnableMouse()
topright:SetWidth(16)
topright:SetHeight(16)
topright:SetPoint("TOPRIGHT", frame, "TOPRIGHT")
local texTR1 = topright:CreateTexture(nil, "OVERLAY")
texTR1:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texTR1:SetBlendMode("ADD")
texTR1:SetTexCoord(0.5, 0, 0, 0, 0.5, 1, 0, 1)
texTR1:SetPoint("TOPRIGHT", topright, "TOPRIGHT", -3, -3)
texTR1:SetPoint("BOTTOMLEFT", topright, "BOTTOM")
local texTR2 = topright:CreateTexture(nil, "OVERLAY")
texTR2:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texTR2:SetBlendMode("ADD")
texTR2:SetTexCoord(0, 0, 0, 1, 0.5, 0, 0.5, 1)
texTR2:SetPoint("TOPRIGHT", texTR1, "TOPLEFT")
texTR2:SetPoint("BOTTOMLEFT", topright, "LEFT")
topright.Highlight = function()
texTR1:Show()
texTR2:Show()
end
topright.Clear = function()
texTR1:Hide()
texTR2:Hide()
end
local bottomright = CreateFrame("FRAME", nil, frame)
bottomright:EnableMouse()
bottomright:SetWidth(16)
bottomright:SetHeight(16)
bottomright:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT")
local texBR1 = bottomright:CreateTexture(nil, "OVERLAY")
texBR1:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texBR1:SetBlendMode("ADD")
texBR1:SetTexCoord(1, 0, 0.5, 0, 1, 1, 0.5, 1)
texBR1:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMRIGHT", -3, 3)
texBR1:SetPoint("TOPLEFT", bottomright, "TOP")
local texBR2 = bottomright:CreateTexture(nil, "OVERLAY")
texBR2:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texBR2:SetBlendMode("ADD")
texBR2:SetTexCoord(0, 0, 0, 1, 0.5, 0, 0.5, 1)
texBR2:SetPoint("BOTTOMRIGHT", texBR1, "BOTTOMLEFT")
texBR2:SetPoint("TOPLEFT", bottomright, "LEFT")
bottomright.Highlight = function()
texBR1:Show()
texBR2:Show()
end
bottomright.Clear = function()
texBR1:Hide()
texBR2:Hide()
end
local bottomleft = CreateFrame("FRAME", nil, frame)
bottomleft:EnableMouse()
bottomleft:SetSize(16, 16)
bottomleft:SetHeight(16)
bottomleft:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT")
local texBL1 = bottomleft:CreateTexture(nil, "OVERLAY")
texBL1:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texBL1:SetBlendMode("ADD")
texBL1:SetTexCoord(1, 0, 0.5, 0, 1, 1, 0.5, 1)
texBL1:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMLEFT", 3, 3)
texBL1:SetPoint("TOPRIGHT", bottomleft, "TOP")
local texBL2 = bottomleft:CreateTexture(nil, "OVERLAY")
texBL2:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texBL2:SetBlendMode("ADD")
texBL2:SetTexCoord(0.5, 0, 0.5, 1, 1, 0, 1, 1)
texBL2:SetPoint("BOTTOMLEFT", texBL1, "BOTTOMRIGHT")
texBL2:SetPoint("TOPRIGHT", bottomleft, "RIGHT")
bottomleft.Highlight = function()
texBL1:Show()
texBL2:Show()
end
bottomleft.Clear = function()
texBL1:Hide()
texBL2:Hide()
end
local topleft = CreateFrame("FRAME", nil, frame)
topleft:EnableMouse(true)
topleft:SetWidth(16)
topleft:SetHeight(16)
topleft:SetPoint("TOPLEFT", frame, "TOPLEFT")
local texTL1 = topleft:CreateTexture(nil, "OVERLAY")
texTL1:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texTL1:SetBlendMode("ADD")
texTL1:SetTexCoord(0.5, 0, 0, 0, 0.5, 1, 0, 1)
texTL1:SetPoint("TOPLEFT", topleft, "TOPLEFT", 3, -3)
texTL1:SetPoint("BOTTOMRIGHT", topleft, "BOTTOM")
local texTL2 = topleft:CreateTexture(nil, "OVERLAY")
texTL2:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texTL2:SetBlendMode("ADD")
texTL2:SetTexCoord(0.5, 0, 0.5, 1, 1, 0, 1, 1)
texTL2:SetPoint("TOPLEFT", texTL1, "TOPRIGHT")
texTL2:SetPoint("BOTTOMRIGHT", topleft, "RIGHT")
topleft.Highlight = function()
texTL1:Show()
texTL2:Show()
end
topleft.Clear = function()
texTL1:Hide()
texTL2:Hide()
end
-- top, right, bottom, left
local top = CreateFrame("FRAME", nil, frame)
top:EnableMouse(true)
top:SetHeight(8)
top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
local texT = top:CreateTexture(nil, "OVERLAY")
texT:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texT:SetBlendMode("ADD")
texT:SetPoint("TOPRIGHT", topright, "TOPRIGHT", -3, -3)
texT:SetPoint("BOTTOMLEFT", topleft, "LEFT", 3, 0)
top.Highlight = function()
texT:Show()
end
top.Clear = function()
texT:Hide()
end
local right = CreateFrame("FRAME", nil, frame)
right:EnableMouse(true)
right:SetWidth(8)
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
local texR = right:CreateTexture(nil, "OVERLAY")
texR:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texR:SetBlendMode("ADD")
texR:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMRIGHT", -3, 3)
texR:SetPoint("TOPLEFT", topright, "TOP", 0, -3)
right.Highlight = function()
texR:Show()
end
right.Clear = function()
texR:Hide()
end
local bottom = CreateFrame("FRAME", nil, frame)
bottom:EnableMouse(true)
bottom:SetHeight(8)
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
local texB = bottom:CreateTexture(nil, "OVERLAY")
texB:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texB:SetBlendMode("ADD")
texB:SetTexCoord(1, 0, 0, 0, 1, 1, 0, 1)
texB:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMLEFT", 3, 3)
texB:SetPoint("TOPRIGHT", bottomright, "RIGHT", -3, 0)
bottom.Highlight = function()
texB:Show()
end
bottom.Clear = function()
texB:Hide()
end
local left = CreateFrame("FRAME", nil, frame)
left:EnableMouse(true)
left:SetWidth(8)
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
local texL = left:CreateTexture(nil, "OVERLAY")
texL:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp")
texL:SetBlendMode("ADD")
texL:SetTexCoord(1, 0, 0, 0, 1, 1, 0, 1)
texL:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMLEFT", 3, 3)
texL:SetPoint("TOPRIGHT", topleft, "TOP", 0, -3)
left.Highlight = function()
texL:Show()
end
left.Clear = function()
texL:Hide()
end
-- return in cw order
return top, topright, right, bottomright, bottom, bottomleft, left, topleft
end
local function BuildAlignLines(mover)
local data = mover.moving.data
local align = {
x = {},
y = {}
}
local x, y = {}, {}
local skipIds = { [data.id] = true }
if data.controlledChildren then
for _, id in pairs(data.controlledChildren) do
skipIds[id] = true
end
end
for k, v in pairs(WeakAuras.displayButtons) do
local region = v.view.region
if not skipIds[k] and v.view.visibility ~= 0 and region then
local scale = region:GetEffectiveScale() / UIParent:GetEffectiveScale()
if not IsControlKeyDown() then
tinsert(x, (region:GetLeft() or 0) * scale)
tinsert(x, (region:GetRight() or 0) * scale)
tinsert(y, (region:GetTop() or 0) * scale)
tinsert(y, (region:GetBottom() or 0) * scale)
else
local centerX, centerY = region:GetCenter()
tinsert(x, centerX or 0 * scale)
tinsert(y, centerY or 0 * scale)
end
end
end
local midX, midY = UIParent:GetCenter()
tinsert(x, midX)
tinsert(y, midY)
table.sort(x)
table.sort(y)
for index, value in ipairs(x) do
if value ~= x[index+1] then
tinsert(align.x, value)
end
end
for index, value in ipairs(y) do
if value ~= y[index+1] then
tinsert(align.y, value)
end
end
return align
end
local function ConstructMoverSizer(parent)
local frame = CreateFrame("FRAME", nil, parent)
frame:SetBackdrop({
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
edgeSize = 12,
insets = {left = 0, right = 0, top = 0, bottom = 0}
})
frame:EnableMouse()
frame.top, frame.topright, frame.right, frame.bottomright, frame.bottom, frame.bottomleft, frame.left, frame.topleft
= ConstructSizer(frame)
frame.lineX, frame.lineY = ConstructMover(frame)
frame.top.Clear()
frame.topright.Clear()
frame.right.Clear()
frame.bottomright.Clear()
frame.bottom.Clear()
frame.bottomleft.Clear()
frame.left.Clear()
frame.topleft.Clear()
local mover = CreateFrame("FRAME", nil, frame)
mover:RegisterEvent("PLAYER_REGEN_DISABLED")
mover:EnableMouse()
mover.moving = {}
mover.interims = {}
mover.selfPointIcon = mover:CreateTexture()
mover.selfPointIcon:SetTexture("Interface\\GLUES\\CharacterSelect\\Glues-AddOn-Icons.blp")
mover.selfPointIcon:SetWidth(16)
mover.selfPointIcon:SetHeight(16)
mover.selfPointIcon:SetTexCoord(0, 0.25, 0, 1)
mover.anchorPointIcon = mover:CreateTexture()
mover.anchorPointIcon:SetTexture("Interface\\GLUES\\CharacterSelect\\Glues-AddOn-Icons.blp")
mover.anchorPointIcon:SetWidth(16)
mover.anchorPointIcon:SetHeight(16)
mover.anchorPointIcon:SetTexCoord(0, 0.25, 0, 1)
local moverText = mover:CreateFontString(nil, "OVERLAY", "GameFontNormal")
mover.text = moverText
moverText:Hide()
local sizerText = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
frame.text = sizerText
sizerText:Hide()
frame.ScaleCorners = function(self, width, height)
local limit = math.min(width, height) + 16
local size = 16
if limit <= 40 then
size = limit * (2/5)
end
frame.bottomleft:SetWidth(size)
frame.bottomleft:SetHeight(size)
frame.bottomright:SetWidth(size)
frame.bottomright:SetHeight(size)
frame.topright:SetWidth(size)
frame.topright:SetHeight(size)
frame.topleft:SetWidth(size)
frame.topleft:SetHeight(size)
end
frame.ReAnchor = function(self)
if mover.moving.region then
self:AnchorPoints(mover.moving.region, mover.moving.data)
end
end
frame.AnchorPoints = function(self, region, data)
local scale = region:GetEffectiveScale() / UIParent:GetEffectiveScale()
if data.regionType == "group" then
mover:SetWidth((region.trx - region.blx) * scale)
mover:SetHeight((region.try - region.bly) * scale)
else
mover:SetWidth(region:GetWidth() * scale)
mover:SetHeight(region:GetHeight() * scale)
end
end
frame.GetCurrentId = function(self)
return self.currentId
end
frame.SetToRegion = function(self, region, data)
frame.currentId = data.id
local scale = region:GetEffectiveScale() / UIParent:GetEffectiveScale()
mover.moving.region = region
mover.moving.data = data
local ok, selfPoint, anchor, anchorPoint, xOff, yOff = pcall(region.GetPoint, region, 1)
if not ok then
return
end
mover.selfPoint, mover.anchor, mover.anchorPoint = selfPoint, anchor, anchorPoint
xOff = xOff or 0
yOff = yOff or 0
mover:ClearAllPoints()
frame:ClearAllPoints()
if data.regionType == "group" then
mover:SetWidth((region.trx - region.blx) * scale)
mover:SetHeight((region.try - region.bly) * scale)
mover:SetPoint(mover.selfPoint or "CENTER", mover.anchor or UIParent, mover.anchorPoint or "CENTER", (xOff + region.blx) * scale, (yOff + region.bly) * scale)
else
mover:SetWidth(region:GetWidth() * scale)
mover:SetHeight(region:GetHeight() * scale)
mover:SetPoint(mover.selfPoint or "CENTER", mover.anchor or UIParent, mover.anchorPoint or "CENTER", xOff * scale, yOff * scale)
end
frame:SetPoint("BOTTOMLEFT", mover, "BOTTOMLEFT", -8, -8)
frame:SetPoint("TOPRIGHT", mover, "TOPRIGHT", 8, 8)
frame:ScaleCorners(region:GetWidth(), region:GetHeight())
local regionStrata = region:GetFrameStrata()
if regionStrata then
local strata = math.min(tIndexOf(WeakAuras.frame_strata_types, regionStrata) + 1, 9)
frame:SetFrameStrata(WeakAuras.frame_strata_types[strata])
mover:SetFrameStrata(WeakAuras.frame_strata_types[strata])
end
local db = savedVars.db
mover.startMoving = function()
WeakAuras.CancelAnimation(region, true, true, true, true, true)
mover:ClearAllPoints()
if data.regionType == "group" then
mover:SetPoint(mover.selfPoint, region, mover.anchorPoint, region.blx * scale, region.bly * scale)
else
mover:SetPoint(mover.selfPoint, region, mover.selfPoint)
end
region:StartMoving()
mover.isMoving = true
mover.text:Show()
-- build list of alignment coordinates
mover.align = BuildAlignLines(mover)
end
mover.doneMoving = function(self, event, key)
if event == "MODIFIER_STATE_CHANGED" then
if key == "LCTRL" or key == "RCTRL" then
mover.align = BuildAlignLines(mover)
end
return
end
if not mover.isMoving then
return
end
region:StopMovingOrSizing()
mover.isMoving = false
mover.text:Hide()
local align = (WeakAurasOptionsSaved.magnetAlign and not IsShiftKeyDown())
or (not WeakAurasOptionsSaved.magnetAlign and IsShiftKeyDown())
if align and (mover.alignXFrom or mover.alignYFrom) then
if mover.alignXFrom == "LEFT" then
local left = region:GetLeft() * scale
local selfPoint, anchor, anchorPoint, xOff, yOff = region:GetPoint(1)
if data.regionType == "group" then
xOff = xOff - region.blx
end
region:ClearAllPoints()
region:SetPoint(selfPoint, anchor, anchorPoint, (xOff * scale - left + mover.alignXOf) / scale, yOff)
elseif mover.alignXFrom == "RIGHT" then
local right = region:GetRight() * scale
local selfPoint, anchor, anchorPoint, xOff, yOff = region:GetPoint(1)
if data.regionType == "group" then
xOff = xOff - region.trx
end
region:ClearAllPoints()
region:SetPoint(selfPoint, anchor, anchorPoint, (xOff * scale - right + mover.alignXOf) / scale, yOff)
elseif mover.alignXFrom == "CENTER" then
local center = region:GetCenter() * scale
local selfPoint, anchor, anchorPoint, xOff, yOff = region:GetPoint(1)
if data.regionType == "group" then
xOff = xOff - region.trx + (region.trx - region.blx) / 2
end
region:ClearAllPoints()
region:SetPoint(selfPoint, anchor, anchorPoint, (xOff * scale - center + mover.alignXOf) / scale, yOff)
end
if mover.alignYFrom == "TOP" then
local top = region:GetTop() * scale
local selfPoint, anchor, anchorPoint, xOff, yOff = region:GetPoint(1)
if data.regionType == "group" then
yOff = yOff - region.try
end
region:ClearAllPoints()
region:SetPoint(selfPoint, anchor, anchorPoint, xOff, (yOff * scale - top + mover.alignYOf) / scale)
elseif mover.alignYFrom == "BOTTOM" then
local bottom = region:GetBottom() * scale
local selfPoint, anchor, anchorPoint, xOff, yOff = region:GetPoint(1)
if data.regionType == "group" then
yOff = yOff - region.bly
end
region:ClearAllPoints()
region:SetPoint(selfPoint, anchor, anchorPoint, xOff, (yOff * scale - bottom + mover.alignYOf) / scale)
elseif mover.alignYFrom == "CENTER" then
local _, center = region:GetCenter()
center = center * scale
local selfPoint, anchor, anchorPoint, xOff, yOff = region:GetPoint(1)
if data.regionType == "group" then
yOff = yOff - region.try + (region.try - region.bly) / 2
end
region:ClearAllPoints()
region:SetPoint(selfPoint, anchor, anchorPoint, xOff, (yOff * scale - center + mover.alignYOf) / scale)
end
end
if data.xOffset and data.yOffset then
local selfX, selfY = mover.selfPointIcon:GetCenter()
local anchorX, anchorY = mover.anchorPointIcon:GetCenter()
local dX = selfX - anchorX
local dY = selfY - anchorY
data.xOffset = dX / scale
data.yOffset = dY / scale
end
region:ResetPosition()
WeakAuras.Add(data, nil, true)
WeakAuras.UpdateThumbnail(data)
local xOff, yOff
mover.selfPoint, mover.anchor, mover.anchorPoint, xOff, yOff = region:GetPoint(1)
mover:ClearAllPoints()
if data.regionType == "group" then
mover:SetWidth((region.trx - region.blx) * scale)
mover:SetHeight((region.try - region.bly) * scale)
mover:SetPoint(mover.selfPoint, mover.anchor, mover.anchorPoint, (xOff + region.blx) * scale, (yOff + region.bly) * scale)
else
mover:SetWidth(region:GetWidth() * scale)
mover:SetHeight(region:GetHeight() * scale)
mover:SetPoint(mover.selfPoint, mover.anchor, mover.anchorPoint, xOff * scale, yOff * scale)
end
if data.parent then
local parentData = db.displays[data.parent]
if parentData then
WeakAuras.Add(parentData)
end
end
AceConfigDialog:Open("WeakAuras", parent.container)
WeakAuras.Animate("display", data, "main", data.animation.main, WeakAuras.regions[data.id].region, false, nil, true)
-- hide alignment lines
frame.lineY:Hide()
frame.lineX:Hide()
end
if data.parent and db.displays[data.parent] and db.displays[data.parent].regionType == "dynamicgroup" then
mover:SetScript("OnMouseDown", nil)
mover:SetScript("OnMouseUp", nil)
mover:SetScript("OnEvent", nil)
mover:SetScript("OnHide", nil)
else
mover:SetScript("OnMouseDown", mover.startMoving)
mover:SetScript("OnMouseUp", mover.doneMoving)
mover:SetScript("OnEvent", mover.doneMoving)
mover:SetScript("OnHide", mover.doneMoving)
mover:RegisterEvent("MODIFIER_STATE_CHANGED")
end
if region:IsResizable() then
frame.startSizing = function(point)
mover.isMoving = true
WeakAuras.CancelAnimation(region, true, true, true, true, true)
local rSelfPoint, rAnchor, rAnchorPoint, rXOffset, rYOffset = region:GetPoint(1)
region:StartSizing(point)
frame.text:ClearAllPoints()
frame.text:SetPoint("CENTER", frame, "CENTER", 0, -15)
frame.text:Show()
mover:ClearAllPoints()
mover:SetAllPoints(region)
frame:SetScript("OnUpdate", function()
frame.text:SetText(("(%.2f, %.2f)"):format(region:GetWidth(), region:GetHeight()))
if data.width and data.height then
if IsControlKeyDown() then
data.width = region:GetWidth()
data.height = region:GetHeight()
else
if point:find("RIGHT") then
data.xOffset = region.xOffset + (region:GetWidth() - data.width) / 2
elseif point:find("LEFT") then
data.xOffset = region.xOffset - (region:GetWidth() - data.width) / 2
end
if point:find("TOP") then
data.yOffset = region.yOffset + (region:GetHeight() - data.height) / 2
elseif point:find("BOTTOM") then
data.yOffset = region.yOffset - (region:GetHeight() - data.height) / 2
end
data.width = region:GetWidth()
data.height = region:GetHeight()
end
end
region:ResetPosition()
WeakAuras.Add(data, nil, true)
frame:ScaleCorners(region:GetWidth(), region:GetHeight())
AceConfigDialog:Open("WeakAuras", parent.container)
end)
mover.align = BuildAlignLines(mover)
mover.sizePoint = point
end
frame.doneSizing = function(point)
mover.isMoving = false
region:StopMovingOrSizing()
local width = region:GetWidth()
local height = region:GetHeight()
local align = (WeakAurasOptionsSaved.magnetAlign and not IsShiftKeyDown())
or (not WeakAurasOptionsSaved.magnetAlign and IsShiftKeyDown())
if not IsControlKeyDown() then
if point:find("RIGHT") then
if mover.alignXFrom and align then
width = math.abs(region:GetLeft() * scale - mover.alignXOf) / scale
end
data.xOffset = region.xOffset + (width - data.width) / 2
elseif point:find("LEFT") then
if mover.alignXFrom and align then
width = math.abs(mover.alignXOf - region:GetRight() * scale) / scale
end
data.xOffset = region.xOffset - (width - data.width) / 2
end
if point:find("TOP") then
if mover.alignYFrom and align then
height = math.abs(region:GetBottom() * scale - mover.alignYOf) / scale
end
data.yOffset = region.yOffset + (height - data.height) / 2
elseif point:find("BOTTOM") then
if mover.alignYFrom and align then
height = math.abs(mover.alignYOf - region:GetTop() * scale) / scale
end
data.yOffset = region.yOffset - (height - data.height) / 2
end
end
data.width = width
data.height = height
region:ResetPosition()
WeakAuras.Add(data, nil, true)
WeakAuras.UpdateThumbnail(data)
frame:ScaleCorners(region:GetWidth(), region:GetHeight())
local xOff, yOff
mover.selfPoint, mover.anchor, mover.anchorPoint, xOff, yOff = region:GetPoint(1)
xOff = xOff or 0
yOff = yOff or 0
mover:ClearAllPoints()
if data.regionType == "group" then
mover:SetWidth((region.trx - region.blx) * scale)
mover:SetHeight((region.try - region.bly) * scale)
mover:SetPoint(mover.selfPoint, mover.anchor, mover.anchorPoint, (xOff + region.blx) * scale, (yOff + region.bly) * scale)
else
mover:SetWidth(region:GetWidth() * scale)
mover:SetHeight(region:GetHeight() * scale)
mover:SetPoint(mover.selfPoint, mover.anchor, mover.anchorPoint, xOff * scale, yOff * scale)
end
frame.text:Hide()
frame:SetScript("OnUpdate", nil)
AceConfigDialog:Open("WeakAuras", parent.container)
WeakAuras.Animate("display", data, "main", data.animation.main, WeakAuras.regions[data.id].region, false, nil, true)
-- hide alignment lines
frame.lineY:Hide()
frame.lineX:Hide()
mover.sizePoint = nil
end
frame.bottomleft:SetScript("OnMouseDown", function() frame.startSizing("BOTTOMLEFT") end)
frame.bottomleft:SetScript("OnMouseUp", function() frame.doneSizing("BOTTOMLEFT") end)
frame.bottomleft:SetScript("OnEnter", frame.bottomleft.Highlight)
frame.bottomleft:SetScript("OnLeave", frame.bottomleft.Clear)
frame.bottom:SetScript("OnMouseDown", function() frame.startSizing("BOTTOM") end)
frame.bottom:SetScript("OnMouseUp", function() frame.doneSizing("BOTTOM") end)
frame.bottom:SetScript("OnEnter", frame.bottom.Highlight)
frame.bottom:SetScript("OnLeave", frame.bottom.Clear)
frame.bottomright:SetScript("OnMouseDown", function() frame.startSizing("BOTTOMRIGHT") end)
frame.bottomright:SetScript("OnMouseUp", function() frame.doneSizing("BOTTOMRIGHT") end)
frame.bottomright:SetScript("OnEnter", frame.bottomright.Highlight)
frame.bottomright:SetScript("OnLeave", frame.bottomright.Clear)
frame.right:SetScript("OnMouseDown", function() frame.startSizing("RIGHT") end)
frame.right:SetScript("OnMouseUp", function() frame.doneSizing("RIGHT") end)
frame.right:SetScript("OnEnter", frame.right.Highlight)
frame.right:SetScript("OnLeave", frame.right.Clear)
frame.topright:SetScript("OnMouseDown", function() frame.startSizing("TOPRIGHT") end)
frame.topright:SetScript("OnMouseUp", function() frame.doneSizing("TOPRIGHT") end)
frame.topright:SetScript("OnEnter", frame.topright.Highlight)
frame.topright:SetScript("OnLeave", frame.topright.Clear)
frame.top:SetScript("OnMouseDown", function() frame.startSizing("TOP") end)
frame.top:SetScript("OnMouseUp", function() frame.doneSizing("TOP") end)
frame.top:SetScript("OnEnter", frame.top.Highlight)
frame.top:SetScript("OnLeave", frame.top.Clear)
frame.topleft:SetScript("OnMouseDown", function() frame.startSizing("TOPLEFT") end)
frame.topleft:SetScript("OnMouseUp", function() frame.doneSizing("TOPLEFT") end)
frame.topleft:SetScript("OnEnter", frame.topleft.Highlight)
frame.topleft:SetScript("OnLeave", frame.topleft.Clear)
frame.left:SetScript("OnMouseDown", function() frame.startSizing("LEFT") end)
frame.left:SetScript("OnMouseUp", function() frame.doneSizing("LEFT") end)
frame.left:SetScript("OnEnter", frame.left.Highlight)
frame.left:SetScript("OnLeave", frame.left.Clear)
frame.bottomleft:Show()
frame.bottom:Show()
frame.bottomright:Show()
frame.right:Show()
frame.topright:Show()
frame.top:Show()
frame.topleft:Show()
frame.left:Show()
else
frame.bottomleft:Hide()
frame.bottom:Hide()
frame.bottomright:Hide()
frame.right:Hide()
frame.topright:Hide()
frame.top:Hide()
frame.topleft:Hide()
frame.left:Hide()
end
mover.alignXFrom = nil
mover.alignYFrom = nil
mover.alignYOf = nil
mover.alignYOf = nil
frame:Show()
end
mover:SetScript("OnUpdate", function(self, elaps)
if not IsShiftKeyDown() then
self.goalAlpha = 1
else
self.goalAlpha = 0.1
end
if self.currentAlpha ~= self.goalAlpha then
self.currentAlpha = self.currentAlpha or self:GetAlpha()
local newAlpha = (self.currentAlpha < self.goalAlpha) and self.currentAlpha + (elaps * 4) or self.currentAlpha - (elaps * 4)
newAlpha = (newAlpha > 1 and 1) or (newAlpha < 0.1 and 0.1) or newAlpha
mover:SetAlpha(newAlpha)
frame:SetAlpha(newAlpha)
self.currentAlpha = newAlpha
end
local align = (WeakAurasOptionsSaved.magnetAlign and not IsShiftKeyDown())
or (not WeakAurasOptionsSaved.magnetAlign and IsShiftKeyDown())
if align then
self.alignGoalAlpha = 1
else
self.alignGoalAlpha = 0.1
end
if self.alignCurrentAlpha ~= self.alignGoalAlpha then
self.alignCurrentAlpha = self.alignCurrentAlpha or self:GetAlpha()
local newAlpha = (self.alignCurrentAlpha < self.alignGoalAlpha) and self.alignCurrentAlpha + (elaps * 4) or self.alignCurrentAlpha - (elaps * 4)
newAlpha = (newAlpha > 1 and 1) or (newAlpha < 0.1 and 0.1) or newAlpha
frame.lineX:SetAlpha(newAlpha)
frame.lineY:SetAlpha(newAlpha)
self.alignCurrentAlpha = newAlpha
end
local db = savedVars.db
local region = self.moving.region
local data = self.moving.data
if not self.isMoving then
self.selfPoint, self.anchor, self.anchorPoint = region:GetPoint(1)
end
self.selfPointIcon:ClearAllPoints()
self.selfPointIcon:SetPoint("CENTER", region, self.selfPoint)
local selfX, selfY = self.selfPointIcon:GetCenter()
selfX, selfY = selfX or 0, selfY or 0
self.anchorPointIcon:ClearAllPoints()
self.anchorPointIcon:SetPoint("CENTER", self.anchor, self.anchorPoint)
local anchorX, anchorY = self.anchorPointIcon:GetCenter()
anchorX, anchorY = anchorX or 0, anchorY or 0
if data.parent and db.displays[data.parent] and db.displays[data.parent].regionType == "dynamicgroup" then
self.selfPointIcon:Hide()
self.anchorPointIcon:Hide()
else
self.selfPointIcon:Show()
self.anchorPointIcon:Show()
end
local dX = selfX - anchorX
local dY = selfY - anchorY
local distance = sqrt(dX^2 + dY^2)
local angle = atan2(dY, dX)
local numInterim = floor(distance/40)
for index, texture in pairs(self.interims) do
texture:Hide()
end
for i = 1, numInterim do
local x = (distance - (i * 40)) * cos(angle)
local y = (distance - (i * 40)) * sin(angle)
self.interims[i] = EnsureTexture(self, self.interims[i])
self.interims[i]:ClearAllPoints()
self.interims[i]:SetPoint("CENTER", self.anchorPointIcon, "CENTER", x, y)
self.interims[i]:Show()
end
local regionScale = self.moving.region:GetScale()
self.text:SetText(("(%.2f, %.2f)"):format(dX*1/regionScale, dY*1/regionScale))
local midx = (distance / 2) * cos(angle)
local midy = (distance / 2) * sin(angle)
self.text:SetPoint("CENTER", self.anchorPointIcon, "CENTER", midx, midy)
local left, right, top, bottom, centerX, centerY = frame:GetLeft(), frame:GetRight(), frame:GetTop(), frame:GetBottom(), frame:GetCenter()
if (midx > 0 and (self.text:GetRight() or 0) > (left or 0))
or (midx < 0 and (self.text:GetLeft() or 0) < (right or 0))
then
if midy > 0 and (self.text:GetTop() or 0) > (top or 0) then
midy = midy - ((self.text:GetTop() or 0) - (bottom or 0))
elseif midy < 0 and (self.text:GetBottom() or 0) < (top or 0) then
midy = midy + ((top or 0) - (self.text:GetBottom() or 0))
end
end
self.text:SetPoint("CENTER", self.anchorPointIcon, "CENTER", midx, midy)
if self.isMoving then
if mover.align then
local ctrlDown = IsControlKeyDown()
local foundX, foundY = false, false
local point = mover.sizePoint
local reverse, start, finish, step
if mover.lastX ~= selfX then
-- if mouse move to the right, take first line found from the right, and match right side of the frame first
reverse = mover.lastX and mover.lastX < selfX -- reverse = mouse move to the right
start = reverse and #mover.align.x or 1
finish = reverse and 1 or #mover.align.x
step = reverse and -1 or 1
for i=start,finish,step do
local v = mover.align.x[i]
if not ctrlDown and (
((left >= v - 5 and left <= v + 5) and (not point or point:find("LEFT")))
or ((right >= v - 5 and right <= v + 5) and (not point or point:find("RIGHT")))
) or (
ctrlDown and centerX >= v - 5 and centerX <= v + 5
)
then
frame.lineY:SetPoint("TOPLEFT", UIParent, v, 0)
frame.lineY:SetPoint("BOTTOMLEFT", UIParent, v, 0)
frame.lineY:Show()
mover.alignXFrom = ctrlDown and "CENTER"
or (reverse and ((right >= v - 5 and right <= v + 5) and "RIGHT" or "LEFT")) -- right side first
or (not reverse and ((left >= v - 5 and left <= v + 5) and "LEFT" or "RIGHT")) -- left side first
mover.alignXOf = v
foundX = true
break
end
end
if not foundX then
mover.alignXFrom = nil
mover.alignXOf = nil
frame.lineY:Hide()
end
end
if mover.lastY ~= selfY then
-- if mouse move to the top, take first line found from the top, and match top side of the frame first
reverse = mover.lastY and mover.lastY < selfY
start = reverse and #mover.align.y or 1
finish = reverse and 1 or #mover.align.y
step = reverse and -1 or 1
for i=start,finish,step do
local v = mover.align.y[i]
if not ctrlDown and (
((top >= v - 5 and top <= v + 5) and (not point or point:find("TOP")))
or ((bottom >= v - 5 and bottom <= v + 5) and (not point or point:find("BOTTOM")))
) or (
ctrlDown and centerY >= v - 5 and centerY <= v + 5
)
then
frame.lineX:SetPoint("BOTTOMLEFT", UIParent, 0, v)
frame.lineX:SetPoint("BOTTOMRIGHT", UIParent, 0, v)
frame.lineX:Show()
mover.alignYFrom = ctrlDown and "CENTER" or (top >= v - 5 and top <= v + 5) and "TOP" or "BOTTOM"
or (reverse and ((top >= v - 5 and top <= v + 5) and "TOP" or "BOTTOM")) -- top side first
or (not reverse and ((bottom >= v - 5 and bottom <= v + 5) and "BOTTOM" or "TOP")) -- bottom side first
mover.alignYOf = v
foundY = true
break
end
end
if not foundY then
mover.alignYFrom = nil
mover.alignYOf = nil
frame.lineX:Hide()
end
end
mover.lastX, mover.lastY = selfX, selfY
end
end
end)
return frame, mover
end
function WeakAuras.MoverSizer(parent)
if not moversizer or not mover then
moversizer, mover = ConstructMoverSizer(parent)
end
return moversizer, mover
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,788 @@
if not WeakAuras.IsCorrectVersion() then
return
end
-- Lua APIs
local pairs, type, ipairs = pairs, type, ipairs
local loadstring = loadstring
-- WoW APIs
local CreateFrame = CreateFrame
local AceGUI = LibStub("AceGUI-3.0")
local SharedMedia = LibStub("LibSharedMedia-3.0")
local IndentationLib = IndentationLib
local WeakAuras = WeakAuras
local L = WeakAuras.L
local textEditor
local valueFromPath = WeakAuras.ValueFromPath
local valueToPath = WeakAuras.ValueToPath
local editor_themes = {
["Standard"] = {
["Table"] = "|c00ff3333",
["Arithmetic"] = "|c00ff3333",
["Relational"] = "|c00ff3333",
["Logical"] = "|c004444ff",
["Special"] = "|c00ff3333",
["Keyword"] = "|c004444ff",
["Comment"] = "|c0000aa00",
["Number"] = "|c00ff9900",
["String"] = "|c00999999"
},
["Monokai"] = {
["Table"] = "|c00ffffff",
["Arithmetic"] = "|c00f92672",
["Relational"] = "|c00ff3333",
["Logical"] = "|c00f92672",
["Special"] = "|c0066d9ef",
["Keyword"] = "|c00f92672",
["Comment"] = "|c0075715e",
["Number"] = "|c00ae81ff",
["String"] = "|c00e6db74"
},
["Obsidian"] = {
["Table"] = "|c00AFC0E5",
["Arithmetic"] = "|c00E0E2E4",
["Relational"] = "|c00B3B689",
["Logical"] = "|c0093C763",
["Special"] = "|c00AFC0E5",
["Keyword"] = "|c0093C763",
["Comment"] = "|c0066747B",
["Number"] = "|c00FFCD22",
["String"] = "|c00EC7600"
}
}
local color_scheme = {[0] = "|r"}
local function set_scheme()
if not WeakAurasSaved.editor_theme then
WeakAurasSaved.editor_theme = "Monokai"
end
local theme = editor_themes[WeakAurasSaved.editor_theme]
color_scheme[IndentationLib.tokens.TOKEN_SPECIAL] = theme["Special"]
color_scheme[IndentationLib.tokens.TOKEN_KEYWORD] = theme["Keyword"]
color_scheme[IndentationLib.tokens.TOKEN_COMMENT_SHORT] = theme["Comment"]
color_scheme[IndentationLib.tokens.TOKEN_COMMENT_LONG] = theme["Comment"]
color_scheme[IndentationLib.tokens.TOKEN_NUMBER] = theme["Number"]
color_scheme[IndentationLib.tokens.TOKEN_STRING] = theme["String"]
color_scheme["..."] = theme["Table"]
color_scheme["{"] = theme["Table"]
color_scheme["}"] = theme["Table"]
color_scheme["["] = theme["Table"]
color_scheme["]"] = theme["Table"]
color_scheme["+"] = theme["Arithmetic"]
color_scheme["-"] = theme["Arithmetic"]
color_scheme["/"] = theme["Arithmetic"]
color_scheme["*"] = theme["Arithmetic"]
color_scheme[".."] = theme["Arithmetic"]
color_scheme["=="] = theme["Relational"]
color_scheme["<"] = theme["Relational"]
color_scheme["<="] = theme["Relational"]
color_scheme[">"] = theme["Relational"]
color_scheme[">="] = theme["Relational"]
color_scheme["~="] = theme["Relational"]
color_scheme["and"] = theme["Logical"]
color_scheme["or"] = theme["Logical"]
color_scheme["not"] = theme["Logical"]
end
-- Define the premade snippets
local premadeSnippets = {
{
name = "Basic function",
snippet = [=[
function()
return
end]=]
},
{
name = "Custom Activation",
snippet = [=[
function(trigger)
return trigger[1] and (trigger[2] or trigger[3])
end]=]
},
{
name = "Trigger: CLEU",
snippet = [=[
function(event, timestamp, subEvent, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, ...)
return
end]=]
},
{
name = "Simple throttle",
snippet = [=[
if not aura_env.last or aura_env.last < GetTime() - 1 then
aura_env.last = GetTime()
end]=]
},
{
name = "Trigger State Updater",
snippet = [=[
function(allstates, event, ...)
allstates[""] = {
show = true,
changed = true,
progressType = "static"||"timed",
value = ,
total = ,
duration = ,
expirationTime = ,
autoHide = true,
name = ,
icon = ,
stacks = ,
index = ,
}
return true
end]=]
},
{
name = "Text: Decimals (percentage)",
snippet = [=[
function()
-- Change percentpower as needed
-- Change [1] to other your trigger number
-- The 0 in `"%.0f"` controls how many decimal places it will round to
if aura_env.states[1] and aura_env.states[1].percentpower then
return string.format("%.0f", aura_env.states[1].percentpower)
end
end]=]
},
{
name = "Text: Abbreviate numbers",
snippet = [=[
function()
-- Change tooltip1 to your value
-- Change [1] to other your trigger number
-- If using a tooltip value, be sure to tick Use Tooltip Values in the trigger
if aura_env.states[1] and aura_env.states[1].tooltip1 then
return AbbreviateNumbers(aura_env.states[1].tooltip1)
end
end]=]
},
{
name = "Text: Colored Name",
snippet = [=[
function()
if aura_env.states[1] and aura_env.states[1].unit then
return WA_ClassColorName(aura_env.states[1].unit)
end
end]=]
},
}
local function settings_dropdown_initialize(frame, level, menu)
for k, v in pairs(editor_themes) do
local item = {
text = k,
isNotRadio = false,
checked = function()
return WeakAurasSaved.editor_theme == k
end,
func = function()
WeakAurasSaved.editor_theme = k
set_scheme()
WeakAuras.editor.editBox:SetText(WeakAuras.editor.editBox:GetText())
end
}
UIDropDownMenu_AddButton(item)
end
UIDropDownMenu_AddButton(
{
text = L["Bracket Matching"],
isNotRadio = true,
checked = function()
return WeakAurasSaved.editor_bracket_matching
end,
func = function()
WeakAurasSaved.editor_bracket_matching = not WeakAurasSaved.editor_bracket_matching
end
}
)
end
local function ConstructTextEditor(frame)
local group = AceGUI:Create("InlineGroup")
group.frame:SetParent(frame)
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 12)
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -10)
group.frame:Hide()
group:SetLayout("fill")
local editor = AceGUI:Create("MultiLineEditBox")
editor:SetWidth(400)
editor.button:Hide()
local fontPath = SharedMedia:Fetch("font", "Fira Mono Medium")
if (fontPath) then
editor.editBox:SetFont(fontPath, 12)
end
group:AddChild(editor)
--editor.frame:SetClipsChildren(true)
-- The indention lib overrides GetText, but for the line number
-- display we ned the original, so save it here.
local originalGetText = editor.editBox.GetText
set_scheme()
IndentationLib.enable(editor.editBox, color_scheme, 4)
local cancel = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
cancel:SetScript(
"OnClick",
function()
group:CancelClose()
end
)
cancel:SetPoint("BOTTOMRIGHT", -27, 13)
cancel:SetFrameLevel(cancel:GetFrameLevel() + 1)
cancel:SetHeight(20)
cancel:SetWidth(100)
cancel:SetText(L["Cancel"])
local close = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
close:SetScript(
"OnClick",
function()
group:Close()
end
)
close:SetPoint("RIGHT", cancel, "LEFT", -10, 0)
close:SetFrameLevel(close:GetFrameLevel() + 1)
close:SetHeight(20)
close:SetWidth(100)
close:SetText(L["Done"])
local settings_frame = CreateFrame("Button", "WASettingsButton", close, "UIPanelButtonTemplate")
settings_frame:SetPoint("RIGHT", close, "LEFT", -10, 0)
settings_frame:SetHeight(20)
settings_frame:SetWidth(100)
settings_frame:SetText(L["Settings"])
settings_frame:RegisterForClicks("LeftButtonUp")
local helpButton = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
helpButton:SetPoint("BOTTOMLEFT", 12, 13)
helpButton:SetFrameLevel(cancel:GetFrameLevel() + 1)
helpButton:SetHeight(20)
helpButton:SetWidth(100)
helpButton:SetText(L["Help"])
local urlText = CreateFrame("editbox", nil, group.frame)
urlText:SetFrameLevel(cancel:GetFrameLevel() + 1)
urlText:SetFont(STANDARD_TEXT_FONT, 12)
urlText:EnableMouse(true)
urlText:SetAutoFocus(false)
urlText:SetCountInvisibleLetters(false)
urlText:Hide()
local urlCopyLabel = urlText:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
urlCopyLabel:SetPoint("BOTTOMLEFT", group.frame, "BOTTOMLEFT", 12, 18)
urlCopyLabel:SetText(L["Press Ctrl+C to copy"])
urlCopyLabel:Hide()
urlText:SetPoint("TOPLEFT", urlCopyLabel, "TOPRIGHT", 12, 13)
urlText:SetPoint("RIGHT", settings_frame, "LEFT")
local dropdown = CreateFrame("Frame", "SettingsMenuFrame", settings_frame, "UIDropDownMenuTemplate")
UIDropDownMenu_Initialize(dropdown, settings_dropdown_initialize, "MENU")
settings_frame:SetScript(
"OnClick",
function(self, button, down)
ToggleDropDownMenu(1, nil, dropdown, settings_frame, 0, 0)
end
)
-- Make Snippets button (top right, near the line number)
local snippetsButton = CreateFrame("Button", "WASnippetsButton", group.frame, "UIPanelButtonTemplate")
snippetsButton:SetPoint("BOTTOMRIGHT", editor.frame, "TOPRIGHT", 0, -15)
snippetsButton:SetFrameLevel(group.frame:GetFrameLevel() + 2)
snippetsButton:SetHeight(20)
snippetsButton:SetWidth(100)
snippetsButton:SetText(L["Snippets"])
snippetsButton:RegisterForClicks("LeftButtonUp")
-- Get the saved snippets from SavedVars
WeakAurasOptionsSaved.savedSnippets = WeakAurasOptionsSaved.savedSnippets or {}
local savedSnippets = WeakAurasOptionsSaved.savedSnippets
-- function to build snippet selection list
local function UpdateSnippets(frame)
-- release first before rebuilding
frame:ReleaseChildren()
table.sort(
savedSnippets,
function(a, b)
return a.name < b.name
end
)
local heading1 = AceGUI:Create("Heading")
heading1:SetText(L["Premade Snippets"])
heading1:SetRelativeWidth(1)
frame:AddChild(heading1)
-- Iterate premade snippets and make buttons for them
for order, snippet in ipairs(premadeSnippets) do
local button = AceGUI:Create("WeakAurasSnippetButton")
button:SetTitle(snippet.name)
button:SetDescription(snippet.snippet)
button:SetCallback(
"OnClick",
function()
editor.editBox:Insert(snippet.snippet)
editor:SetFocus()
end
)
button:SetRelativeWidth(1)
frame:AddChild(button)
end
local heading2 = AceGUI:Create("Heading")
heading2:SetText(L["Your Saved Snippets"])
heading2:SetRelativeWidth(1)
frame:AddChild(heading2)
-- iterate saved snippets and make buttons
for order, snippet in ipairs(savedSnippets) do
local button = AceGUI:Create("WeakAurasSnippetButton")
button:SetTitle(snippet.name)
button:SetDescription(snippet.snippet)
button:SetEditable(true)
button:SetRelativeWidth(1)
button:SetNew(snippet.new)
snippet.new = false
button:SetCallback(
"OnClick",
function()
WeakAuras.editor.editBox:Insert(snippet.snippet)
WeakAuras.editor:SetFocus()
end
)
button.deleteButton:SetScript(
"OnClick",
function()
table.remove(savedSnippets, order)
UpdateSnippets(frame)
end
)
button:SetCallback(
"OnEnterPressed",
function()
local newName = button.renameEditBox:GetText()
if newName and #newName > 0 then
local found = false
for _, snippet in ipairs(savedSnippets) do
if snippet.name == newName then
found = true
break
end
end
if not found then
savedSnippets[order].name = newName
UpdateSnippets(frame)
end
end
end
)
frame:AddChild(button)
end
end
-- Make sidebar for snippets
local snippetsFrame = CreateFrame("FRAME", "WeakAurasSnippets", group.frame)
snippetsFrame:SetPoint("TOPLEFT", group.frame, "TOPRIGHT", 20, 0)
snippetsFrame:SetPoint("BOTTOMLEFT", group.frame, "BOTTOMRIGHT", 20, 0)
snippetsFrame:SetWidth(250)
snippetsFrame:SetBackdrop(
{
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true,
tileSize = 32,
edgeSize = 32,
insets = {left = 8, right = 8, top = 8, bottom = 8}
}
)
snippetsFrame:SetBackdropColor(0, 0, 0, 1)
-- Add button to save new snippet
local AddSnippetButton = CreateFrame("Button", nil, snippetsFrame, "UIPanelButtonTemplate")
AddSnippetButton:SetPoint("TOPLEFT", snippetsFrame, "TOPLEFT", 13, -10)
AddSnippetButton:SetPoint("TOPRIGHT", snippetsFrame, "TOPRIGHT", -13, -10)
AddSnippetButton:SetHeight(20)
AddSnippetButton:SetText(L["Add Snippet"])
AddSnippetButton:RegisterForClicks("LeftButtonUp")
-- house the buttons in a scroll frame
-- All AceGUI from this point, so that buttons can be released and reused
local snippetsScrollContainer = AceGUI:Create("SimpleGroup")
snippetsScrollContainer:SetFullWidth(true)
snippetsScrollContainer:SetFullHeight(true)
snippetsScrollContainer:SetLayout("Fill")
snippetsScrollContainer.frame:SetParent(snippetsFrame)
snippetsScrollContainer.frame:SetPoint("TOPLEFT", snippetsFrame, "TOPLEFT", 17, -35)
snippetsScrollContainer.frame:SetPoint("BOTTOMRIGHT", snippetsFrame, "BOTTOMRIGHT", -10, 10)
local snippetsScroll = AceGUI:Create("ScrollFrame")
snippetsScroll:SetLayout("List")
snippetsScrollContainer:AddChild(snippetsScroll)
snippetsScroll:FixScroll(true)
snippetsScroll.scrollframe:SetScript(
"OnScrollRangeChanged",
function(frame)
frame.obj:DoLayout()
end
)
snippetsFrame:Hide()
-- Toggle the side bar on click
snippetsButton:SetScript(
"OnClick",
function(self, button, down)
if not snippetsFrame:IsShown() then
snippetsFrame:Show()
UpdateSnippets(snippetsScroll)
else
snippetsFrame:Hide()
end
end
)
AddSnippetButton:SetScript(
"OnClick",
function(self)
local snippet = editor.editBox:GetText()
if snippet and #snippet > 0 then
local baseName, name, index = "New Snippet", "New Snippet", 0
local snippetExists = function(name)
for _, snippet in ipairs(savedSnippets) do
if snippet.name == name then
return true
end
end
end
while snippetExists(name) do
index = index + 1
name = format("%s %d", baseName, index)
end
table.insert(savedSnippets, {name = name, snippet = snippet, new = true})
UpdateSnippets(snippetsScroll)
end
end
)
-- CTRL + S saves and closes, ESC cancels and closes
editor.editBox:HookScript(
"OnKeyDown",
function(_, key)
if IsControlKeyDown() and key == "S" then
group:Close()
end
if key == "ESCAPE" then
group:CancelClose()
end
end
)
-- bracket matching
editor.editBox:HookScript(
"OnChar",
function(_, char)
if not IsControlKeyDown() and WeakAurasSaved.editor_bracket_matching then
if char == "(" then
editor.editBox:Insert(")")
editor.editBox:SetCursorPosition(editor.editBox:GetCursorPosition() - 1)
elseif char == "{" then
editor.editBox:Insert("}")
editor.editBox:SetCursorPosition(editor.editBox:GetCursorPosition() - 1)
elseif char == "[" then
editor.editBox:Insert("]")
editor.editBox:SetCursorPosition(editor.editBox:GetCursorPosition() - 1)
end
end
end
)
local editorError = group.frame:CreateFontString(nil, "OVERLAY")
editorError:SetFont(STANDARD_TEXT_FONT, 12)
editorError:SetJustifyH("LEFT")
editorError:SetJustifyV("TOP")
editorError:SetTextColor(1, 0, 0)
editorError:SetPoint("LEFT", helpButton, "RIGHT", 0, 4)
editorError:SetPoint("RIGHT", settings_frame, "LEFT")
local editorLine = CreateFrame("Editbox", nil, group.frame)
-- Set script on enter pressed..
editorLine:SetPoint("BOTTOMRIGHT", editor.frame, "TOPRIGHT", -100, -15)
editorLine:SetFont(STANDARD_TEXT_FONT, 10)
editorLine:SetJustifyH("RIGHT")
editorLine:SetWidth(80)
editorLine:SetHeight(20)
editorLine:SetNumeric(true)
editorLine:SetTextInsets(10, 10, 0, 0)
editorLine:SetAutoFocus(false)
urlText:SetScript(
"OnChar",
function(self)
self:SetText(group.url)
self:HighlightText()
end
)
urlText:SetScript(
"OnEscapePressed",
function()
urlText:ClearFocus()
urlText:Hide()
urlCopyLabel:Hide()
helpButton:Show()
editor:SetFocus()
end
)
helpButton:SetScript(
"OnClick",
function()
urlText:Show()
urlText:SetFocus()
urlText:HighlightText()
urlCopyLabel:Show()
helpButton:Hide()
editorError:Hide()
end
)
local oldOnCursorChanged = editor.editBox:GetScript("OnCursorChanged")
editor.editBox:SetScript(
"OnCursorChanged",
function(...)
oldOnCursorChanged(...)
local cursorPosition = editor.editBox:GetCursorPosition()
local next = -1
local line = 0
while (next and cursorPosition >= next) do
next = originalGetText(editor.editBox):find("[\n]", next + 1)
line = line + 1
end
editorLine:SetNumber(line)
end
)
editorLine:SetScript(
"OnEnterPressed",
function()
local newLine = editorLine:GetNumber()
local newPosition = 0
while (newLine > 1 and newPosition) do
newPosition = originalGetText(editor.editBox):find("[\n]", newPosition + 1)
newLine = newLine - 1
end
if (newPosition) then
editor.editBox:SetCursorPosition(newPosition)
editor.editBox:SetFocus()
end
end
)
function group.Open(self, data, path, enclose, multipath, reloadOptions, setOnParent, url)
self.data = data
self.path = path
self.multipath = multipath
self.reloadOptions = reloadOptions
self.setOnParent = setOnParent
self.url = url
urlText:SetText(url or "")
urlText:Hide()
urlCopyLabel:Hide()
if url then
helpButton:Show()
else
helpButton:Hide()
end
if (frame.window == "texture") then
frame.texturePicker:CancelClose()
elseif (frame.window == "icon") then
frame.iconPicker:CancelClose()
end
frame.window = "texteditor"
frame:UpdateFrameVisible()
local title = (type(data.id) == "string" and data.id or L["Temporary Group"]) .. " -"
if (not multipath) then
for index, field in pairs(path) do
if (type(field) == "number") then
field = "Trigger " .. field + 1
end
title = title .. " " .. field:sub(1, 1):upper() .. field:sub(2)
end
end
editor:SetLabel(title)
editor.editBox:SetScript(
"OnEscapePressed",
function()
group:CancelClose()
end
)
self.oldOnTextChanged = editor.editBox:GetScript("OnTextChanged")
editor.editBox:SetScript(
"OnTextChanged",
function(...)
local str = editor.editBox:GetText()
if not (str) or editor.combinedText == true then
editorError:SetText("")
else
local _, errorString
if (enclose) then
_, errorString = loadstring("return function() " .. str .. "\n end")
else
_, errorString = loadstring("return " .. str)
end
if errorString then
urlText:Hide()
urlCopyLabel:Hide()
if self.url then
helpButton:Show()
end
editorError:Show()
editorError:SetText(errorString)
else
editorError:SetText("")
end
end
self.oldOnTextChanged(...)
end
)
if (data.controlledChildren and not setOnParent) then
local singleText
local sameTexts = true
local combinedText = ""
for index, childId in pairs(data.controlledChildren) do
local childData = WeakAuras.GetData(childId)
local text = valueFromPath(childData, multipath and path[childId] or path)
if text then
if not (singleText) then
singleText = text
else
if not (singleText == text) then
sameTexts = false
end
end
if not (combinedText == "") then
combinedText = combinedText .. "\n\n"
end
combinedText =
combinedText .. L["-- Do not remove this comment, it is part of this trigger: "] .. childId .. "\n"
combinedText = combinedText .. (text or "")
end
end
if (sameTexts) then
editor:SetText(singleText or "")
editor.combinedText = false
else
editor:SetText(combinedText)
editor.combinedText = true
end
else
editor:SetText(valueFromPath(data, path) or "")
end
editor:SetFocus()
end
function group.CancelClose(self)
editor.editBox:SetScript("OnTextChanged", self.oldOnTextChanged)
editor:ClearFocus()
frame.window = "default"
frame:UpdateFrameVisible()
end
local function extractTexts(input, ids)
local texts = {}
local currentPos, id, startIdLine, startId, endId, endIdLine
while (true) do
startIdLine, startId =
string.find(input, L["-- Do not remove this comment, it is part of this trigger: "], currentPos, true)
if (not startId) then
break
end
endId, endIdLine = string.find(input, "\n", startId, true)
if (not endId) then
break
end
if (currentPos) then
local trimmedPosition = startIdLine - 1
while (string.sub(input, trimmedPosition, trimmedPosition) == "\n") do
trimmedPosition = trimmedPosition - 1
end
texts[id] = string.sub(input, currentPos, trimmedPosition)
end
id = string.sub(input, startId + 1, endId - 1)
currentPos = endIdLine + 1
end
if (id) then
texts[id] = string.sub(input, currentPos, string.len(input))
end
return texts
end
function group.Close(self)
if (self.data.controlledChildren and not self.setOnParent) then
local textById = editor.combinedText and extractTexts(editor:GetText(), self.data.controlledChildren)
for index, childId in pairs(self.data.controlledChildren) do
local text = editor.combinedText and (textById[childId] or "") or editor:GetText()
local childData = WeakAuras.GetData(childId)
valueToPath(childData, self.multipath and self.path[childId] or self.path, text)
WeakAuras.Add(childData)
end
else
valueToPath(self.data, self.path, editor:GetText())
WeakAuras.Add(self.data)
end
if (self.reloadOptions) then
if (self.data.controlledChildren) then
for index, childId in pairs(self.data.controlledChildren) do
WeakAuras.ScheduleReloadOptions(WeakAuras.GetData(childId))
end
WeakAuras.ScheduleReloadOptions(self.data)
else
WeakAuras.ScheduleReloadOptions(self.data)
end
else
WeakAuras.ScheduleReloadOptions(self.data)
end
editor.editBox:SetScript("OnTextChanged", self.oldOnTextChanged)
editor:ClearFocus()
frame.window = "default"
frame:UpdateFrameVisible()
frame:RefreshPick()
end
WeakAuras.editor = editor
return group
end
function WeakAuras.TextEditor(frame)
textEditor = textEditor or ConstructTextEditor(frame)
return textEditor
end
@@ -0,0 +1,229 @@
if not WeakAuras.IsCorrectVersion() then return end
-- Lua APIs
local wipe = wipe
local pairs, next, type = pairs, next, type
-- WoW APIs
local CreateFrame = CreateFrame
local AceGUI = LibStub("AceGUI-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local WeakAuras = WeakAuras
local L = WeakAuras.L
local getAll = WeakAuras.getAll
local setAll = WeakAuras.setAll
local texturePicker
local function ConstructTexturePicker(frame)
local group = AceGUI:Create("InlineGroup");
group.frame:SetParent(frame);
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 42);
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -10);
group.frame:Hide();
group.children = {};
group.categories = {};
local dropdown = AceGUI:Create("DropdownGroup");
dropdown:SetLayout("fill");
dropdown.width = "fill";
dropdown:SetHeight(390);
group:SetLayout("fill");
group:AddChild(dropdown);
dropdown.list = {};
dropdown:SetGroupList(dropdown.list);
local scroll = AceGUI:Create("ScrollFrame");
scroll:SetWidth(540);
scroll:SetLayout("flow");
--scroll.frame:SetClipsChildren(true);
dropdown:AddChild(scroll);
local function texturePickerGroupSelected(widget, event, uniquevalue)
scroll:ReleaseChildren();
for texturePath, textureName in pairs(group.textures[uniquevalue]) do
local textureWidget = AceGUI:Create("WeakAurasTextureButton");
if (group.SetTextureFunc) then
group.SetTextureFunc(textureWidget, texturePath, textureName);
else
textureWidget:SetTexture(texturePath, textureName);
local d = group.textureData;
textureWidget:ChangeTexture(d.r, d.g, d.b, d.a, d.rotate, d.discrete_rotation, d.rotation, d.mirror, d.blendMode);
end
textureWidget:SetClick(function()
group:Pick(texturePath);
end);
scroll:AddChild(textureWidget);
table.sort(scroll.children, function(a, b)
local aPath, bPath = a:GetTexturePath(), b:GetTexturePath();
local aNum, bNum = tonumber(aPath:match("%d+")), tonumber(bPath:match("%d+"));
local aNonNumber, bNonNumber = aPath:match("[^%d]+"), bPath:match("[^%d]+")
if(aNum and bNum and aNonNumber == bNonNumber) then
return aNum < bNum;
else
return aPath < bPath;
end
end);
end
group:Pick(group.data[group.field]);
end
dropdown:SetCallback("OnGroupSelected", texturePickerGroupSelected)
function group.UpdateList(self)
wipe(dropdown.list);
for categoryName, category in pairs(self.textures) do
local match = false;
for texturePath, textureName in pairs(category) do
if(texturePath == self.data[self.field]) then
match = true;
break;
end
end
dropdown.list[categoryName] = (match and "|cFF80A0FF" or "")..categoryName;
end
dropdown:SetGroupList(dropdown.list);
end
function group.Pick(self, texturePath)
local pickedwidget;
for index, widget in ipairs(scroll.children) do
widget:ClearPick();
if(widget:GetTexturePath() == texturePath) then
pickedwidget = widget;
end
end
if(pickedwidget) then
pickedwidget:Pick();
end
if(self.data.controlledChildren) then
setAll(self.data, {"region", self.field}, texturePath);
else
self.data[self.field] = texturePath;
end
if(type(self.data.id) == "string") then
WeakAuras.Add(self.data);
WeakAuras.SetIconNames(self.data);
WeakAuras.UpdateThumbnail(self.data);
end
group:UpdateList();
local status = dropdown.status or dropdown.localstatus
dropdown.dropdown:SetText(dropdown.list[status.selected]);
end
function group.Open(self, data, field, textures, SetTextureFunc)
self.data = data;
self.field = field;
self.textures = textures;
self.SetTextureFunc = SetTextureFunc
if(data.controlledChildren) then
self.givenPath = {};
for index, childId in pairs(data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
self.givenPath[childId] = childData[field];
end
end
local colorAll = getAll(data, {"region", "color"}) or {1, 1, 1, 1};
self.textureData = {
r = colorAll[1] or 1,
g = colorAll[2] or 1,
b = colorAll[3] or 1,
a = colorAll[4] or 1,
rotate = getAll(data, {"region", "rotate"}),
discrete_rotation = getAll(data, {"region", "discrete_rotation"}) or 0,
rotation = getAll(data, {"region", "rotation"}) or 0,
mirror = getAll(data, {"region", "mirror"}),
blendMode = getAll(data, {"region", "blendMode"}) or "ADD"
};
else
self.givenPath = data[field];
data.color = data.color or {};
self.textureData = {
r = data.color[1] or 1,
g = data.color[2] or 1,
b = data.color[3] or 1,
a = data.color[4] or 1,
rotate = data.rotate,
discrete_rotation = data.discrete_rotation or 0,
rotation = data.rotation or 0,
mirror = data.mirror,
blendMode = data.blendMode or "ADD"
};
end
frame.window = "texture";
frame:UpdateFrameVisible()
local picked = false;
local _, givenPath
if type(self.givenPath) == "string" then
givenPath = self.givenPath;
else
_, givenPath = next(self.givenPath);
end
WeakAuras.debug(givenPath, 3);
for categoryName, category in pairs(self.textures) do
if not(picked) then
for texturePath, textureName in pairs(category) do
if(texturePath == givenPath) then
dropdown:SetGroup(categoryName);
self:Pick(givenPath);
picked = true;
break;
end
end
end
end
if not(picked) then
local categoryName = next(self.textures)
if(categoryName) then
dropdown:SetGroup(categoryName);
end
end
end
function group.Close()
frame.window = "default";
frame:UpdateFrameVisible()
AceConfigDialog:Open("WeakAuras", frame.container);
end
function group.CancelClose()
if(group.data.controlledChildren) then
for index, childId in pairs(group.data.controlledChildren) do
local childData = WeakAuras.GetData(childId);
if(childData) then
childData[group.field] = group.givenPath[childId];
WeakAuras.Add(childData);
WeakAuras.UpdateThumbnail(childData);
WeakAuras.SetIconNames(childData);
end
end
else
group:Pick(group.givenPath);
end
group.Close();
end
local cancel = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
cancel:SetScript("OnClick", group.CancelClose)
cancel:SetPoint("BOTTOMRIGHT", -27, -23)
cancel:SetSize(100, 20)
cancel:SetText(L["Cancel"])
local close = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
close:SetScript("OnClick", group.Close)
close:SetPoint("RIGHT", cancel, "LEFT", -10, 0)
close:SetSize(100, 20)
close:SetText(L["Okay"])
return group
end
function WeakAuras.TexturePicker(frame)
texturePicker = texturePicker or ConstructTexturePicker(frame)
return texturePicker
end