Scrolling a datagrid form - multiplatform

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
William Jamieson
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 212
Joined: Fri Feb 01, 2013 1:31 am
Contact:

Scrolling a datagrid form - multiplatform

Post by William Jamieson » Fri Apr 19, 2013 11:41 pm

Hello, I have been looking around the forums and the tutorials and eventhough there are some sources out there on how to scroll a datagrid, all of them either work in only certain circumstances or do not run very well. So I would like to ask you if you have found an effective way to scroll a datagrid that runs smooth and is functional on all platforms (meaning not only for iOS). If so please post anything you got even if it is not quite complete because there has to be a better solution out there.

here is what i got so far:

Code: Select all

local xStart,yStart,hScrollStart,vScrollStart,tLastLoc,allowDrag,scrollChunks

on mouseDown
  --###cancel item 1 of line lineOffset("runEase",pendingMessages()) of pendingMessages()
  cancelEaseMsgs
  put "" into tLastLoc
  put "" into scrollChunks
  put mouseH() into xStart
  put mouseV() into yStart
  put hScroll of me into hScrollStart
  put vScroll of me into vScrollStart
  put true into allowDrag
end mouseDown

on mouseMove X,Y
   if not allowDrag then exit mouseMove
   lock screen
   
   --### set hScroll of me to hScrollStart + (xStart - X)
   set vScroll of me to vScrollStart + (yStart - Y)
   unlock screen
   if "storeScrollChunks" is not in pendingMessages() then send "storeScrollChunks X,Y" to me in 100 millisecs
   put X,Y into tLastLoc
end mouseMove

on storeScrollChunks pX,pY
  put item 1 of tLastLoc - pX,item 2 of tLastLoc - pY into scrollChunks
end storeScrollChunks

on mouseUp
  prepareScroll
end mouseUp

on mouseRelease
  prepareScroll
end mouseRelease

command prepareScroll
  put false into allowDrag
  put 4 into xMultiplier
  put 1700 into xDuration
  if abs(item 1 of scrollChunks) < 100 then
    put 3 into xMultiplier
    put 1000 into xDuration
  end if
  put 4 into yMultiplier
  put 1700 into yDuration
  if abs(item 2 of scrollChunks) < 100 then
    put 3 into yMultiplier
    put 1000 into yDuration
  end if
  put max(xDuration,yDuration) into pDuration
  --### put hScroll of me - (xMultiplier * item 1 of scrollChunks),vScroll of me - (xMultiplier * item 2 of scrollChunks) into pDestScroll
  put 0,vScroll of me - (xMultiplier * item 2 of scrollChunks) into pDestScroll
  easeScroll long ID of me,pDestScroll,pDuration
end prepareScroll


local tStartScroll,tDistance,tStartTime,tEaseID,bounceBackBusy

command easeScroll pObj,pDestScroll,pDuration
  # CANCEL ANY EXISTING EASE MOVEMENT
  --### cancel item 1 of line lineOffset("runEase",pendingMessages()) of pendingMessages()
  cancelEaseMsgs
  put empty into tEaseID
  put false into bounceBackBusy
  # BEGIN EASE ROUTINE
  runEase pObj,pDestScroll,pDuration
end easeScroll

on cancelEaseMsgs --###jg
  repeat for each line l in the pendingmessages
    if l contains "runease" then cancel item 1 of l
  end repeat
end cancelEaseMsgs

-- NOTE: HOSTOBJ PARAMETER IS ONLY USED LOCALLY
-- AND SHOULD BE EMPTY WHEN ROUTINE IS FIRST RUN
-- TO INITIALIZE EASE MOVEMENT

command runEase pObj,pDestScroll,pDuration,pHostObj
  lock screen
  # INIT VARIABLES
  if pHostObj = "" then
    put item 1 of line 1 of the executionContexts into pHostObj
    put hScroll of pObj,vScroll of pObj into tStartScroll
    put (item 1 of pDestScroll - item 1 of tStartScroll),(item 2 of pDestScroll - item 2 of tStartScroll) into tDistance
    put the millisecs into tStartTime
  end if
  
  # TRACK TIME
  put (the millisecs - tStartTime)/pDuration into phi
  put min(phi,1) into phi
  put (2*phi - phi^2) into tEase # EASE OUT
  
  # MOVE OBJECT
  put 0 into newHScroll  --### put item 1 of tStartScroll + round(tEase * item 1 of tDistance) into newHScroll
  put item 2 of tStartScroll + round(tEase * item 2 of tDistance) into newVScroll
  set hScroll of pObj to newHScroll
  set vScroll of pObj to newVScroll
  unlock screen
  
  # REVERSE DIRECTION (BOUNCEBACK) IF END OF SCROLL IS REACHED
  put hScroll of pObj,vScroll of pObj into currScroll
  put 0 into hBounce
  put 0 into vBounce
  if item 1 of currScroll < minHScroll(pObj) then put 1 into hBounce
  if item 1 of currScroll > maxHScroll(pObj) then put -1 into hBounce
  if item 2 of currScroll < minVScroll(pObj) then put 1 into vBounce
  if item 2 of currScroll > maxVScroll(pObj) then put -1 into vBounce
  if (hBounce <> 0 or vBounce <> 0) and not bounceBackBusy then
    send "bounceBack pObj,hBounce,vBounce" to me in 10 millisecs
    exit runEase
  end if
  
  # EXIT WHEN OBJECT REACHES ITS DESTINATION
  if ((newHScroll,newVScroll) = pDestScroll) or (phi >= 1) then
    put empty into tEaseID
    put false into bounceBackBusy
    --    try
    --      send "easeScrollDone pObj" to pHostObj
    --    end try
    exit runEase
  end if
  
  # LOOP SCRIPT
  send "runEase pObj,pDestScroll,pDuration,pHostObj" to me in 10 milliseconds
  put the result into tEaseID
