Create a page

Ken
Posts: 29
Joined: Tue Jan 29, 2019 1:49 am
My devices: Ipad
Location: NSW, Australia

Re: Create a page

Post by Ken »

Thanks I like that. More compact but the same logic. I will use that for sure.

That's a swipe I guess.

I might now be able to work out how to program in long touch and short touch or tap.

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Create a page

Post by rbytes »

There was some code posted not long ago that had code for detecting double-taps. It might be in the Libraries folder. It had tap in the title.
The only thing that gets me down is gravity...

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Create a page

Post by rbytes »

Ken, I understand a little better what you want to do. I posted a program last year called Stamper 3.0 that had a nudge function. It works the same way as your code. Drag and release, and the page moves and stops. Repeat drag, and it continues from where it stopped.

The nudge function in Stamper 3.0 works in both x and y directions, if you ever need that capability.

I rewrote it for you here as a vertical-only nudge. It has a bit more code than yours, but allows the processor to run at less than full speed while waiting for a drag movement (the SLOWDOWN command). The code also shows how to attach a sprite to the new page so that it will move where the page moves.

The ratio variable is set to 1, so the page moves exactly as far as the finger is dragged. Set ratio to .5 and the page will move half as far. Set ratio to 2 and the page will move twice as far as the finger drag.

Code: Select all

[/*
Nudge Demo Vertical
by rbytes February 2019
*/
OPTION SPRITE POS CENTRAL
SET ORIENTATION LANDSCAPE
dev$=DEVICE_TYPE$()
GET SCREEN SIZE sw,sh
rw=sw/1024!rh=sh/768     ' rw and rh set display size for iPhone or iPod

' initialize the program

M$="sprite0"
N$="sprite1"
xpos0=sw/2!ypos0=sh/2    ' position of background sprite of lake
xpos=sw*.4!ypos=sh/2     ' starting position of PAGE "turtle"
x=xpos
path2$="Stamper/StampFiles/"
ratio=1
scale1=.5*rw
scale2=1*rh


GRAPHICS
GRAPHICS CLEAR

' load background image as sprite on PAGE ""
SPRITE M$ LOAD "Stamper/Interface/lake.jpg"
SPRITE M$ AT xpos0,ypos0 SCALE scale1
SPRITE M$ SHOW

' create PAGE "turtle"
PAGE "turtle" set
PAGE "turtle" show
PAGE "turtle" FRAME 0,0,200*rw,200*rh
PAGE "turtle" AT xpos,ypos

' load turtle sprite on PAGE "turtle"
SPRITE N$ LOAD "Stamper/Interface/turtle.png"
SPRITE N$ AT 100*rw,100*rh SCALE scale2
SPRITE N$ SHOW

' finger dragged up/down screen will drag page with turtle sprite up and down
DO
  y=TOUCH_Y (0)                
  IF y>-1 THEN   
    nudge(y,xpos,ypos,ratio,scale2)
    ypos=nudge.ypos
  ENDIF
  SLOWDOWN
UNTIL 0
END

' nudge the page vertical position by dragging with a finger
DEF nudge(y,xpos,ypos,ratio,scale2)
  WHILE y<>-1
    yset=ypos!yhold=y
    y=TOUCH_Y (0) 
    ynew=y!ypos+=(ynew-yhold)*ratio
    yhold=ynew
    if yset>-8*.rh and yset<.sh*.8 then       ' keep turtle on screen
      PAGE "turtle" AT xpos,yset
    endif
  ENDWHILE
  ypos=yset
END DEF/code]
The only thing that gets me down is gravity...

matt7
Posts: 115
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone
Location: USA

Re: Create a page

Post by matt7 »

rbytes wrote:
Sat Feb 23, 2019 1:12 am
There was some code posted not long ago that had code for detecting double-taps. It might be in the Libraries folder. It had tap in the title.
You are thinking of sneepy's tappoll routine: viewtopic.php?f=20&t=661

I also wrote my own touch polling routine that was inspired by sneepy's post. Mine is intended to be a bit more minimalistic in terms of the processing done each time TOUCHPOLL() is called, but it provides a lot of information about Touch 0 that you can use to determine gestures like taps, double taps, drags, swipes, etc., rather than the library doing that interpretation for you. The idea is that the main loop of your program calls TOUCHPOLL(), and then you can use the variables written to the scope 'TP' that tell you everything about Touch 0, including info about how long the touch has been going on, the initial movement direction, and its current velocity.

I never posted this library as its own post, but I did mention it in my post on my gradient editor (viewtopic.php?f=20&t=2232&p=13364). That is a massive program and is probably not ideal for browsing and looking at how my touchpoll library is used. But I'll give a really basic, empty example below, and you can read my comments / documentation at the top of the library file. And if you have any questions let me know.

