Skip to content

Commit

Permalink
tutorial: fix descriptions, port to new insert cursor, provide more c…
Browse files Browse the repository at this point in the history
…ompelling example at the end
  • Loading branch information
tom95 committed Jan 3, 2022
1 parent 8e25a15 commit 30684ae
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 29 deletions.
6 changes: 6 additions & 0 deletions packages/Sandblocks-Babylonian/SBMorphExampleCase.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ SBMorphExampleCase >> initialize [
cellGap: 4
]

{ #category : #'as yet unclassified' }
SBMorphExampleCase >> intoWorld: aWorld [

self status = #restartOnSave ifTrue: [self run]
]

{ #category : #'as yet unclassified' }
SBMorphExampleCase >> manualRestart [
<action>
Expand Down
10 changes: 0 additions & 10 deletions packages/Sandblocks-Core/SBEditor.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Class {
'history',
'dragHelper',
'cursor',
'activateForcesButton',
'hoverHighlight',
'suggestAlways',
'activePlugins'
Expand Down Expand Up @@ -284,9 +283,6 @@ SBEditor >> buildCommandBar [
shortcut: (self class anyShortcutForAction: #promptAddArtifact)
do: [self promptAddArtifact];
balloonText: 'Add artifact');
addMorphBack: (activateForcesButton := SBButton new
icon: SBIcon iconMagnet shortcut: (self class anyShortcutForAction: #activateForces) do: [];
balloonText: 'Activate Layouting');
addMorphBack: (Morph new
height: 0;
color: Color transparent;
Expand Down Expand Up @@ -911,12 +907,6 @@ SBEditor >> isSingleArtefactView [
^ false
]

{ #category : #accessing }
SBEditor >> keepForcesActivated [

^ activateForcesButton ifNotNil: #pressed ifNil: [false]
]

{ #category : #events }
SBEditor >> keyboardFocusChange: aBoolean [

Expand Down
2 changes: 1 addition & 1 deletion packages/Sandblocks-Core/SBForceMoveDecorator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ SBForceMoveDecorator >> step [

self isDragging ifTrue: [self panWhenNearEdge].

(forceSteps > 0 or: self morph sandblockEditor keepForcesActivated)
forceSteps > 0
ifTrue: [self isForceCoordinator ifTrue: [self coordinateForces]]
ifFalse: [
super step.
Expand Down
12 changes: 9 additions & 3 deletions packages/Sandblocks-Core/SBInputMapping.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ SBInputMapping >> actionFor: anEvent mode: aMode do: aBlock ifNone: anotherBlock

registerBlock := [:shortcut :action | | ret |(shortcut asSandblockShortcut matchesEvent: anEvent mode: aMode) ifTrue: [(ret := aBlock value: action) ifTrue: [^ ret]]].

self registerDefaultShortcuts.
self class shortcutProviders do: [:provider | provider registerShortcuts: self].
self registerAllShortcuts.

^ anotherBlock value
]
Expand Down Expand Up @@ -101,6 +100,13 @@ SBInputMapping >> inputShortcut: aShortcut do: aSymbol [
self shortcut: aShortcut modes: #(input) do: aSymbol
]

{ #category : #'shortcut execute' }
SBInputMapping >> registerAllShortcuts [

self registerDefaultShortcuts.
self class shortcutProviders do: [:provider | provider registerShortcuts: self]
]

{ #category : #'shortcut execute' }
SBInputMapping >> registerDefaultShortcuts [

Expand Down Expand Up @@ -135,7 +141,7 @@ SBInputMapping >> shortcuts [

^ OrderedCollection streamContents: [:stream |
registerBlock := [:shortcut :action | stream nextPut: shortcut asSandblockShortcut -> action].
self registerDefaultShortcuts]
self registerAllShortcuts]
]

{ #category : #'event handling' }
Expand Down
7 changes: 4 additions & 3 deletions packages/Sandblocks-Core/SBWelcome.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ SBWelcome >> initialize [
openMorphInView: SBScmModule example;
openMorphInView: SBJsModule example;
openMorphInView: (SBStPlayground example name: 'Smalltalk Workspace')]);
addMorphBack: (SBButton new icon: SBIcon iconVine label: 'Use Vim-like Shortcuts' do: [
self sandblockEditor useVimInput.
SBEditor useInputMapping: SBVimInputMapping]);
addMorphBack: (SBButton new
icon: SBIcon iconCog
label: 'Open Preferences'
do: [self sandblockEditor openMorphInView: SBPreferencesEditor new]);
addMorphBack: (SBButton new
icon: SBIcon iconCloudDownload
label: 'Update to bleeding-edge'
Expand Down
41 changes: 41 additions & 0 deletions packages/Sandblocks-Tutorial/SBExampleMorph.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Class {
#name : #SBExampleMorph,
#superclass : #Morph,
#category : #'Sandblocks-Tutorial'
}

{ #category : #'as yet unclassified' }
SBExampleMorph >> drawOn: aCanvas [

aCanvas fillRectangle: self bounds fillStyle: (self color alpha: 0.4)
]

{ #category : #'as yet unclassified' }
SBExampleMorph >> example [

SBMorphExample
setUp: [self class new]
cases: {SBMorphExampleCase name: 'example 1' caseBlock: [:mt | mt]}
extent: 300 @ 300
]

{ #category : #'as yet unclassified' }
SBExampleMorph >> initialize [

super initialize.

self extent: 50 asPoint.
self color: Color red
]

{ #category : #'as yet unclassified' }
SBExampleMorph >> step [

self position: 60 @ ((Time millisecondClock / 100) sin * 30 + 80)
]

{ #category : #'as yet unclassified' }
SBExampleMorph >> stepTime [

^ 0
]
66 changes: 54 additions & 12 deletions packages/Sandblocks-Tutorial/SBTutorialStep.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ SBTutorialStep class >> copyClass: aClass in: anEditor [
copyReplaceAll: aClass category
with: 'UserObjects').
newClass copyAllCategoriesFrom: aClass.
anEditor open: (SBStClassMethodEditor new
class: newClass;
expandAll)
SBToggledCode comment: '' active: 1 do: {
[newClass methodsDo: [:m | anEditor open: m]].
[
anEditor open: (SBStClassMethodEditor new
class: newClass;
expandAll)]}
]

{ #category : #progress }
Expand Down Expand Up @@ -250,8 +253,9 @@ SBTutorialStep class >> stepFinal: anEditor [
SBTutorialStep new
title: 'Congratulations!';
addIntroText: 'You finished the tutorial, well done! Press the button below to create a copy of an example class where you can freely experiment with the shortcuts or jump into any existing Smalltalk method using <#openOpenWindow> (then use <Cmd+f> to directly jump to a class).';
addMorphBack: (SBButton new icon: SBIcon iconFlask label: 'Open Example Class' do: [self copyClass: SBObservableExample in: anEditor]);
addMorphBack: (SBButton new icon: SBIcon iconFlask label: 'Open Example Methods' do: [self copyClass: SBSortExample in: anEditor]);
addMorphBack: (SBButton new icon: SBIcon iconFlask label: 'Open Example Morph Class' do: [
anEditor togglePalette.
self copyClass: SBExampleMorph in: anEditor]);
setup: anEditor do: [:editor | ]
]

Expand Down Expand Up @@ -303,6 +307,45 @@ SBTutorialStep class >> stepLists: anEditor [
title: 'Sequences';
addIntroText: 'Many elements act as sequences, for example arrays, statements in blocks, or even message sends.
By moving your cursor horizontally, you will pass by all the positions where elements can be inserted.';
addAction: #insertElementAfter;
addAction: #insertElementBefore;
addAction: #insertStatementAbove;
addAction: #insertStatementBelow;
setup: anEditor do: [:step | | method |
method := step
createStepMethod: [
{3. 4. 5}.
[].
5 between: 2 + 2]
in: anEditor.
step
addStep: 'Add a 1 at the start of the array by moving the cursor just before it. Sandblocks will display a popup telling you that you are at an insert position. Then just hit the 1 on your keyboard.'
checkCondition: [:editor | method statements first firstSubmorph contents = '1'].
step
addStep: 'To insert an element after the 1, move the cursor out of the 1 and type 2.'
checkCondition: [:editor | method statements first submorphs second contents = '2'].
step
addStep: 'For sequences of statements, there is a special type of insert. Create an empty statement above the array using <#insertStatementAbove>. This works from any block independent of its nesting.'
checkCondition: [:editor | method statements size > 2 and: [method statements second isArrayBlock]].
"step
addStep: 'Create an empty statement below the array by first moving the cursor to any number in the array and pressing <#insertStatementBelow>.'
checkCondition: [:editor | method statements size > 3 and: [method statements second isArrayBlock]]."
step
addStep: 'If you have an empty sequence, you insert an empty element by moving the cursor inside via <#moveCursorLeft> and <#moveCursorRight>. Move the insert cursor into the empty block near the end of the method and insert a `6 squared` statement into it.'
checkCondition: [:editor | (method statements detect: #isBlockBody) statements size > 0].
step
addStep: 'Message sends also act like sequences: each message part with its argument is an element. Complete the expression in the last line by moving the insert cursor until the popup tells you that you are modifying the `between:` message send, then insert an element by typing `and: 6` to form a `between:and:` call.'
checkCondition: [:editor | method statements last prettySourceString = '5 between: 2 + 2 and: 6']]
]

{ #category : #steps }
SBTutorialStep class >> stepListsShortcuts: anEditor [

SBTutorialStep new
title: 'Sequences';
addIntroText: 'Many elements act as sequences, for example arrays, statements in blocks, or even message sends.
<#insertElementBefore> will always insert an **empty** element before the current selection, <#insertElementAfter> after the current, similar to <#pasteBefore> and <#pasteAfter> that insert the **copied** element before and after the selection.';
addAction: #insertElementAfter;
addAction: #insertElementBefore;
Expand Down Expand Up @@ -378,7 +421,6 @@ SBTutorialStep class >> stepMultiSelection: anEditor [
addIntroText: 'You can multiselect elements with a dedicated selection mode. Many commands will then act on all elements at once.';
addAction: #wrapInDynamicArray;
addAction: #unwrapList;
addAction: #appendElement;
addAction: #promptAction;
setup: anEditor do: [:step | | method |
method := step
Expand All @@ -400,10 +442,10 @@ SBTutorialStep class >> stepMultiSelection: anEditor [
addStep: 'Press <#wrapInDynamicArray> to wrap your multi selection in an array.'
checkCondition: [:editor | method statements first isArrayBlock].
step
addStep: 'Add a 6 to the array by selecting the 5 and then pressing <#insertElementAfter> to insert an element after it.'
addStep: 'Add a 6 to the array by moving your cursor after the 5 and typing a 6.'
checkCondition: [:editor | method statements first submorphCount = 4 and: [method statements first lastSubmorph contents = '6']].
step
addStep: 'Finally, you can unwrap the array again using the unwrapList command, which might not be bound (<#unwrapist>). If it is not bound, you can access it by selecting the array and pressing <#promptAction> or right clicking it to see all available commands and filter for unwrap.'
addStep: 'Finally, you can unwrap the array again using the unwrapList command, which might not be bound (<#unwrapList>). If it is not bound, you can access it by selecting the array and pressing <#promptAction> or right clicking it to see all available commands and filter for unwrap.'
checkCondition: [:editor | method statements size = 4]]
]

Expand All @@ -423,10 +465,10 @@ SBTutorialStep class >> stepRestructuring: anEditor [
({1. 4. 9. 16} includes: number) ifTrue: [^ OrderedCollection with: number sqrt + 1]]
in: anEditor.
step
addStep: 'First, let''s add an ifFalse: branch. We want to insert it in the message send''s sequence, so select the send''s last child, which is the block closure after the `ifTrue:`.'
checkCondition: [:editor | editor selection isBlockBody and: [editor selection isMethodBody not]].
addStep: 'First, let''s add an ifFalse: branch. We want to insert it in the message send''s sequence, so move your cursor just after the block in the `ifTrue:`.'
checkCondition: [:editor | editor cursor mode = #insert and: [editor cursor cursorPosition container contents = 'ifTrue:' and: [editor cursor cursorPosition adjacent isBlockBody]]].
step
addStep: 'Press <#insertElementAfter> to now insert a new element in the sequence. Type `ifF`, use the autocompletion and then jump to the next hole using <#inputNextUnknown>.'
addStep: 'Type `iff`, use the autocompletion and then jump to the next hole using <#inputNextUnknown>.'
checkCondition: [:editor | method statements last selector = 'ifTrue:ifFalse:'].
step
addStep: 'Usually, when you want to type an expression, you simply type it and the editor will restructure the tree for you.
Expand Down Expand Up @@ -496,7 +538,7 @@ Note the yellow outline that indicates that a receiver will likely not understan
Morph new]
in: anEditor.
step
addStep: 'Wrap the `Transcript showln: ''true` after the ifTrue: in a block by selecting the whole `Transcript showln:` message send via <#selectUp>, then press <#wrapInBlock>.'
addStep: 'Wrap the `Transcript showln: ''true` after the ifTrue: in a block by selecting the whole `Transcript showln:` message send via <#moveCursorLarger>, then press <#wrapInBlock>.'
checkCondition: [:editor | method statements first arguments first isBlockBody].
step
addStep: 'Next, wrap the 65 in an array by pressing <#wrapInDynamicArray>.'
Expand Down

0 comments on commit 30684ae

Please sign in to comment.