
( Simple `keyframer` RPL example
( This program defines some RPL words and loads Tool window whose buttons
( are bind to the words

"r3d2:rpl/sys/objects.rpl" LOAD

?& KF_Start NOT ?IF

( Variables needed in this example

VARIABLE iLock
VARIABLE aTarget
VARIABLE aKeys
VARIABLE aRoot
VARIABLE iKfActive

( Locking and unlocking object data

: KF_Lock   iLOCK_EXCL   O_LOCK 1 iLock ! ;
: KF_Unlock iLOCK_REMOVE O_LOCK 0 iLock ! ;

( Error handler

: KF_Error
    iLock @ IF
        KF_Unlock
    ENDIF
    0 iKfActive !
;

( Word used for O_SCAN

: KF_Cmp
    OVER = IF
        0       ( found, stop scanning
    ELSE
        1       ( continue
    ENDIF
;

( Checks the `validity` of key framing sequence

: KF_StillValid

    ( Check if aRoot pointer is still valid
    aRoot @ O_GETROOT [&] KF_Cmp O_SCAN IF
        "CONTINUE" "Cannot Find Keyframed Object" GET_KEY DROP
        DROP 0 EXIT
    ENDIF

    DROP

    ( Check if aTarget pointer is still valid
    aTarget @ aRoot @ [&] KF_Cmp O_SCAN IF
        "CONTINUE" "Target Object Missing" GET_KEY DROP
        DROP 0 EXIT
    ENDIF

    DROP

    ( Check if aKeys pointer is still valid
    aKeys @ aRoot @ [&] KF_Cmp O_SCAN IF
        "CONTINUE" "Cannot find Key objects" GET_KEY DROP
        DROP 0 EXIT
    ENDIF

    DROP

    1
;


( Handle `Record` button; creates a new keyframe object

: KF_Rec

    iKfActive @ NOT IF
        "CONTINUE" "Start first please !" GET_KEY DROP
        0 EXIT
    ENDIF

    KF_Lock
    KF_StillValid IF
        0 aTarget @ M_COPY
        aKeys @ 0 M_PASTE
        0 aTarget @ O_SELECT
    ELSE
        0 iKfActive !
    ENDIF
    KF_Unlock
    0
;

( Start keyframing sequence

: KF_Start
    iKfActive @ IF
        "CONTINUE" "Sequence already active !" GET_KEY DROP
        0 EXIT
    ENDIF

    [&] KF_Error ERR_INSTALL
    KF_Lock
    O_GETSEL DUP NOT IF
        "CONTINUE" "Select Objects to be keyframed" GET_KEY DROP
        0 EXIT
    ENDIF
    M_CUT
    wOT_OR "kfobj"  0 "CEND" C_LEVEL DUP aRoot ! O_CURRENT DROP
    wOT_OR "target" 0 "CEND" C_LEVEL aTarget !
    wOT_OR "keys" lOF_RTINVISIBLE lOF_WFINVISIBLE BOR "CEND" "MORPHING OPEN" "SMTH" C_LEVEL aKeys !
    aTarget @ 0 M_PASTE
    0 aTarget @ M_COPY
    aKeys @ 0 M_PASTE
    0 aTarget @ O_SELECT
    KF_Unlock
    [&] KF_Error ERR_REMOVE
    1 iKfActive !
    lWR_SELECT
;

: KF_End
    iKfActive @ NOT IF
        "CONTINUE" "Sequence already terminated !" GET_KEY DROP
        0 EXIT
    ENDIF
    0 iKfActive !
    4 1 8 MENU 0
;

: KF_Help
    "r3d2:help/tools.guide" "KeyFramer" 0 AGUIDE
    0
;

: >> 4 3 0 MENU 0 ;     ( play forwards
: << 4 3 1 MENU 0 ;     ( play backwards
: >| 4 3 3 MENU 0 ;     ( go to end
: |< 4 3 2 MENU 0 ;     ( go to beginning
: STOP 5 4 0 MENU 0 ;   ( cancell all

?ENDIF

