Board index » delphi » Making PAN Work Properly

Making PAN Work Properly

I'm trying to set up a 'pan' function in a TImage so that when the user
drags the mouse across the image with the left mouse key down, the image
is pulled with the mouse.

I have it working, sort of.  The image pulls as it should but a) it is
very "jump" instead of pulling smoothly, and b) the mouse moves faster
than the image, ie, one pixel of mouse movement doesn't move the image
one pixel.

Both of these phenomena can be demo'd with the unit below.

Can anyone tell me why this is such a 'shaky' pan?

Thanks.

A Tform has
  AutoSize = false;
  AutoScroll = true;

A TImage on the form has
  Align = none;
  AutoSize = true;

Loading an image that is larger than the form results in scroll bars
generated by the
form.

Now, I select the mouse down and mouse move events of the TImage and
provde the following event code.

var
  Form1: TForm1;
  MouseLastX : integer; // mouse stuff
  MouseLastY : integer;
  MouseDeltaX : integer; // mouse stuff
  MouseDeltaY : integer;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin

Image1.Picture.LoadFromFile('s:\RasterImages\TestsAndDemos\P531top.bmp');

end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MouseLastX := X;
  MouseLastY := Y;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

  Y: Integer);
begin
  if (ssLeft in Shift) then begin  // if left button down, then pan
    // update location and deltas
    MouseDeltaX := X - MouseLastX;
    MouseDeltaY := Y - MouseLastY;
    MouseLastX := X;
    MouseLastY := Y;
    // situation 1 - dragging right to left
    if (MouseDeltaX <= 0) then begin  // image dragged to the left
      MouseDeltaX := Abs(MouseDeltaX);  // make it pos
      HorzScrollBar.Position  := HorzScrollBar.Position + MouseDeltaX;
      end
    else if (MouseDeltaX > 0) then begin  // image dragged to the right
      HorzScrollBar.Position  := HorzScrollBar.Position - MouseDeltaX;
      end;

    // situation 3 - dragging bottom to top
    if (MouseDeltaY <= 0) then begin  // image dragged to the top
      MouseDeltaY := Abs(MouseDeltaY);  // make it pos
      VertScrollBar.Position  := VertScrollBar.Position + MouseDeltaY;
      end
    // situation 4 - dragging top to bottom
    else if (MouseDeltaY > 0) then begin  // image dragged to the right
      VertScrollBar.Position  := VertScrollBar.Position - MouseDeltaY;
      end;
    end;  // if left Mouse Down
end;

end.

 

Re:Making PAN Work Properly


I know what is causing the problem... now I am stumped for a workaround.

If the image in a TImage is scrolled, then an OnMouseMove event is issued to
update the mouse (x,y) as a result of the image moving under the mouse.

So, I am getting a case of coordinate feedback.  I use the OnMouseMove event
to scroll the image, but as soon as I scroll, the scroll generates an
OnMouseMove event to inform me of the scroll I just initiated.  It's tuff to
figure out, especially since the mouse may have been moved between the scroll
and the scroll induced event.

Thoughts?

Quote
"Sue D. Nom" wrote:
> I'm trying to set up a 'pan' function in a TImage so that when the user
> drags the mouse across the image with the left mouse key down, the image
> is pulled with the mouse.

> I have it working, sort of.  The image pulls as it should but a) it is
> very "jump" instead of pulling smoothly, and b) the mouse moves faster
> than the image, ie, one pixel of mouse movement doesn't move the image
> one pixel.

> Both of these phenomena can be demo'd with the unit below.

> Can anyone tell me why this is such a 'shaky' pan?

> Thanks.

> A Tform has
>   AutoSize = false;
>   AutoScroll = true;

> A TImage on the form has
>   Align = none;
>   AutoSize = true;

> Loading an image that is larger than the form results in scroll bars
> generated by the
> form.

> Now, I select the mouse down and mouse move events of the TImage and
> provde the following event code.

> var
>   Form1: TForm1;
>   MouseLastX : integer; // mouse stuff
>   MouseLastY : integer;
>   MouseDeltaX : integer; // mouse stuff
>   MouseDeltaY : integer;

> implementation

> {$R *.DFM}

> procedure TForm1.FormCreate(Sender: TObject);
> begin

> Image1.Picture.LoadFromFile('s:\RasterImages\TestsAndDemos\P531top.bmp');

> end;

> procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
>   Shift: TShiftState; X, Y: Integer);
> begin
>   MouseLastX := X;
>   MouseLastY := Y;
> end;

> procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

>   Y: Integer);
> begin
>   if (ssLeft in Shift) then begin  // if left button down, then pan
>     // update location and deltas
>     MouseDeltaX := X - MouseLastX;
>     MouseDeltaY := Y - MouseLastY;
>     MouseLastX := X;
>     MouseLastY := Y;
>     // situation 1 - dragging right to left
>     if (MouseDeltaX <= 0) then begin  // image dragged to the left
>       MouseDeltaX := Abs(MouseDeltaX);  // make it pos
>       HorzScrollBar.Position  := HorzScrollBar.Position + MouseDeltaX;
>       end
>     else if (MouseDeltaX > 0) then begin  // image dragged to the right
>       HorzScrollBar.Position  := HorzScrollBar.Position - MouseDeltaX;
>       end;

>     // situation 3 - dragging bottom to top
>     if (MouseDeltaY <= 0) then begin  // image dragged to the top
>       MouseDeltaY := Abs(MouseDeltaY);  // make it pos
>       VertScrollBar.Position  := VertScrollBar.Position + MouseDeltaY;
>       end
>     // situation 4 - dragging top to bottom
>     else if (MouseDeltaY > 0) then begin  // image dragged to the right
>       VertScrollBar.Position  := VertScrollBar.Position - MouseDeltaY;
>       end;
>     end;  // if left Mouse Down
> end;

> end.

Re:Making PAN Work Properly


Sue,

Quote
> So, I am getting a case of coordinate feedback.  I use the OnMouseMove
event
> to scroll the image, but as soon as I scroll, the scroll generates an
> OnMouseMove event to inform me of the scroll I just initiated.  It's tuff
to
> figure out, especially since the mouse may have been moved between the
scroll
> and the scroll induced event.

Disable the OnMouseMove event prior to scrolling. i.e. The following worked
for me.

{ Assumes Image is a child of ScrollBox }

procedure Form1.ImageOnMouseDown(...);
begin
   FStartPoint := Point(X,Y)
end;

procedure Form1.ImageOnMouseUp(...)
begin
  FStartPoint := Point(0,0)
end;

procedure Form1.ImageOnMouseMove(...);
begin
  if (FStartPoint.X <> 0) or (FStartPoint.Y <> 0) { in move state } then
    begin
       Image.OnMouseMove := nil;
       ScrollBox.ScrollBy( X - FStartPoint.X, Y - FStartPoint.Y );
       FStartPoint := Point(X,Y);
       Image.OnMouseMove := ImageOnMouseMove
    end
end;

Either that or consider using a timer. Start it when the mouse is down, stop
it
when the mouse is up, and scroll the box by the distance the mouse has
moved since the last timer call. By adjusting the rate of the timer it
controls
the "smoothless" and responsiveness vs the rate at which the scrollbox can
scroll and display the image.
Hope this helps,

Brett

"Sue D. Nom" <su...@courthouse.com> wrote in message
news:3A81E6C9.BE0E558D@courthouse.com...

Quote
> I know what is causing the problem... now I am stumped for a workaround.

> If the image in a TImage is scrolled, then an OnMouseMove event is issued
to
> update the mouse (x,y) as a result of the image moving under the mouse.

> So, I am getting a case of coordinate feedback.  I use the OnMouseMove
event
> to scroll the image, but as soon as I scroll, the scroll generates an
> OnMouseMove event to inform me of the scroll I just initiated.  It's tuff
to
> figure out, especially since the mouse may have been moved between the
scroll
> and the scroll induced event.

> Thoughts?

> "Sue D. Nom" wrote:

> > I'm trying to set up a 'pan' function in a TImage so that when the user
> > drags the mouse across the image with the left mouse key down, the image
> > is pulled with the mouse.

> > I have it working, sort of.  The image pulls as it should but a) it is
> > very "jump" instead of pulling smoothly, and b) the mouse moves faster
> > than the image, ie, one pixel of mouse movement doesn't move the image
> > one pixel.

> > Both of these phenomena can be demo'd with the unit below.

> > Can anyone tell me why this is such a 'shaky' pan?

> > Thanks.

> > A Tform has
> >   AutoSize = false;
> >   AutoScroll = true;

> > A TImage on the form has
> >   Align = none;
> >   AutoSize = true;

> > Loading an image that is larger than the form results in scroll bars
> > generated by the
> > form.

> > Now, I select the mouse down and mouse move events of the TImage and
> > provde the following event code.

> > var
> >   Form1: TForm1;
> >   MouseLastX : integer; // mouse stuff
> >   MouseLastY : integer;
> >   MouseDeltaX : integer; // mouse stuff
> >   MouseDeltaY : integer;

> > implementation

> > {$R *.DFM}

> > procedure TForm1.FormCreate(Sender: TObject);
> > begin

Image1.Picture.LoadFromFile('s:\RasterImages\TestsAndDemos\P531top.bmp');

- Show quoted text -

Quote

> > end;

> > procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
> >   Shift: TShiftState; X, Y: Integer);
> > begin
> >   MouseLastX := X;
> >   MouseLastY := Y;
> > end;

> > procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

> >   Y: Integer);
> > begin
> >   if (ssLeft in Shift) then begin  // if left button down, then pan
> >     // update location and deltas
> >     MouseDeltaX := X - MouseLastX;
> >     MouseDeltaY := Y - MouseLastY;
> >     MouseLastX := X;
> >     MouseLastY := Y;
> >     // situation 1 - dragging right to left
> >     if (MouseDeltaX <= 0) then begin  // image dragged to the left
> >       MouseDeltaX := Abs(MouseDeltaX);  // make it pos
> >       HorzScrollBar.Position  := HorzScrollBar.Position + MouseDeltaX;
> >       end
> >     else if (MouseDeltaX > 0) then begin  // image dragged to the right
> >       HorzScrollBar.Position  := HorzScrollBar.Position - MouseDeltaX;
> >       end;

> >     // situation 3 - dragging bottom to top
> >     if (MouseDeltaY <= 0) then begin  // image dragged to the top
> >       MouseDeltaY := Abs(MouseDeltaY);  // make it pos
> >       VertScrollBar.Position  := VertScrollBar.Position + MouseDeltaY;
> >       end
> >     // situation 4 - dragging top to bottom
> >     else if (MouseDeltaY > 0) then begin  // image dragged to the right
> >       VertScrollBar.Position  := VertScrollBar.Position - MouseDeltaY;
> >       end;
> >     end;  // if left Mouse Down
> > end;

> > end.

Re:Making PAN Work Properly


I solved the coordinate feedback problem in my pan routine by ignoring the (X,Y)
coordinates passed by the MouseMove event, and instead use the mouse position as
given my the global TMouse object, Mouse.  This solved the problem that

a) I generate mouse events by moving the mouse.  These are the events I need
since they show the displacement of the mouse.
b) Scrollbox generates a mouse move that puts the mouse back over the point it is
in the now scrolled image... these events confuse the issue

NEW PROBLEM - Flicker - how to stop on pan... flciker does not show when scroll
bars are pulled.

Quote
"Sue D. Nom" wrote:
> I know what is causing the problem... now I am stumped for a workaround.

> If the image in a TImage is scrolled, then an OnMouseMove event is issued to
> update the mouse (x,y) as a result of the image moving under the mouse.

> So, I am getting a case of coordinate feedback.  I use the OnMouseMove event
> to scroll the image, but as soon as I scroll, the scroll generates an
> OnMouseMove event to inform me of the scroll I just initiated.  It's tuff to
> figure out, especially since the mouse may have been moved between the scroll
> and the scroll induced event.

> Thoughts?

> "Sue D. Nom" wrote:

> > I'm trying to set up a 'pan' function in a TImage so that when the user
> > drags the mouse across the image with the left mouse key down, the image
> > is pulled with the mouse.

