diff --git a/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Down.blp b/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Down.blp new file mode 100644 index 0000000..bb28300 Binary files /dev/null and b/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Down.blp differ diff --git a/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Highlight.blp b/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Highlight.blp new file mode 100644 index 0000000..0c59ab5 Binary files /dev/null and b/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Highlight.blp differ diff --git a/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Up.blp b/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Up.blp new file mode 100644 index 0000000..3e1428a Binary files /dev/null and b/WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Up.blp differ diff --git a/WeakAurasOptions/OptionsFrames/MoverSizer.lua b/WeakAurasOptions/OptionsFrames/MoverSizer.lua index 79a9ff7..a991691 100644 --- a/WeakAurasOptions/OptionsFrames/MoverSizer.lua +++ b/WeakAurasOptions/OptionsFrames/MoverSizer.lua @@ -1,7 +1,102 @@ if not WeakAuras.IsLibsOK() then return end + local AddonName = ... local OptionsPrivate = select(2, ...) +-- Frame Line Mixin Backport +local LineMethods = {} + +function LineMethods:SetStartPoint(point, relTo, offX, offY) + self._start = { point, relTo, offX or 0, offY or 0 } + if self._shown then self:_layout() end +end + +function LineMethods:SetEndPoint(point, relTo, offX, offY) + self._end = { point, relTo, offX or 0, offY or 0 } + if self._shown then self:_layout() end +end + +function LineMethods:SetThickness(t) + self._thickness = t or 1 + if self._shown then self:_layout() end +end + +function LineMethods:SetTexture(a, b, c, d) + if type(a) == "string" then + self.tex:SetTexture(a) + else + self.tex:SetTexture(a or 1, b or 1, c or 1, d or 1) + end +end + +function LineMethods:SetVertexColor(r, g, b, a) + self.tex:SetVertexColor(r, g, b, a or 1) +end + +function LineMethods:SetAlpha(a) self.tex:SetAlpha(a) end +function LineMethods:SetDrawLayer(layer, sub) self.tex:SetDrawLayer(layer or "ARTWORK", sub) end +function LineMethods:Show() self._shown = true; self.tex:Show(); self:_layout() end +function LineMethods:Hide() self._shown = false; self.tex:Hide() end +function LineMethods:ClearAllPoints() self.tex:ClearAllPoints() end + +function LineMethods:_layout() + if not (self._start and self._end) then return end + local sP, sRel, sX, sY = unpack(self._start) + local eP, eRel, eX, eY = unpack(self._end) + local t = self._thickness or 1 + + self.tex:ClearAllPoints() + + if sP == "TOPLEFT" and eP == "BOTTOMLEFT" and sRel == eRel and sY == 0 and eY == 0 and sX == eX then + local x = sX + self.tex:SetPoint("TOPLEFT", sRel, "TOPLEFT", x - t/2, 0) + self.tex:SetPoint("BOTTOMLEFT", eRel, "BOTTOMLEFT", x - t/2, 0) + self.tex:SetWidth(t) + return + end + + if sP == "BOTTOMLEFT" and eP == "BOTTOMRIGHT" and sRel == eRel and sX == 0 and eX == 0 and sY == eY then + local y = sY + self.tex:SetPoint("BOTTOMLEFT", sRel, "BOTTOMLEFT", 0, y - t/2) + self.tex:SetPoint("BOTTOMRIGHT", eRel, "BOTTOMRIGHT", 0, y - t/2) + self.tex:SetHeight(t) + return + end + + if sRel == eRel then + if sX == eX then + local x = sX + self.tex:SetPoint("TOPLEFT", sRel, "TOPLEFT", x - t/2, min(sY, eY)) + self.tex:SetPoint("BOTTOMLEFT", sRel, "TOPLEFT", x - t/2, max(sY, eY)) + self.tex:SetWidth(t) + return + elseif sY == eY then + local y = sY + self.tex:SetPoint("BOTTOMLEFT", sRel, "BOTTOMLEFT", min(sX, eX), y - t/2) + self.tex:SetPoint("BOTTOMRIGHT", sRel, "BOTTOMLEFT", max(sX, eX), y - t/2) + self.tex:SetHeight(t) + return + end + end +end + +local function CreateLine(parent, layer, sublayer) + local tex = parent:CreateTexture(nil, layer or "ARTWORK", nil, sublayer) + tex:SetTexture("Interface\\Buttons\\WHITE8x8") + tex:SetVertexColor(1, 1, 1, 1) + tex:Hide() + + local line = { tex = tex, _thickness = 1, _shown = false } + return setmetatable(line, { __index = LineMethods }) +end + +local createCenterLines = true -- Creates only the middle lines +local showNormalLines = false -- Show all alignment lines all the time +local highlightColor = { 1, 1, 0 } -- The color of lines that are we are currently aligned too +local gridHighlightColor = { 0.3, 1, 0.3} +local normalColor = { 0.3, 0.3, 0.6, } -- The color of lines if they aren't matched if showNormalLines is enabled +local gridColor = { 0.3, 0.6, 0.3 } -- The color of grid lines, if they aren't matched and enabled + -- Lua APIs local pairs = pairs @@ -14,6 +109,11 @@ local L = WeakAuras.L local moversizer local mover +local MAGNETIC_ALIGNMENT = 10 +local function distance(num1, num2) + return abs(num2 - num1) +end + local function EnsureTexture(self, texture) if texture then return texture @@ -66,43 +166,43 @@ local function ConstructMover(frame) local leftAndRight = CreateFrame("Frame", nil, frame) leftAndRight:SetClampedToScreen(true) - leftAndRight:SetSize(45, 25) + leftAndRight:SetSize(55, 35) leftAndRight:SetPoint("TOP", frame, "BOTTOM", 0, 1) local left = CreateFrame("Button", nil, leftAndRight) - left:SetSize(25, 25) - left:SetPoint("LEFT", leftAndRight) + left:SetSize(35, 35) + left:SetPoint("LEFT", leftAndRight, 0, 0.9) left:SetFrameStrata("BACKGROUND") local right = CreateFrame("Button", nil, leftAndRight) - right:SetSize(25, 25) + right:SetSize(35, 35) right:SetPoint("RIGHT", leftAndRight) right:SetFrameStrata("BACKGROUND") - 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:SetNormalTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Up.blp") + top:SetHighlightTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Highlight.blp") + top:SetPushedTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Down.blp") top:SetScript("OnClick", function() moveOnePxl("top") end) - bottom:SetNormalTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-up.blp") + bottom:SetNormalTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Up.blp") bottom:GetNormalTexture():SetTexCoord(0, 1, 1, 0) - bottom:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp") + bottom:SetHighlightTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Highlight.blp") bottom:GetHighlightTexture():SetTexCoord(0, 1, 1, 0) - bottom:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp") + bottom:SetPushedTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\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:SetNormalTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Up.blp") left:GetNormalTexture():SetRotation(math.pi/2) - left:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp") + left:SetHighlightTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Highlight.blp") left:GetHighlightTexture():SetRotation(math.pi/2) - left:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp") + left:SetPushedTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\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:SetNormalTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Up.blp") right:GetNormalTexture():SetRotation(-math.pi/2) - right:SetHighlightTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-highlight.blp") + right:SetHighlightTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Highlight.blp") right:GetHighlightTexture():SetRotation(-math.pi/2) - right:SetPushedTexture("interface\\buttons\\ui-scrollbar-scrollupbutton-down.blp") + right:SetPushedTexture("Interface\\Addons\\WeakAuras\\Media\\Textures\\UI-ScrollBar-ScrollUpButton-Down.blp") right:GetPushedTexture():SetRotation(-math.pi/2) right:SetScript("OnClick", function() moveOnePxl("right") end) @@ -123,23 +223,7 @@ local function ConstructMover(frame) offscreenText:Hide() offscreenText:SetPoint("CENTER", arrow, "CENTER") - --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, arrowTexture, offscreenText + return arrowTexture, offscreenText end local function ConstructSizer(frame) @@ -369,50 +453,581 @@ local function ConstructSizer(frame) 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 AlignmentLines = CreateFrame("Frame", nil, UIParent) +AlignmentLines:SetAllPoints(UIParent) +AlignmentLines:SetFrameStrata("BACKGROUND") + +local HighlightFrame = CreateFrame("Frame", nil, UIParent) +HighlightFrame:SetAllPoints(UIParent) +HighlightFrame:SetFrameStrata("TOOLTIP") + +AlignmentLines.linePool = CreateObjectPool( + function(self) + return CreateLine(AlignmentLines) + end, + function(self, line) + line:Hide() + end) + +HighlightFrame.texturePool = CreateObjectPool( + function(self) + local tex = HighlightFrame:CreateTexture() + tex:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight.blp") + tex:SetVertexColor(1, 1, 1, 0.3) + return tex + end, + function(self, texture) + texture:Hide() + texture:ClearAllPoints() + end) + +local function MirrorSide(side) + if side == "LEFT" then + return "RIGHT" + elseif side == "RIGHT" then + return "LEFT" + elseif side == "TOP" then + return "BOTTOM" + elseif side == "BOTTOM" then + return "TOP" + else -- "CENTERX" or "CENTERY" + return side + end +end + +local function Pos1Side(side) + if side == "LEFT" or side == "RIGHT" or side == "CENTERX" then + return "BOTTOM" + elseif side == "TOP" or side == "BOTTOM" or side == "CENTERY" then + return "LEFT" + end +end + +local function Pos2Side(side) + if side == "LEFT" or side == "RIGHT" or side == "CENTERX" then + return "TOP" + elseif side == "TOP" or side == "BOTTOM" or side == "CENTERY" then + return "RIGHT" + end +end + +local LineInformationFuncs = { + SetStartPoint = function(self, relativePoint, relativeTo, offsetX, offsetY) + self.startPoint = {relativePoint, relativeTo, offsetX, offsetY} + if self.line then + self.line:SetStartPoint(relativePoint, relativeTo, offsetX, offsetY) + end + end, + SetEndPoint = function(self, relativePoint, relativeTo, offsetX, offsetY) + self.endPoint = {relativePoint, relativeTo, offsetX, offsetY} + if self.line then + self.line:SetEndPoint(relativePoint, relativeTo, offsetX, offsetY) + end + end, + SetThickness = function(self, thickness) + self.thickness = thickness + if self.line then + self.line:SetThickness(thickness) + end + end, + Show = function(self) + if not self.line then + self:AcquireLine() + end + self:UpdateColor() + self.line:SetStartPoint(unpack(self.startPoint)) + self.line:SetEndPoint(unpack(self.endPoint)) + self.line:SetThickness(self.thickness) + self.line:Show() + end, + SetHighlighted = function(self, highlight) + if self.highlight == highlight then + return + end + + local needLine = highlight or showNormalLines + self.highlight = highlight + + if needLine and not self.line then + self:Show() + elseif not needLine and self.line then + self:ReleaseLine() + end + self:UpdateColor() + self:UpdateHighlight() + end, + UpdateColor = function(self) + if not self.line then + return + end + + if self.highlight then + if self.gridLine then + self.line:SetTexture(unpack(gridHighlightColor)) + else + self.line:SetTexture(unpack(highlightColor)) + end + else + if self.gridLine then + self.line:SetTexture(unpack(gridColor)) + else + self.line:SetTexture(unpack(normalColor)) + end + end + end, + UpdateHighlight = function(self) + if self.highlight then + for _, data in ipairs(self.references) do + local region = WeakAuras.GetRegion(data.id) + local texture = HighlightFrame.texturePool:Acquire() + texture:SetAllPoints(region) + texture:SetDrawLayer("ARTWORK") -- ,7 + texture:Show() + tinsert(self.highlightTextures, texture) + end + else + for _, texture in ipairs(self.highlightTextures) do + HighlightFrame.texturePool:Release(texture) + end + wipe(self.highlightTextures) + end + end, + AcquireLine = function(self) + if not self.line then + self.line = AlignmentLines.linePool:Acquire() + end + end, + ReleaseLine = function(self) + if self.line then + AlignmentLines.linePool:Release(self.line) + self.line = nil + end + end, + Release = function(self) + -- Clears any aura highlights + self:SetHighlighted(false) + self:ReleaseLine() + end, + AddReference = function(self, id, side, pos1, pos2) + tinsert(self.references, {id = id, side = side, pos1 = pos1, pos2 = pos2}) + end, + Score = function(self, positions) + if self.gridLine then + return 0 -- Prefer aura lines + else + local score = -1 + + for _, ref in ipairs(self.references) do + -- The line is within MAGNETIC_ALIGNMENT, otherwise we wouldn't be asked to score it + -- This compares whether the line is for the same "side", + -- by checking the distance to that side + local auraPos = positions[ref.side] + local mirrorPos = positions[MirrorSide(ref.side)] + if auraPos then + local dist = distance(auraPos, self.position) + if dist < MAGNETIC_ALIGNMENT then + -- Same side: 100 as a base, meaning these lines are heavily preferred to lines + -- for other sides + score = max(score, 100 + (MAGNETIC_ALIGNMENT - dist)) + elseif mirrorPos then + dist = distance(mirrorPos, self.position) + score = max(score, 10 + (MAGNETIC_ALIGNMENT - dist)) + end + + -- Now check how far away the reference is on the orthogonal direction + -- Add up to 80 points for being near a reference + local auraPos1 = positions[Pos1Side(ref.side)] + local auraPos2 = positions[Pos2Side(ref.side)] + if auraPos1 and auraPos2 then + local minDistanceOrth = min(distance(auraPos1, ref.pos1), distance(auraPos2, ref.pos2)) + if minDistanceOrth < 10 * MAGNETIC_ALIGNMENT then + score = score + 8 * (10 * MAGNETIC_ALIGNMENT - minDistanceOrth) + end + end + end + end + return score + end + end, + +} + +local function CreateLineInformation(position, gridLine) + local line = {} + for k, f in pairs(LineInformationFuncs) do + line[k] = f + end + line.position = position + line.gridLine = gridLine + line.references = {} + line.highlightTextures = {} + line.highlight = nil + return line +end + +AlignmentLines.horizontalLines = {} +AlignmentLines.verticalLines = {} + +local function RoundSmallDifference(input) + local r = Round(input) + if (abs(r - input) < 0.1) then + return r + end + return input +end + +local function AlignToPixelX(virX) + return Round(virX * 1) +end + +local function AlignToPixelY(virY) + return Round(virY * 1) +end + +AlignmentLines.CreateMiddleLines = function(self, sizerPoint) + if not createCenterLines then + return + end + + local midX, midY = UIParent:GetCenter() + midX = RoundSmallDifference(midX) + midY = RoundSmallDifference(midY) + if not sizerPoint or sizerPoint:find("LEFT", 1) or sizerPoint:find("RIGHT", 1) then + local line = CreateLineInformation(midX, true) + line:SetStartPoint("TOPLEFT", UIParent, midX, 0) + line:SetEndPoint("BOTTOMLEFT", UIParent, midX, 0) + line:SetThickness(2) + self.verticalLines[midX] = line + end + + if not sizerPoint or sizerPoint:find("BOTTOM") or sizerPoint:find("TOP") then + local line = CreateLineInformation(midY, true) + line:SetStartPoint("BOTTOMLEFT", UIParent, 0, midY) + line:SetEndPoint("BOTTOMRIGHT", UIParent, 0, midY) + line:SetThickness(2) + self.horizontalLines[midY] = line + end +end + +AlignmentLines.CreateLineInformation = function(self, data, sizerPoint) + local addVertical = not sizerPoint or sizerPoint:find("LEFT", 1) or sizerPoint:find("RIGHT", 1) + local addHorizontal = not sizerPoint or sizerPoint:find("BOTTOM", 1) or sizerPoint:find("TOP", 1) + + local horizontalLines, verticalLines = {}, {} local skipIds = {} for child in OptionsPrivate.Private.TraverseAll(data) do skipIds[child.id] = true end - for k, v in pairs(OptionsPrivate.displayButtons) do + for id, v in pairs(OptionsPrivate.displayButtons) do local region = WeakAuras.GetRegion(v.data.id) - if not skipIds[k] and v.view.visibility ~= 0 and region then + if not skipIds[id] + and v.view.visibility >= 1 + and region + and v.data.regionType ~= "group" + and v.data.regionType ~= "dynamicgroup" + then local scale = region:GetEffectiveScale() / UIParent:GetEffectiveScale() + local left = region:GetLeft() + left = left and AlignToPixelX(left * scale) or nil + local right = region:GetRight() + right = right and AlignToPixelX(right * scale) or nil + local top = region:GetTop() + top = top and AlignToPixelY(top * scale) or nil + local bottom = region:GetBottom() + bottom = bottom and AlignToPixelY(bottom * scale) or nil + local centerX, centerY = region:GetCenter() + centerX = centerX and AlignToPixelX(centerX * scale) or nil + centerY = centerY and AlignToPixelY(centerY * scale) or nil + 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) + if addVertical then + if left and bottom and top then + local leftLine = CreateLineInformation(left, false) + leftLine:AddReference(id, "LEFT", bottom, top) + tinsert(verticalLines, leftLine) + end + + if right and bottom and top then + local rightLine = CreateLineInformation(right, false) + rightLine:AddReference(id, "RIGHT", bottom, top) + tinsert(verticalLines, rightLine) + end + end + if addHorizontal then + if top and left and right then + local topLine = CreateLineInformation(top, false) + topLine:AddReference(id, "TOP", left, right) + tinsert(horizontalLines, topLine) + end + + if bottom and left and right then + local bottomLine = CreateLineInformation(bottom, false) + bottomLine:AddReference(id, "BOTTOM", left, right) + tinsert(horizontalLines, bottomLine) + end + end else - local centerX, centerY = region:GetCenter() - tinsert(x, (centerX or 0) * scale) - tinsert(y, (centerY or 0) * scale) + if addVertical then + if centerX and bottom and top then + local xLine = CreateLineInformation(centerX, false) + xLine:AddReference(id, "CENTERX", bottom, top) + tinsert(verticalLines, xLine) + end + end + if addHorizontal then + if centerY and left and right then + local yLine = CreateLineInformation(centerY, false) + yLine:AddReference(id, "CENTERY", left, right) + tinsert(horizontalLines, yLine) + end + end 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) + + table.sort(verticalLines, function(a, b) return a.position < b.position end) + table.sort(horizontalLines, function(a, b) return a.position < b.position end) + + return self:MergeLineInformation(verticalLines), self:MergeLineInformation(horizontalLines) +end + +AlignmentLines.MergeLineInformation = function(self, lines) + local startIndex + local startPos + -- Add a line at infinity at the end, this makes the loop easier + tinsert(lines, {position = math.huge}) + + local result = {} + for index, line in ipairs(lines) do + if not startPos then + startPos = line.position + startIndex = index + else + if (line.position - startPos) >= 1 then + if startIndex then + -- This line is too far away from the last lines to merge, + -- So merge from startIndex to index - 1 + local lineToInsert = lines[startIndex] + local positionSum = lineToInsert.position + for i = startIndex + 1, index - 1 do + local lineToMerge = lines[i] + positionSum = positionSum + lineToMerge.position + tinsert(lineToInsert.references, lineToMerge.references[1]) + end + lineToInsert.position = positionSum / (index - startIndex) + tinsert(result, lineToInsert) + -- Now start a potential new merge from this line + startPos = line.position + startIndex = index + end + else + -- Will be merged later + end end end - for index, value in ipairs(y) do - if value ~= y[index+1] then - tinsert(align.y, value) + -- And remove the infinity line at the end + lines[#lines] = nil + + return result +end + +AlignmentLines.CleanUpLines = function(self) + for _, line in pairs(self.horizontalLines) do + line:Release() + end + + for _, line in pairs(self.verticalLines) do + line:Release() + end + + wipe(self.horizontalLines) + wipe(self.verticalLines) +end + +AlignmentLines.CreateLines = function(self, data, sizerPoint) + self:CleanUpLines() + + local align = (WeakAurasOptionsSaved.magnetAlign and not IsShiftKeyDown()) + or (not WeakAurasOptionsSaved.magnetAlign and IsShiftKeyDown()) + if align then + self:CreateMiddleLines() + + local auraVerticalLinesInfo, auraHorizontalLinesInfo = self:CreateLineInformation(data, sizerPoint) + + for _, lineInfo in ipairs(auraVerticalLinesInfo) do + local x = lineInfo.position + if self.verticalLines[floor(x)] or self.verticalLines[ceil(x)] then + -- Grid lines are always on integer values + -- Ignore a grid line that is close enough is already there + else + lineInfo:SetStartPoint("TOPLEFT", UIParent, x, 0) + lineInfo:SetEndPoint("BOTTOMLEFT", UIParent, x, 0) + lineInfo:SetThickness(2) + self.verticalLines[x] = lineInfo + end + end + + for _, lineInfo in ipairs(auraHorizontalLinesInfo) do + local y = lineInfo.position + if self.horizontalLines[floor(y)] or self.horizontalLines[ceil(y)] then + -- Grid lines are always on integer values + -- Ignore a grid line that is close enough is already there + else + lineInfo:SetStartPoint("BOTTOMLEFT", UIParent, 0, y) + lineInfo:SetEndPoint("BOTTOMRIGHT", UIParent, 0, y) + lineInfo:SetThickness(2) + self.horizontalLines[y] = lineInfo + end + end + end +end + +local function SelectLines(lines, positions, auraSize) + if #lines == 0 then + -- Nothing to do + elseif #lines == 1 then + lines[1]:SetHighlighted(true) + return lines[1].delta + else + local bestScore = -1 + local bestLine = nil + for _, line in ipairs(lines) do + local lineScore = line:Score(positions) + if lineScore > bestScore then + bestScore = lineScore + bestLine = line + end + end + + for _, line in ipairs(lines) do + if line == bestLine then + line:SetHighlighted(true) + elseif bestLine then + local diffBetweenLines = distance(line.position, bestLine.position) + if auraSize and distance(diffBetweenLines, auraSize) < 1 then + line:SetHighlighted(true) + else + line:SetHighlighted(false) + end + else + line:SetHighlighted(false) + end + end + return bestLine and bestLine.delta + end +end + +AlignmentLines.ShowLinesFor = function(self, ctrlKey, region, sizePoint) + local align = (WeakAurasOptionsSaved.magnetAlign and not IsShiftKeyDown()) + or (not WeakAurasOptionsSaved.magnetAlign and IsShiftKeyDown()) + if not align then + return + end + + local scale = region:GetEffectiveScale() / UIParent:GetScale() + + local centerX, centerY = region:GetCenter() + centerX, centerY = centerX * scale, centerY * scale + local left, right = region:GetLeft() * scale, region:GetRight() * scale + local top, bottom = region:GetTop() * scale, region:GetBottom() * scale + + if region.regionType == "group" then + left = left + region.blx * scale + right = right + region.trx * scale + bottom = bottom + region.bly * scale + top = top + region.try * scale + centerX = (left + right) / 2 + centerY = (bottom + top) / 2 + end + + local positions = { + LEFT = left, + RIGHT = right, + TOP = top, + BOTTOM = bottom, + CENTERX = centerX, + CENTERY = centerY + } + + local verticalPotentials = {} + local horizontalPotentials = {} + if sizePoint then + local sizeX = sizePoint:find("LEFT", 1) and left or right + local sizeY = sizePoint:find("TOP", 1) and top or bottom + + for pos, line in pairs(self.verticalLines) do + if distance(sizeX, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - sizeX + tinsert(verticalPotentials, line) + else + line:SetHighlighted(false) + end + end + + for pos, line in pairs(self.horizontalLines) do + if distance(sizeY, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - sizeY + tinsert(horizontalPotentials, line) + else + line:SetHighlighted(false) + end + end + + mover.verticalDelta = SelectLines(verticalPotentials, positions) + mover.horizontalDelta = SelectLines(horizontalPotentials, positions) + else + if ctrlKey then + for pos, line in pairs(self.verticalLines) do + if distance(centerX, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - centerX + tinsert(verticalPotentials, line) + else + line:SetHighlighted(false) + end + end + + for pos, line in pairs(self.horizontalLines) do + if distance(centerY, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - centerY + tinsert(horizontalPotentials, line) + else + line:SetHighlighted(false) + end + end + mover.verticalDelta = SelectLines(verticalPotentials, positions) + mover.horizontalDelta = SelectLines(horizontalPotentials, positions) + else + for pos, line in pairs(self.verticalLines) do + if distance(left, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - left + tinsert(verticalPotentials, line) + elseif distance(right, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - right + tinsert(verticalPotentials, line) + else + line:SetHighlighted(false) + end + end + + for pos, line in pairs(self.horizontalLines) do + if distance(bottom, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - bottom + tinsert(horizontalPotentials, line) + elseif distance(top, pos) < MAGNETIC_ALIGNMENT then + line.delta = pos - top + tinsert(horizontalPotentials, line) + else + line:SetHighlighted(false) + end + end + + local auraWidth = right - left + local auraHeight = top - bottom + mover.verticalDelta = SelectLines(verticalPotentials, positions, auraWidth) + mover.horizontalDelta = SelectLines(horizontalPotentials, positions, auraHeight) end end - return align end local function ConstructMoverSizer(parent) @@ -427,7 +1042,7 @@ local function ConstructMoverSizer(parent) frame.top, frame.topright, frame.right, frame.bottomright, frame.bottom, frame.bottomleft, frame.left, frame.topleft = ConstructSizer(frame) - frame.lineX, frame.lineY, frame.arrowTexture, frame.offscreenText = ConstructMover(frame) + frame.arrowTexture, frame.offscreenText = ConstructMover(frame) frame.top.Clear() frame.topright.Clear() @@ -439,7 +1054,6 @@ local function ConstructMoverSizer(parent) frame.topleft.Clear() local mover = CreateFrame("Frame", nil, frame) - mover:RegisterEvent("PLAYER_REGEN_DISABLED") mover:EnableMouse() mover.moving = {} mover.interims = {} @@ -499,11 +1113,82 @@ local function ConstructMoverSizer(parent) return self.currentId end + frame.SizingSetData = function(self, data, width, height, alignDeltaX, alignDeltaY, scale) + alignDeltaX = alignDeltaX or 0 + alignDeltaY = alignDeltaY or 0 + + local deltaWidth = width - data.width + local deltaHeight = height - data.height + + local auraSelfPoint = data.selfPoint + local moverSizePoint = mover.sizePoint + + local parent = data.parent + if parent then + local parentData = WeakAuras.GetData(parent) + if parentData == "dynamicgroup" then + -- If the aura is in a dynamic group then we don't want to set xOffset/yOffset at all. + -- These settings ensure that + auraSelfPoint = "TOPRIGHT" + moverSizePoint = "BOTTOMLEFT" + end + end + + if auraSelfPoint:find("LEFT", 1) then + if moverSizePoint:find("LEFT", 1) then + data.xOffset = data.xOffset - deltaWidth + alignDeltaX / scale + data.width = width - alignDeltaX / scale + elseif moverSizePoint:find("RIGHT", 1) then + data.width = width + alignDeltaX / scale + end + elseif auraSelfPoint:find("RIGHT", 1) then + if moverSizePoint:find("LEFT", 1) then + data.width = width - alignDeltaX / scale + elseif moverSizePoint:find("RIGHT", 1) then + data.xOffset = data.xOffset + deltaWidth + alignDeltaX / scale + data.width = width + alignDeltaX / scale + end + else -- CENTER + if moverSizePoint:find("LEFT", 1) then + data.xOffset = data.xOffset - deltaWidth / 2 + alignDeltaX / 2 / scale + data.width = width - alignDeltaX / scale + else + data.xOffset = data.xOffset + deltaWidth / 2 + alignDeltaX / 2 / scale + data.width = width + alignDeltaX / scale + end + end + + if auraSelfPoint:find("BOTTOM", 1) then + if moverSizePoint:find("BOTTOM", 1) then + data.yOffset = data.yOffset - deltaHeight + alignDeltaY / scale + data.height = height - alignDeltaY / scale + elseif moverSizePoint:find("TOP", 1) then + data.height = height + alignDeltaY / scale + end + elseif auraSelfPoint:find("TOP", 1) then + if moverSizePoint:find("BOTTOM", 1) then + data.height = height - alignDeltaY / scale + elseif moverSizePoint:find("TOP", 1) then + data.yOffset = data.yOffset + deltaHeight + alignDeltaY / scale + data.height = height + alignDeltaY / scale + end + else -- CENTER + if moverSizePoint:find("BOTTOM", 1) then + data.yOffset = data.yOffset - deltaHeight / 2 + alignDeltaY / 2 / scale + data.height = height - alignDeltaY / scale + else + data.yOffset = data.yOffset + deltaHeight / 2 + alignDeltaY / 2 / scale + data.height = height + alignDeltaY / scale + end + end + 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 + mover.onUpdate(mover, 0) local ok, selfPoint, anchor, anchorPoint, xOff, yOff = pcall(region.GetPoint, region, 1) if not ok then return @@ -520,11 +1205,14 @@ local function ConstructMoverSizer(parent) local blx, bly, trx, try = region:GetBoundingRect() mover:SetWidth((trx - blx) * scale) mover:SetHeight((try - bly) * scale) - mover:SetPoint("BOTTOMLEFT", mover.anchor or UIParent, mover.anchorPoint or "CENTER", (xOff + region.blx) * scale, (yOff + region.bly) * scale) + + mover:SetPoint("BOTTOMLEFT", 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) + 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) @@ -534,6 +1222,8 @@ local function ConstructMoverSizer(parent) local strata = math.min(tIndexOf(OptionsPrivate.Private.frame_strata_types, regionStrata) + 1, 9) frame:SetFrameStrata(OptionsPrivate.Private.frame_strata_types[strata]) mover:SetFrameStrata(OptionsPrivate.Private.frame_strata_types[strata]) + frame:SetFrameLevel(region:GetFrameLevel() + 1) + mover:SetFrameLevel(region:GetFrameLevel() + 2) end local db = OptionsPrivate.savedVars.db @@ -550,15 +1240,21 @@ local function ConstructMoverSizer(parent) end region:StartMoving() mover.isMoving = true + mover.onUpdate(mover, 0) mover.text:Show() -- build list of alignment coordinates - mover.align = BuildAlignLines(mover) + AlignmentLines:CreateLines(mover.moving.data) + AlignmentLines:Show() + HighlightFrame:Show() end mover.doneMoving = function(self, event, key) if event == "MODIFIER_STATE_CHANGED" then - if key == "LCTRL" or key == "RCTRL" then - mover.align = BuildAlignLines(mover) + if key == "LCTRL" or key == "RCTRL" or key == "LSHIFT" or key == "RSHIFT" then + AlignmentLines:CleanUpLines() + AlignmentLines:CreateLines(mover.moving.data, mover.sizePoint) + AlignmentLines:Show() + HighlightFrame:Show() end return end @@ -569,62 +1265,18 @@ local function ConstructMoverSizer(parent) region:StopMovingOrSizing() mover.isMoving = false mover.text:Hide() + AlignmentLines:CleanUpLines() + AlignmentLines:Hide() + HighlightFrame: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 + local xDelta = 0 + local yDelta = 0 + if align then + xDelta = mover.verticalDelta or 0 + yDelta = mover.horizontalDelta or 0 end if data.xOffset and data.yOffset then @@ -632,31 +1284,35 @@ local function ConstructMoverSizer(parent) local anchorX, anchorY = mover.anchorPointIcon:GetCenter() local dX = selfX - anchorX local dY = selfY - anchorY - data.xOffset = dX / scale - data.yOffset = dY / scale + data.xOffset = dX / scale + xDelta / scale + data.yOffset = dY / scale + yDelta / scale end region:ResetPosition() WeakAuras.Add(data) + OptionsPrivate.Private.AddParents(data) WeakAuras.UpdateThumbnail(data) + 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("BOTTOMLEFT", mover.anchor, mover.anchorPoint, (xOff + region.blx) * scale, (yOff + region.bly) * scale) + mover:SetPoint("BOTTOMLEFT", 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 - OptionsPrivate.Private.AddParents(data) + frame.text:Hide() + frame:SetScript("OnUpdate", nil) + WeakAuras.FillOptions() OptionsPrivate.Private.Animate("display", data.uid, "main", data.animation.main, - OptionsPrivate.Private.EnsureRegion(data.id), false, nil, true) - -- hide alignment lines - frame.lineY:Hide() - frame.lineX:Hide() + OptionsPrivate.Private.EnsureRegion(data.id), false, nil, true) end if data.parent and db.displays[data.parent] and db.displays[data.parent].regionType == "dynamicgroup" then @@ -669,7 +1325,6 @@ local function ConstructMoverSizer(parent) 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 @@ -679,7 +1334,6 @@ local function ConstructMoverSizer(parent) end mover.isMoving = true OptionsPrivate.Private.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) @@ -689,23 +1343,7 @@ local function ConstructMoverSizer(parent) 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 + frame:SizingSetData(data, region:GetWidth(), region:GetHeight(), 0, 0, scale) end region:ResetPosition() WeakAuras.Add(data, true) @@ -713,46 +1351,37 @@ local function ConstructMoverSizer(parent) WeakAuras.FillOptions() end) - mover.align = BuildAlignLines(mover) + AlignmentLines:CreateLines(mover.moving.data, point) + AlignmentLines:Show() + HighlightFrame:Show() mover.sizePoint = point end - frame.doneSizing = function(point) + frame.doneSizing = function() + if not mover.sizePoint then + return + end mover.isMoving = false region:StopMovingOrSizing() + AlignmentLines:CleanUpLines() + AlignmentLines:Hide() + HighlightFrame:Hide() + 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 + local deltaX = 0 + local deltaY = 0 + if align then + deltaX = mover.verticalDelta or 0 + deltaY = mover.horizontalDelta or 0 end - data.width = width - data.height = height + + frame:SizingSetData(data, width, height, deltaX, deltaY, scale) region:ResetPosition() WeakAuras.Add(data, true) @@ -768,7 +1397,9 @@ local function ConstructMoverSizer(parent) if data.regionType == "group" then mover:SetWidth((region.trx - region.blx) * scale) mover:SetHeight((region.try - region.bly) * scale) - mover:SetPoint("BOTTOMLEFT", mover.anchor, mover.anchorPoint, (xOff + region.blx) * scale, (yOff + region.bly) * scale) + mover:SetPoint("BOTTOMLEFT", mover.anchor, mover.anchorPoint, + (xOff + region.blx) * scale, + (yOff + region.bly) * scale) else mover:SetWidth(region:GetWidth() * scale) mover:SetHeight(region:GetHeight() * scale) @@ -778,10 +1409,7 @@ local function ConstructMoverSizer(parent) frame:SetScript("OnUpdate", nil) WeakAuras.FillOptions() OptionsPrivate.Private.Animate("display", data.uid, "main", data.animation.main, - OptionsPrivate.Private.EnsureRegion(data.id), false, nil, true) - -- hide alignment lines - frame.lineY:Hide() - frame.lineX:Hide() + OptionsPrivate.Private.EnsureRegion(data.id), false, nil, true) mover.sizePoint = nil end @@ -836,14 +1464,10 @@ local function ConstructMoverSizer(parent) 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) + mover.onUpdate = function(self, elaps) if not IsShiftKeyDown() then self.goalAlpha = 1 else @@ -859,23 +1483,6 @@ local function ConstructMoverSizer(parent) 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 = OptionsPrivate.savedVars.db local region = self.moving.region local data = self.moving.data @@ -922,7 +1529,6 @@ local function ConstructMoverSizer(parent) self.interims[i]:Show() end - -- HERE frame.arrowTexture:Hide() frame.offscreenText:Hide() @@ -932,9 +1538,8 @@ local function ConstructMoverSizer(parent) local x, y = mover:GetCenter() if x and y then if mover:GetRight() < margin or mover:GetLeft() + margin > GetScreenWidth() or mover:GetTop() < 20 or mover:GetBottom() + margin > GetScreenHeight() then - frame.arrowTexture:GetRect() local arrowX, arrowY = frame.arrowTexture:GetCenter() - local arrowAngle = atan2(y - (arrowY or 0), x - (arrowX or 0)) + local arrowAngle = atan2(y - arrowY, x - arrowX) frame.offscreenText:Show() frame.arrowTexture:Show() frame.arrowTexture:SetRotation( (arrowAngle - 90) / 180 * math.pi) @@ -946,7 +1551,7 @@ local function ConstructMoverSizer(parent) 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() + local left, right, top, bottom = frame:GetLeft(), frame:GetRight(), frame:GetTop(), frame:GetBottom() 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 @@ -958,79 +1563,31 @@ local function ConstructMoverSizer(parent) 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 + AlignmentLines:ShowLinesFor(IsControlKeyDown(), region, mover.sizePoint) end - end) + end + + frame.OptionsOpened = function() + mover:Show() + mover:RegisterEvent("MODIFIER_STATE_CHANGED") + mover:SetScript("OnUpdate", mover.onUpdate) + AlignmentLines:Show() + HighlightFrame:Show() + end + + frame.OptionsClosed = function() + if frame.doneSizing then + frame.doneSizing() + end + if mover.doneMoving then + mover.doneMoving() + end + mover:UnregisterEvent("MODIFIER_STATE_CHANGED") + mover:SetScript("OnUpdate", nil) + mover:Hide() + AlignmentLines:Hide() + HighlightFrame:Hide() + end return frame, mover end diff --git a/WeakAurasOptions/OptionsFrames/OptionsFrame.lua b/WeakAurasOptions/OptionsFrames/OptionsFrame.lua index 6aacf3c..7bdf063 100644 --- a/WeakAurasOptions/OptionsFrames/OptionsFrame.lua +++ b/WeakAurasOptions/OptionsFrames/OptionsFrame.lua @@ -178,9 +178,13 @@ function OptionsPrivate.CreateFrame() OptionsPrivate.Private.personalRessourceDisplayFrame:OptionsClosed() end - if frame.dynamicTextCodesFrame then + if frame.dynamicTextCodesFrame then frame.dynamicTextCodesFrame:Hide() end + + if frame.moversizer then + frame.moversizer:OptionsClosed() + end end) local width, height diff --git a/WeakAurasOptions/WeakAurasOptions.lua b/WeakAurasOptions/WeakAurasOptions.lua index 224edb3..b22ebd5 100644 --- a/WeakAurasOptions/WeakAurasOptions.lua +++ b/WeakAurasOptions/WeakAurasOptions.lua @@ -855,6 +855,10 @@ function WeakAuras.ShowOptions(msg) OptionsPrivate.Private.personalRessourceDisplayFrame:OptionsOpened(); end + if frame.moversizer then + frame.moversizer:OptionsOpened() + end + if not(firstLoad) then -- Show what was last shown local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()