Thread Tools Display Modes
06/23/14, 12:58 PM   #1
SkOODaT
 
SkOODaT's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 58
GetStringWidth() Question

Lua Code:
  1. function OnTargetTest()            
  2. local NSize = ZO_TargetUnitFramereticleoverName:GetStringWidth(GetUnitName("reticleover"))
  3. d(NSize)
  4.                
  5. end
  6.  
  7. EVENT_MANAGER:RegisterForEvent("TargetMaintenance_T", EVENT_RETICLE_TARGET_CHANGED, OnTargetTest)

why does this spit out 49 on a 6 space name lol it seems like its bugged ... i need it to set

***:SetDimensions(NSize,15) for a Name text field

Im looking at an NPC right now with that function the NPC name is "Riina Balen" - 11 Spaces but with the above function its saying its 85?!?!? lol

Last edited by SkOODaT : 06/23/14 at 01:03 PM.
  Reply With Quote
06/23/14, 01:23 PM   #2
ingeniousclown
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 122
Just looking at the numbers, it looks like pixel (or UI unit, in ESO's case) width that the string takes up.

Based on that assumption, "***:SetDimensions(NSize,15) for a Name text field" will probably do exactly what you want it to do.
  Reply With Quote
06/23/14, 01:31 PM   #3
SkOODaT
 
SkOODaT's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 58
Originally Posted by ingeniousclown View Post
Just looking at the numbers, it looks like pixel (or UI unit, in ESO's case) width that the string takes up.

Based on that assumption, "***:SetDimensions(NSize,15) for a Name text field" will probably do exactly what you want it to do.
"***:SetDimensions(NSize,15) it doesnt tho i get extra space on both ends :S even tried :gsub("^%s*(.-)%s*$", "%1") to trim all the blank space
  Reply With Quote
06/23/14, 02:01 PM   #4
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
I saw method label:GetStringWidth(text) just in case of indent:
Lua Code:
  1. function zo_bulletFormat(label, text)
  2.     local bulletSpacer = GetString(SI_FORMAT_BULLET_SPACING)
  3.     local bulletSpacingWidth = label:GetStringWidth(bulletSpacer)
  4.     label:SetNewLineX(bulletSpacingWidth)
  5.     label:SetText(zo_strformat(SI_FORMAT_BULLET_TEXT, text))
  6. end

Try to use something like:
Lua Code:
  1. label:SetText(text)
  2. label:SetDimensions(label:GetTextDimensions())
  Reply With Quote
06/23/14, 02:27 PM   #5
SkOODaT
 
SkOODaT's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 58
label:SetText(text)
label:SetDimensions(label:GetTextDimensions())

works great except the space is still there lol

i found

local NSize = string.len(TMTargetRName)

calculates the spaces correctly BUT

TargetMaintenanceName:SetDimensions(NSize,15)

its not applying to its not adjusting the space even though NSize has the correct var being applyed to it.... im getting lost lol i think something in my addon is stealing or adding space im just not sure lol

Last edited by SkOODaT : 06/23/14 at 02:31 PM.
  Reply With Quote
09/18/15, 07:13 PM   #6
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Necroing an old thread, because I have a related question.

I use GetStringWidth to make labels just a little bit wider than the text they contain (here). Today I noticed that with UI scale other than 1 the width is not correct -- with scale < 1 the text is too wide, it doesn't fit; with scale > 1 the control is too wide. Does GetStringWidth return width in pixels instead of UI units?
  Reply With Quote
09/18/15, 08:32 PM   #7
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
If the tabControl has a scale applied to it then it also scales the text by that amount.
So as an example, if you have a label with a scale of 1.5 and you put text in it that has an actual width of 100 (with a scale of 1.0), the text will get scaled up to 100 * 1.5 = 150.

But the real problem looks like the GetStringWidth() function also applies the scale to the returned value:
Lua Code:
  1. -- lets say the text width is actually 100 (with a scale of 1.0)
  2. -- and you set the label scale to 1.5 and you do:
  3. local width = label:GetStringWidth(label:GetText())
  4.  
  5. -- the width will be 100 * 1.5 * 1.5 = 225

It actually returns the actual text width * 1.5 * 1.5. The first multiplier is from the label being scaled which also scaled the string. The second multiplier is coming from the GetStringWidth() function applying another 1.5 multiplier to the returned width. Since the text width was already scaled I don't know why it would do that, but that is what it looks like its doing.

So you need to get the string width before you scale the control or adjust the width after you get it.
Lua Code:
  1. -- with a scale already applied
  2. tabControl:SetText(title)
  3.  
  4. local textWidth = tabControl:GetStringWidth(title)
  5. local scale = tabControl:GetScale()
  6.  
  7. -- get real text width on a scale of 1.0
  8. textWidth = textWidth / (scale * scale)
  9.  
  10. tabControl:SetWidth(10 + textWidth)

EDIT: I forgot to add, the reason you want the real text width (on a scale of 1.0) is because when you use SetWidth(width) it applies the scale to the width that you pass into it. So if the label has a scale of 1.5 and you do
Lua Code:
  1. label:SetWidth(100)
the width will actually get set to 150

Last edited by circonian : 09/18/15 at 08:51 PM.
  Reply With Quote
09/19/15, 05:06 AM   #8
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Yes, that's what I suspected. It seemed weird that I needed to un-scale the returned value before passing it to SetWidth. GetStringWidth is only used in conjunction with SetNewLineX in ZO code, maybe they both work with pixels.

Edit: I don't think it multiplies twice by the scale. If the text width is 100 UI units and GetStringWidth returns 150 pixels, but I use the value as UI units in SetWidth(150), the control width will end up being 225 pixels. I only considered the global scale, didn't check whether the control's scale is applied. This is my modified code, seems to work ok so far:

Lua Code:
  1. local textWidth = tabControl:GetStringWidth(title) / GetUIGlobalScale()
  2. tabControl:SetText(title)
  3. tabControl:SetWidth(textWidth + TAB_TITLE_PADDING)

Last edited by merlight : 09/19/15 at 05:15 AM.
  Reply With Quote
09/19/15, 02:06 PM   #9
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Ah, I only looked at the controls scale I didn't look at the global UI scale.
Your right, the global scale appears to work differently. Although I'm not sure how. It does not appear to change the control width, it does return a scaled GetStringWidth(), but it does not appear to be a factor of the GetGlobaUIScale(), & it has no effect on SetWidth().

I was using this to examine the values:
Warning: Spoiler

But that would mean if your only using a global ui scale you shouldn't need to divide by GetGlobalUIScale(). Because GetStringWidth() returns the scaled width and setWidth is not effected by the GlobalUIScale. It works for me without it? Are you using both a globalUIScale & a scale on the control?


It is multiplied twice though using the controls scale.
Warning: Spoiler
  Reply With Quote
09/19/15, 03:04 PM   #10
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Just looked at an inventory label containing "Keep Wall Masonry Repair Kit"
Lua Code:
  1. GetUIGlobalScale() == 0.64
  2. label:GetScale() == 1
  3. label:GetTextWidth() == 229.6875
  4. label:GetStringWidth(label:GetText()) == 147 == 0.64 * 229.6875
  5.  
  6. GetUIGlobalScale() == 1.10
  7. label:GetScale() == 1
  8. label:GetTextWidth() == 223.6364
  9. label:GetStringWidth(label:GetText()) == 246 == 1.10 * 223.6364
  10.  
  11. GetUIGlobalScale() == 0.64
  12. label:GetScale() == 1.25
  13. label:GetTextWidth() == 229.6875
  14. label:GetStringWidth(label:GetText()) == 229.6875 == 0.64 * 1.25^2 * 229.6875
  15.  
  16. GetUIGlobalScale() == 1.10
  17. label:GetScale() == 1.25
  18. label:GetTextWidth() == 223.6364
  19. label:GetStringWidth(label:GetText()) == 384.375 == 1.10 * 1.25^2 * 223.6364

You were right about GetStringWidth being multiplied twice by the control's scale. That's really weird. Anyway, with control scale == 1 it's pretty clear that GetStringWidth returns pixels, while GetTextWidth returns UI units (unaffected by scaling).

In the meantime, I found a way around explicitly setting the width of the Label control -- SetWidth(0) and wrap it in a container with SetResizeToFitDescendents(true) and SetResizeToFitPadding(10, 0). Unfortunatelly that trick doesn't work for Button controls, so those still have to adjust to UI scale changes.
  Reply With Quote
09/19/15, 03:16 PM   #11
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by circonian View Post
Lua Code:
  1. d("** After Global Scale 1.1")
  2. local width = label:GetStringWidth(text)
  3. d("GlobalScale: "..GetUIGlobalScale()) -- 1.1
  4. d("StringWidth: "..width) -- 118 (scaled by approx. 1.19 ?)
  5. d("ControlWidth: "..label:GetWidth()) -- 222.75 (unchanged)
That 1.19 is... unexpected. Maybe it also depends on the selected font. They may not scale smoothly but find closest matching font size and use that...
  Reply With Quote
09/21/15, 11:10 AM   #12
ZOS_ChipHilseberg
ZOS Staff!
Premium Member
Yes this person is from ZeniMax!
Join Date: Oct 2014
Posts: 551
GetWidth() = GetStringWidth() / GetGlobalUIScale().
GetWidth() = GetTextWidth() * GetScale()

There was a bug where scale was being double applied in GetStringWidth() (once to each character and once to the total) that is now fixed.
  Reply With Quote
09/21/15, 05:50 PM   #13
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Thanks for the clarification.
  Reply With Quote
02/12/16, 12:44 AM   #14
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by ZOS_ChipHilseberg View Post
GetWidth() = GetStringWidth() / GetGlobalUIScale()
GetWidth() = GetTextWidth() * GetScale()

There was a bug where scale was being double applied in GetStringWidth() (once to each character and once to the total) that is now fixed.
Question 1: What is the proper way to calculate a strings width/height for setting a label controls dimensions (taking possible scaling into account)?
I'm assuming in Chips statement that by GetWidth() = ... he meant that the correct width for the control is = .... and not the actual returned value of GetWidth(), but either way it doesn't seem to add up.

Question 2: Do I missunderstand Chips statement, because it does not seem to always be correct? There must be more to it...or a bug?
By Chips statement then the following should be true?
Lua Code:
  1. GetWidth() = GetStringWidth() / GetGlobalUIScale() = GetTextWidth() * GetScale()
  • But none of them are equal if the control is scaled.
  • Only the first 2 are equal if GetScale() = 1 and the control is to small to display all of the text.
  • All 3 are equal if GetScale() = 1 and the control is large enough to display all of the text.
Why?

If GetScale() = 1.5 and the control is large enough to display all of the text before measuring we get these measurements:

None of these are equal and none are the correct width for setting the labels width:
Lua Code:
  1. GetWidth() = GetStringWidth() / GetGlobalUIScale() = GetTextWidth() * GetScale()
In this case the correct values for setting the controls dimensions are given by GetTextHeight() & GetTextWidth() <without multiplying by * GetScale()> and notice that GetStringWidth() / GetGlobalUIScale() does not give the correct width for the control (the correct width is 220.xxx).


If GetScale() = 1.5 and the control is to small to display all of the text before measuring we get these measurements:

None of these are equal and none are the correct width for setting the labels width:
Lua Code:
  1. GetWidth() = GetStringWidth() / GetGlobalUIScale() = GetTextWidth() * GetScale()
In this case GetTextHeight() is still the correct height, but none of the values reveal the correct width that needs to be set on the control (the correct width is 220.xxx).


Question 3: In the two pictures above notice that the StringWidth measurements are consistent, but the TextWidth measurements are not. Why?

It appears GetTextWidth() only measures the visible text that is not cut off due to the control being to small. If when Chip used GetWidth() he was actually refering to the returned value of GetWidth() and not the "correct value" that should be used for setting the control width, then given his equations that would make sense, but if we solve both equations for the respective functions:
Lua Code:
  1. GetStringWidth() = GetWidth() * GetGlobalUIScale()
  2. GetTextWidth() = GetWidth() / GetScale()
Then shouldn't both functions be effected by the actual width of the control returned by GetWidth()?
And if he did mean the literal returned value of GetWidth() then why are none of these ever equal:
Lua Code:
  1. GetWidth() = GetStringWidth() / GetGlobalUIScale() = GetTextWidth() * GetScale()


Question 4: Why is GetTextWidth effected by the controls width, but GetTextHeight does not appear to be effected by the controls height?


If GetScale() = 1 and the control is to small for the text to be displayed:


This time GetTextWidth() is incorrect, GetStringWidth() / GetUIGlobalScale() returns the correct control width, and GetTextHeight() returns the correct height. I would have assumed that whatever the differences are between GetStringWidth & GetTextWidth that the two GetTextXXXX() functions would both work in the same way, but I guess not because GetTextHeight() seems to always return the correct height for the control, but GetTextWidth() does not <not even when scaled: * GetScale()>


If GetScale() = 1 and the control is large enough to display all of the text, this is the only time that Chips statement seems to be true:



Regardless of any of the above settings, these always appear to be the correct dimensions to use with SetWidth() & SetHeight() (for this example text):



If I reduce the width by just 1, we can see the last letter gets cut off, so 221 was the correct width to use, but
Question 5: Why doesn't reducing the height cut off any text?


I'm assuming whatever the answer is to this question it is the same reason why GetTextHeight() always returns the correct value, but it would be nice to know why.

Last edited by circonian : 02/12/16 at 01:39 AM.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » GetStringWidth() Question

Thread Tools
Display Modes

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