This is an extension to my recent posts about iOS Style WidgetDemo improvements. To get the full demo working get the Improved WidgetDemo Sample from the code exchange:
http://developer.anscamobile.com/code/improved-widgetdemo-sample
This builds on the recent iOS Style Search by adding pull to refresh function as seen in apps like the Twitter client. It also adds some debugging over the previous posts.
You will need to download this image and save it in the WidgetDemo directory:
The code below shows how to add pull to refresh functionality - simply add the ‘pulltorefresh’ value to the header of your content table and give it a function to call. The function will need to take the parent item value and a function to call with the content table once the data has been refreshed. The callback function can be called immediately, but is there in case you need to perform a network request which may not respond immediately.
To add the demo functionality, replace the WidgetDemo ‘menu.lua’ and ‘menustructure.lua’ code with the files below…
But first, a warning. There are three known bugs:
- Images will not be correctly displayed because I have not used newImageRect.
- Searches cannot have a pull to refresh because the list variable appears to be the parent tableView object in the menu.lua at line 556. The pull operation has no way to know that the scroll position has gone beyond the threshold.
- The scrollbar size is incorrect in certain situations, such as search results. You are best served by disabling the scrollbar in those situations.
Please be assured that I am working on these and continuing to improve the functionality. Once this is all working satisfactorily I will begin work on making it iPad compatible and implementing pop-over menus, etc.
menustructure.lua:
[lua]-- menu structure
require(“net”)
rootmenu, byproduct, byjob, byregion, companieswith = nil, nil, nil, nil, nil, nil
byproduct = {
title=“By Product”,
{ id="", text=“Cutlery”, iscategory=false, dataitem=nil },
{ id="", text=“Homewares”, iscategory=false, dataitem=nil },
{ id="", text=“Frozen”, iscategory=false, dataitem=nil },
{ id="", text=“Refreshments”, iscategory=false, dataitem=nil },
}
byjob = {
title=“By Job”,
{ id="", text=“Director”, iscategory=false, dataitem=nil },
{ id="", text=“Sales”, iscategory=false, dataitem=nil },
{ id="", text=“Purchasing”, iscategory=false, dataitem=nil },
}
byafrica = {
title=“Africa”,
{ id="", text=“Mozambique”, iscategory=false, dataitem=nil },
{ id="", text=“Zaire”, iscategory=false, dataitem=nil },
{ id="", text=“Ethiopia”, iscategory=false, dataitem=nil },
}
byregion = {
title=“By Region”,
{ id="", text=“Africa”, iscategory=false, dataitem=byafrica },
{ id="", text=“Asia”, iscategory=false, dataitem=nil },
{ id="", text=“Oceana”, iscategory=false, dataitem=nil },
}
function GetTestSubMenu()
print(‘GetTestSubMenu()’)
local tbl = { title=“Test Items”, defaultscroll=1, hasindex=true, }
for i=65, 90 do
tbl[#tbl+1] = { id="", text=string.char(i), iscategory=false, callback=nil, dataitem=nil, index=string.char(i), }
end
return tbl
end
function GetBbcNewsRss( dataitem, func )
– builds the content for the submenu items
function GetData( name, xml )
– sub menu header info
local tbl = { title=“BBC News”, defaultscroll=1, hasscrollbar=true, hasindex=false, canscrolltotop=true, }
– build submenu items
for i=1, #xml.channel.item do
local item = xml.channel.item[i]
tbl[#tbl+1] = { id="", text=item.title, iscategory=false, callback=nil, dataitem=nil, index=nil, }
end
– return the submenu content
func( tbl )
end
– go read the rss and it will execute the GetData function callback when the network request responds
readBbcNews( “bbcnewsrss”, GetData )
end
function PerformSearch( parentitem, term, callback )
local list = {}
for i=1, math.random(1, 7) do
list[#list+1] = { id="", text=term…’ '…math.random(100,999), iscategory=false, dataitem=nil }
end
print(‘Searching…’)
callback( list )
end
function RefreshRootMenu( parentitem, callback )
print(‘Refreshing…’)
callback( rootmenu )
end
rootmenu = {
title=“Products”, defaultscroll=2, hasindex=true, hasscrollbar=true, canscrolltotop=true,
pulltorefresh=RefreshRootMenu,
{ id="", text=“Search Bar”, issearch=true, dataitem=PerformSearch, },
{ id="", text=“Find”, iscategory=true, dataitem=nil, index=“F” },
{ id="", text=“By Product”, iscategory=false, dataitem=byproduct, candelete=true },
{ id="", text=“By Job”, iscategory=false, dataitem=byjobfunction, candelete=true },
{ id="", text=“By Region”, iscategory=false, dataitem=byregion, candelete=true },
{ id="", text=“Search”, iscategory=true, dataitem=nil, index=“S” },
{ id="", text=“Companies With…”, iscategory=false, dataitem=function(d,f) f(GetTestSubMenu()) end },
{ id="", text=“Info”, iscategory=true, dataitem=nil, index=“I” },
{ id="", text=“About…”, iscategory=false, dataitem=nil },
{ id="", text=“Magazines”, iscategory=true, dataitem=nil, index=“M” },
{ id="", text=“The Times”, iscategory=false, dataitem=nil },
{ id="", text=“The Independent”, iscategory=false, dataitem=nil },
{ id="", text=“The Sun”, iscategory=false, dataitem=nil },
{ id="", text=“News Feeds”, iscategory=true, dataitem=nil, index=“N” },
{ id="", text=“BBC News”, iscategory=false, dataitem=GetBbcNewsRss },
}[/lua]
menu.lua:
[lua]-- menu
function newMenu( parent, rootdata, x, y, width, height )
– renders a title bar for a submenu
local function newTopBar( parent, title, scrollToBack, scrollToTop )
– local this bar
local group = display.newGroup()
group.widgets = {}
parent:insert( group )
– clean out the widgets
function group:clean()
for i=#group.widgets, 1, -1 do
group.widgets[i]:removeSelf()
group.widgets[i] = nil
end
group:removeSelf()
end
– status bar touch pad
if (scrollToTop) then
local touchbar = display.newRect( group, 0, 0, display.contentWidth, display.statusBarHeight )
function touchbar:touch( event )
if (event.phase == “began” and event.y <= display.statusBarHeight) then
scrollToTop()
end
return true
end
touchbar:addEventListener( “touch”, touchbar )
end
– create a gradient for the top-half of the toolbar
local toolbarGradient = graphics.newGradient( {168, 181, 198, 255 }, {139, 157, 180, 255}, “down” )
– create toolbar to go at the top of the screen
local titleBar = widget.newTabBar{
top = display.statusBarHeight,
topGradient = toolbarGradient,
bottomFill = { 117, 139, 168, 255 },
height = 44, width = 320
}
group:insert( titleBar.view )
group.widgets[#group.widgets+1] = titleBar
– create embossed text to go above toolbar
local titleText = display.newEmbossedText( title, 0, 0, native.systemFontBold, 20, { 255 } )
titleText:setReferencePoint( display.CenterReferencePoint )
titleText.x = display.contentWidth * 0.5 – (display.contentWidth * 0.5) – + x
titleText.y = 44 – + (titleBar.y + titleBar.height * 0.5)
group:insert( titleText )
group.widgets[#group.widgets+1] = titleText
– onRelease listener for back button
local function onBackRelease( event )
if (scrollToBack) then
scrollToBack( group.clean )
end
return true
end
– create ‘back’ button to be placed on toolbar
if (parent.parent.numChildren > 1) then
local backButton = widget.newButton{
label = “Back”,
left = 5, top = 28,
style = “backSmall”,
onRelease = onBackRelease
}
group:insert( backButton.view )
group.widgets[#group.widgets+1] = backButton
end
end – newTopBar
– renders a search input box for a search panel
local function newSearchBox( parent, cancel, scrollToTop, searchCallback )
– local this bar
local group = display.newGroup()
group.widgets = {}
parent:insert( group )
– declare the input text box
local inputbox = nil
– clean out the widgets
function group:clean()
for i=#group.widgets, 1, -1 do
group.widgets[i]:removeSelf()
group.widgets[i] = nil
end
group:removeSelf()
end
– status bar touch pad
if (scrollToTop) then
local touchbar = display.newRect( group, 0, 0, display.contentWidth, display.statusBarHeight )
function touchbar:touch( event )
if (event.phase == “began” and event.y <= display.statusBarHeight) then
scrollToTop()
end
return true
end
touchbar:addEventListener( “touch”, touchbar )
end
– search box image
local searchimg = display.newImage( group, “searchcancel.png” )
searchimg.xScale, searchimg.yScale = .5, .5
searchimg.x, searchimg.y = display.contentCenterX, searchimg.height/2-2
– onRelease listener for back button
local function onCancelRelease( event )
if (cancel) then
cancel( group.clean )
end
return true
end
– create ‘cancel’ button to be placed on toolbar
if (parent.parent.numChildren > 1) then
local cancelButton = widget.newButton{
label = “”,
left = 260, top = 27,
–style = “backSmall”,
default=“defaultcancel.png”,
over=“overcancel.png”,
width=110/2, height=58/2,
onRelease = onCancelRelease
}
group:insert( cancelButton.view )
group.widgets[#group.widgets+1] = cancelButton
end
– input box listener function
local function textListener( event )
if (event.phase == “editing”) then
searchCallback( event.text )
end
return true
end
– create native text input box
inputbox = native.newTextBox( 30, 30, 200, 25, textListener )
group.widgets[#group.widgets+1] = inputbox
inputbox.isEditable = true
inputbox.align = “left”
inputbox.size = 16
– return the text input box so pull to refresh can work
return inputbox
end – newSearchBox
– creates the submenu or search panel
local function newSubMenu( contentdata, issearch )
– validate
issearch = issearch or false
– container for all submenu components
local submenugroup = display.newGroup()
parent:insert( submenugroup )
– timers etc
local list = nil – table view containing the items in the menu (the important widget)
local enterFrame = nil – will be called with the regular enterFrame event to call other functions which check and refresh visual elements
local scrollCheck = nil – called by enterframe to check the scroll position of the tableview content
local adjustScrollBar = nil – called by enterframe to check the position of the tableview content and update the scrollbar size and position
local pullToRefresh = nil – function called to refresh the content
– position the submenugroup
if (parent.numChildren > 1 and issearch == true) then
submenugroup.x, submenugroup.y = parent[parent.numChildren-1].x, parent[parent.numChildren-1].y
else
submenugroup.x, submenugroup.y = (parent.numChildren-1) * display.contentWidth, 0
end
– create tableView widget
list = widget.newTableView{
top = display.statusBarHeight + 44,
width = display.contentWidth,
height = 366,
maskFile = “assets/mask-320x366.png”
}
– keeps track of the number of rows
list.totalRowCount = 0
– keeps track of the total height of the widget content
list.totalheight = 0
– remove this if using later than build 2012.826
local function deleteAllRows()
while (list.totalRowCount > 0) do
list:deleteRow( 1 )
list.totalRowCount = list.totalRowCount - 1
end
end
– list of scroll index items
local function populateTableView( menudata, isnewdata )
local scroll = {}
– onEvent listener for the tableView
local function onRowTouch( event )
local row = event.target
local rowGroup = event.view
if (not row.isCategory) then
if (event.phase == “swipeLeft” and menudata[event.index].candelete == true) then
transition.to( rowGroup.del, {time=rowGroup.del.transtime,maskX=-(rowGroup.del.width/2+1),onComplete=rowGroup.del.setActive} )
elseif (event.phase == “swipeRight” and menudata[event.index].candelete == true) then
transition.to( rowGroup.del, {time=rowGroup.del.transtime,maskX=rowGroup.del.width/2+1,onComplete=rowGroup.del.setInactive} )
elseif (event.phase == “release” and not row.isCategory) then
row.reRender = true
print( “You touched row #” … event.index…" - ‘"…menudata[event.index].text…"’" )
– do population of submenu
local menuitem = menudata[event.index]
if (menuitem.dataitem ~= nil) then
– get the submenu’s data and add the new sub menu
– this will shift the parent group left to show a deeper submenu
local dataitem = menuitem.dataitem
– populate the submenu (dataitem passed in is the submenu table of rows)
function callback( dataitem )
– create the submenu or search item tableView
newSubMenu( dataitem, menuitem.issearch )
– use animation to show the next tableView
if (menuitem.issearch == true) then
– lay the search panel over the top of the current tableView menu (should be improved later to look like the smooth contacts list animation)
– ie: right now, do nothing (the search will just snap into place over the current tableView widget)
else
– slide the current tableView widget left to show the submenu animating into position
transition.to( parent, {time=300, x=parent.x-display.contentWidth} )
transition.to( topGroup, {time=300, x=parent.x-display.contentWidth} )
end
end
– if dataitem is a function, call it to get the data to put in the submenu, otherwise just populate the submenu
– if the dataitem is a function it must callback the passed in function to populate the submenu, this allows for network traffic delays
– the callback function does not need to be called, if the dataitem function wants to switch to another tab, for example
if (type(dataitem) == “function”) then
– if the item is a search, populate it with the initial search term
if (menuitem.issearch == true) then
– call the client function as an search
– callback( dataitem( {phase=“began”, term=""} ) )
callback( menuitem )
else
– call the client function with the parent item to get the submenu items…
– pullToRefresh = function()
dataitem( menuitem, callback )
– end
– pullToRefresh()
end
else
– populate directly because the submenu items are known here
callback( dataitem )
end
end
end
end
return true
end – onRowTouch
– onRender listener for the tableView
local function onRowRender( event )
local row = event.target
local rowGroup = event.view
local textFunction = display.newRetinaText
if row.isCategory then textFunction = display.newEmbossedText; end
– add pulltorefresh
if (event.index == 1 and type(pullToRefresh) == “function”) then
print(‘Add Pull To Refresh’)
local refreshgroup = display.newGroup()
list.refreshgroup = refreshgroup
rowGroup:insert( refreshgroup )
refreshgroup.x, refreshgroup.y = 0, -64
local rect = display.newRect( refreshgroup, 0, 0, display.contentWidth, 64 )
–rect:setFillColor(255,0,0)
local refreshimg = display.newImage( refreshgroup, “refresh.png” )
refreshimg.x, refreshimg.y = 50, 25
refreshimg.xScale, refreshimg.yScale = .5, .5
local refreshtext = display.newText( refreshgroup, “Pull to refresh”, 100, 15, native.systemFont, 16 )
refreshtext:setTextColor( 180, 180, 180 )
local releasetext = display.newText( refreshgroup, “Release to refresh”, 100, 15, native.systemFont, 16 )
releasetext:setTextColor( 180, 180, 180 )
releasetext.isVisible = false
rect.willRefresh = false
list.refreshgroup.indicateRefresh = function()
if (not rect.willRefresh) then
rect.willRefresh = true
–rect:setFillColor(0,255,0)
transition.to( refreshimg, { time=200, rotation=-180 } )
refreshtext.isVisible = false
releasetext.isVisible = true
end
end
list.refreshgroup.isRefreshRequested = function()
return rect.willRefresh
end
list.refreshgroup.resetRefresh = function()
rect:setFillColor(255,0,0)
rect.willRefresh = false
refreshimg.rotation = 0
refreshtext.isVisible = true
releasetext.isVisible = false
end
end
if (event.index == 1 and menudata[event.index].issearch == true) then
– is a search bar
row.searchimg = display.newImage( rowGroup, “searchwith.png” )
row.searchimg.xScale, row.searchimg.yScale = .5, .5
row.height = row.searchimg.height/2
row.searchimg.x, row.searchimg.y = display.contentCenterX, row.searchimg.height/4
else
– is regular bar
row.title = textFunction( menudata[event.index].text, 12, 0, native.systemFontBold, 16 )
row.title:setReferencePoint( display.CenterLeftReferencePoint )
row.title.y = row.height * 0.5
if (not row.isCategory) then
row.title.x = 15
row.title:setTextColor( 0 )
local del = nil – the image sitting over the top of the button widget
local onButtonEvent = function (event )
print(‘del.isactive’,del.isactive)
if (not del.isactive) then
return false
end
if (event.phase == “release”) then
print( “You pressed and released a button!” )
end
return true
end
local myButton = widget.newButton{
id = “btn001”,
left = 225,
top = 9,
label = “”,
width = 90, height = 46,
cornerRadius = 8,
onEvent = onButtonEvent,
default=“deleteback.png”,
over=“deleteback.png”,
}
rowGroup:insert(myButton.view)
del = display.newImage(rowGroup,“deletebtn.png”)
del.x, del.y = 270, 32
del.xScale, del.yScale = .7, .7
del.isactive = false
rowGroup.del = del
local mask = graphics.newMask(“slidemask.png”)
del:setMask( mask )
del.maskScaleX, del.maskScaleY = -1, 1
del.maskX = del.width/2+1
del.maskY = 100
del.transtime = 300
function del:setActive()
print(‘active’,deletetap)
del.isactive = true
end
function del:setInactive()
print(‘inactive’)
del.isactive = false
end
end
– must insert everything into event.view:
rowGroup:insert( row.title )
end
end – onRowRender
– assign data to the rows
function createContent()
– defaults
local defaultRowColor = { 174, 183, 190, 255 }
local defaultLineColor = {0,0,0,255}
– Add rows
for i=1, #menudata do
local rowHeight, rowColor, lineColor, isCategory = 64
local menuitem = menudata[i]
if (menuitem.iscategory) then
isCategory = true; rowHeight = 24; rowColor=defaultRowColor; lineColor=defaultLineColor
end
– accumulate the total height of the content rows
list.totalheight = list.totalheight + rowHeight
list.totalRowCount = list.totalRowCount + 1
– insert the row into the tableView widget
list:insertRow{
onEvent=onRowTouch,
onRender=onRowRender,
height=rowHeight,
isCategory=isCategory,
rowColor=rowColor,
lineColor=lineColor,
issearch=true
}
– index can be a string or a function to return a string - string can be one char
if (menuitem.index ~= nil) then
local scrollitem = menuitem.index
if (type(scrollitem) == “function”) then
scrollitem = scrollitem( menuitem )
end
scroll[#scroll+1] = { index=i, char=scrollitem }
end
end
function addAlphaStrip(parent, callback)
local strip = display.newGroup()
parent:insert( strip )
strip.x, strip.y = display.contentWidth - 15, display.statusBarHeight+50
local alpha = display.newRoundedRect( strip, -10, 0, 20, display.contentHeight - 128, 10 )
alpha:setFillColor( 224, 224, 224 )
alpha.isVisible = false
alpha.isHitTestable = true
local size = 13.3
for i=65, 90 do
local index = i-64
local function touch(event)
alpha.isVisible = (event.phase == “began” or event.phase == “moved”)
for s=1, #scroll do
if (scroll[s].char == string.char(i)) then
list:scrollToIndex( scroll[s].index, 300 )
break
end
end
return true
end
local rect = display.newRect( strip, 0, 0, 40, size )
rect.x, rect.y = 0, 10+(i-65)*size
rect.alpha = 0
rect.isHitTestable = true
local letter = display.newText(strip, string.char(i), 0, 0, native.systemFont, 10)
letter:setTextColor(106, 115, 125)
letter.x, letter.y = 0.5, 10+(i-65)*size
rect:addEventListener( “touch”, touch )
end
end
if (isnewdata and menudata.hasindex) then addAlphaStrip( submenugroup ) end
– auto scroll to initial position
if (menudata.defaultscroll) then list:scrollToIndex( menudata.defaultscroll, 0 ) end
local currentpos = list:getScrollPosition()
list.maxscrolltop = 366-list.totalheight+24
–[[scroll bar handling]]–
local function addScrollBar()
local scrollbar = display.newRoundedRect( submenugroup, display.contentWidth - 5, display.statusBarHeight+50, 2.5, display.contentHeight - 128, 2.5 )
scrollbar:setFillColor( 255,0,0 )
scrollbar.lastchangetime = system.getTimer()
adjustScrollBar = function( event )
if (list.totalheight < 366) then
scrollbar.alpha = 0
else
local starty = scrollbar.y
– check scroll position and adjust
local scrollpos = list:getScrollPosition()
if (scrollpos <= 0 and scrollpos >= list.maxscrolltop) then
local heightperc = (346 / list.totalheight) * 100
local scrollperc = (math.abs(scrollpos / math.abs(list.maxscrolltop))) * 100
scrollbar.height = 346/100*heightperc
scrollbar.y = 10 + display.statusBarHeight + 44 + (scrollbar.height/2)+((346-scrollbar.height)/100*scrollperc)
elseif (scrollpos > 0) then
local scrollperc = (scrollpos / 366) * 100
local heightperc = (346 / list.totalheight) * 100
heightperc = heightperc - scrollperc
scrollbar.height = 346/100*heightperc
scrollbar.y = 10 + display.statusBarHeight + 44 + (scrollbar.height/2)
elseif (scrollpos < list.maxscrolltop) then
local scrollperc = ((list.maxscrolltop - scrollpos) / 366) * 100
local heightperc = (346 / list.totalheight) * 100
heightperc = heightperc - scrollperc
scrollbar.height = 346/100*heightperc
scrollbar.y = 10 + display.statusBarHeight + 44 + (346 - (scrollbar.height/2))
end
– fade out the scrollbar
if (starty ~= scrollbar.y) then
scrollbar.lastchangetime = system.getTimer()
end
if (system.getTimer() - scrollbar.lastchangetime > 500) then
if (scrollbar.fadeintrans ~= nil) then
transition.cancel( scrollbar.fadeintrans )
scrollbar.fadeintrans = nil
end
if (scrollbar.fadeouttrans == nil) then
scrollbar.fadeouttrans = transition.to( scrollbar, { time=250, alpha=0 } )
end
else
if (scrollbar.fadeouttrans ~= nil) then
transition.cancel( scrollbar.fadeouttrans )
scrollbar.fadeouttrans = nil
end
if (scrollbar.fadeintrans == nil) then
scrollbar.fadeintrans = transition.to( scrollbar, { time=150, alpha=1 } )
end
end
end
end – adjustScrollBar
–Runtime:addEventListener( “enterFrame”, adjustScrollBar ) – called by the more global enterFrame(event) function
end – addScrollBar
if (isnewdata and menudata.hasscrollbar) then addScrollBar() end
end – createContent
– clear current tableView content
deleteAllRows()
list.totalRowCount = 0
list.totalheight = 0
– create the content
createContent()
end – populateTableView
– scroll to top function
if (contentdata.canscrolltotop) then
submenugroup.scrollToTop = function()
if (contentdata.defaultscroll) then
list:scrollToIndex( contentdata.defaultscroll, 400 )
else
list:scrollToIndex( 1, 400 )
end
end
end
– pull to refresh check
if (contentdata.pulltorefresh) then
scrollCheck = function()
local currentpos = list:getScrollPosition()
if (pullToRefresh) then
–print(‘currentpos’,currentpos)
if (currentpos >= 64) then
list.refreshgroup:indicateRefresh()
elseif (currentpos >= -1 and currentpos <= 1 and list.refreshgroup:isRefreshRequested()) then
list.refreshgroup:resetRefresh()
pullToRefresh()
end
end
end
end
– if this is a search panel provide the search bar at the top, if not provide a title bar
if (issearch == true) then
– is a search panel
– stops the search and removes the search panel
local function cancelSearch( onComplete )
Runtime:removeEventListener( “enterFrame”, enterFrame )
onComplete()
list:removeSelf()
list = nil
submenugroup:removeSelf()
end
– gets the search results from the search callback and populates the tableview
local function searchCallback( searchterm )
– called by the menu’s search function to populate the tableView
function doPopulate( list )
populateTableView( list, false )
end
– call the menu’s search function to get the search results table
contentdata.dataitem( contentdata, tostring(searchterm), doPopulate )
end
– create search bar
local textbox = newSearchBox( submenugroup, cancelSearch, submenugroup.scrollToTop, searchCallback )
– called by the pull to refresh function
pullToRefresh = function()
– get the current search text and call the data retrieval function
searchCallback( textbox.text )
end
else
– is a regular sub/menu
– scroll to origin - this is actually the back button effect
local function scrollToBack( onComplete )
function clean()
Runtime:removeEventListener( “enterFrame”, enterFrame )
onComplete()
list:removeSelf()
list = nil
submenugroup:removeSelf()
end
transition.to( parent, {time=300, x=parent.x+display.contentWidth, onComplete=clean} )
end
– create title bar
newTopBar( submenugroup, contentdata.title, scrollToBack, submenugroup.scrollToTop )
– if there is a refresh function provided the callback
if (type(contentdata.pulltorefresh) == “function”) then
pullToRefresh = function()
– called by the menu’s search function to populate the tableView
function doPopulate( list )
populateTableView( list, false )
end
– call the menu’s refresh function to get the content table
contentdata.pulltorefresh( contentdata, doPopulate )
end
end
end – (issearch == true)
– insert widget into demoGroup
submenugroup:insert( list.view )
– populate the tableView with initial data
populateTableView( contentdata, true )
– call the refresh functions
enterFrame = function( event )
if (scrollCheck) then scrollCheck() end
if (adjustScrollBar) then adjustScrollBar() end
end
– start the enterframe listener to call refresh functions
Runtime:addEventListener( “enterFrame”, enterFrame )
end – newSubMenu
newSubMenu( rootdata, rootdata.issearch )
end[/lua] [import]uid: 8271 topic_id: 27589 reply_id: 327589[/import]
