Game Development Community

T3D 1.1 Beta 3 - GuiCanvas::getCursorPos returns incorrect position - LOGGED

by Dennis Trevillyan · in Torque 3D Professional · 03/27/2011 (8:18 am) · 5 replies

Build: Torque 3D 1.1 Beta 3 Pro

Platform: Windows XP SP3 32 bit

Target: calls to GuiCanvas::getCursorPos during game execution.

Issues: getCursorPos returns position relative to display top left corner and not the canvas (game window) top left corner.

Steps to Repeat: Turn on mouse cursor and setup a mouse event in gameTSCtrl.cpp where a breakpoint can be created to inspect the returned cursor position.

void GameTSCtrl::onMouseDown( const GuiEvent &evt) {
	Point2I p1(200, 300);
	getRoot()->setCursorPos(p1);
	Point2I answer = getRoot()->getCursorPos();
}

Suggested Fix:

Point2I GuiCanvas::getCursorPos()
{
   Point2I p( 0, 0 );
   POINT topleft;
   topleft.x = 0;
   topleft.y = 0;
  
   Win32Window* w = dynamic_cast<Win32Window*>(mPlatformWindow);  
   
   if(w != NULL)  
      ClientToScreen(w->getHWND(), &topleft); 

  if( mPlatformWindow )
      mPlatformWindow->getCursorPosition( p );

   return Point2I( p.x - topleft.x, p.y - topleft.y );
}

Link to Console Log: None

#1
03/29/2011 (11:31 pm)
Ah, I ran into this today in a class I derived from EditTSCtrl. I fixed it in the derived class, but didn't think to look further up stream into GuiCanvas::getCursorPos. Good catch.
#2
03/30/2011 (12:12 am)
So check out this version of getCursorPos:

Point2I GuiCanvas::getCursorPos()
{
	Point2I p( 0, 0 );
	Point2I start( 0, 0 );

	if( mPlatformWindow )   
	{
	  mPlatformWindow->getCursorPosition( p ); 
	  start = getPlatformWindow()->getPosition();
	}
	return Point2I( p.x - start.x, p.y - start.y );   
}

It's working for me and I think it is more platform-agnostic because it doesn't rely on calls directly to POINT and Win32Window.
#3
04/06/2011 (2:31 pm)
Logged as THREED-1554.
#4
07/14/2011 (12:40 pm)
Ian, that seems to get the cursor pos in relation to the window and not the canvas (client area). Here's what I came up with (based on your code):

Point2I GuiCanvas::getCanvasCursorPos()
{
	Point2I p( 0, 0 );
	Point2I np( 0, 0 );

	if( mPlatformWindow )   
	{
	  mPlatformWindow->getCursorPosition( p ); 
	  np = getPlatformWindow()->screenToClient(p);
	}
	return np;

}

I also changed the name of the function so that it doesn't replace the way the other one works.
#5
07/15/2011 (11:32 am)
I like, I like.