Simple Grid demos three styles
1 - Using Associative Arrays as objects
2- Scrolling using region offsetting
3- Monitoring user button presses to navigate the grid
If you are just interested in the navigation then go to
GridModule:EventLoop Use arrow fw and rw keys to navigate
Quickly put together but adequately demonstrates one method
Sub Main()
l_ds = CreateObject( "roDeviceInfo" ).GetDisplaySize()
l_dw = l_ds.w
l_dh = l_ds.h
' Application Globals ( you can create a global object which is a better solution )
m.BkgColor = &hFFFFFFFF
m.Screen = CreateObject( "roScreen", True, l_dw, l_dh )
m.Port = CreateObject( "roMessagePort" )
m.Screen.SetMessagePort( m.Port )
' Create an instance of the grid module
l_module = NewGridModule()
if l_module.Create()
l_module.EventLoop()
else
print "NewGridModule Failed"
end if
l_module.Release()
End Sub
'***************************** Grid Module Object ***********************************************************************
Function NewGridModule() As Object
return {
' Reference to globals declared in main
' They must be referenced during creation, as the m pointer can only point to the AA's members
' once created. However, Screen: and Port: are members referencing the globals so they can be safely used
' once assigned
Screen: m.Screen
Port: m.Port
' Member Variable - our simplegird and a timer
SimpleGrid: Invalid
Timer: Invalid
' Member Functions
Create: grid_module_create
Initialize: grid_module_initialize
Release: grid_module_release
EventLoop: grid_module_event_loop
}
End Function
' All objects work the same, create, initialize, release
Function grid_module_create() As Boolean
if not m.Initialize()
m.Release()
return False
end if
return True
End Function
Function grid_module_initialize() As Boolean
m.SimpleGrid = NewSimpleGrid()
if not m.SimpleGrid.Create() then return False
m.Timer = CreateObject( "roTimeSpan" )
l_ds = CreateObject( "roDeviceInfo" ).GetDisplaySize()
l_dw = l_ds.w
l_dh = l_ds.h
l_x = l_dw / 2 - m.SimpleGrid.GetWidth() / 2
l_y = l_dh / 2 - m.SimpleGrid.GetHeight() / 2
m.SimpleGrid.MoveTo( l_x, l_y )
return True
End Function
Function grid_module_release() As Void
if m.SimpleGrid <> Invalid
m.SimpleGrid.Release()
m.SimpleGrid = Invalid
end if
m.Timer = Invalid
End Function
Function grid_module_event_loop() As Boolean
if m.SimpleGrid = Invalid then return False
l_kp_BK = 0
l_kp_LT = 4
l_kp_RT = 5
l_kp_RW = 8
l_kp_FF = 9
' Frame rates and scroll pause
l_fastRate = 4
l_normalRate = 16
l_scrollPause = 175
' lastkey saves the last button pressed until the button-up event
l_lastKey = -1
l_index = -1
m.Timer.Mark()
while( True )
' Cannot use wait to do this must be always polling
l_msg = m.Port.GetMessage()
' The user pressed a button
if type( l_msg ) = "roUniversalControlEvent"
l_index = l_msg.GetInt()
l_lastKey = l_index
if l_index = l_kp_LT
m.SimpleGrid.ScrollLeft( l_normalRate )
else if l_index = l_kp_RT
m.SimpleGrid.ScrollRight( l_normalRate )
else if l_index = l_kp_RW
m.SimpleGrid.ScrollLeft( l_fastRate )
else if l_index = l_kp_FF
m.SimpleGrid.ScrollRight( l_fastRate )
else if l_index = l_kp_BK
exit while
' The user released a button, set lastkey to -1
else if l_index >= 100
l_lastKey = -1
end if
' Reset the timer regardless of what comes in
m.Timer.Mark()
' user is holding down button because l_lastkey <> -1
' Once the initial pause elapsed then check last key
else if ( l_lastKey >= 0 and m.Timer.TotalMilliseconds() >= l_scrollPause )
if l_lastKey = l_kp_LT
m.SimpleGrid.ScrollLeft( l_normalRate )
else if l_lastKey = l_kp_RT
m.SimpleGrid.ScrollRight( l_normalRate )
else if l_lastKey = l_kp_RW
m.SimpleGrid.ScrollLeft( l_fastRate )
else if l_lastKey = l_kp_FF
m.SimpleGrid.ScrollRight( l_fastRate )
end if
end if
end while
return True
End Function
'***************************************************************************************************************
'********************* Simple Grid Object **************************************************************************
' This grid uses region offsetting to intrinsically scroll the grid
' It also demontrates how to create simple objects using an AA
Function NewSimpleGrid() As Object
return {
' Reference member to global variable. Must be assigned here, once created the m pointer only points to members
' within this AA. Since it now has a member which references a global you can use it safely
Screen: m.Screen
BkgColor: m.BkgColor
' Variable members
Count: 5
GridX: 0
GridY: 0
Width: 150
Height: 100
Margin: 10
Buffer: Invalid
Region: Invalid
' Functions which act upon the variable members. Any function assigned to a function pointer member
' can access any other member ( variables and functions ) via the m pointer.
Create: simple_grid_create
Initialize: simple_grid_initialize
Release: simple_grid_release
MoveTo: simple_grid_move_to
GetWidth: simple_grid_get_width
GetHeight: simple_grid_get_height
Draw: simple_grid_draw
ScrollLeft: simple_grid_scroll_left
ScrollRight: simple_grid_scroll_right
}
End Function
' Once the function is assigned to a function pointer of the AA then all members can be accessed with the m ( this ) pointer
Function simple_grid_create() As Boolean
if not m.Initialize()
m.Release()
return False
end if
return True
End Function
Function simple_grid_initialize() As Boolean
' Insure everything is released. This is important if you use sprites.
' They must be explicitly removed
m.Release()
' Calculate the buffer size and create the buffer
l_w = m.Count * ( m.Width + m.Margin )
m.Buffer = CreateObject( "roBitmap", { width: l_w, height: m.Height, AlphaEnable: True } )
if m.Buffer = Invalid then return False
m.Buffer.Clear( &hC0C0C0FF )
' Create the region same size as the buffer, but minus the end margin . SetWrap to true
m.Region = CreateObject( "roRegion", m.Buffer, 0, 0, l_w - m.Margin, m.Height )
if m.Region = Invalid then return False
m.Region.SetWrap( True )
' Create the font and get it's static one-line-height / 2 for centering
l_font = CreateObject( "roFontRegistry" ).GetDefaultFont( 50, True, False )
l_strh = l_font.GetOneLineHeight() / 2
' Grid poster size and offsets ( all precalulated for optimization )
l_offset = m.Width + m.Margin
l_cw = m.Width / 2
l_ch = m.Height / 2
l_x = 0
l_y = 0
' Draw in the faux grid displaying it's index centered
for l_i = 1 to m.Count
m.Buffer.DrawRect( l_x, l_y, m.Width, m.Height, &h8D798BFF )
l_str = l_i.ToStr()
l_strw = l_font.GetOneLineWidth( l_str, m.Width )
m.Buffer.DrawText( l_str, l_x + ( l_cw - l_strw / 2 ), l_y + ( l_ch - l_strh ), &h606060FF, l_font )
l_x = l_x + l_offset
end for
m.Buffer.Finish()
return True
End Function
Function simple_grid_release() As Void
m.Buffer = Invalid
m.Region = Invalid
End Function
Function simple_grid_move_to( a_x As Integer, a_y As Integer, a_isDraw = True As Boolean ) As Boolean
if m.Buffer = Invalid then return False
m.GridX = a_x
m.GridY = a_y
if a_isDraw then m.Draw()
return True
End Function
Function simple_grid_draw() As Boolean
if m.Region = Invalid then return False
m.Screen.Clear( m.BkgColor )
m.Screen.DrawObject( m.GridX, m.GridY, m.Region )
m.Screen.SwapBuffers()
return True
End Function
Function simple_grid_get_width() As Integer
if m.Region = Invalid then return -1
return m.Region.GetWidth()
End Function
Function simple_grid_get_height() As Integer
if m.Region = Invalid then return -1
return m.Region.GetHeight()
End Function
Function simple_grid_scroll_left( a_frames = 16 As Integer ) As Boolean
if m.Region = Invalid then return False
l_offset = 0
l_prevset = 0
l_offdiff = 0
l_columnWidth = m.Width + m.Margin
for l_i = 1 to a_frames
l_offset = int( l_columnWidth * l_i / a_frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset
m.Region.Offset( -l_offdiff, 0, 0, 0 )
m.Region.Finish()
m.Draw()
end for
return True
End Function
Function simple_grid_scroll_right( a_frames = 16 As Integer ) As Boolean
if m.Region = Invalid then return False
l_offset = 0
l_prevset = 0
l_offdiff = 0
l_columnWidth = m.Width + m.Margin
for l_i = 1 to a_frames
l_offset = int( l_columnWidth * l_i / a_frames )
l_offdiff = l_offset - l_prevset
l_prevset = l_offset
m.Region.Offset( l_offdiff, 0, 0, 0 )
m.Region.Finish()
m.Draw()
end for
return True
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 )