Here is a super stripped-down example:

Code: Select all

{/lib/interface/touchpoll}

DO
  IF TOUCHPOLL() THEN    ' there is touch data to process
  
    IF TOUCHSTARTED() THEN
      ' check where touch started (TP.x0 and TP.y0) and do any setup
    END IF
    
    IF TOUCHONGOING() THEN
      ' use the variables in scope 'TP' to track, interpret, and process the touch
    END IF
    
    IF TOUCHSTOPPED() THEN
      ' do any teardown or final processing
    END IF
    
  ELSE
    SLOWDOWN
  END IF
UNTIL 0


Libary:

Code: Select all

'g'
/*
    TOUCHPOLL ()

    TOUCHSTARTED ()
    TOUCHONGOING ()
    TOUCHSTOPPED ()

    TP ()


Higher order functions for tracking and interpreting touch data.

Inspired by sneepy's click and drag library, TAPPOLL (https://kibernetik.pro/forum/viewtopic.php?f=20&t=661)

'==============================================================

TOUCHPOLL is the main polling routine for tracking touches. This function must be called before the other status functions. Returns 1 if there is touch data to process.

  Parameters
  ----------

    TOUCHPOLL.moveRadius sets the distance (in points) that a touch must travel from its initial location before the touch is considered a movement. Initial movement variables in TP (see below), such as the movmeent angle and direction string, are not determined until the .moveRadius threshold has been reached or exceeded.

    TOUCHPOLL.moveAngleTol sets the angle tolerance for how precise an initial movement must be in an orthagonal direction for TP.d0$ to register as an orthagonal movement. The angle is measured from th = 0 in the positive direction. Therefore, the value of this parameter represents half of the overall angle for an orthagonal direction (see diagram and explanation of common values below).

        |
        |  /
        | /   TOUCHPOLL.moveAngleTol (from th = 0)
        |/╲           \
     ---|--┴----  ┃  Orthagonal movement angle
        |\        /  (2 * TOUCHPOLL.moveAngleTol)
        | \
        |  \
        |

        To eliminate diagonal directions, set to π/4
        (TP.d0$ will only be "U", "D", "L", or "R")

        For equal orthagonal and diagonal angles, set to π/8

        To eliminate orthagonal directions, set to 0
        (TP.d0$ will only be "UL", "UR", "DL", or "DR")

    TOUCHPOLL.velSampleRate sets the movement velocity sampling rate in samples per second.

'==============================================================

TP initializes and contains the touch-related variables and data managed by the TOUCHPOLL() routine.

  Variables
  ---------

    TP.t0     Initial touch time
    TP.x0     Initial touch x-coordinate
    TP.y0     Initial touch y-coordinate

    TP.t0m    Initial movement time
    TP.x0m    Initial movement x-coordinate
    TP.y0m    Initial movement y-coordinate

    TP.t      Current (or final) time
    TP.x      Current (or final) x-coordinate
    TP.y      Current (or final) y-coordinate

    TP.vx     Current (or final) velocity in x-direction
    TP.vy     Current (or final) velocity in y-direction

    TP.th0    Initial movement angle (depends on OPTION ANGLE)

    TP.d0$    Initial movement direction
                "UL" up-left     "U" up     "UR" up-right
                 "L" left         "" none    "R" right
                "DL" down-left   "D" down   "DR" down-right

'==============================================================

TOUCHSTARTED returns 1 if a new touch has been started. Calling this function again during the same touch will return 0.

TOUCHONGOING returns 1 if a touch is currently active.

TOUCHSTOPPED returns 1 if a touch has ended. Calling this function again will return 0 unless a new touch has since started and ended.

'==============================================================
*/
''
'b'
'==============================================================
'  Parameter defaults
'==============================================================

''
TOUCHPOLL.pi = 2*ACOS(0)    ' Depends on OPTION ANGLE

TOUCHPOLL.moveRadius = 13
TOUCHPOLL.moveAngleTol = TOUCHPOLL.pi/8
TOUCHPOLL.velSampleRate = 20

'b'
'==============================================================
'  Variable initialization
'==============================================================

''
TP()

DEF TP ()

  t = 0   !   t0 = 0   !   t0m = 0
  x = 0   !   x0 = 0   !   x0m = 0
  y = 0   !   y0 = 0   !   y0m = 0

  vx = 0
  vy = 0

  th0 = 0
  d0$ = ""

  DIM dirList$(8)
  dirList$(0) = "R"
  dirList$(1) = "UR"
  dirList$(2) = "U"
  dirList$(3) = "UL"
  dirList$(4) = "L"
  dirList$(5) = "DL"
  dirList$(6) = "D"
  dirList$(7) = "DR"

  tStarted = 0
  tOngoing = 0
  tStopped = 0

