Helios-Workspace.st 17 KB

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