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

Commit b7364f7

Browse files
authored
Merge pull request #1603 from livecode/feature-tutorial_enhancements
Feature tutorial enhancements
2 parents fe45543 + c2d9d94 commit b7364f7

2 files changed

Lines changed: 92 additions & 45 deletions

File tree

Documentation/specs/tutorial-syntax.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ satisfied before continuing.
133133
| <Target: Object> "fits" "guide" <Guide: STRING> [ "with" "tolerance" <Tolerance: INTEGER> ]
134134
| "there" "is" ( "a" | "an" ) <Target: Palette>
135135
| "there" "is" ( "a" | "an" ) <Target: ObjPalette> "for" <TargetObject: Object>
136-
| <Target: Object> “is” (“clicked” | “selected” | “scripted” | “focused” | "grouped")
137-
| “the” “tool” “is” (“edit” | “run” | “graphic”)
138-
| “the” <Property: PROPERTY> “of” <Target: Object> “is” <Value: STRING>
139-
| <Target: Object> “pops” “up” “answer” “dialog”
140-
| "this" "card" "is" <Card: STRING>
136+
| <Target: Object> "is" ("clicked" | "selected" | "scripted" | "focused" | "grouped")
137+
| "the" "tool" "is" ("edit" | "run" | "graphic")
138+
| "the" <Property: PROPERTY> "of" <Target: Object> "is" <Value: STRING>
139+
| "the" <Property: PROPERTY> "of" <Target: Object> "is" "changed" "with" "default" <Value: STRING>
140+
| <Target: Object> "pops" "up" "answer" "dialog"
141+
| "this" "card" "is" <Card: STRING>

Toolset/palettes/tutorial/revtutorial.livecodescript

Lines changed: 86 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -674,13 +674,26 @@ on revTutorialParseWait pTokens, @rData
674674
return empty
675675
end if
676676

677+
revTutorialParseSubexpression "the <token> of <object> is changed with default <token>", pTokens, tToken, tCondition
678+
679+
if the result is empty then
680+
put "property" into rData["wait condition"]
681+
put tCondition[1] into rData["property"]
682+
put tCondition[2] into rData["object"]
683+
put tCondition[3] into rData["default"]
684+
put true into rData["is not"]
685+
return empty
686+
end if
687+
677688
revTutorialParseSubexpression "the <token> of <object> is <value>", pTokens, tToken, tCondition
678689

679690
if the result is empty then
680691
put "property" into rData["wait condition"]
681692
put tCondition[1] into rData["property"]
682693
put tCondition[2] into rData["object"]
683694
put tCondition[3] into rData["value"]
695+
put false into rData["is not"]
696+
return empty
684697
end if
685698

686699
return the result
@@ -820,10 +833,12 @@ constant kMaxScriptHeight = 200
820833
local sDontShow
821834
local sLastShape
822835
on revTutorialPositionStack pStack, pObject, pWidthOverride, pForceVertical
823-
local tGotItButtonID, tCopyButtonID
836+
local tGotItButtonID, tCopyButtonID, tDoItButtonID
824837
local tMsgFieldID, tScriptFieldID, tImageID
838+
local tActionButton
825839

826840
put the long id of button "Got It" of stack "revTutorial" into tGotItButtonID
841+
put the long id of button "Do It For Me" of stack "revTutorial" into tDoItButtonID
827842
put the long id of button "Copy Script" of stack "revTutorial" into tCopyButtonID
828843
put the long id of field "Message" of stack "revTutorial" into tMsgFieldID
829844
put the long id of field "Script" of stack "revTutorial" into tScriptFieldID
@@ -844,9 +859,7 @@ on revTutorialPositionStack pStack, pObject, pWidthOverride, pForceVertical
844859
put the defaultStack into tDefaultStack
845860
set the defaultstack to "revTutorial"
846861
if sIsInterlude then
847-
show tGotItButtonID
848-
set the height of tGotItButtonID to the formattedHeight of tGotItButtonID
849-
set the width of tGotItButtonID to the formattedWidth of tGotItButtonID
862+
put tGotItButtonID into tActionButton
850863
put max(pWidthOverride, 460) into pWidthOverride
851864
else
852865
hide tGotItButtonID
@@ -859,9 +872,14 @@ on revTutorialPositionStack pStack, pObject, pWidthOverride, pForceVertical
859872
else
860873
put true into tHasScript
861874
show tScriptFieldID
862-
set the height of tCopyButtonID to the formattedHeight of tCopyButtonID
863-
set the width of tCopyButtonID to the formattedWidth of tCopyButtonID
864-
show tCopyButtonID
875+
put tCopyButtonID into tActionButton
876+
end if
877+
878+
# If this is a non-script action step, show the 'Do It For Me' button
879+
if sIsInterlude or tHasScript then
880+
hide tDoItButtonID
881+
else
882+
put tDoItButtonID into tActionButton
865883
end if
866884

867885
local tHasImage
@@ -945,10 +963,11 @@ on revTutorialPositionStack pStack, pObject, pWidthOverride, pForceVertical
945963
put max(tWidth, the width of tUrlControlID + kMargin * 2) into tWidth
946964
end if
947965