> > I have it working, sort of.  The image pulls as it should but a) it is
> > very "jump" instead of pulling smoothly, and b) the mouse moves faster
> > than the image, ie, one pixel of mouse movement doesn't move the image
> > one pixel.

> > Both of these phenomena can be demo'd with the unit below.

> > Can anyone tell me why this is such a 'shaky' pan?

> > Thanks.

> > A Tform has
> >   AutoSize = false;
> >   AutoScroll = true;

> > A TImage on the form has
> >   Align = none;
> >   AutoSize = true;

> > Loading an image that is larger than the form results in scroll bars
> > generated by the
> > form.

> > Now, I select the mouse down and mouse move events of the TImage and
> > provde the following event code.

> > var
> >   Form1: TForm1;
> >   MouseLastX : integer; // mouse stuff
> >   MouseLastY : integer;
> >   MouseDeltaX : integer; // mouse stuff
> >   MouseDeltaY : integer;

> > implementation

> > {$R *.DFM}

> > procedure TForm1.FormCreate(Sender: TObject);
> > begin

> > Image1.Picture.LoadFromFile('s:\RasterImages\TestsAndDemos\P531top.bmp');

> > end;

> > procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
> >   Shift: TShiftState; X, Y: Integer);
> > begin
> >   MouseLastX := X;
> >   MouseLastY := Y;
> > end;

> > procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

> >   Y: Integer);
> > begin
> >   if (ssLeft in Shift) then begin  // if left button down, then pan
> >     // update location and deltas
> >     MouseDeltaX := X - MouseLastX;
> >     MouseDeltaY := Y - MouseLastY;
> >     MouseLastX := X;
> >     MouseLastY := Y;
> >     // situation 1 - dragging right to left
> >     if (MouseDeltaX <= 0) then begin  // image dragged to the left
> >       MouseDeltaX := Abs(MouseDeltaX);  // make it pos
> >       HorzScrollBar.Position  := HorzScrollBar.Position + MouseDeltaX;
> >       end
> >     else if (MouseDeltaX > 0) then begin  // image dragged to the right
> >       HorzScrollBar.Position  := HorzScrollBar.Position - MouseDeltaX;
> >       end;

> >     // situation 3 - dragging bottom to top
> >     if (MouseDeltaY <= 0) then begin  // image dragged to the top
> >       MouseDeltaY := Abs(MouseDeltaY);  // make it pos
> >       VertScrollBar.Position  := VertScrollBar.Position + MouseDeltaY;
> >       end
> >     // situation 4 - dragging top to bottom
> >     else if (MouseDeltaY > 0) then begin  // image dragged to the right
> >       VertScrollBar.Position  := VertScrollBar.Position - MouseDeltaY;
> >       end;
> >     end;  // if left Mouse Down
> > end;

> > end.

Re:Making PAN Work Properly


Thank you, Brett.  I have looked at TScrollbox but rejected it because it does
not have an OnScroll event.  The lack of an event means I cannot detect a change
in the position of the image when the user repositions the image with the scroll
thumb.  This is why I went with my own scroll bars.
Now that I have got workarounds to make the PAN work properly with my scroll
bars, I need to address flicker which I have done in another post.
Quote
Brett Watters wrote:
> Sue,

> > So, I am getting a case of coordinate feedback.  I use the OnMouseMove
> event
> > to scroll the image, but as soon as I scroll, the scroll generates an
> > OnMouseMove event to inform me of the scroll I just initiated.  It's tuff
> to
> > figure out, especially since the mouse may have been moved between the
> scroll
> > and the scroll induced event.

> Disable the OnMouseMove event prior to scrolling. i.e. The following worked
> for me.

> { Assumes Image is a child of ScrollBox }

> procedure Form1.ImageOnMouseDown(...);
> begin
>    FStartPoint := Point(X,Y)
> end;

> procedure Form1.ImageOnMouseUp(...)
> begin
>   FStartPoint := Point(0,0)
> end;