END DEF

'b'
'==============================================================
'  Polling routine
'==============================================================

''
DEF TOUCHPOLL ()

  GET TOUCH 0 AS x, y

  IF x <> -1 AND y <> -1 THEN

    t = TIME()

    IF TP.tOngoing = 0 THEN

    '====================
    ' New touch detected
    '====================

      TP.tStarted = 1
      TP.tOngoing = 1
      TP.tStopped = 0

      TP.t0 = t   !   TP.t = t   !   tprev = t
      TP.x0 = x   !   TP.x = x   !   xprev = x
      TP.y0 = y   !   TP.y = y   !   yprev = y

      TP.vx = 0
      TP.vy = 0

      TP.th0 = 0
      TP.d0$ = ""

    ELSE

    '========================
    ' Ongoing touch detected
    '========================

      IF (t - tprev) > 1/velSampleRate THEN
        TP.vx = (x-xprev)/(t-tprev)
        TP.vy = (y-yprev)/(t-tprev)

        tprev = TP.t
        xprev = TP.x
        yprev = TP.y
      END IF

      TP.t = t
      TP.x = x
      TP.y = y

      IF TP.d0$ = "" THEN
        IF DIST2(TP.x, TP.y, TP.x0, TP.y0) > moveRadius THEN

          ' Movement detected (swipe or drag)

          TP.t0m = t
          TP.x0m = x
          TP.y0m = y

          TP.th0 = ATAN2(TP.y0-TP.y, TP.x-TP.x0)
          IF TP.th0 < 0 THEN TP.th0 += 2*pi

          th0shift = (TP.th0 + moveAngleTol)%(2*pi)
          th0Q1 = th0shift%(pi/2)

          IF th0Q1 > 2*moveAngleTol THEN i = 1 ELSE i = 0
          TP.d0$ = TP.dirList$(FLOOR(th0shift/(pi/2))*2+i)
        END IF
      END IF

    END IF

  ELSE

    IF TP.tOngoing = 1 THEN

    '=======================
    ' End of touch detected
    '=======================

      TP.tStarted = 0
      TP.tOngoing = 0
      TP.tStopped = 1

    END IF
  END IF

  RETURN OR(OR(TP.tStarted, TP.tOngoing), TP.tStopped)

END DEF

'b'
'==============================================================
'  Status functions
'==============================================================

''
DEF TOUCHSTARTED ()
  TOUCHSTARTED = TP.tStarted
  TP.tStarted = 0
END DEF

DEF TOUCHONGOING () = TP.tOngoing

DEF TOUCHSTOPPED ()
  TOUCHSTOPPED = TP.tStopped
  TP.tStopped = 0
END DEF

'==============================================================

DEF DIST2 (x1, y1, x2, y2) = SQRT((x2-x1)^2 + (y2-y1)^2)

'==============================================================

matt7
Posts: 115
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone
Location: USA

Re: Create a page

Post by matt7 »

And just to follow up since my example above is not a program you can actually run, but the idea is that using all the basic pieces of info in the scope TP, you should be able to detect whatever single-touch gestures you can think of.

For example, to detect a swipe you might require that the following conditions are met:
  • A movement was detected (by checking that TP.t0m > 0, i.e. the touch has not remained in roughly the same location as when the touch started)
  • A certain distance has been covered by the gesture in a certain amount of time (by checking that TP.x 0 - TP.x0m is >= some threshold, and the same for TP.y - TP.y0m, and by checking that TP.t - TP.t0m is <= some threshold); OR alternatively, maybe you consider a swipe to be any movement where the touch velocity (either in only the x direction or y direction, or combined) is >= some threshold
  • Optionally, you might also want to only check for swipes in the horizontal axis (or only in the vertical axis) by checking TP.th0 or TP.d0$ at the moment when a movement is detected (TP.t0m > 0)
Maybe you want to distinguish between a swipe and a flick by checking the if the touch velocity is above a certain threshold at the moment when a movement is detected (indicating a very quick, sudden movement off of the starting touch location). For example, for a flick, you might want the final touch velocity to impart some momentum on a page that is being scrolled, similar to how the LIST and FIELD interface objects work when the number of items makes the object scrollable.

Or maybe you want to distinguish between a swipe and an edge swipe by checking if the starting touch position is close to the edge of the screen. (Like how going "back" a page on a web browser usually requires the swipe to start near the edge of the screen.)

Or to detect a "press and hold" with no movement, you check to see if there is no movement yet (touch is staying at the same spot) and TP.t - TP.t0 is above a certain threshold.

Post Reply