added showBusyIndication mode
authorClaus Gittinger <cg@exept.de>
Wed, 21 Oct 1998 18:18:11 +0200
changeset 1168 35e46761842f
parent 1167 4451606328d2
child 1169 5c1c7f590436
added showBusyIndication mode
ProgressIndicator.st
--- 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 $'
 ! !