Helios-Workspace.st 17 KB

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