Helios-Workspace.st 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. Smalltalk createPackage: 'Helios-Workspace'!
  2. Object subclass: #HLCodeModel
  3. instanceVariableNames: 'announcer environment receiver'
  4. package: 'Helios-Workspace'!
  5. !HLCodeModel methodsFor: 'accessing'!
  6. announcer
  7. ^ announcer ifNil: [ announcer := Announcer new ]
  8. !
  9. environment
  10. ^ environment ifNil: [ HLManager current environment ]
  11. !
  12. environment: anEnvironment
  13. environment := anEnvironment
  14. !
  15. receiver
  16. ^ receiver ifNil: [ receiver := self defaultReceiver ]
  17. !
  18. receiver: anObject
  19. receiver := anObject
  20. ! !
  21. !HLCodeModel methodsFor: 'actions'!
  22. browse: anObject
  23. anObject browse
  24. !
  25. doIt: aString
  26. "Evaluate aString in the receiver's `environment`.
  27. Note: Catch any error and handle it manually, bypassing
  28. boot.js behavior to avoid the browser default action on
  29. ctrl+d/ctrl+p.
  30. See https://github.com/amber-smalltalk/amber/issues/882"
  31. ^ [ self environment evaluate: aString for: self receiver ]
  32. tryCatch: [ :e |
  33. ErrorHandler handleError: e.
  34. nil ]
  35. !
  36. inspect: anObject
  37. self environment inspect: anObject
  38. ! !
  39. !HLCodeModel methodsFor: 'defaults'!
  40. defaultReceiver
  41. ^ self environment doItReceiver
  42. ! !
  43. !HLCodeModel class methodsFor: 'actions'!
  44. on: anEnvironment
  45. ^ self new
  46. environment: anEnvironment;
  47. yourself
  48. ! !
  49. HLWidget subclass: #HLCodeWidget
  50. instanceVariableNames: 'model wrapper code editor state'
  51. package: 'Helios-Workspace'!
  52. !HLCodeWidget methodsFor: 'accessing'!
  53. announcer
  54. ^ self model announcer
  55. !
  56. contents
  57. ^ editor getValue
  58. !
  59. contents: aString
  60. editor setValue: aString.
  61. state ifNotNil: [ self updateState ]
  62. !
  63. currentLine
  64. ^editor getLine: (editor getCursor line)
  65. !
  66. currentLineOrSelection
  67. ^editor somethingSelected
  68. ifFalse: [ self currentLine ]
  69. ifTrue: [ self selection ]
  70. !
  71. editorOptions
  72. ^ #{
  73. 'theme' -> ('helios.editorTheme' settingValueIfAbsent: 'default').
  74. 'mode' -> 'text/x-stsrc'.
  75. 'lineNumbers' -> true.
  76. 'enterMode' -> 'flat'.
  77. 'indentWithTabs' -> true.
  78. 'indentUnit' -> 4.
  79. 'matchBrackets' -> true.
  80. 'electricChars' -> false.
  81. 'keyMap' -> 'Amber'.
  82. 'extraKeys' -> (HashedCollection with: ('helios.completionKey' settingValueIfAbsent: 'Shift-Space') -> 'autocomplete')
  83. }
  84. !
  85. model
  86. ^ model ifNil: [ model := HLCodeModel new ]
  87. !
  88. model: aModel
  89. model := aModel
  90. !
  91. receiver
  92. ^ self model receiver
  93. !
  94. receiver: anObject
  95. self model receiver: anObject
  96. !
  97. selection
  98. ^editor getSelection
  99. !
  100. selectionEnd
  101. ^code element selectionEnd
  102. !
  103. selectionEnd: anInteger
  104. code element selectionEnd: anInteger
  105. !
  106. selectionStart
  107. ^code element selectionStart
  108. !
  109. selectionStart: anInteger
  110. code element selectionStart: anInteger
  111. ! !
  112. !HLCodeWidget methodsFor: 'actions'!
  113. browseIt
  114. | result |
  115. result := [ self doIt ] on: Error do: [ :exception |
  116. ^ ErrorHandler handleError: exception ].
  117. self model browse: result
  118. !
  119. clear
  120. self contents: ''
  121. !
  122. configureEditor
  123. self editor at: 'amberCodeWidget' put: self.
  124. self editor on: 'change' do: [ self onChange ].
  125. self wrapper asJQuery on: 'mousedown' in: '.CodeMirror pre' do: [ :event | | position node |
  126. (event at: 'ctrlKey') ifTrue: [
  127. position := self editor coordsChar: #{
  128. 'left' -> event clientX.
  129. 'top' -> event clientY
  130. }.
  131. self onCtrlClickAt: (position line @ position ch) + 1.
  132. event preventDefault ] ]
  133. !
  134. doIt
  135. | result |
  136. result := self model doIt: self currentLineOrSelection.
  137. self model announcer announce: (HLDoItExecuted on: model).
  138. ^ result
  139. !
  140. editor
  141. ^ editor
  142. !
  143. focus
  144. editor focus
  145. !
  146. inspectIt
  147. self model inspect: self doIt
  148. !
  149. navigateTo: aString
  150. Finder findString: aString
  151. !
  152. navigateToReference: aString
  153. (HLReferences openAsTab)
  154. search: aString
  155. !
  156. print: aString
  157. | start stop currentLine |
  158. currentLine := (editor getCursor: false) line.
  159. start := HashedCollection new.
  160. start at: 'line' put: currentLine.
  161. start at: 'ch' put: (editor getCursor: false) ch.
  162. (editor getSelection) ifEmpty: [
  163. "select current line if selection is empty"
  164. start at: 'ch' put: (editor getLine: currentLine) size.
  165. editor setSelection: #{'line' -> currentLine. 'ch' -> 0} end: start.
  166. ].
  167. stop := HashedCollection new.
  168. stop at: 'line' put: currentLine.
  169. stop at: 'ch' put: ((start at: 'ch') + aString size + 2).
  170. editor replaceSelection: (editor getSelection, ' ', aString, ' ').
  171. editor setCursor: (editor getCursor: true).
  172. editor setSelection: stop end: start
  173. !
  174. printIt
  175. self print: self doIt printString
  176. !
  177. saveIt
  178. "I do not do anything"
  179. !
  180. setEditorOn: aTextarea
  181. <self['@editor'] = self._class()._codeMirror().fromTextArea(aTextarea, self._editorOptions())>
  182. ! !
  183. !HLCodeWidget methodsFor: 'hints'!
  184. messageHintFor: anEditor token: aToken
  185. ^ (Smalltalk core allSelectors asArray
  186. select: [ :each | each includesSubString: aToken string ])
  187. reject: [ :each | each = aToken string ]
  188. !
  189. variableHintFor: anEditor token: aToken
  190. | variables classNames pseudoVariables |
  191. variables := (anEditor display wrapper asJQuery find: 'span.cm-variable') get
  192. collect: [ :each | each asJQuery html ].
  193. classNames := Smalltalk classes collect: [ :each | each name ].
  194. pseudoVariables := Smalltalk pseudoVariableNames.
  195. ^ ((variables, classNames, pseudoVariables) asSet asArray sort
  196. select: [ :each | each includesSubString: aToken string ])
  197. reject: [ :each | each = aToken string ]
  198. ! !
  199. !HLCodeWidget methodsFor: 'reactions'!
  200. onChange
  201. self updateState
  202. !
  203. onCtrlClickAt: aPoint
  204. | ast node |
  205. ast := [ Smalltalk parse: self editor getValue ]
  206. on: Error
  207. do: [ :error | ^ self ].
  208. node := ast
  209. navigationNodeAt: aPoint
  210. ifAbsent: [ ^ nil ].
  211. self navigateTo: node navigationLink
  212. !
  213. onInspectIt
  214. self inspectIt
  215. !
  216. onPrintIt
  217. self printIt
  218. !
  219. onSaveIt
  220. "I do not do anything"
  221. ! !
  222. !HLCodeWidget methodsFor: 'rendering'!
  223. renderButtonsOn: html
  224. html button
  225. class: 'button';
  226. with: 'DoIt';
  227. onClick: [ self doIt ].
  228. html button
  229. class: 'button';
  230. with: 'PrintIt';
  231. onClick: [ self printIt ].
  232. html button
  233. class: 'button';
  234. with: 'InspectIt';
  235. onClick: [ self inspectIt ].
  236. html button
  237. class: 'button';
  238. with: 'BrowseIt';
  239. onClick: [ self browseIt ]
  240. !
  241. renderContentOn: html
  242. html div class: 'editor'; with: [
  243. code := html textarea ].
  244. state := html div class: 'state'.
  245. html div
  246. class: 'buttons_bar';
  247. with: [ self renderButtonsOn: html ].
  248. self
  249. setEditorOn: code element;
  250. configureEditor;
  251. updateState
  252. ! !
  253. !HLCodeWidget methodsFor: 'testing'!
  254. canHaveFocus
  255. ^ true
  256. !
  257. hasFocus
  258. ^ code asJQuery is: ':active'
  259. !
  260. hasModification
  261. ^ false
  262. ! !
  263. !HLCodeWidget methodsFor: 'updating'!
  264. updateState
  265. self hasModification
  266. ifTrue: [ state asJQuery addClass: 'modified' ]
  267. ifFalse: [ state asJQuery removeClass: 'modified' ]
  268. ! !
  269. !HLCodeWidget class methodsFor: 'accessing'!
  270. codeMirror
  271. ^ require value: 'codemirror/lib/codemirror'
  272. !
  273. keyMap
  274. ^ HLManager current keyBinder systemIsMac
  275. ifTrue: [ self macKeyMap ]
  276. ifFalse: [ self pcKeyMap ]
  277. !
  278. macKeyMap
  279. ^ #{
  280. 'Alt-Backspace' -> 'delWordBefore'.
  281. 'Alt-Delete' -> 'delWordAfter'.
  282. 'Alt-Left' -> 'goWordLeft'.
  283. 'Alt-Right' -> 'goWordRight'.
  284. 'Cmd-A' -> 'selectAll'.
  285. 'Cmd-Alt-F' -> 'replace'.
  286. 'Cmd-D' -> 'doIt'.
  287. 'Cmd-B' -> 'browseIt'.
  288. 'Cmd-Down' -> 'goDocEnd'.
  289. 'Cmd-End' -> 'goDocEnd'.
  290. 'Cmd-F' -> 'find'.
  291. 'Cmd-G' -> 'findNext'.
  292. 'Cmd-I' -> 'inspectIt'.
  293. 'Cmd-Left' -> 'goLineStart'.
  294. 'Cmd-P' -> 'printIt'.
  295. 'Cmd-Right' -> 'goLineEnd'.
  296. 'Cmd-S' -> 'saveIt'.
  297. 'Cmd-Up' -> 'goDocStart'.
  298. 'Cmd-Y' -> 'redo'.
  299. 'Cmd-Z' -> 'undo'.
  300. 'Cmd-[' -> 'indentLess'.
  301. 'Cmd-]' -> 'indentMore'.
  302. 'Ctrl-Alt-Backspace' -> 'delWordAfter'.
  303. 'Shift-Cmd-Alt-F' -> 'replaceAll'.
  304. 'Shift-Cmd-G' -> 'findPrev'.
  305. 'Shift-Cmd-Z' -> 'redo'.
  306. 'fallthrough' -> { 'basic'. 'emacsy' }
  307. }
  308. !
  309. pcKeyMap
  310. ^ #{
  311. 'Alt-Left' -> 'goLineStart'.
  312. 'Alt-Right' -> 'goLineEnd'.
  313. 'Alt-Up' -> 'goDocStart'.
  314. 'Ctrl-A' -> 'selectAll'.
  315. 'Ctrl-Backspace' -> 'delWordBefore'.
  316. 'Ctrl-D' -> 'doIt'.
  317. 'Ctrl-B' -> 'browseIt'.
  318. 'Ctrl-Delete' -> 'delWordAfter'.
  319. 'Ctrl-Down' -> 'goDocEnd'.
  320. 'Ctrl-End' -> 'goDocEnd'.
  321. 'Ctrl-F' -> 'find'.
  322. 'Ctrl-G' -> 'findNext'.
  323. 'Ctrl-I' -> 'inspectIt'.
  324. 'Ctrl-Home' -> 'goDocStart'.
  325. 'Ctrl-Left' -> 'goWordLeft'.
  326. 'Ctrl-P' -> 'printIt'.
  327. 'Ctrl-Right' -> 'goWordRight'.
  328. 'Ctrl-S' -> 'saveIt'.
  329. 'Ctrl-Y' -> 'redo'.
  330. 'Ctrl-Z' -> 'undo'.
  331. 'Ctrl-[' -> 'indentLess'.
  332. 'Ctrl-]' -> 'indentMore'.
  333. 'Shift-Ctrl-F' -> 'replace'.
  334. 'Shift-Ctrl-G' -> 'findPrev'.
  335. 'Shift-Ctrl-R' -> 'replaceAll'.
  336. 'Shift-Ctrl-Z' -> 'redo'.
  337. 'fallthrough' -> #('basic')
  338. }
  339. ! !
  340. !HLCodeWidget class methodsFor: 'hints'!
  341. hintFor: anEditor options: options
  342. | cursor token completions codeMirror |
  343. codeMirror := self codeMirror.
  344. cursor := anEditor getCursor.
  345. token := anEditor getTokenAt: cursor.
  346. token at: 'state' put: ((codeMirror basicAt: 'innerMode')
  347. value: anEditor getMode value: (token at: 'state')) state.
  348. completions := token type = 'variable'
  349. ifTrue: [ HLCodeWidget variableHintFor: anEditor token: token ]
  350. ifFalse: [ HLCodeWidget messageHintFor: anEditor token: token ].
  351. ^ #{
  352. 'list' -> completions.
  353. 'from' -> ((codeMirror basicAt: 'Pos') value: cursor line value: token end).
  354. 'to' -> ((codeMirror basicAt: 'Pos') value: cursor line value: token start)
  355. }
  356. !
  357. messageHintFor: anEditor token: aToken
  358. ^ (anEditor at: 'amberCodeWidget')
  359. messageHintFor: anEditor token: aToken
  360. !
  361. variableHintFor: anEditor token: aToken
  362. ^ (anEditor at: 'amberCodeWidget')
  363. variableHintFor: anEditor token: aToken
  364. ! !
  365. !HLCodeWidget class methodsFor: 'initialization'!
  366. initialize
  367. super initialize.
  368. self
  369. setupCodeMirror;
  370. setupCommands;
  371. setupKeyMaps.
  372. !
  373. setupCodeMirror
  374. <
  375. var codeMirror = self._codeMirror();
  376. codeMirror.keyMap["default"].fallthrough = ["basic"];
  377. codeMirror.commands.autocomplete = function(cm) {
  378. codeMirror.showHint(cm, self._hintFor_options_.bind(self));
  379. }
  380. >
  381. !
  382. setupCommands
  383. (self codeMirror basicAt: 'commands')
  384. at: 'doIt' put: [ :cm | cm amberCodeWidget doIt ];
  385. at: 'inspectIt' put: [ :cm | cm amberCodeWidget inspectIt ];
  386. at: 'printIt' put: [ :cm | cm amberCodeWidget printIt ];
  387. at: 'saveIt' put: [ :cm | cm amberCodeWidget saveIt ];
  388. at: 'browseIt' put: [ :cm | cm amberCodeWidget browseIt ]
  389. !
  390. setupKeyMaps
  391. <self._codeMirror().keyMap['Amber'] = self._keyMap()>
  392. ! !
  393. HLCodeWidget subclass: #HLNavigationCodeWidget
  394. instanceVariableNames: 'methodContents'
  395. package: 'Helios-Workspace'!
  396. !HLNavigationCodeWidget methodsFor: 'accessing'!
  397. configureEditor
  398. super configureEditor.
  399. self contents: self methodContents
  400. !
  401. contents: aString
  402. self methodContents: aString.
  403. super contents: aString
  404. !
  405. methodContents
  406. ^ methodContents ifNil: [ '' ]
  407. !
  408. methodContents: aString
  409. ^ methodContents := aString
  410. !
  411. previous
  412. "for browser lists widget"
  413. !
  414. previous: aWidget
  415. "for browser lists widget"
  416. ! !
  417. !HLNavigationCodeWidget methodsFor: 'testing'!
  418. hasModification
  419. ^ (self methodContents = self contents) not
  420. ! !
  421. !HLNavigationCodeWidget class methodsFor: 'instance creation'!
  422. on: aBrowserModel
  423. ^ self new
  424. browserModel: aBrowserModel;
  425. yourself
  426. ! !
  427. !HLNavigationCodeWidget class methodsFor: 'testing'!
  428. canBeOpenAsTab
  429. ^ false
  430. ! !
  431. HLNavigationCodeWidget subclass: #HLBrowserCodeWidget
  432. instanceVariableNames: 'browserModel'
  433. package: 'Helios-Workspace'!
  434. !HLBrowserCodeWidget methodsFor: 'accessing'!
  435. browserModel
  436. ^ browserModel
  437. !
  438. browserModel: aBrowserModel
  439. browserModel := aBrowserModel.
  440. self
  441. observeSystem;
  442. observeBrowserModel
  443. ! !
  444. !HLBrowserCodeWidget methodsFor: 'actions'!
  445. observeBrowserModel
  446. self browserModel announcer
  447. on: HLSaveSourceCode
  448. send: #onSaveIt
  449. to: self;
  450. on: HLShowInstanceToggled
  451. send: #onShowInstanceToggled
  452. to: self;
  453. on: HLSourceCodeSaved
  454. send: #onSourceCodeSaved
  455. to: self;
  456. on: HLAboutToChange
  457. send: #onBrowserAboutToChange:
  458. to: self;
  459. on: HLParseErrorRaised
  460. send: #onParseError:
  461. to: self;
  462. on: HLCompileErrorRaised
  463. send: #onCompileError:
  464. to: self;
  465. on: HLUnknownVariableErrorRaised
  466. send: #onUnknownVariableError:
  467. to: self;
  468. on: HLInstVarAdded
  469. send: #onInstVarAdded
  470. to: self;
  471. on: HLMethodSelected
  472. send: #onMethodSelected:
  473. to: self;
  474. on: HLClassSelected
  475. send: #onClassSelected:
  476. to: self;
  477. on: HLPackageSelected
  478. send: #onPackageSelected:
  479. to: self;
  480. on: HLProtocolSelected
  481. send: #onProtocolSelected:
  482. to: self;
  483. on: HLSourceCodeFocusRequested
  484. send: #onSourceCodeFocusRequested
  485. to: self;
  486. on: HLShowTemplate
  487. send: #onShowTemplate:
  488. to: self
  489. !
  490. observeSystem
  491. self browserModel systemAnnouncer
  492. on: MethodModified
  493. send: #onMethodModified:
  494. to: self
  495. !
  496. refresh
  497. self hasModification ifTrue: [ ^ self ].
  498. self hasFocus ifTrue: [ ^ self ].
  499. self contents: self browserModel selectedMethod source
  500. !
  501. renderButtonsOn: html
  502. html button
  503. class: 'button';
  504. with: 'SaveIt';
  505. onClick: [ self saveIt ].
  506. super renderButtonsOn: html
  507. !
  508. saveIt
  509. self browserModel saveSourceCode
  510. !
  511. unregister
  512. super unregsiter.
  513. self browserModel announcer unsubscribe: self.
  514. self browserModel systemAnnouncer unsubscribe: self
  515. ! !
  516. !HLBrowserCodeWidget methodsFor: 'reactions'!
  517. onBrowserAboutToChange: anAnnouncement
  518. | block |
  519. block := anAnnouncement actionBlock.
  520. self hasModification
  521. ifTrue: [
  522. self
  523. confirm: 'Changes have not been saved. Do you want to discard these changes?'
  524. ifTrue: [
  525. "Don't ask twice"
  526. self methodContents: self contents.
  527. block value ].
  528. HLChangeForbidden signal ]
  529. !
  530. onClassSelected: anAnnouncement
  531. | class |
  532. class:= anAnnouncement item.
  533. class ifNil: [ ^ self contents: '' ].
  534. self contents: class definition
  535. !
  536. onCompileError: anAnnouncement
  537. self alert: anAnnouncement error messageText
  538. !
  539. onInstVarAdded
  540. self browserModel save: self contents
  541. !
  542. onMethodModified: anAnnouncement
  543. | method |
  544. method := anAnnouncement method.
  545. self browserModel selectedClass = method methodClass ifFalse: [ ^ self ].
  546. self browserModel selectedMethod ifNil: [ ^ self ].
  547. self browserModel selectedMethod selector = method selector ifFalse: [ ^ self ].
  548. self refresh
  549. !
  550. onMethodSelected: anAnnouncement
  551. | method |
  552. method := anAnnouncement item.
  553. method ifNil: [ ^ self contents: '' ].
  554. self contents: method source
  555. !
  556. onPackageSelected: anAnnouncement
  557. | package |
  558. package := anAnnouncement item.
  559. package ifNil: [ ^ self contents: '' ].
  560. self contents: package definition
  561. !
  562. onParseError: anAnnouncement
  563. | lineIndex newContents |
  564. lineIndex := 1.
  565. self contents: (String streamContents: [ :stream |
  566. self contents linesDo: [ :each |
  567. lineIndex = anAnnouncement line
  568. ifTrue: [
  569. stream
  570. nextPutAll: (each copyFrom: 1 to: anAnnouncement column);
  571. nextPutAll: '<- ';
  572. nextPutAll: anAnnouncement message;
  573. nextPutAll: ' ';
  574. nextPutAll: (each copyFrom: anAnnouncement column + 1 to: each size) ]
  575. ifFalse: [ stream nextPutAll: each ].
  576. stream nextPutAll: String cr.
  577. lineIndex := lineIndex + 1 ] ])
  578. !
  579. onProtocolSelected: anAnnouncement
  580. self browserModel selectedClass ifNil: [ ^ self contents: '' ].
  581. self contents: self browserModel selectedClass definition
  582. !
  583. onSaveIt
  584. self browserModel save: self contents
  585. !
  586. onShowInstanceToggled
  587. self browserModel selectedClass ifNil: [ ^ self contents: '' ].
  588. self contents: self browserModel selectedClass definition
  589. !
  590. onShowTemplate: anAnnouncement
  591. self contents: anAnnouncement template
  592. !
  593. onSourceCodeFocusRequested
  594. self focus
  595. !
  596. onSourceCodeSaved
  597. self methodContents: self contents.
  598. self updateState
  599. !
  600. onUnknownVariableError: anAnnouncement
  601. | error |
  602. error := anAnnouncement error.
  603. self
  604. confirm: (String streamContents: [ :stream |
  605. stream
  606. nextPutAll: error messageText;
  607. nextPutAll: String cr;
  608. nextPutAll: 'Would you like to define an instance variable?' ])
  609. ifTrue: [
  610. self browserModel addInstVarNamed: error variableName ]
  611. ! !
  612. !HLBrowserCodeWidget class methodsFor: 'instance creation'!
  613. on: aBrowserModel
  614. ^ self new
  615. browserModel: aBrowserModel;
  616. yourself
  617. ! !
  618. !HLBrowserCodeWidget class methodsFor: 'testing'!
  619. canBeOpenAsTab
  620. ^ false
  621. ! !
  622. HLWidget subclass: #HLWorkspace
  623. instanceVariableNames: 'codeWidget transcript'
  624. package: 'Helios-Workspace'!
  625. !HLWorkspace methodsFor: 'accessing'!
  626. codeWidget
  627. ^ codeWidget ifNil: [ codeWidget := HLCodeWidget new ]
  628. !
  629. transcript
  630. ^ transcript ifNil: [ transcript := HLTranscript new ]
  631. ! !
  632. !HLWorkspace methodsFor: 'actions'!
  633. focus
  634. ^ self codeWidget focus
  635. !
  636. unregister
  637. super unregister.
  638. self transcript unregister
  639. ! !
  640. !HLWorkspace methodsFor: 'rendering'!
  641. renderContentOn: html
  642. html with: (HLContainer with: (HLHorizontalSplitter
  643. with: self codeWidget
  644. with: [ :canvas | self renderTranscriptOn: canvas ]))
  645. !
  646. renderTranscriptOn: html
  647. html div
  648. class: 'transcript-container';
  649. with: [
  650. html div
  651. class: 'list-label';
  652. with: 'Transcript'.
  653. self transcript renderOn: html ]
  654. ! !
  655. !HLWorkspace methodsFor: 'testing'!
  656. canHaveFocus
  657. ^ true
  658. ! !
  659. !HLWorkspace class methodsFor: 'accessing'!
  660. tabClass
  661. ^ 'workspace'
  662. !
  663. tabLabel
  664. ^ 'Workspace'
  665. !
  666. tabPriority
  667. ^ 10
  668. ! !
  669. !HLWorkspace class methodsFor: 'testing'!
  670. canBeOpenAsTab
  671. ^ true
  672. ! !