BUG: Canvas setCursorPos() does not work
by David Wyand · in Torque Game Engine · 07/09/2004 (11:32 am) · 43 replies
Greetings!
Introduction
It seems that people are having a problem with getting the Canvas.setCursorPos() method working. I was among those having this very problem. The cursor would move to the new position but would not stay there as soon as the user moved the mouse. I've managed to work around this problem for my DTS Viewing Tool and present my solution here.
Problem Statement
The current Canvas.setCursorPos() method modifies an internal cursorPt variable to change the cursor position. This variable is used in the drawing of the cursor. However, the hardware platform is not aware of the new mouse location. When the user moves the mouse after a Canvas.setCursorPos() call, the platform sends its current absolute mouse position and the TGE obliges by popping the mouse to this hardware position. What is needed is a method of notifying the hardware platform that the mouse position has changed.
Solution
My proposed solution involves a new Input method definition and a change to the Canvas setCursorPos() operation. First the new Input class method.
Open up platform/platformInput.h and go to the Input class definition. Just before the getManager() method definition, add the following (the new code is bolded):
That's it for this file. Next, open up platformWin32/wininput.cc and go to just after the void Input::process() and before the InputManager* Input::getManager() code. Add the following function:
This new setCursorPos() function will move the mouse at the hardware level to the new position (by using the Windows PDK setCursorPos() function). The coordinates passed to it are relative to the client area of the window (the part of the window the TGE draws into).
Finally, we'll need to change how the Canvas.setCursorPos() method works. Open gui/guiCanvas.h and add the following to the top of the file (new code is bolded):
This will make sure the Canvas has access to the new Input::setCursorPos() method through the platform layer. Next, find the Canvas' setCursorPos() method and replace it with the following:
This new function will make sure that the passed coordinates are relative to the Canvas' origin. So, by calling Canvas.setCursorPos(0,0); in script should now place the mouse pointer in the upper left corner of the Canvas' drawing area.
Multi-platform Notice
The presented solution will only work under Windows. All that is required to have it work on another platform is to write the appropriate platform specific code for the Input::setCursorPos() method. Hopefully someone will endeavor to do just that.
Enjoy!
- LightWave Dave
Introduction
It seems that people are having a problem with getting the Canvas.setCursorPos() method working. I was among those having this very problem. The cursor would move to the new position but would not stay there as soon as the user moved the mouse. I've managed to work around this problem for my DTS Viewing Tool and present my solution here.
Problem Statement
The current Canvas.setCursorPos() method modifies an internal cursorPt variable to change the cursor position. This variable is used in the drawing of the cursor. However, the hardware platform is not aware of the new mouse location. When the user moves the mouse after a Canvas.setCursorPos() call, the platform sends its current absolute mouse position and the TGE obliges by popping the mouse to this hardware position. What is needed is a method of notifying the hardware platform that the mouse position has changed.
Solution
My proposed solution involves a new Input method definition and a change to the Canvas setCursorPos() operation. First the new Input class method.
Open up platform/platformInput.h and go to the Input class definition. Just before the getManager() method definition, add the following (the new code is bolded):
static void process();
[b]static void setCursorPos(S32 x, S32 y); // DAW: Set the cursor position relative to the window's client space[/b]
static InputManager* getManager();That's it for this file. Next, open up platformWin32/wininput.cc and go to just after the void Input::process() and before the InputManager* Input::getManager() code. Add the following function:
//------------------------------------------------------------------------------
// DAW: Set the cursor position relative to the window's client space
void Input::setCursorPos(S32 x, S32 y)
{
POINT pt;
pt.x = x;
pt.y = y;
ClientToScreen(winState.appWindow, &pt);
SetCursorPos(pt.x, pt.y);
}This new setCursorPos() function will move the mouse at the hardware level to the new position (by using the Windows PDK setCursorPos() function). The coordinates passed to it are relative to the client area of the window (the part of the window the TGE draws into).
Finally, we'll need to change how the Canvas.setCursorPos() method works. Open gui/guiCanvas.h and add the following to the top of the file (new code is bolded):
#ifndef _EVENT_H_ #include "platform/event.h" #endif [b]#ifndef _PLATFORMINPUT_H_ #include "platform/platformInput.h" #endif[/b] #ifndef _GUICONTROL_H_ #include "gui/guiControl.h" #endif
This will make sure the Canvas has access to the new Input::setCursorPos() method through the platform layer. Next, find the Canvas' setCursorPos() method and replace it with the following:
void setCursorPos(const Point2I &pt) { Input::setCursorPos(mBounds.point.x+pt.x, mBounds.point.y+pt.y); } //DAW: Was: {cursorPt.x = F32(pt.x); cursorPt.y = F32(pt.y); }This new function will make sure that the passed coordinates are relative to the Canvas' origin. So, by calling Canvas.setCursorPos(0,0); in script should now place the mouse pointer in the upper left corner of the Canvas' drawing area.
Multi-platform Notice
The presented solution will only work under Windows. All that is required to have it work on another platform is to write the appropriate platform specific code for the Input::setCursorPos() method. Hopefully someone will endeavor to do just that.
Enjoy!
- LightWave Dave
About the author
A long time Associate of the GarageGames' community and author of the Torque 3D Game Development Cookbook. Buy it today from Packt Publishing!
#42
x - 440
y - 379
cgWndCenter.x - 1082408960
cgWndCenter.y - 0
As you can see, it is reporting some crazy values for the center of the window.
09/21/2007 (10:34 am)
These are the some sample values I am getting in Input::setCursorPos in macCarbInput.cc:x - 440
y - 379
cgWndCenter.x - 1082408960
cgWndCenter.y - 0
As you can see, it is reporting some crazy values for the center of the window.
#43
I had the same problem. I did change the Input::setCursorPos in macCarbInput to :
11/08/2008 (4:48 am)
@scottI had the same problem. I did change the Input::setCursorPos in macCarbInput to :
void Input::setCursorPos(S32 x, S32 y)
{
Rect r;
Point targetPoint;
GrafPtr savePort;
// get the center of the window
if (platState.appWindow )
{
GetWindowBounds(platState.appWindow, kWindowContentRgn, &r);
targetPoint.h = r.left + x;
targetPoint.v = r.top + y;
} else {
targetPoint.h = x;
targetPoint.v = y;
}
CGDirectDisplayID displayID = platState.cgDisplay;
CGRect bounds = CGDisplayBounds(displayID);
CGPoint cgWndCenter;
cgWndCenter.x = targetPoint.h + bounds.origin.x;
cgWndCenter.y = targetPoint.v + bounds.origin.y;
CGSetLocalEventsSuppressionInterval(0);
CGDisplayMoveCursorToPoint(displayID, cgWndCenter);
CGSetLocalEventsSuppressionInterval(0.25);
}
Torque Owner Scott Doerrfeld
Again this only happens on the Mac when in full screen mode. Any thoughts on this?