Humanities Home page   Office of Digital Humanities
Back     BYU LiveCode Lessons Gateway

Mobile Gestures Exercise

1. Create a new Stack "gesturesEx" with at least three cards.

Stack script:

# Everything here you have seen before
#  except the acceleratedRendering property

on preopenstack
    set the acceleratedRendering of this stack to true
    set the fullscreenmode of me to "showAll"
    if mob() then
        mobileSetAllowedOrientations "portrait,portrait upside down,landscape left,landscape right"
    end if
end preopenstack

function dev
    return the environment is "development"
end dev

function mob
    return the environment is "mobile"
end mob

2. On each card, a background group consisting of these objects

Group script:

local sTouchArray, sStartH, sObjWidth, sObjHeight, sDoubleTouchIDs

on preOpenCard
   set the layerMode of image "pict" to "dynamic"
   delete variable sTouchArray
   put the imglist of me into tImgs
   put the number of this cd into tNum
   put line tNum of tImgs & ".png" into tImgName
   set the filename of img "Pict" to (specialFolderPath("resources") & "/" & tImgName)
   resetImg
   setCardLayout the width of this stack, the height of this stack
end preOpenCard

on closeCard
    delete variable sTouchArray
end closeCard

on resetImg
   set the width of img "pict" to the formattedWidth of img "pict"
   set the height of img "pict" to the formattedHeight of img "pict"
   set the loc of img pict to the loc of this card
end resetImg

3. Add screen resizing handlers to the group script to adapt to device screen size and orientation.

on resizeStack pNewWidth,pNewHeight
    setCardLayout pNewWidth,pNewHeight
end resizeStack

on setCardLayout pWdth, pHgt
    resetImg
    # position prev and next buttons
    set the bottomLeft of btn "prev" to 4,pHgt - 4
    set the bottomRight of btn "next" to pWdth - 4, the bottom of btn "prev"
    # position title fld
    set the width of fld "title" to pWdth
    set the topLeft of fld "title" to 0,0
    # position reset button
    if pWdth < pHgt then # portrait
        set the bottom of btn "reset" to the bottom of btn "prev"
        set the loc of btn "reset" to pWdth div 2, item 2 of the loc of btn "reset"
    else # landscape
        set the right of btn "reset" to pWdth - 4
        set the loc of btn "reset" to item 1 of the loc of btn "reset", pHgt div 2
    end if
end setCardLayout

4. Add swipe motion scripting for going between cards

Add to group script:

local sStartH

on touchStart pId
    put the mouseH into sStartH
end touchStart

on touchEnd pId
	if abs(the mouseH - sStartH) > 50 then
		if the mouseH < sStartH then
			goNext
		else
			goPrev
		end if
	end if
end touchEnd

on goNext
   lock screen for visual effect --in rect (the rect of img "pict")
   go next card
   unlock screen with visual push left very fast
end goNext

on goPrev
    lock screen for visual effect --in rect (the rect of img "pict")
   go prev card
   unlock screen with visual effect push right very fast
end goPrev

5. Show multi-touch tutorial at http://lessons.runrev.com/s/lessons/m/4069/l/11509-how-do-i-implement-a-multi-touch-pinch-motion

See sample stack from this tutorial, demo in simulator

Explain what's happening in the card script of the sample stack.

Explain simple trig for figuring out distance between start and end touch.

using the pythagoreum theorem to find the distance between two points

6. Adapt this script to act on the img "pict" instead.

In our stack we need to put the "pinch" scripting in the group script rather than the card script as in the tutorial.

Adapting it to work with our image is fairly straightforward: - set the resizeQuality of the image to "good" - replace all of the references to graphic "square" with image "pict"

The tricky part is making sure that double touches aren't triggering the single-touch swipe scripting. The group script will require these local variables:

local sTouchArray, sStartH, sObjWidth, sObjHeight, sDoubleTouchIDs

The touchStart and touchEnd handlers have to be modified to handle pinch gestures:

on touchStart pId
    put the width of img "pict" into sObjWidth
    put the height of img "pict" into sObjHeight
    put the mouseH into sStartH
end touchStart

# clean things up after the touch
on touchEnd pId
    if pId is not among the lines of sDoubleTouchIDs then
        if abs(the mouseH - sStartH) > 50 then
            if the mouseH < sStartH then
                goNext
            else
                goPrev
            end if
        end if
    end if
    delete variable sTouchArray[pId]
    # remove the touch just ended from the double touch list
    filter sDoubleTouchIDs without pId 
end touchEnd

Finally, these handlers do the actual resizing of the image:

on touchMove pId, pX, pY
    # If this is the first touchMove message for a given touch (see pID), store the startpoint of the touch
    if sTouchArray[pId]["startloc"] is empty then
        put (pX,pY) into sTouchArray[pId]["startloc"]
    end if
    
    # Now store the current position of the touch
    put (pX,pY) into sTouchArray[pId]["currentloc"]
    
    # 2 touches on the screen = a pinch gesture
    if the number of lines of the keys of sTouchArray is 2 then
        # save a list of the IDs involved in the double touch
        #  this lets us check for a single or double touch on touchEnd
        put the keys of sTouchArray into sDoubleTouchIDs 
        
        # get the current loc of the two touches
        # remember, the keys are the touch IDs
        put line 1 of the keys of sTouchArray into tPointOne
        put line 2 of the keys of sTouchArray into tPointTwo
        
        # now get the start positions of the two touches
        # by comparing the start and current positions of the two touches
        #  we can tell if they are getting closer or farther from each other
        put sTouchArray[tPointOne]["startloc"] into tStartLoc1
        put sTouchArray[tPointTwo]["startloc"] into tStartLoc2
        
        put sTouchArray[tPointOne]["currentloc"] into tCurrLoc1
        put sTouchArray[tPointTwo]["currentloc"] into tCurrLoc2
        
        if tStartLoc1 is not empty AND tStartLoc2 is not empty then
            # Calculate two distances:
            #   - distance between the two start locations
            #   - distance between the two current locations
            put resizeDistance(tStartLoc1,tStartLoc2) into tStartDist
            put resizeDistance(tCurrLoc1,tCurrLoc2) into tCurrDist
            
            resizeImg tStartDist,tCurrDist
        end if
    end if
end touchMove

# calculate the distance between two points, using some geometry
#  remember the Pythagorean theorem for the length of the hypotenuse
#   of a right triangle: a2 + b2 = c2

function resizeDistance pLoc1, pLoc2
    put item 2 of pLoc1 - item 2 of pLoc2 into dy
    put item 1 of  pLoc1 - item 1 of pLoc2 into dx
    put sqrt((dy^2) + (dx^2)) into tDistance
    return tDistance
end resizeDistance 

# calculate how to resize the image
on resizeImg pStartDist,pNewDist
    put pNewDist / pStartDist into tRatio
    put the loc of img "pict" of me into tCenterPt
    
    set the width of img "pict" of me to round(sObjWidth * tRatio)
    set the height of img "pict" of me to round(sObjHeight * tRatio)
    set the loc of img "pict" of me to tCenterPt
    unlock screen
end resizeImg

The final working stack is on the server at http://dight310.byu.edu/lesson_materials/12-Motion_and_gestures/. It is named GesturesEx.livecode


Back     BYU LiveCode Lessons Gateway
Maintained by Devin Asay.
Copyright © 2005 Brigham Young University