--- a/ProgressIndicator.st Tue Oct 13 17:40:28 1998 +0200
+++ b/ProgressIndicator.st Wed Oct 21 18:18:11 1998 +0200
@@ -12,7 +12,8 @@
View subclass:#ProgressIndicator
instanceVariableNames:'percentage showPercentage fgColor bgColor connectedTop
- connectedLabel collector finishAction closeTopWhenDone'
+ connectedLabel collector finishAction closeTopWhenDone showBusy
+ busyPosition busyDelta busyIndicationProcess'
classVariableNames:''
poolDictionaries:''
category:'Views-Misc'
@@ -37,7 +38,10 @@
documentation
"
a view showing a rectangle filled according the percentage value.
- Can be used as a progress indicator a la MSwindows.
+ Can be used as a progress indicator a la MSwindows;
+ it can also be configured as a non-percentage busy indication
+ via the showBusyIndication flag (a la netscape).
+
Can be used as a widget within an application, or
via the convenient #inBox: instance creation messages,
which shows a progressDisplay in a modalBox, while some
@@ -45,10 +49,10 @@
See examples.
[author:]
- Claus Gittinger
+ Claus Gittinger
[see also:]
- ActionWaitBox AnimatedLabel
+ ActionWaitBox AnimatedLabel
"
!
@@ -60,7 +64,7 @@
Before you get frustrated - see the convenient-interface examples
at the end ;-)
- [exBegin]
+ [exBegin]
|top p h|
top := ModalBox new.
@@ -71,22 +75,47 @@
p level:-1.
h := p preferredExtent y.
p topInset:(h // 2) negated;
- bottomInset:(h // 2) negated;
- leftInset:5;
- rightInset:5.
+ bottomInset:(h // 2) negated;
+ leftInset:5;
+ rightInset:5.
[
- 1 to:100 do:[:val |
- (Delay forSeconds:0.05) wait.
- p percentage:val
- ].
- top hide.
+ 1 to:100 do:[:val |
+ (Delay forSeconds:0.05) wait.
+ p percentage:val
+ ].
+ top hide.
] fork.
top open.
- [exEnd]
+ [exEnd]
+
+ as a busy indicator
+ [exBegin]
+ |top p h|
+
+ top := ModalBox new.
+ top extent:300@100.
+ top label:'Busy'.
+ p := ProgressIndicator in:top.
+ p origin:(0.0@0.5) corner:(1.0@0.5).
+ p level:-1.
+ h := p preferredExtent y.
+ p topInset:(h // 2) negated;
+ bottomInset:(h // 2) negated;
+ leftInset:5;
+ rightInset:5.
+
+ p showBusyIndication:true.
+ [
+ 'do something here ....'.
+ (Delay forSeconds:5) wait.
+ top hide.
+ ] fork.
+ top open.
+ [exEnd]
changing colors, turning percentage display off:
- [exBegin]
+ [exBegin]
|top p h|
top := StandardSystemView new.
@@ -99,20 +128,57 @@
p foregroundColor:(Color red).
h := 10.
p topInset:(h // 2) negated;
- bottomInset:(h // 2) negated;
- leftInset:5;
- rightInset:5.
+ bottomInset:(h // 2) negated;
+ leftInset:5;
+ rightInset:5.
top open.
[
- 1 to:100 do:[:val |
- (Delay forSeconds:0.05) wait.
- p percentage:val
- ]
+ 1 to:100 do:[:val |
+ (Delay forSeconds:0.05) wait.
+ p percentage:val
+ ]
] fork
- [exEnd]
+ [exEnd]
+
+ as a busy indicator and percentage display (as in netscape)
+ [exBegin]
+ |top p h|
+
+ top := ModalBox new.
+ top extent:300@60.
+ top label:'Busy'.
+ p := ProgressIndicator in:top.
+ p origin:(0.0@0.5) corner:(1.0@0.5).
+ p level:-1.
+ p showPercentage:false.
+ p backgroundColor:(Color cyan).
+ h := p preferredExtent y.
+ p topInset:(h // 3) negated;
+ bottomInset:(h // 3) negated;
+ leftInset:5;
+ rightInset:5.
+
+ p showBusyIndication:true.
+ [
+ top label:'Busy'.
+ 1 to:100 do:[:i |
+ (Delay forSeconds:0.05) wait.
+ ].
+
+ top label:'Percentage'.
+ p showBusyIndication:false.
+ 1 to:100 do:[:i |
+ (Delay forSeconds:0.05) wait.
+ p percentage:i.
+ ].
+
+ top hide.
+ ] fork.
+ top open.
+ [exEnd]
with border (2D look):
- [exBegin]
+ [exBegin]
|top p h|
top := StandardSystemView new.
@@ -123,21 +189,21 @@
p borderWidth:1.
h := p preferredExtent y.
p topInset:(h // 2) negated;
- bottomInset:(h // 2) negated;
- leftInset:5;
- rightInset:5.
+ bottomInset:(h // 2) negated;
+ leftInset:5;
+ rightInset:5.
top open.
[
- 1 to:100 do:[:val |
- (Delay forSeconds:0.05) wait.
- p percentage:val
- ]
+ 1 to:100 do:[:val |
+ (Delay forSeconds:0.05) wait.
+ p percentage:val
+ ]
] fork
- [exEnd]
+ [exEnd]
getting progress from a model:
- [exBegin]
+ [exBegin]
|model top p h|
model := 0 asValue.
@@ -151,24 +217,24 @@
p level:-1.
h := p preferredExtent y.
p topInset:(h // 2) negated;
- bottomInset:(h // 2) negated;
- leftInset:5;
- rightInset:5.
+ bottomInset:(h // 2) negated;
+ leftInset:5;
+ rightInset:5.
top open.
[
- 1 to:100 do:[:val |
- (Delay forSeconds:0.05) wait.
- model value:val
- ]
+ 1 to:100 do:[:val |
+ (Delay forSeconds:0.05) wait.
+ model value:val
+ ]
] fork
- [exEnd]
+ [exEnd]
concrete example:
search all files in the source directory for a string
using grep. Show progress while doing so.
- [exBegin]
+ [exBegin]
|top p h names done|
top := StandardSystemView new.
@@ -179,33 +245,33 @@
p level:-1.
h := p preferredExtent y.
p topInset:(h // 2) negated;
- bottomInset:(h // 2) negated;
- leftInset:5;
- rightInset:5.
+ bottomInset:(h // 2) negated;
+ leftInset:5;
+ rightInset:5.
top openWithPriority:(Processor activePriority + 1).
names := 'source' asFilename directoryContents.
done := 0.
names do:[:aName |
- |fn stream line|
+ |fn stream line|
- p percentage:(done / names size * 100).
- fn := ('source/' , aName) asFilename.
- fn isDirectory ifFalse:[
- stream := fn readStream.
- [stream atEnd] whileFalse:[
- line := stream nextLine.
- (line findString:'subclass:') ~~ 0 ifTrue:[
- Transcript showCR:line
- ].
- ].
- stream close.
- ].
- done := done + 1
+ p percentage:(done / names size * 100).
+ fn := ('source/' , aName) asFilename.
+ fn isDirectory ifFalse:[
+ stream := fn readStream.
+ [stream atEnd] whileFalse:[
+ line := stream nextLine.
+ (line findString:'subclass:') ~~ 0 ifTrue:[
+ Transcript showCR:line
+ ].
+ ].
+ stream close.
+ ].
+ done := done + 1
].
top destroy
- [exEnd]
+ [exEnd]
using the convenient inBox-interface
@@ -214,105 +280,105 @@
to indicate ...)
basic interface demonstration:
- [exBegin]
+ [exBegin]
|p|
p := ProgressIndicator
- inBoxWithLabel:'doing something ...'
- abortable:true.
+ inBoxWithLabel:'doing something ...'
+ abortable:true.
p showProgressOf:
- [:progressValue :currentAction |
+ [:progressValue :currentAction |
- 1 to:100 do:[:val |
- (Delay forSeconds:0.05) wait.
- val == 25 ifTrue:[
- currentAction value:'still going ...'
- ].
- val == 50 ifTrue:[
- currentAction value:'halfway through ...'
- ].
- val == 75 ifTrue:[
- currentAction value:'almost finished ...'
- ].
- progressValue value:val
- ]
- ]
- [exEnd]
+ 1 to:100 do:[:val |
+ (Delay forSeconds:0.05) wait.
+ val == 25 ifTrue:[
+ currentAction value:'still going ...'
+ ].
+ val == 50 ifTrue:[
+ currentAction value:'halfway through ...'
+ ].
+ val == 75 ifTrue:[
+ currentAction value:'almost finished ...'
+ ].
+ progressValue value:val
+ ]
+ ]
+ [exEnd]
above search example using this convenient interface:
- [exBegin]
+ [exBegin]
|p|
p := ProgressIndicator
- inBoxWithLabel:'searching files ...'
- abortable:false.
+ inBoxWithLabel:'searching files ...'
+ abortable:false.
p showProgressOf:
- [:progressValue :currentAction |
- |names nDone|
+ [:progressValue :currentAction |
+ |names nDone|
- names := 'source' asFilename directoryContents.
- nDone := 0.
- names do:[:aName |
- |fn stream line|
+ names := 'source' asFilename directoryContents.
+ nDone := 0.
+ names do:[:aName |
+ |fn stream line|
- progressValue value:(nDone / names size * 100).
- currentAction value:'searching ' , 'source/' , aName , ' ...'.
+ progressValue value:(nDone / names size * 100).
+ currentAction value:'searching ' , 'source/' , aName , ' ...'.
- fn := ('source/' , aName) asFilename.
- fn isDirectory ifFalse:[
- stream := fn readStream.
- [stream atEnd] whileFalse:[
- line := stream nextLine.
- (line findString:'subclass:') ~~ 0 ifTrue:[
- Transcript showCR:line
- ].
- ].
- stream close.
- ].
- nDone := nDone + 1
- ].
- ].
- [exEnd]
+ fn := ('source/' , aName) asFilename.
+ fn isDirectory ifFalse:[
+ stream := fn readStream.
+ [stream atEnd] whileFalse:[
+ line := stream nextLine.
+ (line findString:'subclass:') ~~ 0 ifTrue:[
+ Transcript showCR:line
+ ].
+ ].
+ stream close.
+ ].
+ nDone := nDone + 1
+ ].
+ ].
+ [exEnd]
a nice example: copying files a la windows ...
the following copies all files to /dev/null.
- [exBegin]
+ [exBegin]
|p|
(ProgressIndicator
- inBoxWithLabel:'copy files to /dev/null ...'
- abortable:true)
- showProgressOf:
- [:progressValue :currentAction |
- |files nFiles nDone|
+ inBoxWithLabel:'copy files to /dev/null ...'
+ abortable:true)
+ showProgressOf:
+ [:progressValue :currentAction |
+ |files nFiles nDone|
- files := '.' asFilename directoryContents.
- nFiles := files size.
- nDone := 0.
- files do:[:aFileName |
- |percent|
+ files := '.' asFilename directoryContents.
+ nFiles := files size.
+ nDone := 0.
+ files do:[:aFileName |
+ |percent|
- nDone := nDone + 1.
- percent := nDone / nFiles * 100.
- progressValue value:percent.
- aFileName asFilename isDirectory ifTrue:[
- Transcript showCR:('skipping ' , aFileName , ' ...').
- currentAction value:('skipping ' , aFileName , ' ...').
- ] ifFalse:[
- Transcript showCR:('copying ' , aFileName , ' ...').
- currentAction value:('copying ' , aFileName , ' ...').
- Object errorSignal handle:[:ex |
- self warn:'an error occurred while copying ' , aFileName.
- ex return
- ] do:[
- aFileName asFilename copyTo:'/dev/null'.
- ]
- ].
- ].
- ].
- [exEnd]
+ nDone := nDone + 1.
+ percent := nDone / nFiles * 100.
+ progressValue value:percent.
+ aFileName asFilename isDirectory ifTrue:[
+ Transcript showCR:('skipping ' , aFileName , ' ...').
+ currentAction value:('skipping ' , aFileName , ' ...').
+ ] ifFalse:[
+ Transcript showCR:('copying ' , aFileName , ' ...').
+ currentAction value:('copying ' , aFileName , ' ...').
+ Object errorSignal handle:[:ex |
+ self warn:'an error occurred while copying ' , aFileName.
+ ex return
+ ] do:[
+ aFileName asFilename copyTo:'/dev/null'.
+ ]
+ ].
+ ].
+ ].
+ [exEnd]
"
! !
@@ -456,6 +522,27 @@
]
"Modified: / 6.6.1998 / 19:43:56 / cg"
+!
+
+showBusyIndication:aBooleanHolder
+ "switch between percentage mode (if false) and busy indication (if true)"
+
+ aBooleanHolder ~~ showBusy ifTrue:[
+ showBusy notNil ifTrue:[
+ showBusy removeDependent:self.
+ ].
+ showBusy := aBooleanHolder.
+ showBusy addDependent:self.
+ (showBusy value) ifTrue:[
+ self startBusyIndicationProcess.
+ ] ifFalse:[
+ self stopBusyIndicationProcess
+ ].
+ shown ifTrue:[self redraw]
+ ].
+
+ "Created: / 21.10.1998 / 17:35:16 / cg"
+ "Modified: / 21.10.1998 / 18:03:06 / cg"
! !
!ProgressIndicator methodsFor:'accessing - behavior'!
@@ -549,12 +636,16 @@
(aspect == aspectMsg
and:[changedObject == model]) ifTrue:[
- self percentage:(model perform:aspectMsg).
- ^ self
+ self percentage:(model perform:aspectMsg).
+ ^ self
+ ].
+ changedObject == showBusy ifTrue:[
+ self redraw.
+ ^ self
].
^ super update:aspect with:aParameter from:changedObject
- "Modified: 22.10.1997 / 21:05:11 / cg"
+ "Modified: / 21.10.1998 / 18:01:52 / cg"
! !
!ProgressIndicator methodsFor:'drawing'!
@@ -562,7 +653,7 @@
redraw
"redraw the percentage bar and optional percentage string"
- |s rx sx sy sw m2 m w h|
+ |s lx rx sx sy sw m2 m w h|
m := margin + 1.
m2 := m*2.
@@ -570,10 +661,22 @@
w := width - m2.
h := height - m2.
- rx := (w * percentage / 100) rounded.
-
"/ self clear.
+ showBusy value ifTrue:[
+ self paint:bgColor.
+ self fillRectangleX:m y:m width:w height:h.
+
+ lx := (w * busyPosition / 100) rounded.
+ rx := (w * (busyPosition + 20) / 100) rounded.
+ rx := rx min:w.
+ lx := lx max:m.
+ self paint:fgColor.
+ self fillRectangleX:lx y:m width:(rx - lx) height:h.
+ ^ self
+ ].
+
+ rx := (w * percentage / 100) rounded.
self paint:bgColor.
self fillRectangleX:m+rx y:m width:w-rx height:h.
@@ -601,7 +704,7 @@
]
]
- "Modified: / 6.6.1998 / 19:45:08 / cg"
+ "Modified: / 21.10.1998 / 18:01:58 / cg"
!
sizeChanged:how
@@ -616,6 +719,16 @@
!ProgressIndicator methodsFor:'initialization'!
+destroy
+ busyIndicationProcess notNil ifTrue:[
+ self stopBusyIndicationProcess
+ ].
+ super destroy.
+
+ "Created: / 21.10.1998 / 17:29:58 / cg"
+ "Modified: / 21.10.1998 / 17:30:36 / cg"
+!
+
initStyle
"initialize styleSheet values"
@@ -641,6 +754,9 @@
super initialize.
percentage := 0.
+ showBusy := false.
+
+ "Modified: / 21.10.1998 / 17:33:02 / cg"
! !
!ProgressIndicator methodsFor:'private'!
@@ -648,6 +764,50 @@
connectToTop:top label:label
connectedTop := top.
connectedLabel := label
+!
+
+startBusyIndicationProcess
+ busyIndicationProcess isNil ifTrue:[
+ busyPosition := 0.
+ busyDelta := 5.
+ busyIndicationProcess := [
+ [true] whileTrue:[
+ Delay waitForSeconds:0.2.
+ self updateBusyIndicatorPosition
+ ]
+ ] fork.
+ ].
+
+ "Created: / 21.10.1998 / 18:02:35 / cg"
+ "Modified: / 21.10.1998 / 18:03:49 / cg"
+!
+
+stopBusyIndicationProcess
+ busyIndicationProcess notNil ifTrue:[
+ busyIndicationProcess terminate.
+ busyIndicationProcess := nil
+ ].
+
+ "Created: / 21.10.1998 / 17:30:19 / cg"
+!
+
+updateBusyIndicatorPosition
+ busyPosition := busyPosition + busyDelta.
+ busyPosition >= 80 ifTrue:[
+ busyDelta > 0 ifTrue:[
+ busyDelta := busyDelta negated.
+ ]
+ ] ifFalse:[
+ busyPosition <= 0 ifTrue:[
+ busyDelta < 0 ifTrue:[
+ busyDelta := busyDelta negated.
+ ]
+ ]
+ ].
+ shown ifTrue:[self redraw]
+
+ "Created: / 21.10.1998 / 17:33:28 / cg"
+ "Modified: / 21.10.1998 / 17:58:58 / cg"
! !
!ProgressIndicator methodsFor:'queries'!
@@ -686,10 +846,10 @@
labelValue := '' asValue.
connectedLabel notNil ifTrue:[
- connectedLabel
- model:labelValue;
- aspect:#value;
- labelMessage:#value.
+ connectedLabel
+ model:labelValue;
+ aspect:#value;
+ labelMessage:#value.
].
self model:progressValue.
@@ -697,58 +857,60 @@
"/ the worker process
p := [
- [
- WindowGroup windowGroupQuerySignal handle:[:ex |
- ex proceedWith:self topView windowGroup
- ] do:[
- aBlock value:progressValue value:labelValue
- ]
- ] valueNowOrOnUnwindDo:[
- p := nil.
- closeTopWhenDone ifTrue:[
- connectedTop hide
- ].
- finishAction notNil ifTrue:[
- finishAction value
- ]
- ]
+ [
+ WindowGroup windowGroupQuerySignal handle:[:ex |
+ ex proceedWith:self topView windowGroup
+ ] do:[
+ aBlock value:progressValue value:labelValue
+ ]
+ ] valueNowOrOnUnwindDo:[
+ p := nil.
+ closeTopWhenDone ifTrue:[
+ connectedTop hide
+ ].
+ finishAction notNil ifTrue:[
+ finishAction value
+ ]
+ ]
] fork.
Processor activeProcess
- withPriority:(Processor activePriority + 1)
- do:[
- self topView show.
- ].
+ withPriority:(Processor activePriority + 1)
+ do:[
+ self topView show.
+ ].
p notNil ifTrue:[p terminate].
"
|p|
p := ProgressIndicator inBox.
+ p showBusyIndication:true.
p showProgressOf:
- [:progressValue :currentAction |
- 1 to:100 do:[:percent |
- (Delay forSeconds:0.05) wait.
- progressValue value:percent
- ].
- ].
+ [:progressValue :currentAction |
+ 1 to:200 do:[:percent |
+ (Delay forSeconds:0.05) wait.
+ progressValue value:percent
+ ].
+ ].
'it can be reused ...'.
+ p showBusyIndication:false.
p showProgressOf:
- [:progressValue :currentAction |
- 1 to:100 by:5 do:[:percent |
- (Delay forSeconds:0.05) wait.
- progressValue value:percent
- ].
- ].
+ [:progressValue :currentAction |
+ 1 to:100 by:5 do:[:percent |
+ (Delay forSeconds:0.05) wait.
+ progressValue value:percent
+ ].
+ ].
"
- "Modified: 3.9.1996 / 14:22:43 / cg"
+ "Modified: / 21.10.1998 / 17:37:00 / cg"
! !
!ProgressIndicator class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libwidg2/ProgressIndicator.st,v 1.24 1998-07-20 21:33:08 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/ProgressIndicator.st,v 1.25 1998-10-21 16:18:11 cg Exp $'
! !