948-
if sIsInterlude then
949-
add the height of tGotItButtonID + kMargin to tHeight
950-
else if tHasScript then
951-
add the height of tCopyButtonID + kMargin to tHeight
966+
if tActionButton is not empty then
967+
set the height of tActionButton to the formattedHeight of tActionButton
968+
set the width of tActionButton to the formattedWidth of tActionButton
969+
show tActionButton
970+
add the height of tActionButton + kMargin to tHeight
952971
end if
953972

954973
if tHasImage then
@@ -1013,15 +1032,18 @@ on revTutorialPositionStack pStack, pObject, pWidthOverride, pForceVertical
10131032
set the rect of stack "revTutorial" to 0, 0, tWidth, tHeight
10141033
set the topleft of stack "revTutorial" to tStackLeft, tStackTop
10151034
else
1016-
if sIsInterlude then
1017-
set the bottomright of tGotItButtonID to tWidth - kMargin, tHeight - kMargin
1018-
else if tHasScript then
1019-
set the bottomright of tCopyButtonID to tWidth - kMargin, tHeight - kMargin
1020-
end if
10211035
set the rect of stack "revTutorial" to 0, 0, tWidth, tHeight
10221036
set the loc of stack "revTutorial" to item 3 of tScreenRect / 2, item 4 of tScreenRect / 2
10231037
end if
1024-
1038+
if tActionButton is not empty then
1039+
local tButtonBottom, tButtonRight
1040+
put tWidth - kMargin into tButtonRight
1041+
put tHeight - kMargin into tButtonBottom
1042+
if tHasPointer and not tPointerLeft and not tPointVertical then
1043+
subtract kPointerWidth / 2 from tButtonRight
1044+
end if
1045+
set the bottomright of tActionButton to tButtonRight,tButtonBottom
1046+
end if
10251047
if sIsInterlude then
10261048
set the backColor of stack "revTutorial" to revTutorialInterludeColor()
10271049
else
@@ -1313,6 +1335,10 @@ on revInitialiseTutorial
13131335
delete button "Got It" of stack "revTutorial"
13141336
end if
13151337

1338+
if there is a button "Do It For Me" of stack "revTutorial" then
1339+
delete button "Do It For Me" of stack "revTutorial"
1340+
end if
1341+
13161342
if there is a button "Copy Script" of stack "revTutorial" then
13171343
delete button "Copy Script" of stack "revTutorial"
13181344
end if
@@ -1383,6 +1409,10 @@ on revInitialiseTutorial
13831409
set the backColor of it to revTutorialMessageAltColor()
13841410
set the label of it to "Copy Script To Editor"
13851411

1412+
create button "Do It For Me"
1413+
set the backColor of it to revTutorialMessageAltColor()
1414+
set the label of it to "Do It For Me"
1415+
13861416
reset the templateButton
13871417

13881418
create image "Image"
@@ -1533,33 +1563,39 @@ on revTutorialStartAtStep pCourse, pTutorial, pLesson, pLocation, pStepName
15331563
revTutorialStartWithState pStepName, sTaggedObjects
15341564
end revTutorialStartAtStep
15351565

1566+
command revTutorialSkipCurrentStep
1567+
revTutorialSkipStep sStepName
1568+
end revTutorialSkipCurrentStep
1569+
15361570
on revTutorialSkip
1537-
local tTutorialInfo
1538-
put revIDETutorialInProgress() into tTutorialInfo
1539-
1540-
if tTutorialInfo is empty then
1541-
exit revTutorialSkip
1542-
end if
1543-
15441571
# Calculate the skip point
15451572
local tSkipPoint
15461573
put sStepName into tSkipPoint
15471574
repeat while tSkipPoint is not empty and sSteps[tSkipPoint]["skip point"] is not true
15481575
put sSteps[tSkipPoint]["actions"]["go"]["step"] into tSkipPoint
15491576
end repeat
15501577

1551-
local tRunUntil
1552-
put sSteps[tSkipPoint]["actions"]["go"]["step"] into tRunUntil
1578+
revTutorialSkipStep tSkipPoint
1579+
end revTutorialSkip
1580+
1581+
command revTutorialSkipStep pStep
1582+
local tTutorialInfo
1583+
put revIDETutorialInProgress() into tTutorialInfo
1584+
1585+
if tTutorialInfo is empty then
1586+
exit revTutorialSkipStep
1587+
end if
15531588

15541589
# Run from the current step to the next skip point
15551590
revTutorialRunTutorial tTutorialInfo["course"], tTutorialInfo["tutorial"], \
1556-
tTutorialInfo["lesson"], tTutorialInfo["location"], sStepName, tRunUntil
1591+
tTutorialInfo["lesson"], tTutorialInfo["location"], sStepName, pStep
1592+
15571593
revTutorialInitialiseStep
15581594

15591595
# Due to how the run loop works, we need to continue from the step
15601596
# *prior* to the next executed step
1561-
revTutorialContinueFromStep tSkipPoint
1562-
end revTutorialSkip
1597+
revTutorialContinueFromStep pStep
1598+
end revTutorialSkipStep
15631599

