RPGDXThe center of Indie-RPG gaming
Not logged in. [log in] [register]
 
 
Post new topic Reply to topic  
View previous topic - View next topic  
Author Message
Ninkazu
Demon Hunter


Joined: 08 Aug 2002
Posts: 945
Location: Location:

PostPosted: Mon Dec 12, 2005 3:24 am    Post subject: SDL and the mouse... weird.. [quote]

Ok I'm trying to program the ability to drag my window widgets around, and yes they can be dragged... but they don't stay with the cursor. This has happened to me before where the dragged object slipped away, but I don't know what I did to fix it.

Just a thought... maybe SDL doesn't handle mouse coordinates the right way? I don't know. I'm just in a state of perplexment here.
Code:
bool CWindow::OnMouseDown(SDL_Event* event)
{
   if(event->button.button == 1){
      if(!hitPoint){
         hitPoint = new CPoint(event->button.x, event->button.y);
      }
   }
   return true;
}

bool CWindow::OnMouseUp(SDL_Event* event)
{
   SAFE_DELETE(hitPoint);
   return false;
}

bool CWindow::OnMouseMotion(SDL_Event* event)
{
   if(hitPoint){
      setX(getX() + (event->motion.x - hitPoint->X()));
      setY(getY() + (event->motion.y - hitPoint->Y()));
      return true;
   }
   return false;
}
Back to top  
Rainer Deyke
Demon Hunter


Joined: 05 Jun 2002
Posts: 672

PostPosted: Mon Dec 12, 2005 4:09 am    Post subject: Re: SDL and the mouse... weird.. [quote]

This is probably incorrect:
Code:
bool CWindow::OnMouseMotion(SDL_Event* event)
{
   if(hitPoint){
      setX(getX() + (event->motion.x - hitPoint->X()));
      setY(getY() + (event->motion.y - hitPoint->Y()));
      return true;
   }
   return false;
}


I think this is what you want:

Code:
bool CWindow::OnMouseMotion(SDL_Event* event)
{
   if(hitPoint){
      int x_motion = event->motion.x - hitPoint->X();
      int y_motion = event->motion.y - hitPoint->Y();
      setX(getX() + x_motion);
      setY(getY() + y_motion);
      hitPoint->X() += x_motion();
      hitPoint->X() += y_motion();
      return true;
   }
   return false;
}


If the window receives all mouse events, the following also works:

Code:
bool CWindow::OnMouseMotion(SDL_Event* event)
{
   if(hitPoint){
      setX(getX() + event->xrel);
      setY(getY() + event->yrel);
      return true;
   }
   return false;
}


Also, if hitPoint is a plain pointer, it would be better to use a smart point class usch as boost::scoped_ptr.
Back to top  
Ninkazu
Demon Hunter


Joined: 08 Aug 2002
Posts: 945
Location: Location:

PostPosted: Mon Dec 12, 2005 4:35 am    Post subject: [quote]

Thanks, I used the relative movement technique and that works great. The one problem is if I move the mouse too fast, the window won't keep up.
Back to top  
Adam
Mage


Joined: 30 Dec 2002
Posts: 416
Location: Australia

PostPosted: Mon Dec 12, 2005 5:53 am    Post subject: [quote]

What i did for window movement was grab the actual mouseX and mouseY values on mouse down. Then in mouse move i'd compare the actuall mouse position with the saved ones and move the window. Then i'd update the stored mouse positions ad the end of mouse move.

That should keep working even if you move the mouse really fast.
_________________
https://numbatlogic.com
Back to top  
Ninkazu
Demon Hunter


Joined: 08 Aug 2002
Posts: 945
Location: Location:

PostPosted: Mon Dec 12, 2005 6:17 am    Post subject: [quote]

It won't work that way since I have to delete the reference point when the mouse isn't over the window anymore. If I don't delete it and I move the mouse back over the window, it'll just jump. It's messed up.
Back to top  
RuneLancer
Mage


Joined: 17 Jun 2005
Posts: 441

PostPosted: Mon Dec 12, 2005 6:42 am    Post subject: [quote]

Ninkazu wrote:
If I don't delete it and I move the mouse back over the window, it'll just jump. It's messed up.

Not really. That's perfectly normal.

When the mouse leaves the window, the window no longer receives messages from the mouse. The last message it received was a WM_MOUSEMOVE at one of the window's edges. Then, well, the mouse is no longer in the window. It doesn't make a difference if the button was pressed inside the window, the mouse left the window's client region with its button down and that's all there is to it. When it comes back, another WM_MOUSEMOVE is sent at the edge where the mouse enters the window, causing the object you're dragging to leap back there.

This behavior might vary on another platform depending on how mouse input is handled. (I'm guessing you're writing this on a Windows platform?)

I've only used SDL for graphics, so I can't help you much. But if you plan on making this Windows only, you can rely on the Windows API and window messages to handle your drag and drop code. SetCapture() and ReleaseCapture() both tell Windows to isolate mouse input solely in the specified client region, even once the cursor is physically outside of the client region's bounding rectangle.

MSDN entry for SetCapture() is as follows:

Quote:
The SetCapture function sets the mouse capture to the specified window belonging to the current thread. SetCapture captures mouse input either when the mouse is over the capturing window, or when the mouse button was pressed while the mouse was over the capturing window and the button is still down. Only one window at a time can capture the mouse.

Syntax
HWND SetCapture(HWND hWnd);

Parameters
hWnd
[in] Handle to the window in the current thread that is to capture the mouse.
Return Value

The return value is a handle to the window that had previously captured the mouse. If there is no such window, the return value is NULL.


Basically, when handing WM_LBUTTONDOWN or WM_RBUTTONDOWN, you set the capture. Do whatever, then in the WM_LBUTTONUP or WM_RBUTTONUP, you release the capture. You should also release it in WM_QUIT in case the application is terminated prematurely while the button is being held, or your users will hate you. :)

I did this with Endless Saga to allow the user to manipulate the camera while windowed. Works like a charm.
_________________
Endless Saga
An OpenGL RPG in the making. Now with new hosting!

Back to top  
Ninkazu
Demon Hunter


Joined: 08 Aug 2002
Posts: 945
Location: Location:

PostPosted: Mon Dec 12, 2005 4:48 pm    Post subject: [quote]

I'm using SDL event handling, so I can't really use windows API. I'll check out the documentation for setcapture and see if I can adapt it to my program though.

::EDIT::
Sweet. I forgot about my mouseFocus static variable, so I used that and it works like a charm. Thanks for the help guys.
Back to top  
Post new topic Reply to topic Page 1 of 1 All times are GMT
 



Display posts from previous:   
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum