Martin Rais wrote:
> Already tried that too. What I am trying to avoid is great changes in the
> scrollbar's value, so when I get a new sclRepeatEvent with its newvalue very
> different from its previous value (yes, I am saving its previous value) then
> I set the scrollbar to its previous value. It works ok when debugging up to
> that point, but then when the HandleEvent function of the form returns
> handled = true then the scrollbar goes back again to the original value (the
> one it was originally before I pressed the stylus on it).
> Scroll Bar send exit events but when I stop pressing the screen with the
> stylus, not when I am still on it.
> Any ideas anyone?
Some ways to handle this:
(1) If you get a sclRepeatEvent, call EvtGetPen(). If the pen is
down and the pen is outside the bounds of the scrollbar (plus
some margin of error that you'll have to fudge based on manual
testing of the scrollbar), then ignore the event. The negative
side of this is that I think your scrollbar's car will move
when your text (or whatever you're scrolling) doesn't, so it
will be inconsistent and confusing to the user.
(2) Get the OS sample source and write your own scrollbar based
on it, except remove the behavior you don't like. (While you're
at it, fix the long-standing bug where the scrollbar moves
at hyperspeed when you hold your pen down in the track area
that doesn't contain the car. It should move one page at a
time and repeat slowly, but because of a bad timing calculation
that makes assumptions about how many ticks per second instead
of calling SysTicksPerSecond(), it moves at ridiculous speed.
There is a similar problem with the time interval between the
time the pen goes down and when it starts to repeat.)
(3) If you really are trying to avoid sudden movements, you could
implement a simple low-pass filter. I do this sometimes when
tracking the pen to reduce its jitteriness. When tracking
the pen, it looks something like this:
Coord x, y;
Coord penx, peny;
Boolean pendown;
// get initial values for x and y
EvtGetPen (&x, &y, &pendown);
while (pendown)
{
// do something with x and y, like maybe plot a pixel there
EvtGetPen (&penx, &peny, &pendown);
x = (3 * x + penx) / 4;
y = (3 * y + peny) / 4;
}
By doing a weighted average between the old value and the new
value, you'll see the old value more gradually converge toward
where the new value. (However, if you do this too much,
like if you replace 3 with 15 and 4 with 16, it will appear
really sluggish to the user, like the Palm can't keep up
with them.)
Now, this is for tracking the pen, but you're talking about
tracking sclRepeatEvents. For that, you would need to do a
similar decaying average type thing with the scrollbar value
instead of the pen position. Also, another difference is that
a while loop around EvtGetPen() will keep giving you the x
and y coordinates even if they don't change, whereas I believe
sclRepeatEvent only occurs when some actual change in the
value has occurred. So, you'd need to receive sclRepeatEvent
and store the value it gave you, and then through some timed
process (like receiving periodic nilEvents), you'd need to
slowly adjust *your* value to the value that it should be
according to what you've most-recently stored from the last
sclRepeatEvent.
Unfortunately, the problem with this approach is that it will
only make huge changes in the position of the scrollbar
smaller, not eliminate them. But it could make things a
little smoother.
Another approach is just to live with it. It's what Palm user's
experience with all other programs, so they can probably handle
experiencing it with yours as well.
- Logan
--
For information on using the Palm Developer Forums, or to unsubscribe, please
see http://www.palmos.com/dev/support/forums/