diff --git a/src/Spec2-Adapters-Morphic/SpAbstractMorphicAdapter.class.st b/src/Spec2-Adapters-Morphic/SpAbstractMorphicAdapter.class.st index 2556c907..aa40b32f 100644 --- a/src/Spec2-Adapters-Morphic/SpAbstractMorphicAdapter.class.st +++ b/src/Spec2-Adapters-Morphic/SpAbstractMorphicAdapter.class.st @@ -661,7 +661,6 @@ SpAbstractMorphicAdapter >> type: aString [ SpAbstractMorphicAdapter >> unsubscribe [ super unsubscribe. - self presenter hasAnnouncer ifFalse: [ ^ self ]. self presenter announcer unsubscribe: self widget; diff --git a/src/Spec2-Adapters-Morphic/SpFixedProgressBarState.extension.st b/src/Spec2-Adapters-Morphic/SpFixedProgressBarState.extension.st index a3c05b2b..bae86e39 100644 --- a/src/Spec2-Adapters-Morphic/SpFixedProgressBarState.extension.st +++ b/src/Spec2-Adapters-Morphic/SpFixedProgressBarState.extension.st @@ -9,5 +9,5 @@ SpFixedProgressBarState >> customizeMorphicBar: aProgressBarMorph [ { #category : '*Spec2-Adapters-Morphic' } SpFixedProgressBarState >> customizeMorphicLabel: aLabelMorph [ - aLabelMorph contents: (self value * 100) asInteger asString, '%' + aLabelMorph contents: ((self value * 100) asInteger min: 100) asString, '%' ] diff --git a/src/Spec2-Adapters-Morphic/SpMorphicBoxAdapter.class.st b/src/Spec2-Adapters-Morphic/SpMorphicBoxAdapter.class.st index 4648233d..6ac85271 100644 --- a/src/Spec2-Adapters-Morphic/SpMorphicBoxAdapter.class.st +++ b/src/Spec2-Adapters-Morphic/SpMorphicBoxAdapter.class.st @@ -249,13 +249,15 @@ SpMorphicBoxAdapter >> newWrapMorph [ { #category : 'accessing' } SpMorphicBoxAdapter >> remove: aPresenter [ + | morph adapter | - aPresenter adapter ifNotNil: [ :adapter | - | morph | - morph := adapter widget. - startPanel removeMorph: morph. - endPanel removeMorph: morph. - self verifyBoxExtent ] + (adapter := aPresenter adapter) ifNil: [ ^ self ]. + + adapter unsubscribe. + morph := adapter widget. + startPanel removeMorph: morph. + endPanel removeMorph: morph. + self verifyBoxExtent ] { #category : 'accessing' } diff --git a/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculator.class.st b/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculator.class.st index ce33a4e2..89b67f02 100644 --- a/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculator.class.st +++ b/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculator.class.st @@ -37,6 +37,19 @@ SpMorphicBoxLayoutCalculator class >> newProperties: anObject [ { #category : 'calculating' } SpMorphicBoxLayoutCalculator >> calculateFor: aMorph in: newBounds [ + [ self doCalculateFor: aMorph in: newBounds ] + ensure: [ self cleanUp ] +] + +{ #category : 'private' } +SpMorphicBoxLayoutCalculator >> cleanUp [ + + firstCell := lastCell := nil +] + +{ #category : 'calculating' } +SpMorphicBoxLayoutCalculator >> doCalculateFor: aMorph in: newBounds [ + self subclassResponsibility ] diff --git a/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorLeftToRight.class.st b/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorLeftToRight.class.st index d23921d7..0bf998d0 100644 --- a/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorLeftToRight.class.st +++ b/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorLeftToRight.class.st @@ -53,7 +53,7 @@ SpMorphicBoxLayoutCalculatorLeftToRight >> calculateCellFor: aMorph [ ] { #category : 'calculating' } -SpMorphicBoxLayoutCalculatorLeftToRight >> calculateFor: aMorph in: newBounds [ +SpMorphicBoxLayoutCalculatorLeftToRight >> doCalculateFor: aMorph in: newBounds [ "An optimized left-to-right list layout" | inset extent posX posY centering extraPerCell cell amount last submorphs | @@ -126,6 +126,5 @@ SpMorphicBoxLayoutCalculatorLeftToRight >> calculateFor: aMorph in: newBounds [ width := width + amount ]. cell target layoutInBounds: (posX @ posY extent: width @ height). posX := posX + width + inset. - cell := cell nextCell ]. - + cell := cell nextCell ] ] diff --git a/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorTopToBottom.class.st b/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorTopToBottom.class.st index 3e525296..d512b900 100644 --- a/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorTopToBottom.class.st +++ b/src/Spec2-Adapters-Morphic/SpMorphicBoxLayoutCalculatorTopToBottom.class.st @@ -44,7 +44,7 @@ SpMorphicBoxLayoutCalculatorTopToBottom >> calculateCellFor: aMorph [ ] { #category : 'calculating' } -SpMorphicBoxLayoutCalculatorTopToBottom >> calculateFor: aMorph in: newBounds [ +SpMorphicBoxLayoutCalculatorTopToBottom >> doCalculateFor: aMorph in: newBounds [ "An optimized top-to-bottom list layout" | inset extent posX posY centering extraPerCell cell amount last submorphs | @@ -107,7 +107,7 @@ SpMorphicBoxLayoutCalculatorTopToBottom >> calculateFor: aMorph in: newBounds [ number := 0. extra := last := 0. cell := firstCell. - [cell == nil] whileFalse:[ + [ cell == nil ] whileFalse:[ number := number + 1. height := cell cellSize. (extraPerCell > 0 and:[cell vSpaceFill]) ifTrue:[ @@ -117,6 +117,5 @@ SpMorphicBoxLayoutCalculatorTopToBottom >> calculateFor: aMorph in: newBounds [ ]. cell target layoutInBounds: (posX @ posY extent: width @ height). posY := posY + height + inset. - cell := cell nextCell. - ]. + cell := cell nextCell ] ] diff --git a/src/Spec2-Adapters-Morphic/SpMorphicProgressBarAdapter.class.st b/src/Spec2-Adapters-Morphic/SpMorphicProgressBarAdapter.class.st index 310a6bbe..f6a12f83 100644 --- a/src/Spec2-Adapters-Morphic/SpMorphicProgressBarAdapter.class.st +++ b/src/Spec2-Adapters-Morphic/SpMorphicProgressBarAdapter.class.st @@ -49,16 +49,11 @@ SpMorphicProgressBarAdapter >> buildWidget [ vResizing: #spaceFill; yourself. - progressLabel := LabelMorph new. - - progressBar := (self progressBarState progressBarMorph from: 0 to: 1) - "changeProportionalLayout;" - hResizing: #spaceFill; - vResizing: #rigid; - height: 5; + progressLabel := LabelMorph new + contents: ''; yourself. - self progressBarState customizeMorphicBar: progressBar. + progressBar := self newProgressBar. panel addMorphBack: progressLabel; @@ -86,6 +81,17 @@ SpMorphicProgressBarAdapter >> labelStyle [ otherStyles: self presenterStyles ] +{ #category : 'factory' } +SpMorphicProgressBarAdapter >> newProgressBar [ + + ^ (self progressBarState progressBarMorph from: 0 to: 1) + hResizing: #spaceFill; + vResizing: #rigid; + height: 5; + in: [ :this | self progressBarState customizeMorphicBar: this ]; + yourself +] + { #category : 'accessing' } SpMorphicProgressBarAdapter >> progressBarState [ @@ -95,14 +101,28 @@ SpMorphicProgressBarAdapter >> progressBarState [ { #category : 'accessing' } SpMorphicProgressBarAdapter >> refreshRateInMs: nbMilliSeconds [ "The progress bar will only be updated if the time between 2 refresh is > nbMilliSeconds" - refreshRateInMs := nbMilliSeconds. + refreshRateInMs := nbMilliSeconds ] { #category : 'updating' } -SpMorphicProgressBarAdapter >> updateState [ +SpMorphicProgressBarAdapter >> updateProgressBar [ + | newProgressBar | + + newProgressBar := self newProgressBar. + self widget + replaceSubmorph: progressBar + by: newProgressBar. + progressBar := newProgressBar +] +{ #category : 'updating' } +SpMorphicProgressBarAdapter >> updateState [ | isTimeForRefresh | - self progressBarState + + (self progressBarState progressBarMorph = progressBar class) + ifFalse: [ self updateProgressBar ]. + + self progressBarState customizeMorphicLabel: progressLabel; customizeMorphicBar: progressBar. diff --git a/src/Spec2-Adapters-Morphic/SpMorphicWindowAdapter.class.st b/src/Spec2-Adapters-Morphic/SpMorphicWindowAdapter.class.st index 8ba6afbd..094aef7b 100644 --- a/src/Spec2-Adapters-Morphic/SpMorphicWindowAdapter.class.st +++ b/src/Spec2-Adapters-Morphic/SpMorphicWindowAdapter.class.st @@ -115,12 +115,6 @@ SpMorphicWindowAdapter >> delete [ self application windowClosed: self ] ] -{ #category : 'protocol' } -SpMorphicWindowAdapter >> extent: aPoint [ - - ^ self widget extent: aPoint -] - { #category : 'widget API' } SpMorphicWindowAdapter >> initialExtent [ @@ -190,6 +184,12 @@ SpMorphicWindowAdapter >> minimize [ self widgetDo: [ :w | w minimize ] ] +{ #category : 'protocol' } +SpMorphicWindowAdapter >> moveTo: aPoint [ + + ^ self widget position: aPoint +] + { #category : 'widget API' } SpMorphicWindowAdapter >> okToChange [ @@ -231,7 +231,9 @@ SpMorphicWindowAdapter >> rebuildWithSpecLayout: aSpec [ { #category : 'widget API' } SpMorphicWindowAdapter >> resize: aPoint [ - widget extent: aPoint + widget extent: aPoint. + self presenter isCentered + ifTrue: [ self centered ] ] { #category : 'factory' } diff --git a/src/Spec2-Core/SpApplication.class.st b/src/Spec2-Core/SpApplication.class.st index 12e58206..96fe2e5a 100644 --- a/src/Spec2-Core/SpApplication.class.st +++ b/src/Spec2-Core/SpApplication.class.st @@ -331,6 +331,12 @@ SpApplication >> registerWindow: aWindow [ self windows add: aWindow ] +{ #category : 'accessing - properties' } +SpApplication >> removeProperty: aName [ + + ^ self properties removeKey: aName ifAbsent: [ ] +] + { #category : 'accessing' } SpApplication >> reset [ diff --git a/src/Spec2-Core/SpJob.class.st b/src/Spec2-Core/SpJob.class.st index 60d61fb3..167fd45a 100644 --- a/src/Spec2-Core/SpJob.class.st +++ b/src/Spec2-Core/SpJob.class.st @@ -12,7 +12,7 @@ job := self newBlock: [ :job | progress: (0.1 * each); title: 'Youpi ', each printString. (Delay forMilliseconds: 100) wait. - ] ] + ] ]. job run. ``` @@ -78,7 +78,7 @@ SpJob >> addChild: aJob [ aJob parent: self ] -{ #category : 'accessing' } +{ #category : 'private - announcing' } SpJob >> announce: anAnnouncementClass [ | announcement | @@ -86,14 +86,25 @@ SpJob >> announce: anAnnouncementClass [ self announcer announce: announcement ] -{ #category : 'private' } +{ #category : 'private - announcing' } SpJob >> announceChange [ - isRunning ifFalse: [ ^ self ]. self announce: JobChange ] -{ #category : 'accessing' } +{ #category : 'private - announcing' } +SpJob >> announceEnd [ + + self announce: JobEnd +] + +{ #category : 'private - announcing' } +SpJob >> announceStart [ + + self announce: JobStart +] + +{ #category : 'private - announcing' } SpJob >> announcer [ ^ announcer ifNil: [ announcer := Announcer new ] @@ -122,7 +133,7 @@ SpJob >> cleanupAfterRunning [ isRunning := false. process := nil. - self announce: JobEnd. + self announceEnd. parent ifNotNil: [ :job | job removeChild: self ] ] @@ -175,6 +186,12 @@ SpJob >> initialize [ children := OrderedCollection new ] +{ #category : 'instance creation' } +SpJob >> installOn: aPresenter [ + + announcer := aPresenter +] + { #category : 'testing' } SpJob >> isRunning [ @@ -201,8 +218,8 @@ SpJob >> lookup: lookupBlock ifNone: noneBlock [ (lookupBlock value: self) ifTrue: [ ^ self ]. ^ parent - ifNil: noneBlock - ifNotNil: [ parent lookup: lookupBlock ifNone: noneBlock ] + ifNotNil: [ parent lookup: lookupBlock ifNone: noneBlock ] + ifNil: noneBlock ] { #category : 'accessing' } @@ -221,6 +238,7 @@ SpJob >> max: aNumber [ SpJob >> migrateProgressWhileUpdatingBounds: aBlockChangingBounds [ "Keep the progress value consistent while we change min / max" | progress | + progress := self progress. aBlockChangingBounds value. self progress: progress. @@ -256,10 +274,10 @@ SpJob >> prepareForRunning [ isRunning := true. process := Processor activeProcess. - self announce: JobStart + self announceStart ] -{ #category : 'progress' } +{ #category : 'accessing' } SpJob >> progress [ "Avoid negative progress and divideByZero." @@ -268,7 +286,7 @@ SpJob >> progress [ ifFalse: [ (currentValue - min) / (max - min) ] ] -{ #category : 'progress' } +{ #category : 'accessing' } SpJob >> progress: aNormalizedFloat [ "Set the progress: 0.0 - 1.0" @@ -291,10 +309,11 @@ SpJob >> removeChild: aJob [ { #category : 'running' } SpJob >> run [ - [ + ^ [ self prepareForRunning. - ^ block cull: self ] - ensure: [ self cleanupAfterRunning ] + block cull: self ] + ensure: [ + self cleanupAfterRunning ] ] { #category : 'accessing' } diff --git a/src/Spec2-Core/SpJobListPresenter.class.st b/src/Spec2-Core/SpJobListPresenter.class.st index eeb1e5e2..079f9d3b 100644 --- a/src/Spec2-Core/SpJobListPresenter.class.st +++ b/src/Spec2-Core/SpJobListPresenter.class.st @@ -5,7 +5,9 @@ Class { #name : 'SpJobListPresenter', #superclass : 'SpPresenter', #instVars : [ - 'refreshRateInMs' + 'refreshRateInMs', + 'mutex', + 'jobs' ], #category : 'Spec2-Core-Job', #package : 'Spec2-Core', @@ -20,8 +22,8 @@ SpJobListPresenter class >> example [ [ 1 to: 5 do: [ :index | [ - jobList pushJob: (SpJob - newTitle: 'Job ', index asString + jobList pushJob: (SpJob new + title: 'Job ', index asString; block: [ :job | job min: 1; max: 10. 1 to: 10 do: [ :i | @@ -39,15 +41,46 @@ SpJobListPresenter class >> example [ SpJobListPresenter >> addJobPresenter: aJob [ | presenter | + aJob title ifEmpty: [ aJob title: 'Processing...' ]. + presenter := self instantiate: SpJobPresenter on: aJob. presenter refreshRateInMs: refreshRateInMs. + + jobs at: aJob put: presenter. self layout add: presenter expand: false. self layout children size = 1 ifTrue: [ self open ]. - self withWindowDo: [ :window | - window resize: 500@(layout children size * self jobPresenterHeight) ] + window resize: 500@((layout children size * self jobPresenterHeight) + 10) ] +] + +{ #category : 'private' } +SpJobListPresenter >> ensureOpen [ + + self withWindowDo: [ :aWindow | + aWindow isOpen + ifFalse: [ self open ] ] +] + +{ #category : 'private' } +SpJobListPresenter >> findJob: aJob [ + + ^ jobs + at: aJob + ifAbsent: [ nil ] +] + +{ #category : 'initialization' } +SpJobListPresenter >> initialize [ + + super initialize. + jobs := SmallDictionary new. + mutex := Mutex new. + self announcer + when: JobStart send: #jobStart: to: self; + when: JobChange send: #jobChanged: to: self; + when: JobEnd send: #jobEnd: to: self ] { #category : 'initialization' } @@ -66,37 +99,100 @@ SpJobListPresenter >> initializeWindow: aWindowPresenter [ centered ] +{ #category : 'testing' } +SpJobListPresenter >> isEmpty [ + + ^ self layout children isEmpty +] + +{ #category : 'private - events' } +SpJobListPresenter >> jobChanged: ann [ + + mutex critical: [ + (self findJob: ann job) + ifNotNil: [ :aPresenter | aPresenter updatePresenter ] ] +] + +{ #category : 'private - events' } +SpJobListPresenter >> jobEnd: ann [ + + mutex critical: [ + self removeJobPresenter: ann job ] +] + { #category : 'private' } SpJobListPresenter >> jobPresenterHeight [ - ^ 70 + ^ 80 +] + +{ #category : 'private - events' } +SpJobListPresenter >> jobStart: ann [ + + "Skip if already there" + mutex critical: [ + (self findJob: ann job) ifNotNil: [ :aJobPresenter | + aJobPresenter refresh. + ^ self ]. + self addJobPresenter: ann job ]. + + self ensureOpen +] + +{ #category : 'private' } +SpJobListPresenter >> newJob [ + + ^ Job new ] { #category : 'api' } SpJobListPresenter >> pushJob: aJob [ - aJob whenStartDo: [ :ann | self addJobPresenter: ann job ]. - aJob whenEndDo: [ :ann | self removeJobPresenter: ann job ]. + aJob installOn: self. + aJob run +] + +{ #category : 'api' } +SpJobListPresenter >> pushJobWith: aBlock [ + | job | - aJob run + job := self newJob. + job block: aBlock. + self pushJob: job ] { #category : 'api' } SpJobListPresenter >> refreshRateInMs: anInteger [ - refreshRateInMs := anInteger. + + refreshRateInMs := anInteger ] { #category : 'private' } SpJobListPresenter >> removeJobPresenter: aJob [ | presenter | - presenter := self layout children detect: [ :each | each model = aJob ]. - self layout remove: presenter. - - self layout children - ifEmpty: [ self withWindowDo: [ :window | window close ] ]. + presenter := self findJob: aJob. + presenter ifNil: [ ^ self ]. + jobs removeKey: aJob. + self layout remove: presenter. + self withWindowDo: [ :window | - window resize: 500@(layout children size * self jobPresenterHeight). - window centered ] + self layout children + ifNotEmpty: [ + window resize: 500@(layout children size * self jobPresenterHeight). + window centered ] + ifEmpty: [ + window close. + self flag: #HACK. "This is a hack to prevent a leak that I cannot + detect while executing this several times. Removing the job list + from the application will effectively clean up the process (but + the leak is still there, somewhere in morphic...I need to find it)" + self application removeProperty: #jobList ] ] +] + +{ #category : 'private' } +SpJobListPresenter >> resetLayout [ + + self layout: SpBoxLayout newTopToBottom ] diff --git a/src/Spec2-Core/SpJobPresenter.class.st b/src/Spec2-Core/SpJobPresenter.class.st index 7a043e9f..62dcab43 100644 --- a/src/Spec2-Core/SpJobPresenter.class.st +++ b/src/Spec2-Core/SpJobPresenter.class.st @@ -32,7 +32,7 @@ Class { SpJobPresenter class >> example [ | job | - job := SpJob newBlock: [ :aJob | + job := Job block: [ :aJob | aJob title: 'Test'. aJob min: 1; max: 10. 1 to: 10 do: [ :i | @@ -45,15 +45,24 @@ SpJobPresenter class >> example [ run ] +{ #category : 'layout' } +SpJobPresenter >> defaultLayout [ + + ^ SpBoxLayout newTopToBottom + borderWidth: 10; + spacing: 5; + add: progressLabel expand: false; + add: progressBar expand: false; + yourself +] + { #category : 'initialization' } SpJobPresenter >> initializePresenters [ - self layout: (SpBoxLayout newTopToBottom - borderWidth: 10; - spacing: 5; - add: (progressLabel := self newLabel) expand: false; - add: (progressBar := self newProgressBar) expand: false; - yourself) + progressLabel := self newLabel label: ''. + progressBar := self newProgressBar + "indeterminate;" + yourself ] { #category : 'initialization' } @@ -115,20 +124,23 @@ SpJobPresenter >> setModelBeforeInitialization: aModel [ { #category : 'initialization' } SpJobPresenter >> updatePresenter [ - | currentJob | - currentJob := model ifNil: [ ^ SpJob empty ]. - + model ifNil: [ ^ self ]. + progressLabel label: model title. - progressBar fixedAt: model progress + "progressBar fixedAt: model progress." + model progress > 0 + ifTrue: [ progressBar fixedAt: model progress ] + ifFalse: [ progressBar indeterminate ]. + progressBar refresh ] { #category : 'private' } SpJobPresenter >> updateSubscriptions [ - model announcer weak + "model announcer weak when: JobStart send: #jobStart: to: self; when: JobChange send: #jobChanged: to: self; - when: JobEnd send: #jobEnd: to: self. + when: JobEnd send: #jobEnd: to: self." ] diff --git a/src/Spec2-Core/SpProgressBarPresenter.class.st b/src/Spec2-Core/SpProgressBarPresenter.class.st index a90da698..67f1cc24 100644 --- a/src/Spec2-Core/SpProgressBarPresenter.class.st +++ b/src/Spec2-Core/SpProgressBarPresenter.class.st @@ -30,7 +30,7 @@ SpProgressBarPresenter class >> documentFactoryMethodSelector [ SpProgressBarPresenter >> fixedAt: aNumber [ "Declare that the progress bar will be fixed at a certain value. The value should be the completed ratio between 0 and 1." - + self state: (SpFixedProgressBarState value: aNumber) ] @@ -74,6 +74,12 @@ SpProgressBarPresenter >> progress: aBlock every: aDelay [ self state: (SpProgressingProgressBarState progression: aBlock every: aDelay) ] +{ #category : 'api' } +SpProgressBarPresenter >> refresh [ + + ^ self withAdapterDo: [ :anAdapter | anAdapter updateState ] +] + { #category : 'private' } SpProgressBarPresenter >> state [ diff --git a/src/Spec2-Core/SpWindowPresenter.class.st b/src/Spec2-Core/SpWindowPresenter.class.st index c3baa3fa..92f96deb 100644 --- a/src/Spec2-Core/SpWindowPresenter.class.st +++ b/src/Spec2-Core/SpWindowPresenter.class.st @@ -289,7 +289,10 @@ SpWindowPresenter >> initialPosition [ { #category : 'api' } SpWindowPresenter >> initialPosition: aPoint [ "Set initial position of the window. - `aPoint` is an instance of `Point`, indicating x@y coordinates" + `aPoint` is an instance of `Point`, indicating x@y coordinates + WARNING: Not all backends will support this (for example Gtk lets + the window manager position windows and hence it ignores any positioning + we set)." initialPosition := aPoint ] @@ -442,6 +445,20 @@ SpWindowPresenter >> minimize [ self withAdapterDo: [ :anAdapter | anAdapter minimize ] ] +{ #category : 'api' } +SpWindowPresenter >> moveTo: aPoint [ + "Moves the window to a specific location. + `aPoint` is an instance of `Point`, indicating x@y coordinates + + To set initial position of a window, use #initialPosition:, not this. + WARNING: Not all backends will support this (for example Gtk lets + the window manager position windows and hence it ignores any positioning + we set)." + + self withAdapterPerformOrDefer: [ :anAdapter | anAdapter moveTo: aPoint ] + +] + { #category : 'notifying' } SpWindowPresenter >> notify: aSpecNotification [ "Receives a notification and delivers it as required" diff --git a/src/Spec2-Dialogs/SpApplication.extension.st b/src/Spec2-Dialogs/SpApplication.extension.st index 63ee3852..ecbf4766 100644 --- a/src/Spec2-Dialogs/SpApplication.extension.st +++ b/src/Spec2-Dialogs/SpApplication.extension.st @@ -29,10 +29,25 @@ SpApplication >> inform: aString [ { #category : '*Spec2-Dialogs' } SpApplication >> informUser: aString during: aBlock [ "Displays an inform user dialog." + | result | - ^ self newInformUser - title: aString; - informUserDuring: aBlock + result := nil. + self jobList pushJob: (Job new + title: aString; + block: [ :job | + job min: 0; max: 100. + result := aBlock cull: job ]; + yourself). + + ^ result +] + +{ #category : '*Spec2-Dialogs' } +SpApplication >> jobList [ + + ^ self + propertyAt: #jobList + ifAbsentPut: [ self newJobList ] ] { #category : '*Spec2-Dialogs' } diff --git a/src/Spec2-Dialogs/SpInformUserDialog.class.st b/src/Spec2-Dialogs/SpInformUserDialog.class.st index a57cce3f..92fbd1e5 100644 --- a/src/Spec2-Dialogs/SpInformUserDialog.class.st +++ b/src/Spec2-Dialogs/SpInformUserDialog.class.st @@ -51,11 +51,13 @@ SpInformUserDialog >> afterOpenAction [ openAction ifNil: [ ^ self ]. [ - [ - returnValue := openAction value. - self accept ] on: Error fork: [ :e | - self cancel. - e pass ] ] fork + [ + returnValue := openAction value. + self accept ] + on: Error fork: [ :e | + self cancel. + e pass ] + ] fork ] { #category : 'simple dialog helpers' } diff --git a/src/Spec2-Layout/SpExecutableLayout.class.st b/src/Spec2-Layout/SpExecutableLayout.class.st index 5b143640..b5c4adaa 100644 --- a/src/Spec2-Layout/SpExecutableLayout.class.st +++ b/src/Spec2-Layout/SpExecutableLayout.class.st @@ -270,7 +270,7 @@ SpExecutableLayout >> remove: aPresenter ifAbsent: aBlock [ ^ (children includesKey: aPresenter) ifTrue: [ children removeKey: aPresenter ] - ifFalse: aBlock + ifFalse: [ aBlock value ] ] { #category : 'private' } @@ -306,12 +306,14 @@ SpExecutableLayout >> resolvePresenter: aPresenterOrLayout presenter: aPresenter { #category : 'accessing' } SpExecutableLayout >> selector [ + ^ selector ] { #category : 'accessing' } -SpExecutableLayout >> selector: anObject [ - selector := anObject +SpExecutableLayout >> selector: aSelector [ + + selector := aSelector ] { #category : 'private' } @@ -338,7 +340,10 @@ SpExecutableLayout >> unsubscribe [ { #category : 'events' } SpExecutableLayout >> whenChildrenAddedDo: aBlock [ - self announcer when: SpChildrenAdded do: aBlock for: aBlock receiver + self announcer + when: SpChildrenAdded + do: aBlock + for: aBlock receiver ] { #category : 'events' } diff --git a/src/Spec2-Morphic-Tests/SpJobListPresenterTest.class.st b/src/Spec2-Morphic-Tests/SpJobListPresenterTest.class.st index 1d76cf30..155541fc 100644 --- a/src/Spec2-Morphic-Tests/SpJobListPresenterTest.class.st +++ b/src/Spec2-Morphic-Tests/SpJobListPresenterTest.class.st @@ -17,9 +17,10 @@ SpJobListPresenterTest >> testJobIsFinishedWhenWaitingMoreThanWorkBlockDuration self skipOnPharoCITestingEnvironment. progress := 0. - job := SpJob - newTitle: 'some job' - block: [ : myjob | 1 to: 25 do: [ :i | myjob value: i*4. 20 milliSeconds wait. ] ]. + job := Job new + title: 'some job'; + block: [ : myjob | 1 to: 25 do: [ :i | myjob value: i*4. 20 milliSeconds wait. ] ]; + yourself. [ presenter := SpJobListPresenter new pushJob: job; yourself. ] fork. @@ -35,9 +36,10 @@ SpJobListPresenterTest >> testJobIsNotFinishedWhenWaitingLessThanWorkBlockDurati self skipOnPharoCITestingEnvironment. progress := 0. - job := SpJob - newTitle: 'some job' - block: [ : myjob | 1 to: 25 do: [ :i | myjob value: i*4. 60 milliSeconds wait. ] ]. + job := Job new + title: 'some job'; + block: [ : myjob | 1 to: 25 do: [ :i | myjob value: i*4. 60 milliSeconds wait ] ]; + yourself. [ presenter := SpJobListPresenter new pushJob: job; yourself. ] fork. @@ -57,9 +59,12 @@ SpJobListPresenterTest >> testProgressDoesNotRefreshMoreThanRefreshRate [ refreshRateInMs := 150. nbUpdates := 25. counter := 0. - job := SpJob - newTitle: 'some job' - block: [ : myjob | 1 to: nbUpdates do: [ :i | myjob value: i * 4. waitBetweenJobUpdate wait. ] ]. + job := Job new + title: 'some job'; + block: [ : myjob | + 1 to: nbUpdates do: [ :i | + myjob value: i * 4. waitBetweenJobUpdate wait ] ]; + yourself. presenter := SpJobPresenter on: job. [ presenter open.