Quantcast
WoWInterface - View Single Post - Why frame never attaches to UIParent?
View Single Post
07-19-19, 03:53 AM   #9
aallkkaa
A Warpwood Thunder Caller
 
aallkkaa's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2017
Posts: 98
And in the light of jeruku's post, I winged up an addon with your (slightly edited) code and my previous suggestion does work. I.e.:
Lua Code:
  1. print("Detach called");
  2.  
  3. self:SetParent(nil);
  4. self:SetParent(UIParent);
  5. self:ClearAllPoints();
  6. self:SetPoint("CENTER", UIParent, "CENTER", 0, -150);
  7.  
  8. print("attached to: " .. self:GetParent():GetName());
Output:
Code:
Detach called
attached to: UIParent

Furthermore, :GetPoint should be added to the list jeruku quoted under "The following APIs are now blocked from being called on restricted frames:" If you add thiese two lines to the end of the snippet above:
Lua Code:
  1. local point, anchor, anchorTo, x, y = self:GetPoint(1);
  2. print("at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
The output is:
Code:
Detach called
attached to: UIParent
at point #1: CENTER, UIParent, CENTER, 0, -150
But, if you add that same code to your :Attach method, you get an error:
Code:
Message: Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:22: Action[FrameMeasurement] failed because[Can't measure restricted regions]: attempted from: LybrialUIAnchor:GetPoint().
Time: Fri Jul 19 10:47:09 2019
Count: 1
Stack: Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:22: Action[FrameMeasurement] failed because[Can't measure restricted regions]: attempted from: LybrialUIAnchor:GetPoint().
[C]: in function `GetPoint'
Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:22: in function `Attach'
Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:64: in function <Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:55>

Locals: (*temporary) = LybrialUIAnchor {
 0 = <userdata>
 Attach = <function> defined @Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:12
 Detach = <function> defined @Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:32
 TestTexture = <unnamed> {
 }
 eventHandler = <function> defined @Interface\AddOns\alkaTestLyabral\alkaTestLyabral.lua:55
}
(*temporary) = 1

Finally, I also created a texture on the frame. And it's weird.
The texture reportedly attaches correctly to the frame, wich on Detach is reportedly positioned at "CENTER, UIParent, CENTER, 0, -150".
Code:
Lua Code:
  1. print("Detach called");
  2. print("attached to: " .. self:GetParent():GetName());
  3. local point, anchor, anchorTo, x, y = self:GetPoint(1);
  4. print("at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
  5. local point, anchor, anchorTo, x, y = self.TestTexture:GetPoint(1);
  6. print("Texture at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
Output:
Code:
Detach called
attached to: UIParent
at point #1: CENTER, UIParent, CENTER, 0, -150
Texture at point #1: TOPLEFT, LybrialUIAnchor, TOPLEFT, 0, 0
BUT the texture is always drawn at the position the player's nameplate was last drawn at (on :Attach), never resetting to "CENTER, UIParent, CENTER, 0, -150" (as set and reportedly done on : Dettach).
I'm actually rather unfamiliar with working with textures, so I may be missing something.

For reference, here's the full code I ran:
Lua Code:
  1. local LybrialAnchors = {};
  2.  
  3. function LybrialAnchors:SetupFrames()
  4.     if (not self.anchorFrame) then
  5.         self.anchorFrame = CreateFrame("Frame", "LybrialUIAnchor");
  6.  
  7.         self.anchorFrame.TestTexture = self.anchorFrame:CreateTexture(NIL, "ARTWORK");
  8.         self.anchorFrame.TestTexture:SetColorTexture(1, 1, 1, 1);
  9.  
  10.         self.anchorFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED");
  11.         self.anchorFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED");
  12.         self.anchorFrame.Attach = function(self, frame, frameTopLeft, frameBottomRight)
  13.             print("Attach called");
  14.  
  15.             self:SetParent(frame);
  16.             self:ClearAllPoints();
  17.             self:SetPoint("TOPLEFT", frameTopLeft, "TOPLEFT", 0, 0);
  18.             self:SetPoint("BOTTOMRIGHT", frameBottomRight, "BOTTOMRIGHT", 0, 0);
  19.  
  20.             print("attached to: " .. self:GetParent():GetName());
  21.             -- NB: The following line will error (cannot get measurements from restricted frame
  22.             -- local point, anchor, anchorTo, x, y = self:GetPoint(1);
  23.             -- print("at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
  24.  
  25.             -- LybrialAnchors:OnUpdate();
  26.             self.TestTexture:ClearAllPoints();
  27.             self.TestTexture:SetAllPoints();
  28.             -- NB: The following line will error (cannot get measurements from restricted frame)
  29.             -- local point, anchor, anchorTo, x, y = self.TestTexture:GetPoint(1);
  30.             -- print("Texture at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
  31.         end
  32.         self.anchorFrame.Detach = function(self)
  33.             print("Detach called");
  34.  
  35.             self:SetParent(nil);
  36.             self:SetParent(UIParent);
  37.             self:ClearAllPoints();
  38.             self:SetPoint("CENTER", UIParent, "CENTER", 0, -150);
  39.  
  40.             print("attached to: " .. self:GetParent():GetName());
  41.             -- NB: The following line will NOT error
  42.             local point, anchor, anchorTo, x, y = self:GetPoint(1);
  43.             print("at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
  44.  
  45.             -- LybrialAnchors:OnUpdate();
  46.             -- NB: The following line will error (cannot set a Texture's parent to nil)
  47.             -- self.TestTexture:SetParent(nil);
  48.             -- self.TestTexture:SetParent(self);
  49.             self.TestTexture:ClearAllPoints();
  50.             self.TestTexture:SetAllPoints();
  51.             -- NB: The following line will NOT error
  52.             local point, anchor, anchorTo, x, y = self.TestTexture:GetPoint(1);
  53.             print("Texture at point #1: " .. point.. ", ".. anchor:GetName().. ", ".. anchorTo.. ", ".. x.. ", ".. y);
  54.         end
  55.         self.anchorFrame.eventHandler = function(_, event, nameplate)
  56.             if (event == "NAME_PLATE_UNIT_ADDED") then
  57.                 if (UnitIsUnit(nameplate, "player")) then
  58.                     if (InCombatLockdown() or C_PetBattles.IsInBattle()) then
  59.                         LybrialAnchors.anchorFrame:Detach();
  60.                     else
  61.                         local frame = C_NamePlate.GetNamePlateForUnit("player");
  62.  
  63.                         if (frame) then
  64.                             LybrialAnchors.anchorFrame:Attach(frame, frame.UnitFrame.healthBar, NamePlateDriverFrame.classNamePlatePowerBar);
  65.                         else
  66.                             LybrialAnchors.anchorFrame:Detach();
  67.                         end
  68.                     end
  69.                 end
  70.             elseif (event == "NAME_PLATE_UNIT_REMOVED") then
  71.                 if (UnitIsUnit(nameplate, "player")) then
  72.                     LybrialAnchors.anchorFrame:Detach();
  73.                 end
  74.             end
  75.         end
  76.  
  77.         self.anchorFrame:SetScript("OnEvent", self.anchorFrame.eventHandler);
  78.     end
  79. end
  80.    
  81. LybrialAnchors:SetupFrames()

I'll be going back to my own nerve-wrecking projects now. But if anyone has any more insight on any of this, I'd be curious.

And... happy coding, Lybrial!
  Reply With Quote