Scrollers Sometimes Go Too Fast

One of the Newton 2.x OS Q&As
Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.


NEW: Scrollers Sometimes Go Too Fast (6/9/97)

Q: When using protoUpDownScroller on an Apple MessagePad 2000 , tapping on the scroller once calls the viewScroll2DScript two or three times. Shouldn't the scroller call the script only once per tap?

A: The problem happens because the processor in the MessagePad 2000 is so fast. The scroller doesn't call the viewScroll2DScript once per tap, but rather calls it repeatedly while the pen is held down over the scroll arrow. This is normal scroller behavior, and has in fact been there all along. with the MP2000, the processor is so much faster that it can chug through many scroll operations before the pen is released.

That is, the scrolling code in the scroller itself does the equivalent of a "while not StrokeDone(unit) do targetView:viewScroll2dscript(....)". If it takes even 1 tick for the StrokeDone function to report true, it's possible that the viewScroll2DScript might have been called more than once.

If you need to slow down scrolling, add a delay in your viewScroll2DScript. Use the global function Sleep for this, as that call will yeild the NewtonScript task and let other parts of the OS work (or sleep the processor, saving battery power.)

A simple delay after each scroll event will work fine, and is probably the best solution overall. If you want to have the function operate consistently on all processors, you might do something like this;

    constant kMaxScrollSpeed := 60;  // ticks
    viewScroll2DScript: func(...)
        begin
            local t := ticks();
            ... // do scrolling stuff
            RefreshViews(); // show scrolled result
            Sleep(MAX(kMaxScrollSpeed - (ticks() - t), 0));
        end;


The above code should have the unit scrolling at a fairly consistent one-scroll-per-second unless the time it takes to do the scrolling stuff is more than 1 second, in which case it'll just go as fast as it can. The drawback to this approach is that the script will always delay for at least a second, so if for example the user taps the up arrow then the down arrow in less than a second, there will seem to be a delay between the up scroll and down scroll that would not necessarily need to be there.

You could certainly be more clever with your delays by counting ticks and watching the count paramater to your scroll script. This might even result in a better performing delay. However, it's probably not worth the effort it would take to implement this. The one-scroll-per-second approach works well, is simple, and it's unlikely that the user will ever notice the small extra delay. (Don't try to do one-scroll-every-5-seconds using this method though, your users may quickly grow annoyed at the extra delay!)