end runEase


command bounceBack pObj,hBounce,vBounce
  exit bounceBack  --###jg: no bounce on android
  
  put true into bounceBackBusy
  put hScroll of pObj,vScroll of pObj into pDestScroll
  if hBounce = 1 then put minHScroll(pObj) into item 1 of pDestScroll
  if hBounce = -1 then put maxHScroll(pObj) into item 1 of pDestScroll
  if vBounce = 1 then put minVScroll(pObj) into item 2 of pDestScroll
  if vBounce = -1 then put maxVScroll(pObj) into item 2 of pDestScroll
  put 500 into pDuration
  runEase pObj,pDestScroll,pDuration
end bounceBack

function minHScroll pObj
  return item 1 of marginValues(pObj)
end minHScroll

function maxHScroll pObj
  if formattedWidth of pObj <= width of pObj then return width of pObj
  return (formattedWidth of pObj - item 3 of marginValues(pObj) - width of pObj)
end maxHScroll

function minVScroll pObj
  return item 2 of marginValues(pObj)
end minVScroll

function maxVScroll pObj
  if formattedHeight of pObj <= height of pObj then return height of pObj
  return (formattedHeight of pObj - item 4 of marginValues(pObj) - height of pObj)
end maxVScroll

function marginValues pObj
  if number of items of margins of pObj > 1 then return margins of pObj
  repeat 4
    put margins of pObj & "," after tValues
  end repeat
  delete last char of tValues
  return tValues
end marginValues
That is placed into an invisible button on the card which is also placed into a group with the data grid.

Code: Select all

local sScrollerId

on setupScroller
  if the environment is not "mobile" then exit setupScroller
  
  -- Turn on 'out-of-bounds' scrolling for our image group
  set the unboundedHScroll of group "Contact List" to false
  set the unboundedVScroll of group "Contact List" to true
  
  -- Create the scroller and store its id
  iphoneControlCreate "scroller"
  put the result into sScrollerId
  
  -- The 'rect' is the region of the card it should cover
  iphoneControlSet sScrollerId, "rect", the rect of group "Contact List"
  -- The 'contentRect' is the region the scroller scrolls over
  iphoneControlSet sScrollerId, "contentRect", (0, 0,the width of group "Contact List",the formattedHeight of group "Task List")
  -- The 'visible' determines if the scroller is displayed
  iphoneControlSet sScrollerId, "visible", "true"
  -- The 'canBounce' determines whether the standard iOS 'bouncing' occurs
  -- at extremities of scrolling
  iphoneControlSet sScrollerId, "canBounce", "true"
  -- The 'pagingEnabled' determines whether scrolling only happens in multiples
  -- of the width/height
  iphoneControlSet sScrollerId, "pagingEnabled", "false"
  -- The 'canScrollToTop' determines whether touching the status bar scrolls
  -- the scroller to the top
  iphoneControlSet sScrollerId, "canScrollToTop", "true"
  -- ensure scroller processes gestures meant for it
  iphoneControlSet sScrollerId, "delayTouches", "true"
end setupScroller


on scrollerDidScroll pOffsetX, pOffsetY
  -- Set the scroll values of the group based on feedback from the scroller
  -- notice that we can just use the values directly and because out-of-bounds
  -- scrolling is enabled for the group, the bounce effect needs no extra
  -- code.
  if the number of this cd <> 1 then exit scrollerDidScroll
  lock screen
  set the hilitedline of fld "contactListFld" to 0
  -- set the hScroll of group "Task List" to pOffsetX
  set the vScroll of group "Contact List" to pOffsetY
  unlock screen
end scrollerDidScroll

on removeScroller
  log the params
  if the environment <> "mobile" or sScrollerId = "" then exit removeScroller
  iphoneControlDelete sScrollerId
  put "" into sScrollerId
end removeScroller

on errorDialog
   write the params to stderr
end errorDialog
This is the same thing for iOS only

Code: Select all

on setupUIScroll
   ## The scrollers are implemented as behaviors in hidden buttons on this card
   ## Please investigate if you are interested
   ## They are quite complex so can just be used as porvided
   
   if the environment is not "mobile" or the platform is "android" then 
      ## desktop & android
      set the behavior of group "contact list" to the long ID of button "tmTouchScrollLib"
   else 
      ## iOS
      set the behavior of group "contact list" to the long ID of button "iOSScroller"
      send "setupScroller" to group "contact list" -- passes to behavior script
   end if
end setupUIScroll
These are directly from Runrev's ticked off example for scrolling a field. I adjusted the original a little to what I thought would work with the data grid, but so far i have only got it to scroll less than a centimeter, then it stops. So now how do you get these to scroll a data grid?? Please post anything you have and lets seee if we can come up with a really great method as a community!!

Tester2
Posts: 102
Joined: Wed May 18, 2011 7:02 pm

Re: Scrolling a datagrid form - multiplatform

Post by Tester2 » Tue Nov 12, 2013 6:50 pm

Hey William,

Did you figure out a convenient way for scrolling a Datagrid form on iOS?

Thanks,

Milo

Post Reply