Mouse events, mouse slips off rectangle

Hi all,

I’m doing a simple SDL spike in C++ where a rectangle is drawn (openGL)
and you can grab it with the mouse (press and hold) and move it around.
It uses SDL events.

But although the rectangle’s and the mouse pointer’s location get
updated by the same event (when processing a mouse move event), the
mouse can “slip” off the rectangle when you move it very fast. And you
lose the grip until you move it back into the rectangle where it snaps
to the mouse pointer again.

Any idea whats causing it?

I can’t see a reason why the mouse pointer should be updated to some
other position but not the rectangle as both happens in the same “case
SDL_MOUSEMOTION:”.

IMPORTANT:
It also happens if I do not draw/update the mouse pointer myself at all
but use the OS’s arrow instead.

runtime pattern:
process all events;
draw everything;

As this is a spike and I am trying different appoaches all the time, the
code is quite dirty. :smiley:

from event handling:


while (SDL_PollEvent(&event)) {
// Switching negative y values here
event.motion.y = masterController.getHeight() - event.motion.y;
event.motion.yrel *= -1;

switch (event.type) {


case SDL_MOUSEMOTION:

      // This works, just sets a flag on any previous
      //+SDL_MOUSEBUTTONDOWN:

      if (masterController.isMouseLDown()) {

         // This sets the location for the rectangle, see below
         masterController.setRelativeMouseMovement(
            event.motion.xrel,
            event.motion.yrel,
            event.motion.x,
            event.motion.y
         );
      }

      // Update mouse pointer location
      // Not important at all when not drawing mouse myself
      masterController.setMouseX(event.motion.x);
      masterController.setMouseY(event.motion.y);

      break;


void MasterController::setRelativeMouseMovement(int xrel, int yrel, int xpos, int ypos) { Panel *p = panelList[0]; // basically a rectangle
// Mouse inside rectangle							
if (isFocused &&								       xpos >= p->getPanelX() &&
    ypos >= p->getPanelY() &&
    xpos <= p->getPanelX()+p->getWidth() &&
    ypos <= p->getPanelY()+p->getHeight()
) {	

   // Calculate relative mouse movement ourselves to make sure
   // it is not depending on event's xrel/yrel		
   int dirX = xpos - mouseOriginX;
   int dirY = ypos - mouseOriginY;

   // Don't move rectangle outside of window		
   if (p->getPanelX() + dirX < width - p->getWidth() &&
       p->getPanelY() + dirY < height - p->getHeight()
   ) {	

      // Update location of rectangle
      p->setPanelX(p->getPanelX()+dirX);
      p->setPanelY(p->getPanelY()+dirY);

      // Update origin to compute relative movement next time		 
 mouseOriginX = xpos;
      mouseOriginY = ypos;
   }
}

}

Any help is appreciated, thanks!

Helmut Duregger

Heya Helmut,

It sounds like the problem is tied to how mice work. If you move them very
slowly you can see them move smoothly across the screen, but if you move
them faster, they actualy jump across the screen skipping pixels.

How I would do this would be more like this:

  1. when user presses mouse button down, check to see if it was over the
    rectangle. If so, store a unique ID of this rectangle in a variable like
    int FocusObject so the program remembers which object is being moved
    (assuming you are going to be having multiple objects to move around later).

  2. as the user moves the mouse around, if FocusObject isnt 0, move the
    object FocusObject points to around along with the mouse

  3. if the user lets go of the mouse button, set FocusObject to 0 so we stop
    moving the object.

That should give you what you want, let me know if you have any questions on
how to detect when the mouse button is released or anything like that.> ----- Original Message -----

From: helmutduregger@chello.at (Helmut Duregger)
To:
Sent: Tuesday, May 17, 2005 8:38 AM
Subject: [SDL] Mouse events, mouse slips off rectangle

Hi all,

I’m doing a simple SDL spike in C++ where a rectangle is drawn (openGL)
and you can grab it with the mouse (press and hold) and move it around.
It uses SDL events.

But although the rectangle’s and the mouse pointer’s location get
updated by the same event (when processing a mouse move event), the
mouse can “slip” off the rectangle when you move it very fast. And you
lose the grip until you move it back into the rectangle where it snaps
to the mouse pointer again.

Any idea whats causing it?

I can’t see a reason why the mouse pointer should be updated to some
other position but not the rectangle as both happens in the same “case
SDL_MOUSEMOTION:”.

IMPORTANT:
It also happens if I do not draw/update the mouse pointer myself at all
but use the OS’s arrow instead.

runtime pattern:
process all events;
draw everything;

As this is a spike and I am trying different appoaches all the time, the
code is quite dirty. :smiley:

from event handling:


while (SDL_PollEvent(&event)) {
// Switching negative y values here
event.motion.y = masterController.getHeight() - event.motion.y;
event.motion.yrel *= -1;

switch (event.type) {


case SDL_MOUSEMOTION:

      // This works, just sets a flag on any previous
      //+SDL_MOUSEBUTTONDOWN:

      if (masterController.isMouseLDown()) {

         // This sets the location for the rectangle, see below
         masterController.setRelativeMouseMovement(
            event.motion.xrel,
            event.motion.yrel,
            event.motion.x,
            event.motion.y
         );
      }

      // Update mouse pointer location
      // Not important at all when not drawing mouse myself
      masterController.setMouseX(event.motion.x);
      masterController.setMouseY(event.motion.y);

      break;


void MasterController::setRelativeMouseMovement(int xrel, int yrel, int xpos, int ypos) { Panel *p = panelList[0]; // basically a rectangle
// Mouse inside rectangle
if (isFocused &&        xpos >= p->getPanelX() &&
    ypos >= p->getPanelY() &&
    xpos <= p->getPanelX()+p->getWidth() &&
    ypos <= p->getPanelY()+p->getHeight()
) {

   // Calculate relative mouse movement ourselves to make sure
   // it is not depending on event's xrel/yrel
   int dirX = xpos - mouseOriginX;
   int dirY = ypos - mouseOriginY;

   // Don't move rectangle outside of window
   if (p->getPanelX() + dirX < width - p->getWidth() &&
       p->getPanelY() + dirY < height - p->getHeight()
   ) {

      // Update location of rectangle
      p->setPanelX(p->getPanelX()+dirX);
      p->setPanelY(p->getPanelY()+dirY);

      // Update origin to compute relative movement next time
 mouseOriginX = xpos;
      mouseOriginY = ypos;
   }
}

}

Any help is appreciated, thanks!

Helmut Duregger


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Hey Alan,

Actually I thought I was following that pattern. But not exactly as it
turned out.
I changed it now and it already works much better.

Time to tweak and clean it up a bit…

Thanks alot,

Helmut

Alan Wolfe wrote:> Heya Helmut,

It sounds like the problem is tied to how mice work. If you move them very
slowly you can see them move smoothly across the screen, but if you move
them faster, they actualy jump across the screen skipping pixels.

How I would do this would be more like this:

  1. when user presses mouse button down, check to see if it was over the
    rectangle. If so, store a unique ID of this rectangle in a variable like
    int FocusObject so the program remembers which object is being moved
    (assuming you are going to be having multiple objects to move around later).

  2. as the user moves the mouse around, if FocusObject isnt 0, move the
    object FocusObject points to around along with the mouse

  3. if the user lets go of the mouse button, set FocusObject to 0 so we stop
    moving the object.

That should give you what you want, let me know if you have any questions on
how to detect when the mouse button is released or anything like that.

----- Original Message -----
From: “Helmut Duregger” <@Helmut_Duregger>
To:
Sent: Tuesday, May 17, 2005 8:38 AM
Subject: [SDL] Mouse events, mouse slips off rectangle

Hi all,

I’m doing a simple SDL spike in C++ where a rectangle is drawn (openGL)
and you can grab it with the mouse (press and hold) and move it around.
It uses SDL events.

But although the rectangle’s and the mouse pointer’s location get
updated by the same event (when processing a mouse move event), the
mouse can “slip” off the rectangle when you move it very fast. And you
lose the grip until you move it back into the rectangle where it snaps
to the mouse pointer again.

Any idea whats causing it?

I can’t see a reason why the mouse pointer should be updated to some
other position but not the rectangle as both happens in the same “case
SDL_MOUSEMOTION:”.

IMPORTANT:
It also happens if I do not draw/update the mouse pointer myself at all
but use the OS’s arrow instead.

runtime pattern:
process all events;
draw everything;

As this is a spike and I am trying different appoaches all the time, the
code is quite dirty. :smiley:

from event handling:


while (SDL_PollEvent(&event)) {
// Switching negative y values here
event.motion.y = masterController.getHeight() - event.motion.y;
event.motion.yrel *= -1;

switch (event.type) {

case SDL_MOUSEMOTION:

     // This works, just sets a flag on any previous
     //+SDL_MOUSEBUTTONDOWN:

     if (masterController.isMouseLDown()) {

        // This sets the location for the rectangle, see below
        masterController.setRelativeMouseMovement(
           event.motion.xrel,
           event.motion.yrel,
           event.motion.x,
           event.motion.y
        );
     }

     // Update mouse pointer location
     // Not important at all when not drawing mouse myself
     masterController.setMouseX(event.motion.x);
     masterController.setMouseY(event.motion.y);

     break;


void MasterController::setRelativeMouseMovement(int xrel, int yrel, int xpos, int ypos) { Panel *p = panelList[0]; // basically a rectangle

// Mouse inside rectangle
if (isFocused && xpos >= p->getPanelX() &&
ypos >= p->getPanelY() &&
xpos <= p->getPanelX()+p->getWidth() &&
ypos <= p->getPanelY()+p->getHeight()
) {

  // Calculate relative mouse movement ourselves to make sure
  // it is not depending on event's xrel/yrel
  int dirX = xpos - mouseOriginX;
  int dirY = ypos - mouseOriginY;

  // Don't move rectangle outside of window
  if (p->getPanelX() + dirX < width - p->getWidth() &&
      p->getPanelY() + dirY < height - p->getHeight()
  ) {

     // Update location of rectangle
     p->setPanelX(p->getPanelX()+dirX);
     p->setPanelY(p->getPanelY()+dirY);

     // Update origin to compute relative movement next time
mouseOriginX = xpos;
     mouseOriginY = ypos;
  }

}
}

Any help is appreciated, thanks!

Helmut Duregger


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl