Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
bcoding
Visitor

scrolling in roScreen, roBitmap, roRegion, roCompositor

Hi Guys,
Since the default listscreen doesnot meet my needs, I have trying to create a custom scroll area using roScreen, roBitmap, roRegion AND roCompositor. I want some text to be displayed at the top part of the screen then on the middle to bottom part, I want to present the user with the available offers which can be scrolled vertically. Therefore I drew some text on the top part of the screen. Then created a bitmap, drew text on the bitmap, used region and compositor to get the bitmap to the lower part of the screen.
It is scrolling but whenever I scroll, it will erase the text that I drew on the screen then if I scroll again it will display it again, I dont know the reason, Can any of you please help.


Library "v30/bslDefender.brs"
Function Main () AS void

'creating screen object
screen=CreateObject("roScreen",true)
screen.clear(&hff0000ff)

' font for the text
fontRegistry = CreateObject("roFontRegistry")
font = fontRegistry.GetDefaultFont(24,false,false)


'writing the text to the screen
screen.DrawText("Hi Customer",400,90, &h00FFFFFF ,font)
screen.DrawText("Your name is : John Doe",285,145,&h00FFFFFF,font)
screen.DrawText("__________________________________",400,180, &h00FFFFFF,font)
screen.DrawText("Here are your choices: ",270,225, &h00FFFFFF,font)

'creating compositor objects
compositor=CreateObject("roCompositor")
' compositor.SetDrawTo(screen, &hff0000ff)
compositor.SetDrawTo(screen,0)

'creaating bitmap and writing text to bitmap
srollBm=CreateObject("roBitmap",{ width: 650, height: 200, AlphaEnable: false })

srollBm.DrawText("Get a Macbook pro with 4GB ram and 250gb harddrive",0,0,&h00FFFFFF,font)
srollBm.DrawText("Get a Macbook pro with 8GB ram and 250gb harddrive",0,50,&h00FFFFFF,font)
srollBm.DrawText("Get a Macbook pro with 12GB ram and 250gb harddrive",0,100,&h00FFFFFF,font)


'creating region that will be used for scrolling
region=CreateObject("roRegion", srollBm, 0, 0, srollBm.getwidth(), srollBm.getheight())'size of scroll area

region.SetWrap(True)

'this will create new sprite
view_sprite=compositor.NewSprite(370,400, region)

'draw the sprites created
compositor.drawAll()
screen.SwapBuffers()

'creating port inorder to listen to user events
msgport = CreateObject("roMessagePort")
screen.SetMessagePort(msgport)
codes = bslUniversalControlEventCodes()

While True
msg=wait(0, msgport) ' wait for a button
print "Msg: "; type(msg); " event: "; msg.GetInt()
If type(msg)="roUniversalControlEvent" Then
If msg.GetInt()=codes.BUTTON_UP_PRESSED Then
Shift(screen, view_sprite, compositor, 0,-15) 'up 0,-15
Else If msg.GetInt()=codes.BUTTON_DOWN_PRESSED Then
Shift(screen, view_sprite, compositor, 0,+15) ' down 0,+15

Else If msg.GetInt() = codes.BUTTON_BACK_PRESSED ' back button
Exit While
End If
End If
End While
End Function

