Today I noticed that the Xojo docs state that StringWidth was deprecated in v2019r2 and it suggests that you use TextWidth as a replacement.
But, StringWidth returns a measurement in Pixels whereas TextWidth returns a measurement in Points. So how can you replace StringWidth with TextWidth if they don’t return the same values?
StringWidth also uses points, so both StringWidth and TextWidth work exactly the same. Looks like the docs for StringWidth were never updated when things went from pixels to points a few years ago.
Ah Ok. I’m trying to figure out a way to determine if a string in a particular font will fit inside of a label. If the string is too long to fit I want to truncate the rightmost part enough to fit into the label with a trailing ellipsis.
Create a static picture, using new Picture(1,1,32) and use the graphics from that to set the font name, size and call textWidth to find the size. Then if too long remove last char and test with “…” on the edit repeating until it fits or the last char is removed.
Also note there is padding on the label so might need to add some margins to your check
An extension method like this is a start:
Public Sub TruncatedText(Extends lbl As Label, Assigns value As String)
Var p As Picture = lbl.TrueWindow.BitmapForCaching(1, 1)
Var g As Graphics = p.Graphics
g.FontName = lbl.FontName
g.FontSize = lbl.FontSize
Var w As Integer = g.TextWidth(value)
// Text fits in the Label
If w <= lbl.Width Then
lbl.Text = value
// Find the maximum length of text that will
// fit in the label (with an ellipses) and
// use that.
Var ellipsesWidth As Integer = g.TextWidth("…")
For i As Integer = value.Length DownTo 1
w = g.TextWidth(value.Left(i))
If w <= lbl.Width - ellipsesWidth Then
lbl.Text = value.Left(i) + "…"
MyLabel.TruncatedText = "Some really long text that should get cut off"
Thanks Paul, I found a similar bit of code in the forum and modified it.
This is what I came up with. This code prevents the ellipsis from being tacked-on after a trailing space. And prevents the ellipsis from being displayed without at least one character preceding it.
Public Sub TextWithEllipsis(Extends This_lbl As Label, Assigns This_str As String)
' Creat a picture object that we can use for its
' Graphics properties.
Dim Pic As New Picture(1,1)
' Set the picture object to the same font characteristics
' as the label we are trying to populate.
Pic.Graphics.FontUnit = This_lbl.FontUnit
Pic.Graphics.FontSize = This_lbl.FontSize
Pic.Graphics.FontName = This_lbl.FontName
Pic.Graphics.Italic = This_lbl.Italic
Pic.Graphics.Bold = This_lbl.Bold
' If the specified string (after trimming) fits within this
' label we update the label and exit.
This_str = This_str.Trim
If Pic.Graphics.TextWidth(This_str) <= This_lbl.Width Then
This_lbl.Text = This_str
' If the specified string doesn't fit within this label we
' start shortening the string one character at a time.
Var Temp_str As String
For i As Integer = This_str.Length DownTo 1
' Build new shorter string (right trimmed) with a
' trailing ellipsis.
Temp_str = This_str.Left(i).TrimRight + "..."
' Does the new shorter string (with ellipsis) fit
' into the label?
If Pic.Graphics.TextWidth(Temp_str) <= This_lbl.Width Then
' Update the label and exit.
This_lbl.Text = Temp_str
' If we made it this far we have a label that is too
' small to display one character (with an ellipsis
' tacked-on), so update label with an empty string.
This_lbl.Text = ""