Helios-Core.st 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  1. Smalltalk current createPackage: 'Helios-Core'!
  2. Object subclass: #HLModel
  3. instanceVariableNames: 'announcer environment'
  4. package: 'Helios-Core'!
  5. !HLModel commentStamp!
  6. I am the abstract superclass of all models of Helios.
  7. I am the "Model" part of the MVC pattern implementation in Helios.
  8. I provide access to an `Environment` object and both a local (model-specific) and global (system-specific) announcer.
  9. The `#withChangesDo:` method is handy for performing model changes ensuring that all widgets are aware of the change and can prevent it from happening.
  10. Modifications of the system should be done via commands (see `HLCommand` and subclasses).!
  11. !HLModel methodsFor: 'accessing'!
  12. announcer
  13. ^ announcer ifNil: [ announcer := Announcer new ]
  14. !
  15. environment
  16. ^ environment ifNil: [ self manager environment ]
  17. !
  18. environment: anEnvironment
  19. environment := anEnvironment
  20. !
  21. manager
  22. ^ HLManager current
  23. !
  24. systemAnnouncer
  25. ^ self environment systemAnnouncer
  26. ! !
  27. !HLModel methodsFor: 'error handling'!
  28. withChangesDo: aBlock
  29. [
  30. self announcer announce: (HLAboutToChange new
  31. actionBlock: aBlock).
  32. aBlock value.
  33. ]
  34. on: HLChangeForbidden
  35. do: [ :ex | ]
  36. ! !
  37. !HLModel methodsFor: 'testing'!
  38. isBrowserModel
  39. ^ false
  40. !
  41. isReferencesModel
  42. ^ false
  43. !
  44. isToolModel
  45. ^ false
  46. ! !
  47. HLModel subclass: #HLToolModel
  48. instanceVariableNames: 'selectedClass selectedPackage selectedProtocol selectedSelector'
  49. package: 'Helios-Core'!
  50. !HLToolModel commentStamp!
  51. I am a model specific to package and class manipulation. All browsers should either use me or a subclass as their model.
  52. I provide methods for package, class, protocol and method manipulation and access, forwarding to my environment.
  53. I also handle compilation of classes and methods as well as compilation and parsing errors.!
  54. !HLToolModel methodsFor: 'accessing'!
  55. allSelectors
  56. ^ self environment allSelectors
  57. !
  58. availableClassNames
  59. ^ self environment availableClassNames
  60. !
  61. availablePackageNames
  62. ^ self environment availablePackageNames
  63. !
  64. availablePackages
  65. ^ self environment availablePackageNames
  66. !
  67. availableProtocols
  68. ^ self environment availableProtocolsFor: self selectedClass
  69. !
  70. packages
  71. ^ self environment packages
  72. !
  73. selectedClass
  74. ^ selectedClass
  75. !
  76. selectedClass: aClass
  77. (self selectedClass = aClass and: [ aClass isNil ])
  78. ifTrue: [ ^ self ].
  79. self withChangesDo: [
  80. selectedClass = aClass ifTrue: [
  81. self selectedProtocol: nil ].
  82. aClass
  83. ifNil: [ selectedClass := nil ]
  84. ifNotNil: [
  85. self selectedPackage: aClass theNonMetaClass package.
  86. self showInstance
  87. ifTrue: [ selectedClass := aClass theNonMetaClass ]
  88. ifFalse: [ selectedClass := aClass theMetaClass ] ].
  89. self selectedProtocol: nil.
  90. self announcer announce: (HLClassSelected on: self selectedClass) ]
  91. !
  92. selectedMethod
  93. ^ self selectedClass ifNotNil: [
  94. self selectedClass methodDictionary
  95. at: selectedSelector
  96. ifAbsent: [ nil ] ]
  97. !
  98. selectedMethod: aCompiledMethod
  99. selectedSelector = aCompiledMethod ifTrue: [ ^ self ].
  100. self withChangesDo: [
  101. aCompiledMethod
  102. ifNil: [ selectedSelector := nil ]
  103. ifNotNil: [
  104. selectedClass := aCompiledMethod methodClass.
  105. selectedPackage := selectedClass theNonMetaClass package.
  106. selectedSelector := aCompiledMethod selector ].
  107. self announcer announce: (HLMethodSelected on: aCompiledMethod) ]
  108. !
  109. selectedPackage
  110. ^ selectedPackage
  111. !
  112. selectedPackage: aPackage
  113. selectedPackage = aPackage ifTrue: [ ^ self ].
  114. self withChangesDo: [
  115. selectedPackage := aPackage.
  116. self selectedClass: nil.
  117. self announcer announce: (HLPackageSelected on: aPackage) ]
  118. !
  119. selectedProtocol
  120. ^ selectedProtocol
  121. !
  122. selectedProtocol: aString
  123. selectedProtocol = aString ifTrue: [ ^ self ].
  124. self withChangesDo: [
  125. selectedProtocol := aString.
  126. self selectedMethod: nil.
  127. self announcer announce: (HLProtocolSelected on: aString) ]
  128. ! !
  129. !HLToolModel methodsFor: 'actions'!
  130. addInstVarNamed: aString
  131. self environment addInstVarNamed: aString to: self selectedClass.
  132. self announcer announce: (HLInstVarAdded new
  133. theClass: self selectedClass;
  134. variableName: aString;
  135. yourself)
  136. !
  137. inspect: anObject
  138. self environment inspect: anObject
  139. !
  140. save: aString
  141. self announcer announce: HLSourceCodeSaved new.
  142. (self shouldCompileClassDefinition: aString)
  143. ifTrue: [ self compileClassDefinition: aString ]
  144. ifFalse: [ self compileMethod: aString ]
  145. !
  146. saveSourceCode
  147. self announcer announce: HLSaveSourceCode new
  148. ! !
  149. !HLToolModel methodsFor: 'commands actions'!
  150. commitPackage
  151. "self
  152. withHelperLabelled: 'Committing package ', self selectedPackage name, '...'
  153. do: [ "self environment commitPackage: self selectedPackage" ]"
  154. !
  155. copyClassTo: aClassName
  156. self withChangesDo: [
  157. self environment
  158. copyClass: self selectedClass theNonMetaClass
  159. to: aClassName ]
  160. !
  161. moveClassToPackage: aPackageName
  162. self withChangesDo: [
  163. self environment
  164. moveClass: self selectedClass theNonMetaClass
  165. toPackage: aPackageName ]
  166. !
  167. moveMethodToClass: aClassName
  168. self withChangesDo: [
  169. self environment
  170. moveMethod: self selectedMethod
  171. toClass: aClassName ]
  172. !
  173. moveMethodToProtocol: aProtocol
  174. self withChangesDo: [
  175. self environment
  176. moveMethod: self selectedMethod
  177. toProtocol: aProtocol ]
  178. !
  179. openClassNamed: aString
  180. | class |
  181. self withChangesDo: [
  182. class := self environment classNamed: aString.
  183. self selectedPackage: class package.
  184. self selectedClass: class ]
  185. !
  186. removeClass
  187. self withChangesDo: [
  188. self manager
  189. confirm: 'Do you REALLY want to remove class ', self selectedClass name
  190. ifTrue: [ self environment removeClass: self selectedClass ] ]
  191. !
  192. removeMethod
  193. self withChangesDo: [
  194. self manager
  195. confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector
  196. ifTrue: [ self environment removeMethod: self selectedMethod ] ]
  197. !
  198. removeProtocol
  199. self withChangesDo: [
  200. self manager
  201. confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol
  202. ifTrue: [ self environment
  203. removeProtocol: self selectedProtocol
  204. from: self selectedClass ] ]
  205. !
  206. renameClassTo: aClassName
  207. self withChangesDo: [
  208. self environment
  209. renameClass: self selectedClass theNonMetaClass
  210. to: aClassName ]
  211. !
  212. renameProtocolTo: aString
  213. self withChangesDo: [
  214. self environment
  215. renameProtocol: self selectedProtocol
  216. to: aString
  217. in: self selectedClass ]
  218. ! !
  219. !HLToolModel methodsFor: 'compiling'!
  220. compileClassComment: aString
  221. self environment
  222. compileClassComment: aString
  223. for: self selectedClass
  224. !
  225. compileClassDefinition: aString
  226. self environment compileClassDefinition: aString
  227. !
  228. compileMethod: aString
  229. | method |
  230. self withCompileErrorHandling: [
  231. method := self environment
  232. compileMethod: aString
  233. for: self selectedClass
  234. protocol: self compilationProtocol.
  235. self selectedMethod: method ]
  236. ! !
  237. !HLToolModel methodsFor: 'defaults'!
  238. allProtocol
  239. ^ '-- all --'
  240. !
  241. unclassifiedProtocol
  242. ^ 'as yet unclassified'
  243. ! !
  244. !HLToolModel methodsFor: 'error handling'!
  245. handleCompileError: anError
  246. self announcer announce: (HLCompileErrorRaised new
  247. error: anError;
  248. yourself)
  249. !
  250. handleParseError: anError
  251. | split line column messageToInsert |
  252. split := anError messageText tokenize: ' : '.
  253. messageToInsert := split second.
  254. "21 = 'Parse error on line ' size + 1"
  255. split := split first copyFrom: 21 to: split first size.
  256. split := split tokenize: ' column '.
  257. line := split first.
  258. column := split second.
  259. self announcer announce: (HLParseErrorRaised new
  260. line: line asNumber;
  261. column: column asNumber;
  262. message: messageToInsert;
  263. error: anError;
  264. yourself)
  265. !
  266. handleUnkownVariableError: anError
  267. self announcer announce: (HLUnknownVariableErrorRaised new
  268. error: anError;
  269. yourself)
  270. !
  271. withCompileErrorHandling: aBlock
  272. self environment
  273. evaluate: [
  274. self environment
  275. evaluate: [
  276. self environment
  277. evaluate: aBlock
  278. on: ParseError
  279. do: [:ex | self handleParseError: ex ] ]
  280. on: UnknownVariableError
  281. do: [ :ex | self handleUnkownVariableError: ex ] ]
  282. on: CompilerError
  283. do: [ :ex | self handleCompileError: ex ]
  284. ! !
  285. !HLToolModel methodsFor: 'private'!
  286. compilationProtocol
  287. | currentProtocol |
  288. currentProtocol := self selectedProtocol.
  289. currentProtocol ifNil: [ currentProtocol := self unclassifiedProtocol ].
  290. self selectedMethod ifNotNil: [ currentProtocol := self selectedMethod protocol ].
  291. ^ currentProtocol = self allProtocol
  292. ifTrue: [ self unclassifiedProtocol ]
  293. ifFalse: [ currentProtocol ]
  294. !
  295. withHelperLabelled: aString do: aBlock
  296. "TODO: doesn't belong here"
  297. (window jQuery: '#helper') remove.
  298. [ :html |
  299. html div
  300. id: 'helper';
  301. with: aString ] appendToJQuery: 'body' asJQuery.
  302. [
  303. aBlock value.
  304. (window jQuery: '#helper') remove
  305. ]
  306. valueWithTimeout: 10
  307. ! !
  308. !HLToolModel methodsFor: 'testing'!
  309. isToolModel
  310. ^ true
  311. !
  312. shouldCompileClassDefinition: aString
  313. ^ self selectedClass isNil or: [
  314. aString match: '^[A-Z]' ]
  315. ! !
  316. !HLToolModel class methodsFor: 'actions'!
  317. on: anEnvironment
  318. ^ self new
  319. environment: anEnvironment;
  320. yourself
  321. ! !
  322. ProgressHandler subclass: #HLProgressHandler
  323. instanceVariableNames: ''
  324. package: 'Helios-Core'!
  325. !HLProgressHandler commentStamp!
  326. I am a specific progress handler for Helios, displaying progresses in a modal window.!
  327. !HLProgressHandler methodsFor: 'progress handling'!
  328. do: aBlock on: aCollection displaying: aString
  329. HLProgressWidget default
  330. do: aBlock
  331. on: aCollection
  332. displaying: aString
  333. ! !
  334. Widget subclass: #HLTabWidget
  335. instanceVariableNames: 'widget label root'
  336. package: 'Helios-Core'!
  337. !HLTabWidget commentStamp!
  338. I am a widget specialized into building another widget as an Helios tab.
  339. I should not be used directly, `HLWidget class >> #openAsTab` should be used instead.
  340. ## Example
  341. HLWorkspace openAsTab!
  342. !HLTabWidget methodsFor: 'accessing'!
  343. activate
  344. self manager activate: self
  345. !
  346. add
  347. self manager addTab: self
  348. !
  349. cssClass
  350. ^ self widget tabClass
  351. !
  352. displayLabel
  353. ^ self label size > 20
  354. ifTrue: [ (self label first: 20), '...' ]
  355. ifFalse: [ self label ]
  356. !
  357. focus
  358. self widget canHaveFocus ifTrue: [
  359. self widget focus ]
  360. !
  361. label
  362. ^ label ifNil: [ '' ]
  363. !
  364. label: aString
  365. label := aString
  366. !
  367. manager
  368. ^ HLManager current
  369. !
  370. widget
  371. ^ widget
  372. !
  373. widget: aWidget
  374. widget := aWidget
  375. ! !
  376. !HLTabWidget methodsFor: 'actions'!
  377. hide
  378. root ifNotNil: [ root asJQuery css: 'visibility' put: 'hidden' ]
  379. !
  380. registerBindings
  381. self widget registerBindings
  382. !
  383. remove
  384. self widget unregister.
  385. root ifNotNil: [ root asJQuery remove ]
  386. !
  387. show
  388. root
  389. ifNil: [ self appendToJQuery: 'body' asJQuery ]
  390. ifNotNil: [ root asJQuery css: 'visibility' put: 'visible' ]
  391. ! !
  392. !HLTabWidget methodsFor: 'rendering'!
  393. renderOn: html
  394. root := html div
  395. class: 'tab';
  396. yourself.
  397. self renderTab
  398. !
  399. renderTab
  400. root contents: [ :html |
  401. html div
  402. class: 'amber_box';
  403. with: [ self widget renderOn: html ] ]
  404. ! !
  405. !HLTabWidget methodsFor: 'testing'!
  406. isActive
  407. ^ self manager activeTab = self
  408. ! !
  409. !HLTabWidget class methodsFor: 'instance creation'!
  410. on: aWidget labelled: aString
  411. ^ self new
  412. widget: aWidget;
  413. label: aString;
  414. yourself
  415. ! !
  416. Widget subclass: #HLWidget
  417. instanceVariableNames: 'wrapper'
  418. package: 'Helios-Core'!
  419. !HLWidget commentStamp!
  420. I am the abstract superclass of all Helios widgets.
  421. I provide common methods, additional behavior to widgets useful for Helios, like dialog creation, command execution and tab creation.
  422. ## API
  423. 1. Rendering
  424. Instead of overriding `#renderOn:` as with other Widget subclasses, my subclasses should override `#renderContentOn:`.
  425. 2. Refreshing
  426. To re-render a widget, use `#refresh`.
  427. 3. Key bindings registration and tabs
  428. When displayed as a tab, the widget has a chance to register keybindings with the `#registerBindingsOn:` hook method.
  429. 4. Unregistration
  430. When a widget has subscribed to announcements or other actions that need to be cleared when closing the tab, the hook method `#unregister` will be called by helios.
  431. 5. Tabs
  432. To enable a widget class to be open as a tab, override the class-side `#canBeOpenAsTab` method to answer `true`. `#tabClass` and `#tabPriority` can be overridden too to respectively change the css class of the tab and the order of tabs in the main menu.
  433. 6. Command execution
  434. An helios command (instance of `HLCommand` or one of its subclass) can be executed with `#execute:`.!
  435. !HLWidget methodsFor: 'accessing'!
  436. manager
  437. ^ HLManager current
  438. !
  439. tabClass
  440. ^ self class tabClass
  441. !
  442. wrapper
  443. ^ wrapper
  444. ! !
  445. !HLWidget methodsFor: 'actions'!
  446. alert: aString
  447. window alert: aString
  448. !
  449. confirm: aString ifTrue: aBlock
  450. self manager confirm: aString ifTrue: aBlock
  451. !
  452. execute: aCommand
  453. HLManager current keyBinder
  454. activate;
  455. applyBinding: aCommand asBinding
  456. !
  457. openAsTab
  458. HLManager current addTab: (HLTabWidget on: self labelled: self class tabLabel)
  459. !
  460. request: aString do: aBlock
  461. self manager request: aString do: aBlock
  462. !
  463. request: aString value: valueString do: aBlock
  464. self manager
  465. request: aString
  466. value: valueString
  467. do: aBlock
  468. !
  469. unregister
  470. "This method is called whenever the receiver is closed (as a tab).
  471. Widgets subscribing to announcements should unregister there"
  472. ! !
  473. !HLWidget methodsFor: 'keybindings'!
  474. registerBindings
  475. self registerBindingsOn: self manager keyBinder bindings
  476. !
  477. registerBindingsOn: aBindingGroup
  478. ! !
  479. !HLWidget methodsFor: 'rendering'!
  480. renderContentOn: html
  481. !
  482. renderOn: html
  483. wrapper := html div.
  484. [ :renderer | self renderContentOn: renderer ] appendToJQuery: wrapper asJQuery
  485. ! !
  486. !HLWidget methodsFor: 'testing'!
  487. canHaveFocus
  488. ^ false
  489. ! !
  490. !HLWidget methodsFor: 'updating'!
  491. refresh
  492. self wrapper ifNil: [ ^ self ].
  493. self wrapper asJQuery empty.
  494. [ :html | self renderContentOn: html ] appendToJQuery: self wrapper asJQuery
  495. ! !
  496. !HLWidget class methodsFor: 'accessing'!
  497. openAsTab
  498. HLManager current addTab: (HLTabWidget on: self new labelled: self tabLabel)
  499. !
  500. tabClass
  501. ^ ''
  502. !
  503. tabLabel
  504. ^ 'Tab'
  505. !
  506. tabPriority
  507. ^ 500
  508. ! !
  509. !HLWidget class methodsFor: 'testing'!
  510. canBeOpenAsTab
  511. ^ false
  512. ! !
  513. HLWidget subclass: #HLFocusableWidget
  514. instanceVariableNames: ''
  515. package: 'Helios-Core'!
  516. !HLFocusableWidget commentStamp!
  517. I am a widget that can be focused.
  518. ## API
  519. Instead of overriding `#renderOn:` as with other `Widget` subclasses, my subclasses should override `#renderContentOn:`.
  520. To bring the focus to the widget, use the `#focus` method.!
  521. !HLFocusableWidget methodsFor: 'accessing'!
  522. focusClass
  523. ^ 'focused'
  524. ! !
  525. !HLFocusableWidget methodsFor: 'events'!
  526. blur
  527. self wrapper asJQuery blur
  528. !
  529. focus
  530. self wrapper asJQuery focus
  531. !
  532. hasFocus
  533. ^ self wrapper notNil and: [ self wrapper asJQuery is: ':focus' ]
  534. ! !
  535. !HLFocusableWidget methodsFor: 'rendering'!
  536. renderContentOn: html
  537. !
  538. renderOn: html
  539. wrapper := html div
  540. class: 'hl_widget';
  541. yourself.
  542. wrapper with: [ self renderContentOn: html ].
  543. wrapper
  544. at: 'tabindex' put: '0';
  545. onBlur: [ self wrapper asJQuery removeClass: self focusClass ];
  546. onFocus: [ self wrapper asJQuery addClass: self focusClass ]
  547. ! !
  548. !HLFocusableWidget methodsFor: 'testing'!
  549. canHaveFocus
  550. ^ true
  551. ! !
  552. HLFocusableWidget subclass: #HLListWidget
  553. instanceVariableNames: 'items selectedItem mapping'
  554. package: 'Helios-Core'!
  555. !HLListWidget methodsFor: 'accessing'!
  556. cssClassForItem: anObject
  557. ^ ''
  558. !
  559. items
  560. ^ items ifNil: [ items := self defaultItems ]
  561. !
  562. items: aCollection
  563. items := aCollection
  564. !
  565. listCssClassForItem: anObject
  566. ^ self selectedItem = anObject
  567. ifTrue: [ 'active' ]
  568. ifFalse: [ 'inactive' ]
  569. !
  570. positionOf: aListItem
  571. <
  572. return aListItem.parent().children().get().indexOf(aListItem.get(0)) + 1
  573. >
  574. !
  575. selectedItem
  576. ^ selectedItem
  577. !
  578. selectedItem: anObject
  579. selectedItem := anObject
  580. ! !
  581. !HLListWidget methodsFor: 'actions'!
  582. activateFirstListItem
  583. self activateListItem: (window jQuery: ((wrapper asJQuery find: 'li.inactive') get: 0))
  584. !
  585. activateItem: anObject
  586. self activateListItem: (mapping
  587. at: anObject
  588. ifAbsent: [ ^ self ]) asJQuery
  589. !
  590. activateListItem: aListItem
  591. | item |
  592. (aListItem get: 0) ifNil: [ ^self ].
  593. aListItem parent children removeClass: 'active'.
  594. aListItem addClass: 'active'.
  595. self ensureVisible: aListItem.
  596. "Activate the corresponding item"
  597. item := (self items at: (aListItem attr: 'list-data') asNumber).
  598. self selectedItem == item ifFalse: [
  599. self selectItem: item ]
  600. !
  601. activateNextListItem
  602. self activateListItem: (self wrapper asJQuery find: 'li.active') next.
  603. "select the first item if none is selected"
  604. (self wrapper asJQuery find: ' .active') get ifEmpty: [
  605. self activateFirstListItem ]
  606. !
  607. activatePreviousListItem
  608. self activateListItem: (self wrapper asJQuery find: 'li.active') prev
  609. !
  610. ensureVisible: aListItem
  611. "Move the scrollbar to show the active element"
  612. | perent position |
  613. position := self positionOf: aListItem.
  614. parent := aListItem parent.
  615. aListItem position top < 0 ifTrue: [
  616. (parent get: 0) scrollTop: ((parent get: 0) scrollTop + aListItem position top - 10) ].
  617. aListItem position top + aListItem height > parent height ifTrue: [
  618. (parent get: 0) scrollTop: ((parent get: 0) scrollTop + aListItem height - (parent height - aListItem position top)) +10 ]
  619. !
  620. focus
  621. super focus.
  622. self items isEmpty ifFalse: [
  623. self selectedItem ifNil: [ self activateFirstListItem ] ]
  624. !
  625. refresh
  626. super refresh.
  627. self ensureVisible: (mapping
  628. at: self selectedItem
  629. ifAbsent: [ ^ self ]) asJQuery
  630. !
  631. selectItem: anObject
  632. self selectedItem: anObject
  633. ! !
  634. !HLListWidget methodsFor: 'defaults'!
  635. defaultItems
  636. ^ #()
  637. ! !
  638. !HLListWidget methodsFor: 'events'!
  639. setupKeyBindings
  640. "TODO: refactor this!!"
  641. | active interval delay repeatInterval |
  642. active := false.
  643. repeatInterval := 70.
  644. self wrapper asJQuery unbind: 'keydown'.
  645. self wrapper asJQuery keydown: [ :e |
  646. (e which = 38 and: [ active = false ]) ifTrue: [
  647. active := true.
  648. self activatePreviousListItem.
  649. delay := [
  650. interval := [
  651. (self wrapper asJQuery hasClass: self focusClass)
  652. ifTrue: [
  653. self activatePreviousListItem ]
  654. ifFalse: [
  655. active := false.
  656. interval ifNotNil: [ interval clearInterval ].
  657. delay ifNotNil: [ delay clearTimeout] ] ]
  658. valueWithInterval: repeatInterval ]
  659. valueWithTimeout: 300 ].
  660. (e which = 40 and: [ active = false ]) ifTrue: [
  661. active := true.
  662. self activateNextListItem.
  663. delay := [
  664. interval := [
  665. (self wrapper asJQuery hasClass: self focusClass)
  666. ifTrue: [
  667. self activateNextListItem ]
  668. ifFalse: [
  669. active := false.
  670. interval ifNotNil: [ interval clearInterval ].
  671. delay ifNotNil: [ delay clearTimeout] ] ]
  672. valueWithInterval: repeatInterval ]
  673. valueWithTimeout: 300 ] ].
  674. self wrapper asJQuery keyup: [ :e |
  675. active ifTrue: [
  676. active := false.
  677. interval ifNotNil: [ interval clearInterval ].
  678. delay ifNotNil: [ delay clearTimeout] ] ]
  679. ! !
  680. !HLListWidget methodsFor: 'initialization'!
  681. initialize
  682. super initialize.
  683. mapping := Dictionary new.
  684. ! !
  685. !HLListWidget methodsFor: 'private'!
  686. registerMappingFrom: anObject to: aTag
  687. mapping at: anObject put: aTag
  688. ! !
  689. !HLListWidget methodsFor: 'rendering'!
  690. renderButtonsOn: html
  691. !
  692. renderContentOn: html
  693. html ul
  694. class: 'nav nav-pills nav-stacked';
  695. with: [ self renderListOn: html ].
  696. html div class: 'pane_actions form-actions'; with: [
  697. self renderButtonsOn: html ].
  698. self setupKeyBindings
  699. !
  700. renderItem: anObject on: html
  701. | li |
  702. li := html li.
  703. self registerMappingFrom: anObject to: li.
  704. li
  705. at: 'list-data' put: (self items indexOf: anObject) asString;
  706. class: (self listCssClassForItem: anObject);
  707. with: [
  708. html a
  709. with: [
  710. (html tag: 'i') class: (self cssClassForItem: anObject).
  711. self renderItemLabel: anObject on: html ];
  712. onClick: [
  713. self activateListItem: li asJQuery ] ]
  714. !
  715. renderItemLabel: anObject on: html
  716. html with: anObject asString
  717. !
  718. renderListOn: html
  719. mapping := Dictionary new.
  720. self items do: [ :each |
  721. self renderItem: each on: html ]
  722. ! !
  723. HLListWidget subclass: #HLNavigationListWidget
  724. instanceVariableNames: 'previous next'
  725. package: 'Helios-Core'!
  726. !HLNavigationListWidget methodsFor: 'accessing'!
  727. next
  728. ^ next
  729. !
  730. next: aWidget
  731. next := aWidget.
  732. aWidget previous = self ifFalse: [ aWidget previous: self ]
  733. !
  734. previous
  735. ^ previous
  736. !
  737. previous: aWidget
  738. previous := aWidget.
  739. aWidget next = self ifFalse: [ aWidget next: self ]
  740. ! !
  741. !HLNavigationListWidget methodsFor: 'actions'!
  742. nextFocus
  743. self next ifNotNil: [ self next focus ]
  744. !
  745. previousFocus
  746. self previous ifNotNil: [ self previous focus ]
  747. ! !
  748. !HLNavigationListWidget methodsFor: 'events'!
  749. setupKeyBindings
  750. super setupKeyBindings.
  751. self wrapper asJQuery keydown: [ :e |
  752. e which = 39 ifTrue: [
  753. self nextFocus ].
  754. e which = 37 ifTrue: [
  755. self previousFocus ] ]
  756. ! !
  757. HLNavigationListWidget subclass: #HLToolListWidget
  758. instanceVariableNames: 'model'
  759. package: 'Helios-Core'!
  760. !HLToolListWidget methodsFor: 'accessing'!
  761. commandCategory
  762. ^ self label
  763. !
  764. label
  765. ^ 'List'
  766. !
  767. menuCommands
  768. "Answer a collection of commands to be put in the cog menu"
  769. ^ ((HLToolCommand concreteClasses
  770. select: [ :each | each isValidFor: self model ])
  771. collect: [ :each | each for: self model ])
  772. select: [ :each |
  773. each category = self commandCategory and: [
  774. each isAction and: [ each isActive ] ] ]
  775. !
  776. model
  777. ^ model
  778. !
  779. model: aBrowserModel
  780. model := aBrowserModel.
  781. self
  782. observeSystem;
  783. observeModel
  784. !
  785. selectedItem: anItem
  786. "Selection changed, update the cog menu"
  787. super selectedItem: anItem.
  788. self updateMenu
  789. ! !
  790. !HLToolListWidget methodsFor: 'actions'!
  791. activateListItem: anItem
  792. self model withChangesDo: [ super activateListItem: anItem ]
  793. !
  794. activateNextListItem
  795. self model withChangesDo: [ super activateNextListItem ]
  796. !
  797. activatePreviousListItem
  798. self model withChangesDo: [ super activatePreviousListItem ]
  799. !
  800. observeModel
  801. !
  802. observeSystem
  803. !
  804. unregister
  805. super unregister.
  806. self model announcer unsubscribe: self.
  807. self model systemAnnouncer unsubscribe: self
  808. ! !
  809. !HLToolListWidget methodsFor: 'rendering'!
  810. renderContentOn: html
  811. self renderHeadOn: html.
  812. super renderContentOn: html
  813. !
  814. renderHeadOn: html
  815. html div
  816. class: 'list-label';
  817. with: [
  818. html with: self label.
  819. self renderMenuOn: html ]
  820. !
  821. renderMenuOn: html
  822. | commands |
  823. commands := self menuCommands.
  824. commands isEmpty ifTrue: [ ^ self ].
  825. html div
  826. class: 'btn-group cog';
  827. with: [
  828. html a
  829. class: 'btn dropdown-toggle';
  830. at: 'data-toggle' put: 'dropdown';
  831. with: [ (html tag: 'i') class: 'icon-cog' ].
  832. html ul
  833. class: 'dropdown-menu pull-right';
  834. with: [
  835. self menuCommands do: [ :each |
  836. html li with: [ html a
  837. with: each menuLabel;
  838. onClick: [ self execute: each ] ] ] ] ]
  839. ! !
  840. !HLToolListWidget methodsFor: 'updating'!
  841. updateMenu
  842. (self wrapper asJQuery find: '.cog') remove.
  843. [ :html | self renderMenuOn: html ]
  844. appendToJQuery: (self wrapper asJQuery find: '.list-label')
  845. ! !
  846. !HLToolListWidget class methodsFor: 'instance creation'!
  847. on: aModel
  848. ^ self new
  849. model: aModel;
  850. yourself
  851. ! !
  852. HLWidget subclass: #HLManager
  853. instanceVariableNames: 'tabs activeTab keyBinder environment history'
  854. package: 'Helios-Core'!
  855. !HLManager methodsFor: 'accessing'!
  856. activeTab
  857. ^ activeTab
  858. !
  859. environment
  860. "The default environment used by all Helios objects"
  861. ^ environment ifNil: [ environment := self defaultEnvironment ]
  862. !
  863. environment: anEnvironment
  864. environment := anEnvironment
  865. !
  866. history
  867. ^ history ifNil: [ history := OrderedCollection new ]
  868. !
  869. history: aCollection
  870. history := aCollection
  871. !
  872. keyBinder
  873. ^ keyBinder ifNil: [ keyBinder := HLKeyBinder new ]
  874. !
  875. tabs
  876. ^ tabs ifNil: [ tabs := OrderedCollection new ]
  877. ! !
  878. !HLManager methodsFor: 'actions'!
  879. activate: aTab
  880. self keyBinder flushBindings.
  881. aTab registerBindings.
  882. activeTab := aTab.
  883. self
  884. refresh;
  885. addToHistory: aTab;
  886. show: aTab
  887. !
  888. addTab: aTab
  889. self tabs add: aTab.
  890. self activate: aTab
  891. !
  892. addToHistory: aTab
  893. self removeFromHistory: aTab.
  894. self history add: aTab
  895. !
  896. confirm: aString ifFalse: aBlock
  897. (HLConfirmationWidget new
  898. confirmationString: aString;
  899. cancelBlock: aBlock;
  900. yourself)
  901. appendToJQuery: 'body' asJQuery
  902. !
  903. confirm: aString ifTrue: aBlock
  904. (HLConfirmationWidget new
  905. confirmationString: aString;
  906. actionBlock: aBlock;
  907. yourself)
  908. appendToJQuery: 'body' asJQuery
  909. !
  910. registerErrorHandler: anErrorHandler
  911. self environment registerErrorHandler: anErrorHandler
  912. !
  913. registerInspector: anInspector
  914. self environment registerInspector: anInspector
  915. !
  916. registerProgressHandler: aProgressHandler
  917. self environment registerProgressHandler: aProgressHandler
  918. !
  919. removeActiveTab
  920. self removeTab: self activeTab
  921. !
  922. removeFromHistory: aTab
  923. self history: (self history reject: [ :each | each == aTab ])
  924. !
  925. removeTab: aTab
  926. (self tabs includes: aTab) ifFalse: [ ^ self ].
  927. self removeFromHistory: aTab.
  928. self tabs remove: aTab.
  929. self keyBinder flushBindings.
  930. aTab remove.
  931. self refresh.
  932. self history ifNotEmpty: [
  933. self history last activate ]
  934. !
  935. request: aString do: aBlock
  936. self
  937. request: aString
  938. value: ''
  939. do: aBlock
  940. !
  941. request: aString value: valueString do: aBlock
  942. (HLRequestWidget new
  943. confirmationString: aString;
  944. actionBlock: aBlock;
  945. value: valueString;
  946. yourself)
  947. appendToJQuery: 'body' asJQuery
  948. ! !
  949. !HLManager methodsFor: 'defaults'!
  950. defaultEnvironment
  951. "If helios is loaded from within a frame, answer the parent window environment"
  952. | parent |
  953. parent := window opener ifNil: [ window parent ].
  954. parent ifNil: [ ^ Environment new ].
  955. ^ ((parent at: 'smalltalk')
  956. at: 'Environment') new
  957. ! !
  958. !HLManager methodsFor: 'initialization'!
  959. initialize
  960. super initialize.
  961. HLErrorHandler register.
  962. HLProgressHandler register.
  963. self registerInspector: HLInspector.
  964. self registerErrorHandler: ErrorHandler current.
  965. self registerProgressHandler: ProgressHandler current.
  966. self keyBinder setupEvents
  967. ! !
  968. !HLManager methodsFor: 'rendering'!
  969. refresh
  970. (window jQuery: '.navbar') remove.
  971. self appendToJQuery: 'body' asJQuery
  972. !
  973. renderAddOn: html
  974. html li
  975. class: 'dropdown';
  976. with: [
  977. html a
  978. class: 'dropdown-toggle';
  979. at: 'data-toggle' put: 'dropdown';
  980. with: [
  981. html with: 'Open...'.
  982. (html tag: 'b') class: 'caret' ].
  983. html ul
  984. class: 'dropdown-menu';
  985. with: [
  986. ((HLWidget withAllSubclasses
  987. select: [ :each | each canBeOpenAsTab ])
  988. sorted: [ :a :b | a tabPriority < b tabPriority ])
  989. do: [ :each |
  990. html li with: [
  991. html a
  992. with: each tabLabel;
  993. onClick: [ each openAsTab ] ] ] ] ]
  994. !
  995. renderContentOn: html
  996. html div
  997. class: 'navbar navbar-fixed-top';
  998. with: [ html div
  999. class: 'navbar-inner';
  1000. with: [ self renderTabsOn: html ] ]
  1001. !
  1002. renderTabsOn: html
  1003. html ul
  1004. class: 'nav';
  1005. with: [
  1006. self tabs do: [ :each |
  1007. html li
  1008. class: (each isActive ifTrue: [ 'active' ] ifFalse: [ 'inactive' ]);
  1009. with: [
  1010. html a
  1011. with: [
  1012. ((html tag: 'i') class: 'close')
  1013. onClick: [ self removeTab: each ].
  1014. html span
  1015. class: each cssClass;
  1016. with: each displayLabel ];
  1017. onClick: [ each activate ] ] ].
  1018. self renderAddOn: html ]
  1019. !
  1020. show: aTab
  1021. self tabs do: [ :each | each hide ].
  1022. aTab show; focus
  1023. ! !
  1024. HLManager class instanceVariableNames: 'current'!
  1025. !HLManager class methodsFor: 'accessing'!
  1026. current
  1027. ^ current ifNil: [ current := self basicNew initialize ]
  1028. ! !
  1029. !HLManager class methodsFor: 'initialization'!
  1030. initialize
  1031. self current appendToJQuery: 'body' asJQuery
  1032. ! !
  1033. !HLManager class methodsFor: 'instance creation'!
  1034. new
  1035. "Use current instead"
  1036. self shouldNotImplement
  1037. ! !
  1038. HLWidget subclass: #HLModalWidget
  1039. instanceVariableNames: ''
  1040. package: 'Helios-Core'!
  1041. !HLModalWidget commentStamp!
  1042. I implement an abstract modal widget.!
  1043. !HLModalWidget methodsFor: 'accessing'!
  1044. cssClass
  1045. ^ ''
  1046. ! !
  1047. !HLModalWidget methodsFor: 'actions'!
  1048. cancel
  1049. self remove
  1050. !
  1051. remove
  1052. (window jQuery: '.dialog') removeClass: 'active'.
  1053. [
  1054. (window jQuery: '#overlay') remove.
  1055. (window jQuery: '.dialog') remove
  1056. ] valueWithTimeout: 300
  1057. ! !
  1058. !HLModalWidget methodsFor: 'rendering'!
  1059. renderButtonsOn: html
  1060. !
  1061. renderContentOn: html
  1062. | confirmButton |
  1063. html div id: 'overlay'.
  1064. html div
  1065. class: 'dialog ', self cssClass;
  1066. with: [
  1067. self
  1068. renderMainOn: html;
  1069. renderButtonsOn: html ].
  1070. (window jQuery: '.dialog') addClass: 'active'.
  1071. self setupKeyBindings
  1072. !
  1073. renderMainOn: html
  1074. !
  1075. setupKeyBindings
  1076. (window jQuery: '.dialog') keyup: [ :e |
  1077. e keyCode = 27 ifTrue: [ self cancel ] ]
  1078. ! !
  1079. HLModalWidget subclass: #HLConfirmationWidget
  1080. instanceVariableNames: 'confirmationString actionBlock cancelBlock'
  1081. package: 'Helios-Core'!
  1082. !HLConfirmationWidget commentStamp!
  1083. I display confirmation messages.
  1084. Instead of creating an instance directly, use `HLWidget >> #confirm:ifTrue:`.!
  1085. !HLConfirmationWidget methodsFor: 'accessing'!
  1086. actionBlock
  1087. ^ actionBlock ifNil: [ [] ]
  1088. !
  1089. actionBlock: aBlock
  1090. actionBlock := aBlock
  1091. !
  1092. cancelBlock
  1093. ^ cancelBlock ifNil: [ [] ]
  1094. !
  1095. cancelBlock: aBlock
  1096. cancelBlock := aBlock
  1097. !
  1098. confirmationString
  1099. ^ confirmationString ifNil: [ 'Confirm' ]
  1100. !
  1101. confirmationString: aString
  1102. confirmationString := aString
  1103. ! !
  1104. !HLConfirmationWidget methodsFor: 'actions'!
  1105. cancel
  1106. self cancelBlock value.
  1107. self remove
  1108. !
  1109. confirm
  1110. self actionBlock value.
  1111. self remove
  1112. !
  1113. remove
  1114. (window jQuery: '.dialog') removeClass: 'active'.
  1115. [
  1116. (window jQuery: '#overlay') remove.
  1117. (window jQuery: '.dialog') remove
  1118. ] valueWithTimeout: 300
  1119. ! !
  1120. !HLConfirmationWidget methodsFor: 'rendering'!
  1121. renderButtonsOn: html
  1122. | confirmButton |
  1123. html div
  1124. class: 'buttons';
  1125. with: [
  1126. html button
  1127. class: 'button';
  1128. with: 'Cancel';
  1129. onClick: [ self cancel ].
  1130. confirmButton := html button
  1131. class: 'button default';
  1132. with: 'Confirm';
  1133. onClick: [ self confirm ] ].
  1134. confirmButton asJQuery focus
  1135. !
  1136. renderMainOn: html
  1137. html span with: self confirmationString
  1138. ! !
  1139. HLConfirmationWidget subclass: #HLRequestWidget
  1140. instanceVariableNames: 'input value'
  1141. package: 'Helios-Core'!
  1142. !HLRequestWidget commentStamp!
  1143. I display a modal window requesting user input.
  1144. Instead of creating instances manually, use `HLWidget >> #request:do:` and `#request:value:do:`.!
  1145. !HLRequestWidget methodsFor: 'accessing'!
  1146. cssClass
  1147. ^ 'large'
  1148. !
  1149. value
  1150. ^ value ifNil: [ '' ]
  1151. !
  1152. value: aString
  1153. value := aString
  1154. ! !
  1155. !HLRequestWidget methodsFor: 'actions'!
  1156. confirm
  1157. self actionBlock value: input asJQuery val.
  1158. self remove
  1159. ! !
  1160. !HLRequestWidget methodsFor: 'rendering'!
  1161. renderMainOn: html
  1162. super renderMainOn: html.
  1163. input := html textarea.
  1164. input asJQuery val: self value
  1165. ! !
  1166. HLModalWidget subclass: #HLProgressWidget
  1167. instanceVariableNames: 'progressBars visible'
  1168. package: 'Helios-Core'!
  1169. !HLProgressWidget commentStamp!
  1170. I am a widget used to display progress modal dialogs.
  1171. My default instance is accessed with `HLProgressWidget class >> #default`.
  1172. See `HLProgressHandler` for usage.!
  1173. !HLProgressWidget methodsFor: 'accessing'!
  1174. progressBars
  1175. ^ progressBars ifNil: [ progressBars := OrderedCollection new ]
  1176. ! !
  1177. !HLProgressWidget methodsFor: 'actions'!
  1178. addProgressBar: aProgressBar
  1179. self show.
  1180. self progressBars add: aProgressBar.
  1181. aProgressBar appendToJQuery: (self wrapper asJQuery find: '.dialog')
  1182. !
  1183. do: aBlock on: aCollection displaying: aString
  1184. | progressBar |
  1185. progressBar := HLProgressBarWidget new
  1186. parent: self;
  1187. label: aString;
  1188. workBlock: aBlock;
  1189. collection: aCollection;
  1190. yourself.
  1191. self addProgressBar: progressBar.
  1192. progressBar start
  1193. !
  1194. flush
  1195. self progressBars do: [ :each |
  1196. self removeProgressBar: each ]
  1197. !
  1198. remove
  1199. self isVisible ifTrue: [
  1200. visible := false.
  1201. super remove ]
  1202. !
  1203. removeProgressBar: aProgressBar
  1204. self progressBars remove: aProgressBar ifAbsent: [].
  1205. aProgressBar wrapper asJQuery remove.
  1206. self progressBars ifEmpty: [ self remove ]
  1207. !
  1208. show
  1209. self isVisible ifFalse: [
  1210. visible := true.
  1211. self appendToJQuery: 'body' asJQuery ]
  1212. ! !
  1213. !HLProgressWidget methodsFor: 'rendering'!
  1214. renderButtonsOn: html
  1215. !
  1216. renderMainOn: html
  1217. self progressBars do: [ :each |
  1218. html with: each ]
  1219. ! !
  1220. !HLProgressWidget methodsFor: 'testing'!
  1221. isVisible
  1222. ^ visible ifNil: [ false ]
  1223. ! !
  1224. HLProgressWidget class instanceVariableNames: 'default'!
  1225. !HLProgressWidget class methodsFor: 'accessing'!
  1226. default
  1227. ^ default ifNil: [ default := self new ]
  1228. ! !
  1229. HLWidget subclass: #HLProgressBarWidget
  1230. instanceVariableNames: 'label parent workBlock collection bar'
  1231. package: 'Helios-Core'!
  1232. !HLProgressBarWidget commentStamp!
  1233. I am a widget used to display a progress bar while iterating over a collection.!
  1234. !HLProgressBarWidget methodsFor: 'accessing'!
  1235. collection
  1236. ^ collection
  1237. !
  1238. collection: aCollection
  1239. collection := aCollection
  1240. !
  1241. label
  1242. ^ label
  1243. !
  1244. label: aString
  1245. label := aString
  1246. !
  1247. parent
  1248. ^ parent
  1249. !
  1250. parent: aProgress
  1251. parent := aProgress
  1252. !
  1253. workBlock
  1254. ^ workBlock
  1255. !
  1256. workBlock: aBlock
  1257. workBlock := aBlock
  1258. ! !
  1259. !HLProgressBarWidget methodsFor: 'actions'!
  1260. evaluateAt: anInteger
  1261. self updateProgress: (anInteger / self collection size) * 100.
  1262. anInteger <= self collection size
  1263. ifTrue: [
  1264. [
  1265. self workBlock value: (self collection at: anInteger).
  1266. self evaluateAt: anInteger + 1 ] valueWithTimeout: 10 ]
  1267. ifFalse: [ [ self remove ] valueWithTimeout: 500 ]
  1268. !
  1269. remove
  1270. self parent removeProgressBar: self
  1271. !
  1272. start
  1273. "Make sure the UI has some time to update itself between each iteration"
  1274. self evaluateAt: 1
  1275. !
  1276. updateProgress: anInteger
  1277. bar asJQuery css: 'width' put: anInteger asString, '%'
  1278. ! !
  1279. !HLProgressBarWidget methodsFor: 'rendering'!
  1280. renderContentOn: html
  1281. html span with: self label.
  1282. html div
  1283. class: 'progress';
  1284. with: [
  1285. bar := html div
  1286. class: 'bar';
  1287. style: 'width: 0%' ]
  1288. ! !
  1289. HLProgressBarWidget class instanceVariableNames: 'default'!
  1290. !HLProgressBarWidget class methodsFor: 'accessing'!
  1291. default
  1292. ^ default ifNil: [ default := self new ]
  1293. ! !
  1294. HLWidget subclass: #HLSUnit
  1295. instanceVariableNames: ''
  1296. package: 'Helios-Core'!
  1297. !HLSUnit class methodsFor: 'accessing'!
  1298. tabClass
  1299. ^ 'sunit'
  1300. !
  1301. tabLabel
  1302. ^ 'SUnit'
  1303. !
  1304. tabPriority
  1305. ^ 1000
  1306. ! !
  1307. !HLSUnit class methodsFor: 'testing'!
  1308. canBeOpenAsTab
  1309. ^ true
  1310. ! !