From 97a26222d0096dbf96495ba38a60b78cf293bdac Mon Sep 17 00:00:00 2001 From: NoM0Re <1629787+NoM0Re@users.noreply.github.com> Date: Sat, 25 Oct 2025 08:13:01 +0200 Subject: [PATCH] (feat/MoverSizer): Rework Magnetic Edit (cherry picked from commit 49badc3c83d222d6fa2bb8b0c13c861163e0e25d) --- .../UI-ScrollBar-ScrollUpButton-Down.blp | Bin 0 -> 2564 bytes .../UI-ScrollBar-ScrollUpButton-Highlight.blp | Bin 0 -> 1868 bytes .../UI-ScrollBar-ScrollUpButton-Up.blp | Bin 0 -> 2564 bytes WeakAurasOptions/OptionsFrames/MoverSizer.lua | 1111 +++++++++++++---- .../OptionsFrames/OptionsFrame.lua | 6 +- WeakAurasOptions/WeakAurasOptions.lua | 4 + 6 files changed, 843 insertions(+), 278 deletions(-) create mode 100644 WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Down.blp create mode 100644 WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Highlight.blp create mode 100644 WeakAuras/Media/Textures/UI-ScrollBar-ScrollUpButton-Up.blp 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 0000000000000000000000000000000000000000..bb28300cabe34a62c102abd3882a19e7551b08e4 GIT binary patch literal 2564 zcmZ?r2{2-0U|?Y4U}RJP(jYvA1&BF-n3I9w3J^a5;x9l(nRb#4G0h$L&5Kw6bQ2ZeCLGDH7gXBYy)Kh9def6iLq1urAh-zF_y`RZ6@_I8m1l<}LPMvTLUP0Z|E|?a459h||1dGIfg#*HknRl(3ZU@2 zdUYx|zW@KfeV3`2QG)qaJtTVH-_2E6b4VhhJUkSn8`|Un1vflC;O0RiNLdjzK0xLd zU{`M(@W0@HbF%`-JW~b+Wrp`m|CyJ7^K*Pe!GD8yAR`|~GBEJ|eH!|o`5ee9hQ&z? v3^DQXp#qGb`L(jYvA1&G-g7)00^7)*fJ28dmNm}mertO2N40f;$}FpxP4 zMnhmU1V%#uZwP?Oqfj6iE;NG%&_7qFnlc_>5D5Lco*PVu*HthG0L8<@!wC74!GeLo z)YNn<;|a!$z~De$#uE${#l^*7{UISCg!M}R^sX9WWX_g@HI5g!@~Dx5>Yhj2L0 z0Hu?ws*D{VIy?p=949a^^zv>EWqiQE5f>Lue0q8TGB5Nh;|eex4l-X96n+Je@M16k Wiq|HFg5vN0umArUIT$#A>O%ouLy7PJ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3e1428afb80df58aedc07349998ca22a91af8a57 GIT binary patch literal 2564 zcmZ?r2{2-0U|?Y4U}RJP(jYvA1&BF-n3I9w3J^a5;x9lYyqQCz` zfQFL-2O|>$1C;y!>Az)`KzUOb|M;FZ&HtfSul%q6zaJ#V-=e?}EzgMq- z>?X(lW9arzW>Itu42K#2|HzqUhbbXpkuU+Lvxf~_T~p!wr+c1CT)KJnKN= 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()