WebLabel wrap

Hi everbody.

When using a WebLabel, it’s very hard to find out how many characters can fit inside it in one single line and even if the multiline is set to false, it’s allways wraped.

Is there a way to prevent this ?

Thanks

[quote=157673:@ValryTarondeau]When using a WebLabel, it’s very hard to find out how many characters can fit inside it in one single line and even if the multiline is set to false, it’s allways wraped.

Is there a way to prevent this ?[/quote]

I do not know how to measure text length in a web app, since most of the time there are no fonts installed so Graphics.Textsize cannot be used. It is possible to create a width table in a desktop app and measure the width of each character, then save in a file and use that data in the web app to get the line length, but you will have to make sure to set the font and point size to make sure it is accurate. Choose a font that you are sure exists on the target platforms. Arial is a good candidate for Mac and Windows, but you will have to find a Linux equivalent font with a compatible width table.

To create a non wrapping, one line label :

  • Place a label onto a Container at 0, 0
  • Make the label width 2000 or something real large, larger than the longest possible line.
  • Lock the label up, left, bottom
  • Drag an instance of the container onto your page

To address the content, prefix with the instance name, for instance :

CC1.Label1.Text = "really long line"

I forgot : set the scrollbar invisible in the inspector, or add in the container Open event :

me.ScrollbarsVisible = 0

From my understanding AutoLayout is coming to Web next since we now have it for iOS. Hopefully our lives should be made easier once this is complete.

In the meantime you can use Michel’s method or a WebControlWrapper to generate your own label control.

[quote=157719:@Brock Nash]From my understanding AutoLayout is coming to Web next since we now have it for iOS. Hopefully our lives should be made easier once this is complete.

In the meantime you can use Michel’s method or a WebControlWrapper to generate your own label control.[/quote]

As far as I know, iOS AutoLayout does not provide anything like the equivalent of VB label autosize, which grows a label with the text length. So it’s arrival for WE will not change the issue for the OP.

That said, after creating a first app for iOS, I see now how Auto Layout could greatly help web design. In particular, as portable devices grow in the share of web clients, with their screen sizes very dissimilar to computers.

Actually it does. You set the width to intrinsic content width. It’s one of the main reasons we wanted to add autolayout to the framework because it makes localizing apps dead simple.

[quote=157673:@ValryTarondeau]When using a WebLabel, it’s very hard to find out how many characters can fit inside it in one single line and even if the multiline is set to false, it’s allways wraped.

Is there a way to prevent this ?[/quote]
I use this code in a separate utility app when designing a WE app:

[code]Function CalcWidth(Phrase As String, FontSize As Integer = 0) As Integer
Dim p As New Picture(1, 1)
Dim g As Graphics
g = p.Graphics
g.TextFont = “Lucida Grande”
If FontSize > 0 Then
g.TextSize = FontSize
End If
Return g.StringWidth( Phrase )

End Function
[/code]
Or you can use it in the actual WE app to auto-adjust. But it’s not perfect - the label width usually needs a little more, especially for larger font sizes, and it also varies by browser/platform. But it helps me get close while designing so that it only needs small tweaks.

[quote=157731:@Greg O’Lone]As far as I know, iOS AutoLayout does not provide anything like the equivalent of VB label autosize, which grows a label with the text length. So it’s arrival for WE will not change the issue for the OP.
Actually it does. You set the width to intrinsic content width. It’s one of the main reasons we wanted to add autolayout to the framework because it makes localizing apps dead simple.[/quote]

Greg, I am elated to read this, but a bit puzzled. How do you set that ? I see nowhere intrinsic content in a label Auto Layout settings. I also searched for anything like that in the LR, but not a trace.

[quote=157740:@Jay Madren]I use this code in a separate utility app when designing a WE app:

[code]Function CalcWidth(Phrase As String, FontSize As Integer = 0) As Integer
Dim p As New Picture(1, 1)
Dim g As Graphics
g = p.Graphics
g.TextFont = “Lucida Grande”
If FontSize > 0 Then
g.TextSize = FontSize
End If
Return g.StringWidth( Phrase )

End Function
[/code]
Or you can use it in the actual WE app to auto-adjust. But it’s not perfect - the label width usually needs a little more, especially for larger font sizes, and it also varies by browser/platform. But it helps me get close while designing so that it only needs small tweaks.[/quote]

Testing that code in debug will work in debug, because a PC, a Mac or a Linux desktop box all have fonts for their UI.

