Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit e338a8a

Browse files
Merge pull request #1671 from livecode/bugfix-20046
[Bug 20046] Interactive Tutorial: Make copy script / apply script into separate steps
2 parents bd8d199 + 9f0be30 commit e338a8a

5 files changed

Lines changed: 152 additions & 34 deletions

File tree

Toolset/palettes/script editor/behaviors/revsestackbehavior.livecodescript

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,17 @@ end seGetObjectState
797797
# Stores the specified state for the object for later use. And updates any
798798
# script editor components that may depend on this information.
799799
command seSetObjectState pObject, pState
800+
if pState is "edited" then
801+
local tObj
802+
put the long id of pObject into tObj
803+
if not revIDEObjectIsOnIDEStack(tObj) then
804+
local tParams
805+
put the text of field "Script" into tParams[1]
806+
put tObj into tParams[2]
807+
send "ideMessageSendWithParameters" && "ideScriptEdited, tObj, tParams" to stack "revIDELibrary" in 0 milliseconds
808+
end if
809+
end if
810+
800811
# Small optimization, if pState is equal to the current state, don't do anything
801812
if pState is sObjectStates[seGetRuggedId(pObject)] then
802813
exit seSetObjectState

Toolset/palettes/tutorial/revtutorial.livecodescript

Lines changed: 129 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,11 +2111,11 @@ on revTutorialDoLoad pLesson
21112111
revTutorialRunTutorial tTutorialInfo["course"], tTutorialInfo["tutorial"], pLesson, tTutorialInfo["location"]
21122112
end revTutorialDoLoad
21132113

2114-
on revTutorialSetText pStep
2115-
revTutorialConfigureMessage sSteps[pStep]
2114+
on revTutorialSetText pStep, pTopLeft
2115+
revTutorialConfigureMessage sSteps[pStep], pTopLeft
21162116
end 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
21742174
end revTutorialConfigureMessage
21752175

21762176
function 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"
24862492
end revTutorialWaitUntilObjectIsScripted
24872493

24882494
on revTutorialWaitUntilObjectIsClicked
@@ -3058,6 +3064,52 @@ on idePropertyChanged pObject
30583064
end if
30593065
end 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+
30613113
on ideStackMoved pStack
30623114
local tStack
30633115
put revIDEStackOfObject(pStack) into tStack
@@ -3345,32 +3397,32 @@ function revTutorialObjectIsHighlighted pObject
33453397
return false
33463398
end 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
35963649
end 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

36123707
constant kColorTolerance = 10
36133708
function revTutorialColorIs pColor, pTarget

notes/bugfix-20044.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Detect specific errors in user scripts in tutorial

notes/bugfix-20046.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Ensure there are separate scripting / apply steps in tutorial

notes/feature-ide_script_edited.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# ideScriptEdited message
2+
3+
A new IDE message has been added:
4+
5+
ideScriptEdited pScript, pObj
6+
7+
This message is sent when the script of an object as displayed
8+
in the script editor is changed. pScript contains the current
9+
contents of the script editor field for pObj, which, until applied,
10+
is not necessarily the same as `the script of pObj`.

0 commit comments

Comments
 (0)