@@ -2111,11 +2111,11 @@ on revTutorialDoLoad pLesson
21112111 revTutorialRunTutorial tTutorialInfo ["course" ], tTutorialInfo ["tutorial" ], pLesson , tTutorialInfo ["location" ]
21122112end revTutorialDoLoad
21132113
2114- on revTutorialSetText pStep
2115- revTutorialConfigureMessage sSteps [pStep ]
2114+ on revTutorialSetText pStep, pTopLeft
2115+ revTutorialConfigureMessage sSteps [pStep ], pTopLeft
21162116end revTutorialSetText
21172117
2118- on revTutorialConfigureMessage pData
2118+ on revTutorialConfigureMessage pData, pTopLeft
21192119 local tWidthOverride
21202120 put kMessageWidth into tWidthOverride
21212121 set the width of field "Message" of stack "revTutorial" to kMessageWidth
@@ -2170,7 +2170,7 @@ on revTutorialConfigureMessage pData
21702170 end if
21712171 end if
21722172
2173- revTutorialPositionStack "" , "" , tWidthOverride , false
2173+ revTutorialPositionStackForHighlight pTopLeft , tWidthOverride
21742174end revTutorialConfigureMessage
21752175
21762176function revTutorialImageForScreenSize pImage
@@ -2447,21 +2447,26 @@ function revTutorialCheckWaitCondition pActionData, pBeforeDisplay
24472447 end if
24482448 break
24492449 case "scripted"
2450- # If the script hasn't changed then don't do anything.
2451- if revTutorialScriptIs(the script of tObject , sWait ["current script" ]) then
2450+ # This code path is triggered by any propertyChanged message,
2451+ # so if the script hasn't changed then don't do anything.
2452+ local tScript
2453+ put the script of tObject into tScript
2454+ if tScript is sWait ["current script" ] then
24522455 break
24532456 end if
2454- if revTutorialObjectPropertyIsValue(tObject , "script" , pActionData ["script" ], false ) then
2457+ local tMistake
2458+ revTutorialCompareScript tScript , pActionData ["script" ]
2459+ put the result into tMistake
2460+ if tMistake is empty then
24552461 return true
2456- else if sWait ["current script" ] is not empty then
2457- add 1 to sWait ["incorrect attempts" ]
2458- put the script of tObject into sWait ["current script" ]
2459- # Show the current script and the target script in the tip stack
2460- local tData
2461- put revTutorialScriptRetry(sWait ["current script" ]) into tData ["text" ]
2462- put pActionData ["script" ] into tData ["script" ]
2463- revTutorialConfigureMessage tData
24642462 end if
2463+ put tScript into sWait ["current script" ]
2464+ add 1 to sWait ["incorrect attempts" ]
2465+ # Show the current script and the target script in the tip stack
2466+ local tData
2467+ put revTutorialScriptRetry(tMistake ) into tData ["text" ]
2468+ put pActionData ["script" ] into tData ["script" ]
2469+ revTutorialConfigureMessage tData , revTutorialGetEffectiveTopLeft()
24652470 break
24662471 end switch
24672472 break
@@ -2483,6 +2488,7 @@ on revTutorialWaitUntilObjectIsScripted pTaggedObject
24832488 revTutorialSetSEPreference "explicitVariables" , false
24842489
24852490 revIDESubscribe "idePropertyChanged" , tObjID
2491+ revIDESubscribe "ideScriptEdited"
24862492end revTutorialWaitUntilObjectIsScripted
24872493
24882494on revTutorialWaitUntilObjectIsClicked
@@ -3058,6 +3064,52 @@ on idePropertyChanged pObject
30583064 end if
30593065end idePropertyChanged
30603066
3067+ local sScriptCheck
3068+ on revTutorialCheckScript pScript, pObject
3069+ if revTutorialObjectIsTaggedObject(pObject , sWait ["object" ]) then
3070+ if sWait ["wait condition" ] is "state" and \
3071+ sWait ["state" ] is "scripted" then
3072+ revTutorialCompareScript pScript , sWait ["script" ]
3073+ lock screen
3074+ if the result is empty and sWait ["correct script" ] is not true then
3075+ -- If the currently typed script is correct, then
3076+ -- remind about clicking Apply
3077+ -- Remember the chosen location
3078+ put revTutorialGetEffectiveTopLeft() into sScriptCheck ["topleft" ]
3079+ put true into sScriptCheck ["correct script" ]
3080+ put "Apply" into sHighlight ["object" ]
3081+ put "object" into sHighlight ["type" ]
3082+ local tData
3083+ put "Click 'Apply' to apply the script" into tData ["text" ]
3084+ revTutorialConfigureMessage tData
3085+ else if sScriptCheck ["correct script" ] is true then
3086+ -- Otherwise, the script has been changed from the correct one
3087+ put false into sScriptCheck ["correct script" ]
3088+ -- Reset the highlight
3089+ put "stack" into sHighlight ["type" ]
3090+ -- Reset the text
3091+ revTutorialSetText sStepName , sScriptCheck ["topleft" ]
3092+ end if
3093+ unlock screen
3094+ end if
3095+ end if
3096+ end revTutorialCheckScript
3097+
3098+ local sCheckScriptMsg
3099+ constant kCheckBufferMS = 800
3100+ on ideScriptEdited pScript, pObject
3101+ -- In order to mitigate against forgetting to press the
3102+ -- apply button, we subscribe to ideScriptEdited and check
3103+ -- to see if the script entered is correct. However, we
3104+ -- don't want to interrupt the flow of typing, so add a
3105+ -- buffer
3106+ if sCheckScriptMsg is not empty then
3107+ cancel sCheckScriptMsg
3108+ end if
3109+ send "revTutorialCheckScript pScript, pObject" to me in kCheckBufferMS millisecs
3110+ put the result into sCheckScriptMsg
3111+ end ideScriptEdited
3112+
30613113on ideStackMoved pStack
30623114 local tStack
30633115 put revIDEStackOfObject(pStack ) into tStack
@@ -3345,32 +3397,32 @@ function revTutorialObjectIsHighlighted pObject
33453397 return false
33463398end revTutorialObjectIsHighlighted
33473399
3348- on revTutorialPositionStackForHighlight pTopLeft
3400+ on revTutorialPositionStackForHighlight pTopLeft, pWidthOverride
33493401 lock screen
33503402 switch sHighlight ["type" ]
33513403 case "guide"
3352- revTutorialPositionStack "" , sGuides [sHighlight ["guide" ]], "" , "" , pTopLeft
3404+ revTutorialPositionStack "" , sGuides [sHighlight ["guide" ]], pWidthOverride , "" , pTopLeft
33533405 break
33543406 case "property"
3355- revTutorialPositionStack "inspector" , sHighlight , "" , "" , pTopLeft
3407+ revTutorialPositionStack "inspector" , sHighlight , pWidthOverride , "" , pTopLeft
33563408 break
33573409 case "menu"
3358- revTutorialPositionStack "menubar" , sHighlight ["menu" ], "" , "" , pTopLeft
3410+ revTutorialPositionStack "menubar" , sHighlight ["menu" ], pWidthOverride , "" , pTopLeft
33593411 break
33603412 case "toolbar"
3361- revTutorialPositionStack "menubar" , sHighlight ["item" ], "" , "" , pTopLeft
3413+ revTutorialPositionStack "menubar" , sHighlight ["item" ], pWidthOverride , "" , pTopLeft
33623414 break
33633415 case "tool"
3364- revTutorialPositionStack "tools" , sHighlight ["tool" ], "" , "" , pTopLeft
3416+ revTutorialPositionStack "tools" , sHighlight ["tool" ], pWidthOverride , "" , pTopLeft
33653417 break
33663418 case "object"
3367- revTutorialPositionStack sHighlight ["stack" ], sHighlight ["object" ], "" , sHighlight ["line" ] is not empty , pTopLeft
3419+ revTutorialPositionStack sHighlight ["stack" ], sHighlight ["object" ], pWidthOverride , sHighlight ["line" ] is not empty , pTopLeft
33683420 break
33693421 case "stack"
3370- revTutorialPositionStack sHighlight ["stack" ], "" , "" , "" , pTopLeft
3422+ revTutorialPositionStack sHighlight ["stack" ], "" , pWidthOverride , "" , pTopLeft
33713423 break
33723424 default
3373- revTutorialPositionStack "" , "" , "" , "" , pTopLeft
3425+ revTutorialPositionStack "" , "" , pWidthOverride , "" , pTopLeft
33743426 break
33753427 end switch
33763428 unlock screen
@@ -3534,7 +3586,8 @@ function revTutorialObjectPropertyIsValue pObjectIDs, pProperty, pValue, pIsNot
35343586 return false
35353587 end if
35363588 else if pProperty is "script" then
3537- if revTutorialScriptIs(the script of tObject , pValue ) is pIsNot then
3589+ revTutorialCompareScript the script of tObject , pValue
3590+ if (the result is empty ) is pIsNot then
35383591 return false
35393592 end if
35403593 else if pProperty is "name" then
@@ -3595,19 +3648,61 @@ on revTutorialSnapObjectToGuide pObject, pGuide
35953648 unlock screen
35963649end revTutorialSnapObjectToGuide
35973650
3651+ private function revTutorialGetMistake pObjScript, pTokenNum, pReadToken, pTargetToken
3652+ lock messages
3653+ local tDefaultStack
3654+ put the defaultStack into tDefaultStack
3655+ set the defaultStack to "revTutorial"
3656+ create invisible field "script_tester"
3657+ put pObjScript into field "script_tester"
3658+
3659+ local tCharIndex , tLineIndex , tLineChars
3660+ put the lineIndex of token pTokenNum of field "script_tester" into tLineIndex
3661+ put the charIndex of token pTokenNum of field "script_tester" into tCharIndex
3662+ put the number of chars in line 0 to tLineIndex - 1 \
3663+ of field "script_tester" into tLineChars
3664+ subtract tLineChars from tCharIndex
3665+
3666+ local tMistake
3667+ if pTargetToken is not empty then
3668+ put merge (quote & "[[pReadToken]]" & quote && \
3669+ "instead of" && quote & "[[pTargetToken]]" & quote && \
3670+ "at char [[tCharIndex]] of line [[tLineIndex]]" ) into tMistake
3671+ else
3672+ put merge ("Unexpected additional script" && \
3673+ quote & "[[pReadToken]]" & quote && \
3674+ "at char [[tCharIndex]] of line [[tLineIndex]]" ) into tMistake
3675+ end if
3676+ delete field "script_tester"
3677+ set the defaultStack to tDefaultStack
3678+ unlock messages
3679+ return tMistake
3680+ end revTutorialGetMistake
3681+
35983682// In the future we might want to add a bit more "approximity" to this.
3599- function revTutorialScriptIs pObjScript, pTargetScript
3600- local tObjTokens , tTargetTokens
3601- repeat for each token tToken in pObjScript
3602- put tToken & " " after tObjTokens
3683+ command revTutorialCompareScript pObjScript, pTargetScript
3684+ local tTokenNum , tMistake , tToken
3685+ repeat for each token tTargetToken in pTargetScript
3686+ add 1 to tTokenNum
3687+ put token tTokenNum of pObjScript into tToken
3688+ if tTargetToken is not tToken then
3689+ put revTutorialGetMistake(pObjScript , tTokenNum , tToken , tTargetToken ) \
3690+ into tMistake
3691+ exit repeat
3692+ end if
36033693 end repeat
36043694
3605- repeat for each token tToken in pTargetScript
3606- put tToken & " " after tTargetTokens
3607- end repeat
3695+ if tMistake is empty then
3696+ add 1 to tTokenNum
3697+ put token tTokenNum of pObjScript into tToken
3698+ if tToken is not empty then
3699+ put revTutorialGetMistake(pObjScript , tTokenNum , tToken , empty ) \
3700+ into tMistake
3701+ end if
3702+ end if
36083703
3609- return tObjTokens is tTargetTokens
3610- end revTutorialScriptIs
3704+ return tMistake
3705+ end revTutorialCompareScript
36113706
36123707constant kColorTolerance = 10
36133708function revTutorialColorIs pColor, pTarget
0 commit comments