> procedure Form1.ImageOnMouseMove(...);
> begin
>   if (FStartPoint.X <> 0) or (FStartPoint.Y <> 0) { in move state } then
>     begin
>        Image.OnMouseMove := nil;
>        ScrollBox.ScrollBy( X - FStartPoint.X, Y - FStartPoint.Y );
>        FStartPoint := Point(X,Y);
>        Image.OnMouseMove := ImageOnMouseMove
>     end
> end;

> Either that or consider using a timer. Start it when the mouse is down, stop
> it
> when the mouse is up, and scroll the box by the distance the mouse has
> moved since the last timer call. By adjusting the rate of the timer it
> controls
> the "smoothless" and responsiveness vs the rate at which the scrollbox can
> scroll and display the image.

> Hope this helps,

> Brett

> "Sue D. Nom" <su...@courthouse.com> wrote in message
> news:3A81E6C9.BE0E558D@courthouse.com...
> > I know what is causing the problem... now I am stumped for a workaround.

> > If the image in a TImage is scrolled, then an OnMouseMove event is issued
> to
> > update the mouse (x,y) as a result of the image moving under the mouse.

> > So, I am getting a case of coordinate feedback.  I use the OnMouseMove
> event
> > to scroll the image, but as soon as I scroll, the scroll generates an
> > OnMouseMove event to inform me of the scroll I just initiated.  It's tuff
> to
> > figure out, especially since the mouse may have been moved between the
> scroll
> > and the scroll induced event.

> > Thoughts?

> > "Sue D. Nom" wrote:

> > > I'm trying to set up a 'pan' function in a TImage so that when the user
> > > drags the mouse across the image with the left mouse key down, the image
> > > is pulled with the mouse.

> > > I have it working, sort of.  The image pulls as it should but a) it is
> > > very "jump" instead of pulling smoothly, and b) the mouse moves faster
> > > than the image, ie, one pixel of mouse movement doesn't move the image
> > > one pixel.

> > > Both of these phenomena can be demo'd with the unit below.

> > > Can anyone tell me why this is such a 'shaky' pan?

> > > Thanks.

> > > A Tform has
> > >   AutoSize = false;
> > >   AutoScroll = true;

> > > A TImage on the form has
> > >   Align = none;
> > >   AutoSize = true;

> > > Loading an image that is larger than the form results in scroll bars
> > > generated by the
> > > form.

> > > Now, I select the mouse down and mouse move events of the TImage and
> > > provde the following event code.

> > > var
> > >   Form1: TForm1;
> > >   MouseLastX : integer; // mouse stuff
> > >   MouseLastY : integer;
> > >   MouseDeltaX : integer; // mouse stuff
> > >   MouseDeltaY : integer;

> > > implementation

> > > {$R *.DFM}

> > > procedure TForm1.FormCreate(Sender: TObject);
> > > begin

> Image1.Picture.LoadFromFile('s:\RasterImages\TestsAndDemos\P531top.bmp');

> > > end;

> > > procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
> > >   Shift: TShiftState; X, Y: Integer);
> > > begin
> > >   MouseLastX := X;
> > >   MouseLastY := Y;
> > > end;

> > > procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

> > >   Y: Integer);
> > > begin
> > >   if (ssLeft in Shift) then begin  // if left button down, then pan
> > >     // update location and deltas
> > >     MouseDeltaX := X - MouseLastX;
> > >     MouseDeltaY := Y - MouseLastY;
> > >     MouseLastX := X;
> > >     MouseLastY := Y;
> > >     // situation 1 - dragging right to left
> > >     if (MouseDeltaX <= 0) then begin  // image dragged to the left
> > >       MouseDeltaX := Abs(MouseDeltaX);  // make it pos
> > >       HorzScrollBar.Position  := HorzScrollBar.Position + MouseDeltaX;
> > >       end
> > >     else if (MouseDeltaX > 0) then begin  // image dragged to the right
> > >       HorzScrollBar.Position  := HorzScrollBar.Position - MouseDeltaX;
> > >       end;

> > >     // situation 3 - dragging bottom to top
> > >     if (MouseDeltaY <= 0) then begin  // image dragged to the top
> > >       MouseDeltaY := Abs(MouseDeltaY);  // make it pos
> > >       VertScrollBar.Position  := VertScrollBar.Position + MouseDeltaY;
> > >       end
> > >     // situation 4 - dragging top to bottom
> > >     else if (MouseDeltaY > 0) then begin  // image dragged to the right
> > >       VertScrollBar.Position  := VertScrollBar.Position - MouseDeltaY;
> > >       end;
> > >     end;  // if left Mouse Down
> > > end;

> > > end.

Re:Making PAN Work Properly


Sue,

You can add your own OnScroll event to a ScrollBox. Something like.

type
  TMyScrollBox = class(TScrollBox)
  private
    FOnScroll : TNotifyEvent;
    procedure WMVScroll (var Msg : TMessage); message wm_vscroll;
    procedure WMHScroll (var Msg : TMessage); message wm_hscroll;
    procedure DoOnScroll;
  public
    property OnScroll : TNotifyEvent read FOnScroll write FOnScroll;
    constructor Create (AOwner : TComponent); override;
  end;
...

constructor TMyScrollBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FOnScroll := nil
end;

procedure TMyScrollBox.DoOnScroll;
begin
  if assigned(FOnScroll) then FOnScroll(Self)
end;

procedure TMyScrollBox.WMHScroll(var Msg: TMessage);
begin
  inherited;
  DoOnScroll
end;

procedure TMyScrollBox.WMVScroll(var Msg: TMessage);
begin
  inherited;
  DoOnScroll
end;

As far as the flicker goes, the easiest way is to use a Timer. On the
OnMouseMove,
start a timer and resposition just the point. On the time, actually move the
control to
the point position, and turn off the timer.

By adjusting the interval of the timer you can control responsiveness vs
flicker.

Also, adjust the background color of the scrollbox.

Thanks,

Brett

"Sue D. Nom" <su...@courthouse.com> wrote in message
news:3A82C70C.63FBF927@courthouse.com...

Quote
> Thank you, Brett.  I have looked at TScrollbox but rejected it because it
does
> not have an OnScroll event.  The lack of an event means I cannot detect a
change
> in the position of the image when the user repositions the image with the
scroll
> thumb.  This is why I went with my own scroll bars.

> Now that I have got workarounds to make the PAN work properly with my
scroll
> bars, I need to address flicker which I have done in another post.

> Brett Watters wrote:

> > Sue,

> > > So, I am getting a case of coordinate feedback.  I use the OnMouseMove
> > event
> > > to scroll the image, but as soon as I scroll, the scroll generates an
> > > OnMouseMove event to inform me of the scroll I just initiated.  It's
tuff
> > to
> > > figure out, especially since the mouse may have been moved between the
> > scroll
> > > and the scroll induced event.

> > Disable the OnMouseMove event prior to scrolling. i.e. The following
worked
> > for me.

> > { Assumes Image is a child of ScrollBox }

> > procedure Form1.ImageOnMouseDown(...);
> > begin
> >    FStartPoint := Point(X,Y)
> > end;

> > procedure Form1.ImageOnMouseUp(...)
> > begin
> >   FStartPoint := Point(0,0)
> > end;

> > procedure Form1.ImageOnMouseMove(...);
> > begin
> >   if (FStartPoint.X <> 0) or (FStartPoint.Y <> 0) { in move state } then
> >     begin
> >        Image.OnMouseMove := nil;
> >        ScrollBox.ScrollBy( X - FStartPoint.X, Y - FStartPoint.Y );
> >        FStartPoint := Point(X,Y);
> >        Image.OnMouseMove := ImageOnMouseMove
> >     end
> > end;

> > Either that or consider using a timer. Start it when the mouse is down,
stop
> > it
> > when the mouse is up, and scroll the box by the distance the mouse has
> > moved since the last timer call. By adjusting the rate of the timer it
> > controls
> > the "smoothless" and responsiveness vs the rate at which the scrollbox
can
> > scroll and display the image.

> > Hope this helps,

> > Brett

> > "Sue D. Nom" <su...@courthouse.com> wrote in message
> > news:3A81E6C9.BE0E558D@courthouse.com...
> > > I know what is causing the problem... now I am stumped for a
workaround.

