Merge jv
authorJan Vrany <jan.vrany@fit.cvut.cz>
Tue, 17 May 2016 14:42:25 +0100
branchjv
changeset 5754 d960975fec46
parent 5748 8fa14ad33457 (current diff)
parent 5753 d8465881eb1f (diff)
child 5760 9a0b5601b3f4
Merge
Label.st
ScrollableView.st
--- a/Label.st	Mon May 16 06:10:49 2016 +0100
+++ b/Label.st	Tue May 17 14:42:25 2016 +0100
@@ -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,44 +1478,94 @@
     "by slow scrolling the label, ensure that the label's text is readable.
      (stops when the cursor enters)"
     
-    |offset animator atTop atBottom|
+    |animatorState offset atTop atBottom nextOffset nextMoveDirection nextAnimationDelay focusView|
     
-    (animator := self objectAttributeAt:#animator) isNil ifTrue:[^ self "I have been stopped"].
-    self drawableId isNil ifTrue:[^ self].
+    animatorState := self objectAttributeAt:#animator.
+    animatorState isNil ifTrue:[^ self "I have been stopped in the meanwhile"].
     
-    offset := self objectAttributeAt:#animatorOffset.
-    atTop := (offset == 0).
-    atBottom := (offset - self font ascent + labelHeight) > self height .
-    
-    atBottom ifTrue:[
-        "/ after a longer delay, start again from top
-        self objectAttributeAt:#animatorOffset put:0.
-        Processor addTimedBlock:animator after:(self animationDelayTopOrBottom).
+    (self drawableId isNil) ifTrue:[
+        "/ view has been closed.
+        self stopAnimation.
+        ^ self
+    ].
+    logo == (animatorState logoShown) ifFalse:[
+        "/ logo changed - stop it
+        self stopAnimation.
+        ^ self
+    ].
+    shown ifFalse:[
+        "/ currently invisible (iconified/hidden)
+        Processor addTimedBlock:(animatorState timedBlock) after:self animationDelayTopOrBottom.
+        self computeLabelOrigin.
         ^ self.
     ].
     
-    labelOriginY := offset negated.
-    offset := offset + 1.
-    self objectAttributeAt:#animatorOffset put:offset.
-    self invalidate.
+    offset := animatorState nextOffset max:0.
+
+    atTop := (offset <= 0).
+    "/ Transcript printf:'labelHeight: %d offset: %d fA: %d fH: %d height: %d\n'
+    "/              withAll:{ labelHeight . offset . self font ascent . self font height . height }.
+    "/ (labelHeight - offset) is restHeight
+    atBottom := (labelHeight - offset) < height.
+    
+    nextAnimationDelay := (atTop | atBottom)
+                                ifTrue:[ self animationDelayTopOrBottom ]
+                                ifFalse:[ self animationDelay ]. 
+
+    nextMoveDirection := animatorState moveDirection.
+    atTop ifTrue:[
+        nextMoveDirection := #down
+    ].
     
-    Processor addTimedBlock:animator 
-              after:(atTop 
-                        ifTrue:[self animationDelayTopOrBottom] 
-                        ifFalse:[self animationDelay]).
+    atBottom ifTrue:[
+        "/ after a longer delay, start again from top
+        "/ 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 - 2.
+            nextAnimationDelay := nextAnimationDelay / 4. "/ fast
+        ].    
+    ].
+
+    "/ If I am not part of the active window, scroll back to top and wait longer...
+    ((focusView := Display focusView) notNil
+    and:[ focusView windowGroup == self windowGroup ]) ifFalse:[
+        nextOffset := offset := 0.
+        nextAnimationDelay := self animationDelayTopOrBottom.
+        nextMoveDirection := #down.
+    ].
+
+    labelOriginY := offset negated.
+    animatorState nextOffset:nextOffset.
+    animatorState moveDirection:nextMoveDirection.
+
+    self invalidate.
+    Processor addTimedBlock:(animatorState timedBlock) after:nextAnimationDelay.
 !
 
 startAnimation
-    "start an animator, which ensures that the label's text is visible
+    "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:#animatorOffset put:0.
-    self objectAttributeAt:#animator put:animator.
-    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|
@@ -1520,7 +1577,6 @@
 Line3
 Line4'.
      l openAndWait.
-     Delay waitForSeconds:10.
      l startAnimation.
      Delay waitForSeconds:10.
      l stopAnimation.
@@ -1528,15 +1584,18 @@
 !
 
 stopAnimation
-    |animator|
+    |animatorState timedBlock|
     
-    (animator := (self objectAttributeAt:#animator) notNil) ifTrue:[
-        self objectAttributeAt:#animator put:nil.
-        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.
-        self invalidate.
+        shown ifTrue:[
+            self invalidate.
+        ].
     ].
 ! !
 
@@ -2061,6 +2120,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
--- a/ScrollableView.st	Mon May 16 06:10:49 2016 +0100
+++ b/ScrollableView.st	Tue May 17 14:42:25 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
               All Rights Reserved
@@ -1349,6 +1347,7 @@
     |anyChange|
 
     anyChange := self updateVScrollBarVisibility.
+    "/ evaluating or here    
     anyChange := anyChange | self updateHScrollBarVisibility.
 
     "/ stupid - showing one may need the other and vice versa...