'''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''' Shift Function To shift the bitmap region
''''''''''by the given numbers
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Function Shift(screen, view_sprite, compositor, xd, yd)
view_sprite.OffsetRegion(xd,yd,0,0)
compositor.drawAll()
screen.SwapBuffers()
End Function
0 Kudos
18 REPLIES 18
belltown
Roku Guru

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

You draw the text on the screen (in the back-buffer), then call SwapBuffers (now the text you drew is in the front-buffer; the back-buffer will have no text). Each time through your main loop you call SwapBuffers. The first call to SwapBuffers in your loop will swap the front and back buffers, so the screen buffer with no text is now in the front-buffer (the text is in the back-buffer) and the text seems to disappear. The next time you call SwapBuffers the text, which was in the back-buffer, is swapped to the front-buffer, and the text re-appears. Etc, etc, etc. One way to fix this is to re-draw the text after the initial SwapBuffers call.
0 Kudos
bcoding
Visitor

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

"belltown" wrote:
You draw the text on the screen (in the back-buffer), then call SwapBuffers (now the text you drew is in the front-buffer; the back-buffer will have no text). Each time through your main loop you call SwapBuffers. The first call to SwapBuffers in your loop will swap the front and back buffers, so the screen buffer with no text is now in the front-buffer (the text is in the back-buffer) and the text seems to disappear. The next time you call SwapBuffers the text, which was in the back-buffer, is swapped to the front-buffer, and the text re-appears. Etc, etc, etc. One way to fix this is to re-draw the text after the initial SwapBuffers call.



Thank you for the reply. It worked that way however the background color is different between the two buffers. I mean I can again set the screen background color along with text after the initial swappBuffer(). But is it a good programming practice to set everything again.
Also, i noticed that if I use single buffer instead of double buffer, I don't have to deal with these problems. I can set everything once then call finish(). So, what advantage does the double buffer have over single buffer.
0 Kudos
belltown
Roku Guru

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

If you use the double-buffered approach (for reasons described in RokuMarkn's answer to your same question last week, http://forums.roku.com/viewtopic.php?f=34&t=90259), then yes, you have to take into account that you are only writing to the current back-buffer, and every time you call SwapBuffers that back-buffer becomes the next front-buffer (displayed on screen), and the new current back-buffer will contain whatever it contained before the previous call to SwapBuffers.

Rather than trying to keep track of what was written to the previous back-buffer and only displaying what has changed, you may find it easier each time through your processing loop to completely Clear the back-buffer, re-write everything, then call SwapBuffers again. For text, make sure you draw the text to a bitmap once during your initial setup then draw that bitmap to the back-buffer in each loop. The same appies to scaled images: do the scaling once to a bitmap, then write the scaled bitmap each time through the loop.
0 Kudos
bcoding
Visitor

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

Drawing the text to bitmap and drawing the bitmap to screen when needed makes more sense. Thanks for these information. I will edit it later.
For now, I am confused in the scrolling region. If I increased the quantity of offers(here I have listed 12 offers), only the ones that fit inside the region are displayed and even if I scroll the remaining items are not displayed. I thought the remaining offers will be hidden somewhere downside and would appear once i scroll the region, but even if I scroll the same items that were displayed earlier keeps repeating.
What should I do inorder for my region to accomodate more items and display them when scrolling?


Library "v30/bslDefender.brs"
Function Main () AS void

'creating screen object
screen=CreateObject("roScreen",false)
screen.clear(&hff0000ff)

' font for the text
fontRegistry = CreateObject("roFontRegistry")
font = fontRegistry.GetDefaultFont(24,false,false)


'writing the text to the screen
screen.DrawText("Hi Customer",400,90, &h00FFFFFF ,font)
screen.DrawText("Your name is : John Doe",285,145,&h00FFFFFF,font)
screen.DrawText("__________________________________",400,180, &h00FFFFFF,font)
screen.DrawText("Here are your choices: ",270,225, &h00FFFFFF,font)

'creating compositor objects
compositor=CreateObject("roCompositor")
' compositor.SetDrawTo(screen, &hff0000ff)
compositor.SetDrawTo(screen,0)

'creaating bitmap and writing text to bitmap
srollBm=CreateObject("roBitmap",{ width: 650, height: 200, AlphaEnable: false })

srollBm.DrawText("1)Get a Macbook pro with 4GB ram and 250gb harddrive",0,0,&h00FFFFFF,font)
srollBm.DrawText("2)Get a Macbook pro with 8GB ram and 260gb harddrive",0,20,&h00FFFFFF,font)
srollBm.DrawText("3)Get a Macbook pro with 12GB ram and 270gb harddrive",0,40,&h00FFFFFF,font)
srollBm.DrawText("4)Get a Macbook pro with 14GB ram and 280gb harddrive",0,60,&h00FFFFFF,font)
srollBm.DrawText("5)Get a Macbook pro with 16GB ram and 290gb harddrive",0,80,&h00FFFFFF,font)
srollBm.DrawText("6)Get a Macbook pro with 18GB ram and 300gb harddrive",0,100,&h00FFFFFF,font)
srollBm.DrawText("7)Get a Macbook pro with 20GB ram and 310gb harddrive",0,120,&h00FFFFFF,font)
srollBm.DrawText("8)Get a Macbook pro with 22GB ram and 320gb harddrive",0,140,&h00FFFFFF,font)
srollBm.DrawText("9)Get a Macbook pro with 24GB ram and 330gb harddrive",0,160,&h00FFFFFF,font)
srollBm.DrawText("10)Get a Macbook pro with 26GB ram and 340gb harddrive",0,180,&h00FFFFFF,font)
srollBm.DrawText("11)Get a Macbook pro with 28GB ram and 350gb harddrive",0,200,&h00FFFFFF,font)
srollBm.DrawText("12)Get a Macbook pro with 30GB ram and 360gb harddrive",0,220,&h00FFFFFF,font)


'creating region that will be used for scrolling
region=CreateObject("roRegion", srollBm, 0, 0, srollBm.getwidth(), srollBm.getheight())'size of scroll area

region.SetWrap(True)

'this will create new sprite
view_sprite=compositor.NewSprite(370,400, region)

'draw the sprites created
compositor.drawAll()
screen.finish()



'creating port inorder to listen to user events
msgport = CreateObject("roMessagePort")
screen.SetMessagePort(msgport)
codes = bslUniversalControlEventCodes()

While True
msg=wait(0, msgport) ' wait for a button
print "Msg: "; type(msg); " event: "; msg.GetInt()
If type(msg)="roUniversalControlEvent" Then
If msg.GetInt()=codes.BUTTON_UP_PRESSED Then
Shift(screen, view_sprite, compositor, 0,-15) 'up 0,-15
Else If msg.GetInt()=codes.BUTTON_DOWN_PRESSED Then
Shift(screen, view_sprite, compositor, 0,+15) ' down 0,+15

Else If msg.GetInt() = codes.BUTTON_BACK_PRESSED ' back button
Exit While
End If
End If
End While
End Function

'''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''' Shift Function To shift the bitmap region
''''''''''by the given numbers
''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''
Function Shift(screen, view_sprite, compositor, xd, yd)
view_sprite.OffsetRegion(xd,yd,0,0)
compositor.drawAll()
screen.finish()
End Function
0 Kudos
NewManLiving
Visitor

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