15641600
on revTutorialStop
15651601
revTutorialClearHighlights
@@ -2026,7 +2062,7 @@ function revTutorialCheckWaitCondition pActionData
20262062
put pActionData["value"] into tValue
20272063
end if
20282064

2029-
if revTutorialObjectPropertyIsValue(tObject, pActionData["property"], tValue) then
2065+
if revTutorialObjectPropertyIsValue(tObject, pActionData["property"], tValue, pActionData["is not"]) then
20302066
return true
20312067
end if
20322068
break
@@ -2140,6 +2176,9 @@ end revTutorialWaitUntilTheToolIs
21402176
on revTutorialWaitUntilObjectPropertyHasValue pTaggedObject
21412177
local tObjID
21422178
put revTutorialResolveObjectToLongID(pTaggedObject) into tObjID
2179+
if sWait["is not"] then
2180+
put the sWait["property"] of tObjID into sWait["value"]
2181+
end if
21432182
revIDESubscribe "idePropertyChanged", tObjID
21442183
end revTutorialWaitUntilObjectPropertyHasValue
21452184

@@ -2706,6 +2745,10 @@ on mouseUp pWhich
27062745
revTutorialCopyScriptToEditor
27072746
end if
27082747

2748+
if tObject is the long id of button "Do It For Me" of stack "revTutorial" then
2749+
revTutorialSkipCurrentStep
2750+
end if
2751+
27092752
if word 1 of tObject is "button" then
27102753
revTutorialSetUnpressedState tObject
27112754
end if
@@ -3004,22 +3047,22 @@ function revTutorialThereIsAPalette pPalette
30043047
return false
30053048
end revTutorialThereIsAPalette
30063049

3007-
function revTutorialObjectPropertyIsValue pObjectIDs, pProperty, pValue
3050+
function revTutorialObjectPropertyIsValue pObjectIDs, pProperty, pValue, pIsNot
30083051
repeat for each line tObject in pObjectIDs
30093052
if pProperty ends with "color" then
3010-
if revTutorialColorIs(the pProperty of tObject, pValue) is false then
3053+
if revTutorialColorIs(the pProperty of tObject, pValue) is pIsNot then
30113054
return false
30123055
end if
30133056
else if pProperty is "script" then
3014-
if revTutorialScriptIs(the script of tObject, pValue) is false then
3057+
if revTutorialScriptIs(the script of tObject, pValue) is pIsNot then
30153058
return false
30163059
end if
30173060
else if pProperty is "name" then
3018-
if the short name of tObject is not pValue then
3061+
if (the short name of tObject is pValue) is pIsNot then
30193062
return false
30203063
end if
30213064
else
3022-
if the pProperty of tObject is not pValue then
3065+
if (the pProperty of tObject is pValue) is pIsNot then
30233066
return false
30243067
end if
30253068
end if
@@ -3155,12 +3198,11 @@ on revTutorialRunSteps pSteps, pFromStep, pUntilStep
31553198
local tStep, tStepNum
31563199
put pFromStep into tStep
31573200
repeat until tStep is empty
3201+
revTutorialSetContextualStepData pSteps[tStep]
3202+
revTutorialRunStep pSteps[tStep]["actions"]
31583203
if tStep is pUntilStep then
31593204
exit repeat
31603205
end if
3161-
3162-
revTutorialSetContextualStepData pSteps[tStep]
3163-
revTutorialRunStep pSteps[tStep]["actions"]
31643206
put pSteps[tStep]["actions"]["go"]["step"] into tStep
31653207
end repeat
31663208
unlock screen
@@ -3202,7 +3244,7 @@ on revTutorialRunAction pActionData
32023244
break
32033245
case "property"
32043246
# Set the property of the objects
3205-
revTutorialSetPropertyOfObjects revTutorialResolveObjectToLongID(tWaitData["object"]), tWaitData["property"], tWaitData["value"]
3247+
revTutorialSetPropertyOfObjects revTutorialResolveObjectToLongID(tWaitData["object"]), tWaitData["property"], tWaitData["value"], tWaitData["is not"], tWaitData["default"]
32063248
break
32073249
case "fits"
32083250
# Set the rect of the objects
@@ -3341,12 +3383,16 @@ on revTutorialCreateAndCaptureObjects pWaitData, pCaptureData, pHighlightData
33413383
end if
33423384
end revTutorialCreateAndCaptureObjects
33433385

3344-
on revTutorialSetPropertyOfObjects pObjects, pProp, pValue
3386+
on revTutorialSetPropertyOfObjects pObjects, pProp, pValue, pIsNot, pDefault
33453387
# If the step specified a value then we set this instead of the string "value"
33463388
if pValue is "value" and sStepContextA["value"] is not empty then
33473389
put sStepContextA["value"] into pValue
33483390
end if
33493391

3392+
if pIsNot then
3393+
put pDefault into pValue
3394+
end if
3395+
33503396
if the environment begins with "development" then
33513397
revIDESetPropertyOfObject pObjects, pProp, pValue
33523398
else

0 commit comments

Comments
 (0)