If the font is not installed on the host machine, StringWidth will simply report zero, as if you used an invalid font name. Unfortunately, most hosts do not have fonts installed. See https://forum.xojo.com/15834-install-fonts-on-linux-server

Xojo Cloud does not have fonts installed as default, and when I tried on my 1701 account, it did not work either until Phillip installed the fonts for me.

Hence the need to use an ad hoc font table width generated on desktop.

Thanks for these workarounds, quite complex to implement because even if the with in pixels is known, it remains hard to set the correct text length…
In our app, there’s more than 1000 labels and the issue can possibly appear in a lot of them.
The best option would be to fix the issue in WebLabel itself making it behave as it does in the IDE.

[quote=157782:@ValryTarondeau]Thanks for these workarounds, quite complex to implement because even if the with in pixels is known, it remains hard to set the correct text length…
In our app, there’s more than 1000 labels and the issue can possibly appear in a lot of them.
The best option would be to fix the issue in WebLabel itself making it behave as it does in the IDE.[/quote]

If you have the width of the text, you can truncate it to avoid the wrap. Trim until the width = that of the label. Does not look terribly complex to do. Here is the way to measure text in a web app when fonts are not present on the server :

In a desktop app, to create a width table :

[code]Sub Action()
dim f as folderitem = SpecialFolder.Desktop.child(“widthtable.text”)
Dim p As New Picture(1, 1)
Dim g As Graphics
g = p.Graphics
g.TextFont = “Lucida Grande”
g.TextSize = 12

Dim t As TextOutputStream
If f <> Nil Then
t = TextOutputStream.Create(f)
for i as integer = 32 to 256
t.Write(str(g.StringWidth(chr(i)))+chr(9))
next
t.Close
End If
End Sub
[/code]

In the web app :

[code]Function stringW(mystring as string) As double
dim texte as string
dim charwidth() as string
dim stringwid as double

dim f as folderitem = SpecialFolder.Desktop.child(“widthtable.text”)
If f <> Nil Then
If f.Exists Then
// Be aware that TextInputStream.Open coud raise an exception
Dim t As TextInputStream
Try
t = TextInputStream.Open(f)
t.Encoding = Encodings.MacRoman
texte = t.ReadAll
Catch e As IOException
t.Close
MsgBox(“Error accessing file.”)
End Try
End If
End If

charwidth = split(texte,chr(9))

for i as integer = 1 to len(mystring)
stringwid = stringwid+val(charwidth( asc(mid(mystring,i,1))-31 ))
next

return stringwid
End Function
[/code]

Sure, if labels behaved as in the IDE it would be better, but until then…

Have you filed a bug report ?

@Michel Bujardet Thanks ! I’ll try that… and let you if it’s not too complex with all my different labels and styles.

I’ve just filled a bug report in Feedback (37666)

I just tried this to automatically cut the text to the length of all labels of a page at once. I also modified the stringW method to use the widthtable.txt document dragged into the project.

[code]Function stringW(mystring as string) As double
dim charwidth() as string
dim stringwid as double

charwidth = split(widthtable,chr(9)) //widthtable has been dragged into the project

for i as integer = 1 to len(mystring)
stringwid = stringwid+val(charwidth( asc(mid(mystring,i,1))-31 ))
next

return stringwid
End Function
[/code]

[code]Function trimtext(s as string, leng as integer) As string
if stringw(s) < leng then return s

dim news as string = s

while stringw(news) > leng
news = left(news,len(news)-1)
system.DebugLog str(stringw(news))
wend

return news
End Function[/code]

To have all labels text cut to width, in a button :

Sub Action() for ii as integer = 0 to self.ControlCount-1 if self.ControlAtIndex(ii) isa WebLabel then WebLabel(self.ControlAtIndex(ii)).text = trimtext(WebLabel(self.ControlAtIndex(ii)).text, WebLabel(self.ControlAtIndex(ii)).Width) end if next End Sub

And this works the other way around, to resize the label to accommodate the content, so a longer text will not be cut. I added 10 to the label size to allow for some imprecision.

Sub Action() for ii as integer = 0 to self.ControlCount-1 if self.ControlAtIndex(ii) isa WebLabel then WebLabel(self.ControlAtIndex(ii)).width = stringW(WebLabel(self.ControlAtIndex(ii)).text)+10 end if next End Sub

With these methods, if you already have thousands of labels in you project, all you have to do is add the cut text or resize to the open event of the window and they are all set.