Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
ttown253
Level 7

Text Wrapping in roImageCanvas

Hi all,

I'm using an roImageCanvas to build a grid of rectangles that will make a grid for TV listings.

Basically how I understand it is, you position your text on the screen via a TargetRect with an X, Y position and a length and width.

The width of the TargetRect handles the wrapping great. If the text is too wide for the TargetRect, it wraps to the next line.

What I'm trying to figure out is how to get it to stop displaying text if there are too many lines. It's not doing anything about the height of the TargetRect. It will just keep printing the text, albeit the correct width, on several lines well beneath the TargetRect.

Is there any way to solve this issue without complex coding, text width analysis, etc?

Here's my code which put's a red rectangle on the screen the same size as the Text's TargetRect. The text printed goes outside of the bottom of the TargetRect because it's too long.


function Main()

canvas = CreateObject("roImageCanvas")

canvas.SetLayer(0, [
{
Color: "#FF0000",
TargetRect: {x: 400, y: 300, h: 100, w: 400}
},
{
Text: "Hello this is a long sentence about something I will see on TV someday and this is a continuation of that sentence which will wrap beneath the target rectangle",
TextAttrs: {color: "#FFFFFF", valign: "Top", halign: "Left"},
TargetRect: {x: 400, y: 300, h: 100, w: 400}
}
])

port = CreateObject("roMessagePort")
canvas.SetMessagePort(port)
canvas.Show()
while true
event = Wait(0, port)
if (event.IsRemoteKeyPressed())
index = event.GetIndex()
if (index = 6) ' Press OK to exit
exit while
end if
end if
end while

end function
0 Kudos
6 Replies
Highlighted
Komag
Level 9

Re: Text Wrapping in roImageCanvas

Here's a bit of code I use to cut off something that's too long:
IF Len(adjusters) > 30 THEN adjusters = Left(adjusters, 28) +"..." ' If there are many stat adjusters, cut this off short
0 Kudos
ttown253
Level 7

Re: Text Wrapping in roImageCanvas

I had thought about doing something like that, but it doesn't take into account the width of the font. Like 30 capital W's versus 30 lower case i's.

I think I'm going to explore the EPGGrid of the scene graph API to implement my project instead of ImageCanvas.
0 Kudos
RokuMarkn
Level 7

Re: Text Wrapping in roImageCanvas

I posted some code to do wrapping, to which height counting could easily be added: viewtopic.php?f=34&t=64824&p=415848#p415848

However this probably only works well with roScreen; I don't think it will work correctly with ImageCanvas.

--Mark
0 Kudos
NewManLiving
Level 7

Re: Text Wrapping in roImageCanvas

That is a very useful function that I currently use and have used quite a bit. Thanks for sharing that. It saved me a great deal of time not having to write it myself. Just be aware, and I believe it was mentioned somewhere, perhaps by yourself, that it does not address strings without whitespace that happen to be longer than "width". Such as a long URL that you wanted to display in a dialog. If it is longer than the width and the function cannot find whitespace to break it up then it will go into an endless loop. I have made adjustments to it myself to accommodate those types of strings pretty much the same way as the Scene Graph components handle it, at least according to the Scene Graph documentation. But for normal strings it is a great piece of code.
My Channels: 2D API Framework Presentation: https://owner.roku.com/add/2M9LCVC
Updated: 11-11-2015 - Completed Keyboard interface
The Joel Channel ( Final Beta )
0 Kudos
TheEndless
Level 7

Re: Text Wrapping in roImageCanvas

If you just want to prevent the text from overlapping other UI elements, you could redraw the background in that section at a higher layer (using SourceRect to slice out the area you need to repeat). The text would still overrun your TargetRect, but it'd be hidden behind the background slice.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
belltown
Level 7

Re: Text Wrapping in roImageCanvas

"ttown253" wrote:
What I'm trying to figure out is how to get it to stop displaying text if there are too many lines. It's not doing anything about the height of the TargetRect. It will just keep printing the text, albeit the correct width, on several lines well beneath the TargetRect.

Is there any way to solve this issue without complex coding, text width analysis, etc

If you do decide to use an roImageCanvas, compute the height for your text rectangle by taking the number of lines of text you want in each rectangle multiplied by GetOneLineHeight(). By drawing another text rectangle immediately adjacent to the one with overflowing text, as long as its background is completely filled, you will over-write any overflow text from the previous text rectangle, as demonstrated in the following code (which does require you to use a custom font):

function Main()

fontFile = "pkg:/fonts/Font.ttf" ' From: http://www.dafont.com/liberation-sans.font
fontName = "Liberation Sans"
fontSize = 24

fr = CreateObject ("roFontRegistry")
fr.Register (fontFile)

fontObject = fr.GetFont (fontName, fontSize, false, false)
fontString = fr.Get (fontName, fontSize, false, false)

lineH = fontObject.GetOneLineHeight ()
nLines = 3
rectH = nLines * lineH

canvas = CreateObject("roImageCanvas")

canvas.SetLayer(0, [
{
Color: "#FF0000",
TargetRect: {x: 200, y: 200, h: rectH, w: 400}
},
{
Text: "Hello this is a long sentence about something I will see on TV someday and this is a continuation of that sentence which will wrap beneath the target rectangle",
TextAttrs: {font: fontString, color: "#FFFFFF", valign: "Top", halign: "Left"},
TargetRect: {x: 200, y: 200, h: rectH, w: 400}
},
{
' The next grid element over-writes any overflow from the previous element
Color: "#00FF00",
TargetRect: {x: 200, y: 200 + rectH, h: rectH, w: 400}
},
{
Text: "This is the next sentence",
TextAttrs: {font: fontString, color: "#FFFFFF", valign: "Top", halign: "Left"},
TargetRect: {x: 200, y: 200 + rectH, h: rectH, w: 400}
}
])

port = CreateObject("roMessagePort")
canvas.SetMessagePort(port)
canvas.Show()
while true
event = Wait(0, port)
if (event.IsRemoteKeyPressed())
index = event.GetIndex()
if (index = 6) ' Press OK to exit
exit while
end if
end if
end while

end function
https://github.com/belltown/
0 Kudos