Label.st
changeset 5751 17064cf2e823
parent 5750 12b4fa216382
child 5752 15cf293cf929
--- a/Label.st	Mon May 16 09:17:08 2016 +0200
+++ b/Label.st	Mon May 16 15:02:22 2016 +0200
@@ -22,6 +22,13 @@
 	category:'Views-Layout'
 !
 
+Object subclass:#AnimatorState
+	instanceVariableNames:'timedBlock nextOffset logoShown moveDirection'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:Label
+!
+
 !Label class methodsFor:'documentation'!
 
 copyright
@@ -1471,27 +1478,24 @@
     "by slow scrolling the label, ensure that the label's text is readable.
      (stops when the cursor enters)"
     
-    |animatorAndOffset offset animator logoScrolled 
-     atTop atBottom nextOffset nextAnimationDelay focusView|
+    |animatorState offset atTop atBottom nextOffset nextMoveDirection nextAnimationDelay focusView|
     
-    animatorAndOffset := self objectAttributeAt:#animator.
-    animatorAndOffset isNil ifTrue:[^ self "I have been stopped in the meanwhile"].
+    animatorState := self objectAttributeAt:#animator.
+    animatorState isNil ifTrue:[^ self "I have been stopped in the meanwhile"].
     
     (drawableId notNil and:[shown]) ifFalse:[
         "/ view has been closed.
-        self removeObjectAttribute:#animator.
+        self stopAnimation.
         ^ self
     ].
-
-    animator := animatorAndOffset at:1.
-    offset := animatorAndOffset at:2.
-    logoScrolled := animatorAndOffset at:3.
-    logo == logoScrolled ifFalse:[
+    logo == (animatorState logoShown) ifFalse:[
         "/ logo changed - stop it
-        self removeObjectAttribute:#animator.
+        self stopAnimation.
         ^ self
     ].
     
+    offset := animatorState nextOffset.
+
     atTop := (offset == 0).
     atBottom := (offset - self font ascent + self font height) > (self height + 1).
     
@@ -1499,11 +1503,25 @@
                                 ifTrue:[ self animationDelayTopOrBottom ]
                                 ifFalse:[ self animationDelay ]. 
 
+    nextMoveDirection := animatorState moveDirection.
+    atTop ifTrue:[
+        nextMoveDirection := #down
+    ].
+    
     atBottom ifTrue:[
         "/ after a longer delay, start again from top
-        nextOffset := 0.
-    ] ifFalse:[    
-        nextOffset := offset + 1.
+        "/ nextOffset := 0.
+        "/ nextMoveDirection := #down.
+        "/ after a longer delay, start moving up again (fast)
+        nextOffset := offset - 1.
+        nextMoveDirection := #up.
+    ] ifFalse:[
+        nextMoveDirection == #down ifTrue:[
+            nextOffset := offset + 1.
+        ] ifFalse:[
+            nextOffset := offset - 1.
+            nextAnimationDelay := nextAnimationDelay / 3. "/ fast
+        ].    
     ].
 
     "/ If I am not part of the active window, scroll back to top and wait longer...
@@ -1511,26 +1529,34 @@
     and:[ focusView windowGroup == self windowGroup ]) ifFalse:[
         nextOffset := offset := 0.
         nextAnimationDelay := self animationDelayTopOrBottom.
+        nextMoveDirection := #down.
     ].
 
     labelOriginY := offset negated.
-    animatorAndOffset at:2 put:nextOffset.
+    animatorState nextOffset:nextOffset.
+    animatorState moveDirection:nextMoveDirection.
 
     self invalidate.
-    Processor addTimedBlock:animator after:nextAnimationDelay.
+    Processor addTimedBlock:(animatorState timedBlock) after:nextAnimationDelay.
 !
 
 startAnimation
     "start an animator, which scrolls the label's text.
      (slow scroll which stops when the cursor enters)"
     
-    |animator|
+    |timedBlock|
     
     self stopAnimation.
 
-    animator := [ self doAnimate ].
-    self objectAttributeAt:#animator put:{ animator . 0 . logo}.
-    Processor addTimedBlock:animator after:(self animationDelay)
+    timedBlock := [ self doAnimate ].
+    self 
+        objectAttributeAt:#animator 
+        put:(AnimatorState new 
+                timedBlock:timedBlock 
+                nextOffset:0 
+                moveDirection:#down 
+                logoShown:logo).
+    Processor addTimedBlock:timedBlock after:(self animationDelay)
 
     "
      |l|
@@ -1549,16 +1575,16 @@
 !
 
 stopAnimation
-    |animatorAndOffset animator|
+    |animatorState timedBlock|
     
-    animatorAndOffset := self removeObjectAttribute:#animator.
-    animatorAndOffset notNil ifTrue:[
-        animator := animatorAndOffset first.
-        Processor removeTimedBlock:animator.
-
+    animatorState := self removeObjectAttribute:#animator.
+    animatorState notNil ifTrue:[
+        timedBlock := animatorState timedBlock.
+        Processor removeTimedBlock:timedBlock.
+
+        "/ ensure that things are in their normal state again
+        self computeLabelOrigin.
         shown ifTrue:[
-            "/ ensure that things are in their normal state again
-            self computeLabelOrigin.
             self invalidate.
         ].
     ].
@@ -2085,6 +2111,39 @@
     ]
 ! !
 
+!Label::AnimatorState methodsFor:'accessing'!
+
+logoShown
+    ^ logoShown
+!
+
+moveDirection
+    ^ moveDirection
+!
+
+moveDirection:something
+    moveDirection := something.
+!
+
+nextOffset
+    ^ nextOffset
+!
+
+nextOffset:something
+    nextOffset := something.
+!
+
+timedBlock
+    ^ timedBlock
+!
+
+timedBlock:timedBlockArg nextOffset:nextOffsetArg moveDirection:moveDirectionArg logoShown:logoShownArg
+    timedBlock := timedBlockArg.
+    nextOffset := nextOffsetArg.
+    moveDirection := moveDirectionArg.
+    logoShown := logoShownArg.
+! !
+
 !Label class methodsFor:'documentation'!
 
 version