> > > If the image in a TImage is scrolled, then an OnMouseMove event is
issued
> > to
> > > update the mouse (x,y) as a result of the image moving under the
mouse.

> > > So, I am getting a case of coordinate feedback.  I use the OnMouseMove
> > event
> > > to scroll the image, but as soon as I scroll, the scroll generates an
> > > OnMouseMove event to inform me of the scroll I just initiated.  It's
tuff
> > to
> > > figure out, especially since the mouse may have been moved between the
> > scroll
> > > and the scroll induced event.

> > > Thoughts?

> > > "Sue D. Nom" wrote:

> > > > I'm trying to set up a 'pan' function in a TImage so that when the
user
> > > > drags the mouse across the image with the left mouse key down, the
image
> > > > is pulled with the mouse.

> > > > I have it working, sort of.  The image pulls as it should but a) it
is
> > > > very "jump" instead of pulling smoothly, and b) the mouse moves
faster
> > > > than the image, ie, one pixel of mouse movement doesn't move the
image
> > > > one pixel.

> > > > Both of these phenomena can be demo'd with the unit below.

> > > > Can anyone tell me why this is such a 'shaky' pan?

> > > > Thanks.

> > > > A Tform has
> > > >   AutoSize = false;
> > > >   AutoScroll = true;

> > > > A TImage on the form has
> > > >   Align = none;
> > > >   AutoSize = true;

> > > > Loading an image that is larger than the form results in scroll bars
> > > > generated by the
> > > > form.

> > > > Now, I select the mouse down and mouse move events of the TImage and
> > > > provde the following event code.

> > > > var
> > > >   Form1: TForm1;
> > > >   MouseLastX : integer; // mouse stuff
> > > >   MouseLastY : integer;
> > > >   MouseDeltaX : integer; // mouse stuff
> > > >   MouseDeltaY : integer;

> > > > implementation

> > > > {$R *.DFM}

> > > > procedure TForm1.FormCreate(Sender: TObject);
> > > > begin

Image1.Picture.LoadFromFile('s:\RasterImages\TestsAndDemos\P531top.bmp');

- Show quoted text -

Quote

> > > > end;

> > > > procedure TForm1.Image1MouseDown(Sender: TObject; Button:
TMouseButton;
> > > >   Shift: TShiftState; X, Y: Integer);
> > > > begin
> > > >   MouseLastX := X;
> > > >   MouseLastY := Y;
> > > > end;

> > > > procedure TForm1.Image1MouseMove(Sender: TObject; Shift:
TShiftState; X,

> > > >   Y: Integer);
> > > > begin
> > > >   if (ssLeft in Shift) then begin  // if left button down, then pan
> > > >     // update location and deltas
> > > >     MouseDeltaX := X - MouseLastX;
> > > >     MouseDeltaY := Y - MouseLastY;
> > > >     MouseLastX := X;
> > > >     MouseLastY := Y;
> > > >     // situation 1 - dragging right to left
> > > >     if (MouseDeltaX <= 0) then begin  // image dragged to the left
> > > >       MouseDeltaX := Abs(MouseDeltaX);  // make it pos
> > > >       HorzScrollBar.Position  := HorzScrollBar.Position +
MouseDeltaX;
> > > >       end
> > > >     else if (MouseDeltaX > 0) then begin  // image dragged to the
right
> > > >       HorzScrollBar.Position  := HorzScrollBar.Position -
MouseDeltaX;
> > > >       end;

> > > >     // situation 3 - dragging bottom to top
> > > >     if (MouseDeltaY <= 0) then begin  // image dragged to the top
> > > >       MouseDeltaY := Abs(MouseDeltaY);  // make it pos
> > > >       VertScrollBar.Position  := VertScrollBar.Position +
MouseDeltaY;
> > > >       end
> > > >     // situation 4 - dragging top to bottom
> > > >     else if (MouseDeltaY > 0) then begin  // image dragged to the
right
> > > >       VertScrollBar.Position  := VertScrollBar.Position -
MouseDeltaY;
> > > >       end;
> > > >     end;  // if left Mouse Down
> > > > end;

> > > > end.

Other Threads