Sub Main()

' This is strictly for example - You really should NOT create your globals this way
' There is a much better way which I will not go into now, but to demonstrate how a region works
' this will have to do

l_color = &h262626FF

m.Screen = CreateObject( "roScreen", True )
m.Compositor = CreateObject( "roCompositor" )
Port = CreateObject( "roMessagePort" )
m.Screen.SetMessagePort( Port )
m.Screen.Clear( l_color )
m.Compositor.SetDrawTo( m.Screen, l_color )

Registry = CreateObject( "roFontRegistry" )
FontR26 = Registry.GetDefaultFont( 26, False, False )

l_data = [
"1) Get a Macbook pro with 4GB ram and 250gb harddrive",
"2) Get a Macbook pro with 8GB ram and 260gb harddrive",
"3) Get a Macbook pro with 12GB ram and 270gb harddrive",
"4) Get a Macbook pro with 14GB ram and 280gb harddrive",
"5) Get a Macbook pro with 16GB ram and 290gb harddrive",
"6) Get a Macbook pro with 18GB ram and 300gb harddrive",
"7) Get a Macbook pro with 20GB ram and 310gb harddrive",
"8) Get a Macbook pro with 22GB ram and 320gb harddrive",
"9) Get a Macbook pro with 24GB ram and 330gb harddrive",
"10) Get a Macbook pro with 26GB ram and 340gb harddrive",
"11) Get a Macbook pro with 28GB ram and 350gb harddrive",
"12) Get a Macbook pro with 30GB ram and 360gb harddrive"
]

