ProfStef.st 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. Smalltalk createPackage: 'ProfStef'!
  2. (Smalltalk packageAt: 'ProfStef' ifAbsent: [ self error: 'Package not created: ProfStef' ]) imports: {'amber/legacy/IDE'}!
  3. Object subclass: #AbstractTutorial
  4. slots: {}
  5. package: 'ProfStef'!
  6. !AbstractTutorial commentStamp!
  7. Parent class of all ProfStef tutorials.
  8. To create your own tutorial:
  9. - subclass AbstractTutorial
  10. - implement a few methods which returns a Lesson instance
  11. - implement tutorial which returns a Collection of selectors to the methods you've created.!
  12. !AbstractTutorial methodsFor: 'accessing'!
  13. indexOfLesson: aSelector
  14. ^self tableOfContents indexOf: aSelector.
  15. !
  16. lessonAt: anInteger
  17. | lessonSelector |
  18. lessonSelector := self tableOfContents at: anInteger.
  19. ^ self perform: lessonSelector.
  20. !
  21. size
  22. ^ self tableOfContents size
  23. !
  24. tableOfContents
  25. ^ #(
  26. 'welcome'
  27. 'testLesson'
  28. 'theEnd'
  29. )
  30. ! !
  31. !AbstractTutorial methodsFor: 'pages'!
  32. testLesson
  33. ^ Lesson
  34. title: 'Test Lesson'
  35. contents: '"This lesson is a test"'
  36. !
  37. theEnd
  38. ^ Lesson
  39. title: 'The End'
  40. contents: '"And that''d be pretty much it :)"'
  41. !
  42. welcome
  43. ^ Lesson
  44. title: 'Welcome'
  45. contents: '"Hi, this is a test tutorial."'
  46. ! !
  47. AbstractTutorial subclass: #SmalltalkSyntaxTutorial
  48. slots: {}
  49. package: 'ProfStef'!
  50. !SmalltalkSyntaxTutorial commentStamp!
  51. The default ProfStef tutorial to learn Smalltalk syntax!
  52. !SmalltalkSyntaxTutorial methodsFor: 'contents'!
  53. tableOfContents
  54. ^ #( 'welcome'
  55. 'doingVSPrinting'
  56. 'printing'
  57. 'basicTypesNumbers'
  58. "'basicTypesCharacters'"
  59. 'basicTypesString'
  60. "'basicTypesSymbol'"
  61. 'basicTypesArray'
  62. 'basicTypesDynamicArray'
  63. 'messageSyntaxUnary'
  64. 'messageSyntaxBinary'
  65. 'messageSyntaxKeyword'
  66. 'messageSyntaxExecutionOrder'
  67. 'messageSyntaxExecutionOrderParentheses'
  68. 'mathematicalPrecedence'
  69. 'messageSyntaxCascade'
  70. 'messageSyntaxCascadeShouldNotBeHere'
  71. 'blocks'
  72. 'blocksAssignation'
  73. 'conditionals'
  74. 'loops'
  75. 'iterators'
  76. 'instantiation'
  77. 'reflection'
  78. 'reflectionContinued'
  79. "'pharoEnvironment'"
  80. "'debugger'"
  81. 'theEnd' )
  82. ! !
  83. !SmalltalkSyntaxTutorial methodsFor: 'pages'!
  84. basicTypesArray
  85. ^ Lesson
  86. title: 'Basic types: Array'
  87. contents:
  88. '"Literal arrays are created at parse time:"
  89. #(1 2 3).
  90. #( 1 2 3 #(4 5 6)) size.
  91. #(1 2 4) isEmpty.
  92. #(1 2 3) first.
  93. #(''hello'' ''Javascript'') at: 2 put: ''Smalltalk''; yourself.
  94. ProfStef next.'
  95. !
  96. basicTypesCharacters
  97. ^ Lesson
  98. title: 'Basic types: Characters'
  99. contents:
  100. '"A Character can be instantiated using $ operator:"
  101. $A.
  102. $A class.
  103. $B charCode.
  104. Character cr.
  105. Character space.
  106. "You can print all 256 characters of the ASCII extended set:"
  107. Character allByteCharacters.
  108. ProfStef next.'
  109. !
  110. basicTypesDynamicArray
  111. ^ Lesson
  112. title: 'Basic types: Dynamic Array'
  113. contents:
  114. '"Dynamic Arrays are created at execution time:"
  115. { (2+3) . (6*6) }.
  116. { (2+3) . (6*6) . ''hello'', '' Stef''} size.
  117. { ProfStef } first next.'
  118. !
  119. basicTypesNumbers
  120. ^ Lesson
  121. title: 'Basic types: Numbers'
  122. contents:
  123. '"You now know how to execute Smalltalk code.
  124. Now let''s talk about basic objects.
  125. 1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
  126. Evaluate these ones:"
  127. 2.
  128. (1/3).
  129. (1/3) + (4/5).
  130. (18/5) rounded.
  131. 1 class.
  132. 1 negated.
  133. 1 negated negated.
  134. (1 + 3) odd.
  135. ProfStef next.'
  136. !
  137. basicTypesString
  138. ^ Lesson
  139. title: 'Basic types: Strings'
  140. contents:
  141. '"A String is a collection of characters. Use single quotes to create a String object. Print these expressions:"
  142. ''ProfStef''.
  143. ''ProfStef'' size.
  144. ''abc'' asUppercase.
  145. ''Hello World'' reversed.
  146. "You can access each character using at: message"
  147. ''ProfStef'' at: 1.
  148. "String concatenation uses the comma operator:"
  149. ''ProfStef'', '' is cool''.
  150. ProfStef next.'
  151. !
  152. basicTypesSymbol
  153. ^ Lesson
  154. title: 'Basic types: Symbols'
  155. contents:
  156. '"A Symbol is a String which is guaranteed to be globally unique.
  157. There is one and only one Symbol #ProfStef. There may be several ''ProfStef'' String objects.
  158. (Message == returns true if the two objects are the SAME)"
  159. ''ProfStef'' asSymbol.
  160. #ProfStef asString.
  161. (2 asString) == (2 asString).
  162. (2 asString) asSymbol == (2 asString) asSymbol.
  163. (Smalltalk at: #ProfStef) next.'
  164. !
  165. blocks
  166. ^ Lesson
  167. title: 'Blocks'
  168. contents:
  169. '"Cascade is cool !! Let''s talk about blocks.
  170. Blocks are anonymous methods that can be stored into variables and executed on demand.
  171. Blocks are delimited by square brackets: []"
  172. [Transcript open].
  173. "does not open a Transcript because the block is not executed.
  174. Here is a block that adds 2 to its argument (its argument is named x):"
  175. [:x | x+2].
  176. "We can execute a block by sending it value messages."
  177. [:x | x+2] value: 5.
  178. [Transcript open] value.
  179. [:x | x+2] value: 10.
  180. [:x :y| x + y] value:3 value:5.
  181. [ProfStef next] value.'
  182. !
  183. blocksAssignation
  184. ^ Lesson
  185. title: 'Block assignation'
  186. contents:
  187. '"Blocks can be assigned to a variable then executed later.
  188. Note that |b| is the declaration of a variable named ''b'' and that '':='' assigns a value to a variable.
  189. Select the three lines then Print It:"
  190. |b|
  191. b := [:x | x+2].
  192. b value: 12.
  193. ProfStef next.'
  194. !
  195. conditionals
  196. ^ Lesson
  197. title: 'Conditionals'
  198. contents:
  199. '"Conditionals are just messages sent to Boolean objects"
  200. 1 < 2
  201. ifTrue: [100]
  202. ifFalse: [42].
  203. "Here the message is ifTrue:ifFalse
  204. Try this:"
  205. Transcript open.
  206. 3 > 10
  207. ifTrue: [Transcript show: ''maybe there''''s a bug ....'']
  208. ifFalse: [Transcript show: ''No : 3 is less than 10''].
  209. 3 = 3 ifTrue: [ProfStef next].'.
  210. !
  211. debugger
  212. ^ Lesson
  213. title: 'Debugger'
  214. contents: '"The Debugger may be the most famous tool of Smalltalk environments. It will open as soon as an unmanaged Exception occurs.
  215. The following code will open the debugger.
  216. ***This should be rethought completely***"
  217. '
  218. !
  219. doingVSPrinting
  220. ^ Lesson
  221. title: 'Doing VS Printing: Doing'
  222. contents:
  223. '"Cool !! (I like to say Cooool :) ).
  224. You''ve just executed a Smalltalk expression.
  225. More precisely, you sent the message ''next'' to ProfStef class (it''s me !!).
  226. Note you can run this tutorial again by evaluating: ''ProfStef go''.
  227. ''ProfStef previous'' returns to the previous lesson.
  228. You can also Do It using the keyboard shortcut ''CTRL d''
  229. Try to evaluate this expression:"
  230. window alert: ''hello world!!''.
  231. "Then go to the next lesson:"
  232. ProfStef next.'
  233. !
  234. instantiation
  235. ^ Lesson
  236. title: 'Instantiation'
  237. contents:
  238. '"Objects are instances of their class. Usually, we send the message #new to a class for creating an instance of this class.
  239. For example, let''s create an instance of the class Array:"
  240. Array new
  241. add: ''Some text'';
  242. add: 3;
  243. yourself.
  244. "See the array we''ve created? Actually, #(''Some text'' 3) is just a shorthand for instantiating arrays."
  245. "If we use a variable to keep track of this object, we''ll be able to do stuff with it."
  246. "The following code must be ran all at one, as the ''anArray'' variable will cease to exist once the execution finishes:"
  247. |anArray|
  248. anArray := Array new
  249. add: ''Some text'';
  250. add: 3;
  251. yourself.
  252. Transcript show: anArray; cr.
  253. anArray remove: 3.
  254. Transcript show: anArray; cr.
  255. anArray add: ''Some more text!!''.
  256. Transcript show: anArray; cr.
  257. "I''ll put myself in an instance of a class named Dictionary and go to the next lesson:"
  258. ((Dictionary new add: (''move on!!'' -> ProfStef)) at: ''move on!!'') next'
  259. !
  260. iterators
  261. ^ Lesson
  262. title: 'Iterators'
  263. contents:
  264. '"The message do: is sent to a collection of objects (Array, Dictionary, String, etc), evaluating the block for each element.
  265. Here we want to print all the numbers on the Transcript (a console)"
  266. #(11 38 3 -2 10) do: [:each |
  267. Transcript show: each printString; cr].
  268. "Some other really nice iterators"
  269. #(11 38 3 -2 10) collect: [:each | each negated].
  270. #(11 38 3 -2 10) collect: [:each | each odd].
  271. #(11 38 3 -2 10) select: [:each | each odd].
  272. #(11 38 3 -2 10) select: [:each | each > 10].
  273. #(11 38 3 -2 10) reject: [:each | each > 10].
  274. #(11 38 3 -2 10)
  275. do: [:each | Transcript show: each printString]
  276. separatedBy: [Transcript show: ''.''].
  277. (Smalltalk classes select: [:eachClass | eachClass name = ''ProfStef'']) do: [:eachProfstef | eachProfstef next].'
  278. !
  279. loops
  280. ^ Lesson
  281. title: 'Loops'
  282. contents:
  283. '"Loops are high-level collection iterators, implemented as regular methods."
  284. "Basic loops:
  285. to:do:
  286. to:by:do"
  287. 1 to: 100 do:
  288. [:i | Transcript show: i asString; cr ].
  289. 1 to: 100 by: 3 do: [:i | Transcript show: i asString; cr].
  290. 100 to: 0 by: -2 do:
  291. [:i | Transcript show: i asString; cr].
  292. 1 to: 1 do: [:i | ProfStef next].'
  293. !
  294. mathematicalPrecedence
  295. ^ Lesson
  296. title: 'Mathematical precedence'
  297. contents:
  298. '"Traditional precedence rules from mathematics do not follow in Smalltalk."
  299. 2 * 10 + 2.
  300. "Here the message * is sent to 2, which answers 20, then 20 receive the message +
  301. Remember that all messages always follow a simple left-to-right precedence rule, * without exceptions *."
  302. 2 + 2 * 10.
  303. 2 + (2 * 10).
  304. 8 - 5 / 2.
  305. (8 - 5) / 2.
  306. 8 - (5 / 2).
  307. ProfStef next.'
  308. !
  309. messageSyntaxBinary
  310. ^ Lesson
  311. title: 'Message syntax: Binary messages'
  312. contents:
  313. '"Binary messages have the following form:
  314. anObject + anotherObject"
  315. 3 * 2.
  316. Date today year = 2011.
  317. false | false.
  318. true & true.
  319. true & false.
  320. 10 @ 100.
  321. 10 <= 12.
  322. ''ab'', ''cd''.
  323. ProfStef next.'
  324. !
  325. messageSyntaxCascade
  326. ^ Lesson
  327. title: 'Message syntax: Cascade'
  328. contents:
  329. '"; is the cascade operator. It''s useful to send message to the SAME receiver
  330. Open a Transcript (console):"
  331. Transcript open.
  332. "Then:"
  333. Transcript show: ''hello''.
  334. Transcript show: ''Smalltalk''.
  335. Transcript cr.
  336. "is equivalent to:"
  337. Transcript
  338. show: ''hello'';
  339. show: ''Smalltalk'' ;
  340. cr.
  341. "You can close the development tools by clicking on the red circle with a cross at the bottom left of the website.
  342. Try to go to the next lesson with a cascade of two ''next'' messages:"
  343. ProfStef'.
  344. !
  345. messageSyntaxCascadeShouldNotBeHere
  346. ^ Lesson
  347. title: 'Lost ?'
  348. contents:
  349. '"Hey, you should not be here !!!!
  350. Go back and use a cascade !!"
  351. ProfStef previous.'.
  352. !
  353. messageSyntaxExecutionOrder
  354. ^ Lesson
  355. title: 'Message syntax: Execution order'
  356. contents:
  357. '"Unary messages are executed first, then binary messages and finally keyword messages:
  358. Unary > Binary > Keywords"
  359. 2.5 + 3.8 rounded.
  360. 3 max: 2 + 2.
  361. (0@0) class.
  362. 0@0 x: 100.
  363. (0@0 x: 100) class.
  364. "Between messages of similar precedence, expressions are executed from left to right"
  365. -12345 negated asString reversed.
  366. ProfStef next.'
  367. !
  368. messageSyntaxExecutionOrderParentheses
  369. ^ Lesson
  370. title: 'Message syntax: Parentheses'
  371. contents:
  372. '"Use parentheses to change order of evaluation"
  373. (2.5 + 3.8) rounded.
  374. (3 max: 2) + 2.
  375. ProfStef next.'
  376. !
  377. messageSyntaxKeyword
  378. ^ Lesson
  379. title: 'Message syntax: Keyword messages'
  380. contents:
  381. '"Keyword Messages are messages with arguments. They have the following form:
  382. anObject akey: anotherObject akey2: anotherObject2"
  383. ''Web development is a good deal of pain'' copyFrom: 1 to: 30
  384. "The message is copyFrom:to: sent to the String ''Web development is a good deal of pain''"
  385. 1 max: 3.
  386. Array with: ''hello'' with: 2 with: Smalltalk.
  387. "The message is with:with:with: implemented on class Array. Note you can also write"
  388. Array
  389. with: ''Hi there!!''
  390. with: 2
  391. with: Smalltalk.
  392. ProfStef perform: ''next''.'
  393. !
  394. messageSyntaxUnary
  395. ^ Lesson
  396. title: 'Message syntax: Unary messages'
  397. contents:
  398. '"Messages are sent to objects. There are three types of message: Unary, Binary and Keyword.
  399. Unary messages have the following form:
  400. anObject aMessage
  401. You''ve already sent unary messages. For example:"
  402. 1 class.
  403. false not.
  404. Date today.
  405. Number pi.
  406. "And of course: "
  407. ProfStef next.'
  408. !
  409. pharoEnvironment
  410. ^ Lesson
  411. title: 'Pharo environment'
  412. contents:
  413. '"Every Smalltalk system is full of objects.
  414. There are windows, text, numbers, dates, colors, points and much more.
  415. You can interact with objects in a much more direct way than is possible with other programming languages.
  416. Every object understands the message ''explore''. As a result, you get an Explorer window that shows details about the object."
  417. Date today explore.
  418. "This shows that the date object consists of a point in time (start) and a duration (one day long)."
  419. ProfStef explore.
  420. "You see, ProfStef class has a lot of objects. Let''s take a look at my code:"
  421. ProfStef browse.
  422. ProfStef next.'
  423. !
  424. printing
  425. ^ Lesson
  426. title: 'Doing VS Printing: Printing'
  427. contents:
  428. '"Now you''re a Do It master !! Let''s talk about printing.
  429. It''s a Do It which prints the result next to the expression you''ve selected.
  430. For example, select the text below, and click on ''PrintIt'':"
  431. 1 + 2.
  432. "As with ''DoIt'', there is also a shortcut to execute this command.
  433. Try CTRL-p on the following expressions:"
  434. Date today.
  435. "The result is selected, so you can erase it using the backspace key. Try it !!"
  436. Date today asDateString.
  437. Date today asTimeString.
  438. ProfStef next.'
  439. !
  440. reflection
  441. ^ Lesson
  442. title: 'Reflection'
  443. contents:
  444. '"You can inspect and change the system at runtime.
  445. Take a look at the source code of the method #and: of the class Boolean:"
  446. (Boolean methodDictionary at: ''and:'') source.
  447. "Or all the methods it sends:"
  448. (Boolean methodDictionary at: ''and:'') messageSends.
  449. "Here''s all the methods I implement:"
  450. ProfStef class methodDictionary.
  451. "Let''s create a new method to go to the next lesson:"
  452. |newMethod|
  453. newMethod := Compiler new
  454. install: ''goToNextLesson ProfStef next.''
  455. forClass: ProfStef class
  456. protocol: ''navigation''.
  457. "Wow!! I can''t wait to use my new method!!"
  458. ProfStef goToNextLesson.'
  459. !
  460. reflectionContinued
  461. ^ Lesson
  462. title: 'Reflection continued'
  463. contents:
  464. '"So cool, isn''t it ? Before going further, let''s remove this method:"
  465. ProfStef class methodAt: #goToNextLesson.
  466. ProfStef class removeCompiledMethod: (ProfStef class methodAt: #goToNextLesson).
  467. ProfStef class methodAt: #goToNextLesson.
  468. "Then move forward:"
  469. ProfStef perform: #next'
  470. !
  471. theEnd
  472. ^ Lesson
  473. title: 'Tutorial done !!'
  474. contents:
  475. '"This tutorial is done. Enjoy programming Smalltalk with Amber.
  476. You can run this tutorial again by evaluating: ProfStef go.
  477. See you soon !!"
  478. '
  479. !
  480. welcome
  481. ^ Lesson
  482. title: 'Welcome'
  483. contents:
  484. ' "Hello!! I''m Professor Stef.
  485. You must want me to help you learn Smalltalk.
  486. So let''s go to the first lesson. Select the text below and click on the ''DoIt'' button"
  487. ProfStef next.'
  488. ! !
  489. Object subclass: #Lesson
  490. slots: {#title. #contents}
  491. package: 'ProfStef'!
  492. !Lesson methodsFor: 'accessing'!
  493. contents
  494. ^ contents ifNil: [contents := '']
  495. !
  496. contents: aString
  497. contents := aString
  498. !
  499. title
  500. ^ title ifNil: [title := '']
  501. !
  502. title: aString
  503. title := aString
  504. ! !
  505. !Lesson class methodsFor: 'instance creation'!
  506. title: aTitle contents: someContents
  507. ^ (self new)
  508. title: aTitle;
  509. contents: someContents
  510. ! !
  511. Object subclass: #ProfStef
  512. slots: {#tutorialPlayer. #widget}
  513. package: 'ProfStef'!
  514. !ProfStef commentStamp!
  515. A ProfStef is the Smalltalk teacher. To start the tutorial, evaluate:
  516. ProfStef go.
  517. To go to the next lesson evaluate:
  518. ProfStef next.
  519. To execute your own tutorial:
  520. ProfStef goOn: MyOwnTutorial
  521. To see a table of contents with all defined tutorials:
  522. ProfStef contents!
  523. !ProfStef methodsFor: 'accessing'!
  524. progress
  525. ^ '(', self tutorialPositionString, '/', self tutorialSizeString, ')'.
  526. !
  527. showCurrentLesson
  528. | lesson |
  529. lesson := self tutorialPlayer currentLesson.
  530. widget contents: lesson contents.
  531. widget setTitle: lesson title , ' ' , self progress.
  532. !
  533. tutorialPlayer
  534. ^ tutorialPlayer ifNil: [tutorialPlayer := TutorialPlayer new]
  535. !
  536. tutorialPositionString
  537. ^ self tutorialPlayer tutorialPosition asString.
  538. !
  539. tutorialSizeString
  540. ^ self tutorialPlayer size asString
  541. !
  542. widget: aWidget
  543. widget := aWidget
  544. ! !
  545. !ProfStef methodsFor: 'navigation'!
  546. first
  547. self tutorialPlayer first.
  548. ^ self showCurrentLesson.
  549. !
  550. next
  551. self tutorialPlayer next.
  552. ^ self showCurrentLesson.
  553. !
  554. previous
  555. self tutorialPlayer previous.
  556. ^ self showCurrentLesson.
  557. ! !
  558. ProfStef class slots: {#instance}!
  559. !ProfStef class methodsFor: 'initialize'!
  560. default
  561. ^ instance ifNil: [instance := self new]
  562. ! !
  563. !ProfStef class methodsFor: 'navigation'!
  564. first
  565. ^ self default first.
  566. !
  567. go
  568. self first.
  569. !
  570. next
  571. ^ self default next.
  572. !
  573. previous
  574. ^ self default previous.
  575. ! !
  576. !ProfStef class methodsFor: 'startup'!
  577. start
  578. ^ TrySmalltalkWidget open
  579. ! !
  580. Widget subclass: #TrySmalltalkWidget
  581. slots: {#workspace. #contents. #header}
  582. package: 'ProfStef'!
  583. !TrySmalltalkWidget methodsFor: 'accessing'!
  584. contents
  585. ^self workspace val
  586. !
  587. contents: aString
  588. self workspace val: aString
  589. !
  590. setTitle: aString
  591. header contents: [:html | html with: aString]
  592. !
  593. workspace
  594. ^ workspace ifNil: [
  595. workspace := SourceArea new]
  596. ! !
  597. !TrySmalltalkWidget methodsFor: 'rendering'!
  598. renderButtonsOn: html
  599. html button
  600. with: 'DoIt';
  601. title: 'ctrl+d';
  602. onClick: [self workspace doIt].
  603. html button
  604. with: 'PrintIt';
  605. title: 'ctrl+p';
  606. onClick: [self workspace printIt].
  607. html button
  608. with: 'InspectIt';
  609. title: 'ctrl+i';
  610. onClick: [self workspace inspectIt]
  611. !
  612. renderOn: html
  613. html div
  614. class: 'profStef';
  615. with: [header := html h2];
  616. with: [self workspace renderOn: html];
  617. with: [self renderButtonsOn: html].
  618. ProfStef default
  619. widget: self;
  620. showCurrentLesson
  621. ! !
  622. !TrySmalltalkWidget class methodsFor: 'initialize'!
  623. open
  624. self new appendToBrush: 'body' asBrush
  625. ! !
  626. Object subclass: #TutorialPlayer
  627. slots: {#tutorialPosition. #tutorial}
  628. package: 'ProfStef'!
  629. !TutorialPlayer commentStamp!
  630. I can navigate through an AbstractTutorial subclass. With #next and #previous you can go forward and backward through the tutorial.!
  631. !TutorialPlayer methodsFor: 'accessing'!
  632. currentLesson
  633. ^ self tutorial lessonAt: self tutorialPosition.
  634. !
  635. size
  636. ^ self tutorial size
  637. !
  638. tutorial
  639. ^ tutorial ifNil: [tutorial := SmalltalkSyntaxTutorial new]
  640. !
  641. tutorial: aTutorial
  642. tutorial := aTutorial
  643. !
  644. tutorialPosition
  645. ^ tutorialPosition ifNil: [
  646. self rewind.
  647. tutorialPosition.
  648. ].
  649. !
  650. tutorialPosition: aTutorialPosition
  651. tutorialPosition := aTutorialPosition
  652. ! !
  653. !TutorialPlayer methodsFor: 'navigation'!
  654. first
  655. self rewind.
  656. ^ self currentLesson
  657. !
  658. last
  659. tutorialPosition := self size.
  660. ^ self currentLesson
  661. !
  662. next
  663. self tutorialPosition < self size
  664. ifTrue: [tutorialPosition := tutorialPosition + 1].
  665. ^ self currentLesson
  666. !
  667. previous
  668. tutorialPosition > 1 ifTrue: [tutorialPosition := tutorialPosition - 1].
  669. ^ self currentLesson
  670. !
  671. rewind
  672. tutorialPosition := 1.
  673. ! !