Thread Tools Display Modes
10-10-13, 05:22 AM   #1
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
Problems with GetWidth()

I have some issues with incorrect zero returns from frame:GetWidth(). I set the width of the frame in question by using SetPoint()
Lua Code:
  1. local AddOverlay = function(self, unit)
  2.     local overlay = CreateFrame("Frame", self:GetName().."_Overlay", self.Portrait)
  3.     overlay:SetPoint("TOPLEFT", self.Portrait, 0, 1)
  4.     overlay:SetPoint("BOTTOMRIGHT", self.Portrait, 0, -1)
  5.  
  6.     local tex = overlay:CreateTexture(nil, "BORDER")
  7.     tex:SetAllPoints()
  8.     tex:SetTexture(ns.media.OVERLAY)
  9.     tex:SetVertexColor(0.1, 0.1, 0.1, 0.75)
  10.  
  11.     if (unit == "target") then
  12.         self.CCWarn = tex
  13.     end
  14.  
  15.     self.Overlay = overlay
  16. end

I then position some elements on the overlay and need its width to size them appropriately

Lua Code:
  1. local AddComboPointsBar = function(self, height, spacing)
  2.     local comboPoints = {}
  3.     local maxCPoints = MAX_COMBO_POINTS
  4.  
  5.     local width = self.Overlay:GetWidth()
  6.     width = (width - maxCPoints * spacing - spacing) / maxCPoints -- factoring causes rounding issues?
  7.     spacing = width + spacing
  8.  
  9.     for i = 1, maxCPoints do
  10.         local cPoint = self.Overlay:CreateTexture("oUF_Rain_ComboPoint_"..i, "OVERLAY")
  11.         cPoint:SetSize(width, height)
  12.         cPoint:SetPoint("BOTTOMLEFT", (i - 1) * spacing + 1, 1)
  13.         local color = ns.colors.cpoints[i]
  14.         cPoint:SetTexture(color[1], color[2], color[3])
  15.         comboPoints[i] = cPoint
  16.     end
  17.  
  18.     self.CPoints = comboPoints
  19. end

Here self.Overlay:GetWidth() returns 0. Further self.Overlay:GetPoint(1) returns just TOPLEFT, but self.Overlay:GetPoint(2) returns BOTTOMRIGHT, table: 01234, BOTTOMRIGHT, 0, -1 as expected. I'm sure I added self.Overlay before adding the combo points as otherwise I would get errors about self.Overlay being unknown. GetLeft(), GetRight() and GetSize() also return 0.

The frames get created at PLAYER_ENTERING_WORLD (the code is from my oUF layout) if this plays a role. /dump oUF_Rain_Player_Overlay:GetWidth() from in-game returns correct values.

So is this some limitation of GetWidth() or is something wrong on my side?

Last edited by Rainrider : 10-10-13 at 05:29 AM.
  Reply With Quote
10-10-13, 05:42 AM   #2
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,360
Is there a :SetSize() or :SetWidth()/:SetHeight() in part of the code we don't see?
I've found :SetSize() to be messing with :SetPoint() where textures are concerned.

Since I see a SetAllPoints() on your overlay might a workaround be to go off the dimensions of the parent frame that the texture is anchored to?

Edit: Need my coffee, this seems to already be the case.

Last edited by Dridzt : 10-10-13 at 05:49 AM.
  Reply With Quote
10-10-13, 05:53 AM   #3
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
You may try to add elements(or set their sizes) in the main frame's OnSizeChanged, check the width > 0 then add those elements or just wait for the next event.

Last edited by kurapica.igas : 10-10-13 at 05:55 AM.
  Reply With Quote
10-10-13, 07:51 AM   #4
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
Well, it appears that GetSize() and the like return values different than 0 before the interface has been drawn only if set explicitly. If I use
Code:
health:SetHeight(30)
health:SetPoint("TOPLEFT")
health:SetPoint("TOPRIGHT")
then health:GetSize() will return 0, 30. Also, what probably Dridzt means too, if I set
Code:
health:SetSize(250, 30)
health:SetPoint("TOPLEFT")
health:SetPoint("TOPRIGHT")
where the parent frame has a width of 230 px, GetSize() would return 250, 30 on PEW but the correct 230, 30 from in-game.

This is probably being delayed by the graphics engine in order to account for the relative position of other ui elements and/or scaling, don't know how this is done as the reported dimensions does not change with scale.
  Reply With Quote
10-10-13, 12:35 PM   #5
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
This is because you are handling the width by two SetPoint calls and not SetWidth or SetSize. There is no explicit width set.

You could try GetRight() - GetLeft() or something...

------------
Here's another example of this behavior from the default UI:

The WatchFrame's height is set via two SetPoint calls, since screen sizes are different and all that. If you wish to move the WatchFrame, you would call ClearAllPoints on it and give it a new location. This clears both points from the frame, thus resetting its height to the default. (I forget what the value is, exactly, but it's only tall enough for about two quests.) I have seen people then complain about how they can't see much in their WatchFrame anymore. So, you need to either add a second SetPoint call again, or explicitly set the height of the frame.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
10-10-13, 04:19 PM   #6
Rainrider
A Firelord
AddOn Author - Click to view addons
Join Date: Nov 2008
Posts: 454
I had already tried GetRight() - GetLeft() as I stated in my initial post. Beware also the incorrect return of GetPoint(1) also mentioned in the first post, despite of being set explicitly. I don't know from when on I can trust the returns of GetWidth() and the like, but it is obvious that the game returns correct data for those after some point even if dimension are set implicitly through anchoring. Can I know programmatically when this occurs?
  Reply With Quote
10-10-13, 07:35 PM   #7
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
I also has a layout system, so I can set element's size such like 1/3 width of the parent , and many other settings.

The 0-problem normally happened before the first drawn, modify the elements's size in OnSizeChanged works for me, just have a try.
  Reply With Quote
10-11-13, 01:54 AM   #8
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
I have a similar problem when calculating the width of my unit healthbar. Basically I do is this in my oUF layout.

Lua Code:
  1. if not IsGroupHeaderUnitButton then
  2.   self:SetSize(200,80)
  3. else
  4.   --size is set by init-width/height
  5. end
  6. self.Health = CreateFrame("Statusbar", nil, self)
  7. self.Health:SetPoint("TOPLEFT")
  8. self.Health:SetPoint("BOTTOMRIGHT")
  9. self.Health:RegisterEvent("UNIT_HEALTH_FREQUENT")
  10. self.Health:SetScript("OnEvent", function(hb)
  11.   print(hb:GetWidth())
  12. end)

It will work for all units except group header unit buttons.

When the unit is not a group header unit button and size is applied to the parent directly it works without problem.

Currently I sail around it by just using self:GetWidth() and substract the self.Health setpoints.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 10-11-13 at 02:09 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Problems with GetWidth()


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off