' Keep in mind there are only so many text strings that you can fit into a bitmap buffer, before you exceed its maximum size
' there is a much better way to do all of this, but for now to help you understand regions, i'll keep it simple

' You have 12 items in your data
l_count = l_data.Count()
' You want to show a page size of 5 items
l_pageSize = 5
' The height of one text line for this font is GetOneLineHeight()
l_textHeight = FontR26.GetOneLineHeight()
' The largest width for your data is probably item 12 + some padding, normally you would interate
' the data and save the maximum width for your bitmap buffer. So this is the bitmap buffers width
l_width = FontR26.GetOneLineWidth( l_data[ l_count - 1 ], 1000 ) + 25
' For this examle you have to fit all those strings into a bitmap buffer. If you had 250 + strings you could not
' do this, but there is a better way like i said
' so the total height of your bitmap buffer is l_height, which is the total count * the height of each line
l_height = l_count * l_textHeight
' Now for the region size. It will be the same width as the bitmap but you only want to show pagesize of data
' So the height of the region will bee the textheight * the page size
l_pageHeight = l_textHeight * l_pageSize

' Create the bitmap with l_width and l_height
Bitmap = CreateObject( "roBitmap", { Width: l_width, Height: l_height, AlphaEnable: True } )
'Clear it or leave it transparent
Bitmap.Clear( &h333333FF )
' Starting at y offset 0 ( you could play with this for margins, but then the region would have to change
' write each line of text, offsetting the y coord by text height
l_y = 0
for each l_str in l_data
Bitmap.DrawText( l_str, 0, l_y, &hCCCCCCFF, FontR26 )
l_y = l_y + l_textHeight
end for

' Create your region the same with, but only the page height
Region = CreateObject( "roRegion", Bitmap, 0, 0, l_width, l_pageHeight )
' Set wrap true
Region.SetWrap( True )
' Create the sprite
Sprite = m.Compositor.NewSprite( 200, 300, Region, 1 )
' Draw everything
m.Compositor.DrawAll()
m.Screen.SwapBuffers()

' Set up your event loop
' The frame rate for the up/down arrow
l_slowRate = 8
' The frame rate/number fwd/reverse arrows - ( this is not a true rate but good enough for lists )
l_fastRate = 2
' Delay between the button presses
l_delay = 200

' These are the constants for the buttons you can use the AA if you wish, probably best to
l_bp_BK = 0
l_bp_UP = 2
l_bp_DN = 3
l_bp_REV = 8
l_bp_FWD = 9

' Button pressed
l_index = 0
' Last button pressed
l_lastKey = -1
l_running = True

l_timer = CreateObject( "roTimeSpan" )

while( l_running )

' Get used to GetMessage, Wait is not really very good for anything but simple interface
l_msg = Port.GetMessage()

if type( l_msg ) = "roUniversalControlEvent"

l_index = l_msg.GetInt()
l_lastKey = l_index

' Based upon the key press, call the functions below
if l_index = l_bp_DN or l_index = l_bp_FWD
ScrollDown( Region, l_textHeight, l_slowRate )
else if l_index = l_bp_UP or l_index = l_bp_REV
ScrollUp( Region, l_textHeight, l_slowRate )
else if l_index = l_bp_BK
l_running = False
else if l_index >= 100 ' All key ups are value + 100
l_lastKey = -1
end if

' reset the timer for the delay
l_timer.Mark()
' User is holding down a button and the delay has been exceeded
else if ( l_lastKey >= 0 and l_timer.TotalMilliseconds() >= l_delay )

if l_lastKey = l_bp_DN
ScrollDown( Region, l_textHeight, l_slowRate )
else if l_lastKey = l_bp_FWD
ScrollDown( Region, l_textHeight, l_fastRate )
else if l_lastKey = l_bp_UP
ScrollUp( Region, l_textHeight, l_slowRate )
else if l_lastKey = l_bp_REV
ScrollUp( Region, l_textHeight, l_fastRate )
end if

end if

end while

' Always remove the sprite or you will have a memory leak, even out of scope it is not released
' must be explicity released at all times
if ( Sprite <> Invalid ) then Sprite.Remove()

