From cc6cd4028b40e011d6a74cff52f92ab3cfa0c910 Mon Sep 17 00:00:00 2001 From: Narcasung Date: Tue, 18 Aug 2026 16:00:49 +0200 Subject: [PATCH] Create movers eagerly so they always show in Toggle Anchors The Extra Action Button, Instance Swap, and class resource frame movers only got built once their native frame had already appeared on screen with a resolvable position -- so if the frame never showed up in a session (e.g. a class resource bar the current class doesn't use), Toggle Anchors had nothing to display for it. Movers are now created up front from a default size/position, and just get resized and anchored once the real frame shows up. Also fixes each mover's right-click config shortcut, which pointed at a pre-restructure options path. --- Modules/ClassResources.lua | 69 ++++++++++++++++++++++++-------------- Modules/ExtraActionBar.lua | 51 ++++++++++++++++++---------- Modules/LayerPicker.lua | 43 +++++++++++++++--------- 3 files changed, 105 insertions(+), 58 deletions(-) diff --git a/Modules/ClassResources.lua b/Modules/ClassResources.lua index 942f382..0c1da10 100644 --- a/Modules/ClassResources.lua +++ b/Modules/ClassResources.lua @@ -1,13 +1,18 @@ local E, L, V, P, G = unpack(ElvUI) local CoA = E:GetModule("CoA") +-- defaultY staggers the movers' first-run default position (LEFT of screen, +-- spaced vertically) so they don't stack on top of each other before the +-- player has ever dragged them. local FRAMES = { - {name = "CoAResourceSegmentBar", moverText = "Resource Segment Bar", hideKey = "hideResourceSegmentBar"}, - {name = "CoAResourceOrb", moverText = "Resource Orb", hideKey = "hideResourceOrb"}, - {name = "CoAResourceBar", moverText = "Resource Bar", hideKey = "hideResourceBar"}, - {name = "CoAMultiCastActionBarFrame", moverText = "Multi Cast Action Bar", hideKey = "hideMultiCastActionBar"}, + {name = "CoAResourceSegmentBar", moverText = "Resource Segment Bar", hideKey = "hideResourceSegmentBar", defaultY = 40}, + {name = "CoAResourceOrb", moverText = "Resource Orb", hideKey = "hideResourceOrb", defaultY = 100}, + {name = "CoAResourceBar", moverText = "Resource Bar", hideKey = "hideResourceBar", defaultY = 160}, + {name = "CoAMultiCastActionBarFrame", moverText = "Multi Cast Action Bar", hideKey = "hideMultiCastActionBar", defaultY = 220}, } +local DEFAULT_WIDTH, DEFAULT_HEIGHT = 150, 30 + local FRAME_NAMES = {} for _, def in ipairs(FRAMES) do FRAME_NAMES[def.name] = true @@ -179,30 +184,42 @@ local function LockPosition(frame, holder) end) end -local function SetupMover(frame, name, moverText) - if frame.CoAMoverCreated then return true end +-- Created eagerly (independent of the native frame ever showing up -- several +-- of these are class-specific and may never appear for a given character) so +-- every mover always appears in Toggle Anchors. The default point is only +-- used until the player drags it once; after that E:CreateMover restores the +-- saved position from E.db.movers. +local function CreateMoverHolder(def) + if CoA.classResourceMoversCreated and CoA.classResourceMoversCreated[def.name] then return end + CoA.classResourceMoversCreated = CoA.classResourceMoversCreated or {} + CoA.classResourceMoversCreated[def.name] = true + + local holder = CreateFrame("Frame", "CoA_"..def.name.."Holder", E.UIParent) + holder:Size(DEFAULT_WIDTH, DEFAULT_HEIGHT) + holder:Point("LEFT", E.UIParent, "LEFT", 150, def.defaultY) + + E:CreateMover(holder, "CoA_"..def.name.."Mover", def.moverText, nil, nil, nil, "ALL,COA", nil, "CoA,classResources") + holder:SetAllPoints(_G["CoA_"..def.name.."Mover"]) +end + +local function SyncHolderSize(frame, name) + local holder = _G["CoA_"..name.."Holder"] + if not holder then return end local width, height = frame:GetSize() - if width == 0 or height == 0 then return false end + if width > 0 and height > 0 then + holder:Size(width, height) + end +end - local left, bottom = frame:GetLeft(), frame:GetBottom() - if not left or not bottom then return false end - - frame.CoAMoverCreated = true - - local holder = CreateFrame("Frame", "CoA_"..name.."Holder", E.UIParent) - holder:Size(width, height) - holder:Point("BOTTOMLEFT", E.UIParent, "BOTTOMLEFT", left, bottom) - - E:CreateMover(holder, "CoA_"..name.."Mover", moverText, nil, nil, nil, "ALL,COA", nil, "CoA,skin,classResources") - holder:SetAllPoints(_G["CoA_"..name.."Mover"]) +local function AnchorFrame(frame, name) + local holder = _G["CoA_"..name.."Holder"] + if not holder then return end QueueAnchor(function() AnchorToHolder(frame, holder) LockPosition(frame, holder) end) - - return true end -- The server never Show()s a frame the current class doesn't use, so its @@ -259,12 +276,10 @@ local function TryHookAll() DisableDrag(frame) SetupVisibility(frame, def.hideKey) FixTooltip(frame) + SyncHolderSize(frame, def.name) + AnchorFrame(frame, def.name) - if SetupMover(frame, def.name, def.moverText) then - hooked[def.name] = true - else - allHooked = false - end + hooked[def.name] = true else allHooked = false end @@ -275,6 +290,10 @@ local function TryHookAll() end function CoA:InitializeClassResources() + for _, def in ipairs(FRAMES) do + CreateMoverHolder(def) + end + if TryHookAll() then return end self.classResourcesTimer = self:ScheduleRepeatingTimer(function() diff --git a/Modules/ExtraActionBar.lua b/Modules/ExtraActionBar.lua index c4609a1..c82ecc4 100644 --- a/Modules/ExtraActionBar.lua +++ b/Modules/ExtraActionBar.lua @@ -53,6 +53,11 @@ end function CoA:UpdateExtraActionButtonSize() UpdateSize() + + local holder = _G["CoA_ExtraActionBarHolder"] + if holder then + holder:Size(CoA.db.profile.extraActionButtonSize or 52) + end end local function UpdateHotkeyText(button) @@ -157,26 +162,34 @@ local function SkinButton(button, container) SkinGlow(button, name) end -local function SetupMover(container, button) - if CoA.extraActionBarMoverCreated then return true end - - local width, height = button:GetSize() - if width == 0 or height == 0 then return false end - - local left, bottom = button:GetLeft(), button:GetBottom() - if not left or not bottom then return false end - +-- Created eagerly (independent of the native ExtraActionBar ever showing up) +-- so the mover always appears in Toggle Anchors. The default point below is +-- only used until the player drags it once; after that E:CreateMover restores +-- the saved position from E.db.movers. +local function CreateMoverHolder() + if CoA.extraActionBarMoverCreated then return end CoA.extraActionBarMoverCreated = true + local size = CoA.db.profile.extraActionButtonSize or 52 + local holder = CreateFrame("Frame", "CoA_ExtraActionBarHolder", E.UIParent) + holder:Size(size, size) + holder:Point("BOTTOM", E.UIParent, "BOTTOM", 0, 260) + + E:CreateMover(holder, "CoA_ExtraActionBarMover", "Extra Action Bar", nil, nil, nil, "ALL,COA", nil, "CoA,skins,extraActionButton") + holder:SetAllPoints(_G["CoA_ExtraActionBarMover"]) +end + +local function SetupContainer(container) + if container.CoAContainerSetup then return end + container.CoAContainerSetup = true + container:StripTextures(true) container:EnableMouse(false) +end - local holder = CreateFrame("Frame", "CoA_ExtraActionBarHolder", E.UIParent) - holder:Size(width, height) - holder:Point("BOTTOMLEFT", E.UIParent, "BOTTOMLEFT", left, bottom) - - E:CreateMover(holder, "CoA_ExtraActionBarMover", "Extra Action Bar", nil, nil, nil, "ALL,COA", nil, "CoA,skin,extraActionBar") - holder:SetAllPoints(_G["CoA_ExtraActionBarMover"]) +local function AnchorContainer(container) + local holder = _G["CoA_ExtraActionBarHolder"] + if not holder then return end local function Anchor() container:ClearAllPoints() @@ -191,8 +204,6 @@ local function SetupMover(container, button) else Anchor() end - - return true end local function TryHook() @@ -201,13 +212,17 @@ local function TryHook() if container and button then SkinButton(button, container) - return SetupMover(container, button) + SetupContainer(container) + AnchorContainer(container) + return true end return false end function CoA:InitializeExtraActionBar() + CreateMoverHolder() + if TryHook() then return end self.extraActionBarTimer = self:ScheduleRepeatingTimer(function() diff --git a/Modules/LayerPicker.lua b/Modules/LayerPicker.lua index e4f9f68..da71678 100644 --- a/Modules/LayerPicker.lua +++ b/Modules/LayerPicker.lua @@ -19,8 +19,17 @@ local function UpdateFont(button) ) end +local function SyncHolderSize(button) + local holder = _G["CoA_LayerPickerHolder"] + button = button or _G[BUTTON_NAME] + if holder and button then + holder:Size(button:GetSize()) + end +end + function CoA:UpdateInstanceButtonFont() UpdateFont() + SyncHolderSize() end -- Hooked at file scope, so unlike the rest of the skin it stays live even when @@ -69,24 +78,26 @@ local function DisableDrag(button) end) end -local function SetupMover(button) - if CoA.layerPickerMoverCreated then return true end - - local width, height = button:GetSize() - if width == 0 or height == 0 then return false end - - local left, bottom = button:GetLeft(), button:GetBottom() - if not left or not bottom then return false end - +-- Created eagerly (independent of the native LayerPickerFrame ever showing +-- up) so the mover always appears in Toggle Anchors. The default point below +-- is only used until the player drags it once; after that E:CreateMover +-- restores the saved position from E.db.movers. +local function CreateMoverHolder() + if CoA.layerPickerMoverCreated then return end CoA.layerPickerMoverCreated = true local holder = CreateFrame("Frame", "CoA_LayerPickerHolder", E.UIParent) - holder:Size(width, height) - holder:Point("BOTTOMLEFT", E.UIParent, "BOTTOMLEFT", left, bottom) + holder:Size(MIN_WIDTH, MIN_HEIGHT) + holder:Point("TOPLEFT", E.UIParent, "TOPLEFT", 250, -250) - E:CreateMover(holder, "CoA_LayerPickerMover", "Instance", nil, nil, nil, "ALL,COA", nil, "CoA,skin,instance") + E:CreateMover(holder, "CoA_LayerPickerMover", "Instance", nil, nil, nil, "ALL,COA", nil, "CoA,skins,instanceSwap") holder:SetAllPoints(_G["CoA_LayerPickerMover"]) _G["CoA_LayerPickerMover"]:SetFrameStrata("FULLSCREEN") +end + +local function AnchorButton(button) + local holder = _G["CoA_LayerPickerHolder"] + if not holder then return end local function Anchor() button:ClearAllPoints() @@ -101,8 +112,6 @@ local function SetupMover(button) else Anchor() end - - return true end local function SkinButton(button) @@ -122,13 +131,17 @@ local function TryHook() if button then DisableDrag(button) SkinButton(button) - return SetupMover(button) + SyncHolderSize(button) + AnchorButton(button) + return true end return false end function CoA:InitializeLayerPicker() + CreateMoverHolder() + if TryHook() then return end self.layerPickerTimer = self:ScheduleRepeatingTimer(function()