End Sub

' This employs region offsetting and a very simple ease. You want to move the regions y pos by textheight each time the function is called
Function ScrollDown( roRegion As Object, height As Integer, frames As Integer ) As Void

' Not sure how optimized the byte code is so I simplify references when in loops
l_compositor = m.Compositor
l_screen = m.Screen
l_prevset = 0

for l_i = 1 to frames
' Offset means to move from the current position by the value
l_offset = int( height * l_i / frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset

' Moving forward in Y direction so everything else is 0
roRegion.Offset( 0, l_offdiff, 0, 0 )
l_compositor.DrawAll()
l_screen.SwapBuffers()
end for

End Function

Function ScrollUp( roRegion As Object, height As Integer, frames As Integer ) As Void
l_compositor = m.Compositor
l_screen = m.Screen
l_prevset = 0

for l_i = 1 to frames
l_offset = int( height * l_i / frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset
' same as aobve only moving back so the offset is negative
roRegion.Offset( 0, -l_offdiff, 0, 0 )
l_compositor.DrawAll()
l_screen.SwapBuffers()
end for
End Function
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
bcoding
Visitor

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

"NewManLiving" wrote:
Sub Main()

' This is strictly for example - You really should NOT create your globals this way
' There is a much better way which I will not go into now, but to demonstrate how a region works
' this will have to do

l_color = &h262626FF

m.Screen = CreateObject( "roScreen", True )
m.Compositor = CreateObject( "roCompositor" )
Port = CreateObject( "roMessagePort" )
m.Screen.SetMessagePort( Port )
m.Screen.Clear( l_color )
m.Compositor.SetDrawTo( m.Screen, l_color )

Registry = CreateObject( "roFontRegistry" )
FontR26 = Registry.GetDefaultFont( 26, False, False )

l_data = [
"1) Get a Macbook pro with 4GB ram and 250gb harddrive",
"2) Get a Macbook pro with 8GB ram and 260gb harddrive",
"3) Get a Macbook pro with 12GB ram and 270gb harddrive",
"4) Get a Macbook pro with 14GB ram and 280gb harddrive",
"5) Get a Macbook pro with 16GB ram and 290gb harddrive",
"6) Get a Macbook pro with 18GB ram and 300gb harddrive",
"7) Get a Macbook pro with 20GB ram and 310gb harddrive",
"8) Get a Macbook pro with 22GB ram and 320gb harddrive",
"9) Get a Macbook pro with 24GB ram and 330gb harddrive",
"10) Get a Macbook pro with 26GB ram and 340gb harddrive",
"11) Get a Macbook pro with 28GB ram and 350gb harddrive",
"12) Get a Macbook pro with 30GB ram and 360gb harddrive"
]

' Keep in mind there are only so many text strings that you can fit into a bitmap buffer, before you exceed its maximum size
' there is a much better way to do all of this, but for now to help you understand regions, i'll keep it simple

' You have 12 items in your data
l_count = l_data.Count()
' You want to show a page size of 5 items
l_pageSize = 5
' The height of one text line for this font is GetOneLineHeight()
l_textHeight = FontR26.GetOneLineHeight()
' The largest width for your data is probably item 12 + some padding, normally you would interate
' the data and save the maximum width for your bitmap buffer. So this is the bitmap buffers width
l_width = FontR26.GetOneLineWidth( l_data[ l_count - 1 ], 1000 ) + 25
' For this examle you have to fit all those strings into a bitmap buffer. If you had 250 + strings you could not
' do this, but there is a better way like i said
' so the total height of your bitmap buffer is l_height, which is the total count * the height of each line
l_height = l_count * l_textHeight
' Now for the region size. It will be the same width as the bitmap but you only want to show pagesize of data
' So the height of the region will bee the textheight * the page size
l_pageHeight = l_textHeight * l_pageSize

' Create the bitmap with l_width and l_height
Bitmap = CreateObject( "roBitmap", { Width: l_width, Height: l_height, AlphaEnable: True } )
'Clear it or leave it transparent
Bitmap.Clear( &h333333FF )
' Starting at y offset 0 ( you could play with this for margins, but then the region would have to change
' write each line of text, offsetting the y coord by text height
l_y = 0
for each l_str in l_data
Bitmap.DrawText( l_str, 0, l_y, &hCCCCCCFF, FontR26 )
l_y = l_y + l_textHeight
end for

' Create your region the same with, but only the page height
Region = CreateObject( "roRegion", Bitmap, 0, 0, l_width, l_pageHeight )
' Set wrap true
Region.SetWrap( True )
' Create the sprite
Sprite = m.Compositor.NewSprite( 200, 300, Region, 1 )
' Draw everything
m.Compositor.DrawAll()
m.Screen.SwapBuffers()

' Set up your event loop
' The frame rate for the up/down arrow
l_slowRate = 8
' The frame rate/number fwd/reverse arrows - ( this is not a true rate but good enough for lists )
l_fastRate = 2
' Delay between the button presses
l_delay = 200

' These are the constants for the buttons you can use the AA if you wish, probably best to
l_bp_BK = 0
l_bp_UP = 2
l_bp_DN = 3
l_bp_REV = 8
l_bp_FWD = 9

' Button pressed
l_index = 0
' Last button pressed
l_lastKey = -1
l_running = True

l_timer = CreateObject( "roTimeSpan" )

while( l_running )

' Get used to GetMessage, Wait is not really very good for anything but simple interface
l_msg = Port.GetMessage()

if type( l_msg ) = "roUniversalControlEvent"

l_index = l_msg.GetInt()
l_lastKey = l_index

' Based upon the key press, call the functions below
if l_index = l_bp_DN or l_index = l_bp_FWD
ScrollDown( Region, l_textHeight, l_slowRate )
else if l_index = l_bp_UP or l_index = l_bp_REV
ScrollUp( Region, l_textHeight, l_slowRate )
else if l_index = l_bp_BK
l_running = False
else if l_index >= 100 ' All key ups are value + 100
l_lastKey = -1
end if

' reset the timer for the delay
l_timer.Mark()
' User is holding down a button and the delay has been exceeded
else if ( l_lastKey >= 0 and l_timer.TotalMilliseconds() >= l_delay )

if l_lastKey = l_bp_DN
ScrollDown( Region, l_textHeight, l_slowRate )
else if l_lastKey = l_bp_FWD
ScrollDown( Region, l_textHeight, l_fastRate )
else if l_lastKey = l_bp_UP
ScrollUp( Region, l_textHeight, l_slowRate )
else if l_lastKey = l_bp_REV
ScrollUp( Region, l_textHeight, l_fastRate )
end if

end if

end while

' Always remove the sprite or you will have a memory leak, even out of scope it is not released
' must be explicity released at all times
if ( Sprite <> Invalid ) then Sprite.Remove()

End Sub

' This employs region offsetting and a very simple ease. You want to move the regions y pos by textheight each time the function is called
Function ScrollDown( roRegion As Object, height As Integer, frames As Integer ) As Void

' Not sure how optimized the byte code is so I simplify references when in loops
l_compositor = m.Compositor
l_screen = m.Screen
l_prevset = 0

for l_i = 1 to frames
' Offset means to move from the current position by the value
l_offset = int( height * l_i / frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset

' Moving forward in Y direction so everything else is 0
roRegion.Offset( 0, l_offdiff, 0, 0 )
l_compositor.DrawAll()
l_screen.SwapBuffers()
end for

End Function

Function ScrollUp( roRegion As Object, height As Integer, frames As Integer ) As Void
l_compositor = m.Compositor
l_screen = m.Screen
l_prevset = 0

for l_i = 1 to frames
l_offset = int( height * l_i / frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset
' same as aobve only moving back so the offset is negative
roRegion.Offset( 0, -l_offdiff, 0, 0 )
l_compositor.DrawAll()
l_screen.SwapBuffers()
end for
End Function



Thanks a lot for helping me with the examples. It helped me a lot. Really appreciate it.
0 Kudos
bcoding
Visitor

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

Hi,
Sorry I was out for a while. So, I have been trying to get have a background image then, on top of it this scrollable items whose background will be transparent so that the main background image is visible. I tried modifying the code by enabling alpha enable in the screen and making the bitmap transparent.
However, when I scroll the items(text) in the scrollable area, the text are all over the place. please find the attached picture as well as the modified code. Any input is appreciated.


Sub Main()

' This is strictly for example - You really should NOT create your globals this way
' There is a much better way which I will not go into now, but to demonstrate how a region works
' this will have to do

' l_color = &h262626FF
img=CreateObject("roBitmap", "pkg:/locale/default/images/backgroundimg.jpg")
img.SetAlphaEnable(true)

m.Screen = CreateObject( "roScreen", True )
m.Compositor = CreateObject( "roCompositor" )
Port = CreateObject( "roMessagePort" )
m.Screen.SetMessagePort( Port )
m.Screen.Clear( 0 )
m.Screen.DrawObject(0,0,img)

'alphaenable is set to true
m.Screen.SetAlphaEnable(true)

'making the screen transparent
m.Compositor.SetDrawTo( m.Screen, &h00000000 )

Registry = CreateObject( "roFontRegistry" )
FontR26 = Registry.GetDefaultFont( 26, False, False )

l_data = [
"1) Get a Macbook pro with 4GB ram and 250gb harddrive",
"2) Get a Macbook pro with 8GB ram and 260gb harddrive",
"3) Get a Macbook pro with 12GB ram and 270gb harddrive",
"4) Get a Macbook pro with 14GB ram and 280gb harddrive",
"5) Get a Macbook pro with 16GB ram and 290gb harddrive",
"6) Get a Macbook pro with 18GB ram and 300gb harddrive",
"7) Get a Macbook pro with 20GB ram and 310gb harddrive",
"8) Get a Macbook pro with 22GB ram and 320gb harddrive",
"9) Get a Macbook pro with 24GB ram and 330gb harddrive",
"10) Get a Macbook pro with 26GB ram and 340gb harddrive",
"11) Get a Macbook pro with 28GB ram and 350gb harddrive",
"12) Get a Macbook pro with 30GB ram and 360gb harddrive"
]

' Keep in mind there are only so many text strings that you can fit into a bitmap buffer, before you exceed its maximum size
' there is a much better way to do all of this, but for now to help you understand regions, i'll keep it simple

' You have 12 items in your data
l_count = l_data.Count()
' You want to show a page size of 5 items
l_pageSize = 5
' The height of one text line for this font is GetOneLineHeight()
l_textHeight = FontR26.GetOneLineHeight()
' The largest width for your data is probably item 12 + some padding, normally you would interate
' the data and save the maximum width for your bitmap buffer. So this is the bitmap buffers width
l_width = FontR26.GetOneLineWidth( l_data[ l_count - 1 ], 1000 ) + 25
' For this examle you have to fit all those strings into a bitmap buffer. If you had 250 + strings you could not
' do this, but there is a better way like i said
' so the total height of your bitmap buffer is l_height, which is the total count * the height of each line
l_height = l_count * l_textHeight
' Now for the region size. It will be the same width as the bitmap but you only want to show pagesize of data
' So the height of the region will bee the textheight * the page size
l_pageHeight = l_textHeight * l_pageSize

' Create the bitmap with l_width and l_height
Bitmap = CreateObject( "roBitmap", { Width: l_width, Height: l_height, AlphaEnable: false } )
'Clear it or leave it transparent

'making it transparent
Bitmap.Clear(&h00000000 )

' Starting at y offset 0 ( you could play with this for margins, but then the region would have to change
' write each line of text, offsetting the y coord by text height
l_y = 0
for each l_str in l_data
Bitmap.DrawText( l_str, 0, l_y, &hCCCCCCFF, FontR26 )
l_y = l_y + l_textHeight
end for

' Create your region the same with, but only the page height
Region = CreateObject( "roRegion", Bitmap, 0, 0, l_width, l_pageHeight )
' Set wrap true
Region.SetWrap( True )
' Create the sprite
Sprite = m.Compositor.NewSprite( 200, 300, Region, 1 )
' Draw everything
m.Compositor.DrawAll()
m.Screen.SwapBuffers()

' Set up your event loop
' The frame rate for the up/down arrow
l_slowRate = 8
' The frame rate/number fwd/reverse arrows - ( this is not a true rate but good enough for lists )
l_fastRate = 2
' Delay between the button presses
l_delay = 200

' These are the constants for the buttons you can use the AA if you wish, probably best to
l_bp_BK = 0
l_bp_UP = 2
l_bp_DN = 3
l_bp_REV = 8
l_bp_FWD = 9

' Button pressed
l_index = 0
' Last button pressed
l_lastKey = -1
l_running = True

l_timer = CreateObject( "roTimeSpan" )

while( l_running )

' Get used to GetMessage, Wait is not really very good for anything but simple interface
l_msg = Port.GetMessage()

if type( l_msg ) = "roUniversalControlEvent"

l_index = l_msg.GetInt()
l_lastKey = l_index

' Based upon the key press, call the functions below
if l_index = l_bp_DN or l_index = l_bp_FWD
ScrollDown( Region, l_textHeight, l_slowRate )
else if l_index = l_bp_UP or l_index = l_bp_REV
ScrollUp( Region, l_textHeight, l_slowRate )
else if l_index = l_bp_BK
l_running = False
else if l_index >= 100 ' All key ups are value + 100
l_lastKey = -1
end if

' reset the timer for the delay
l_timer.Mark()
' User is holding down a button and the delay has been exceeded
else if ( l_lastKey >= 0 and l_timer.TotalMilliseconds() >= l_delay )

if l_lastKey = l_bp_DN
ScrollDown( Region, l_textHeight, l_slowRate )
else if l_lastKey = l_bp_FWD
ScrollDown( Region, l_textHeight, l_fastRate )
else if l_lastKey = l_bp_UP
ScrollUp( Region, l_textHeight, l_slowRate )
else if l_lastKey = l_bp_REV
ScrollUp( Region, l_textHeight, l_fastRate )
end if

end if

end while

' Always remove the sprite or you will have a memory leak, even out of scope it is not released
' must be explicity released at all times
if ( Sprite <> Invalid ) then Sprite.Remove()

End Sub

' This employs region offsetting and a very simple ease. You want to move the regions y pos by textheight each time the function is called
Function ScrollDown( roRegion As Object, height As Integer, frames As Integer ) As Void

' Not sure how optimized the byte code is so I simplify references when in loops
l_compositor = m.Compositor
l_screen = m.Screen
l_prevset = 0

for l_i = 1 to frames
' Offset means to move from the current position by the value
l_offset = int( height * l_i / frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset

' Moving forward in Y direction so everything else is 0
roRegion.Offset( 0, l_offdiff, 0, 0 )
l_compositor.DrawAll()
l_screen.SwapBuffers()
end for

End Function

Function ScrollUp( roRegion As Object, height As Integer, frames As Integer ) As Void
l_compositor = m.Compositor
l_screen = m.Screen
l_prevset = 0

for l_i = 1 to frames
l_offset = int( height * l_i / frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset
' same as aobve only moving back so the offset is negative
roRegion.Offset( 0, -l_offdiff, 0, 0 )
l_compositor.DrawAll()
l_screen.SwapBuffers()
end for
End Function




0 Kudos
Komag
Roku Guru

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

You might try .Clear() on whatever bitmap/region you are drawing your text to
0 Kudos
bcoding
Visitor

Re: scrolling in roScreen, roBitmap, roRegion, roCompositor

"Komag" wrote:
You might try .Clear() on whatever bitmap/region you are drawing your text to


Thank your for the input. I already have the code to clear the bitmap. I am not sure if i am doing it right though.

'making the bitmap transparent
Bitmap.Clear(&h00000000 )
0 Kudos
Need Assistance?
Welcome to the Roku Community! Feel free to search our Community for answers or post your question to get help.

Become a Roku Streaming Expert!

Share your expertise, help fellow streamers, and unlock exclusive rewards as part of the Roku Community. Learn more.