add a canvas.constrainMouse(true/false);

command keeps a mouse point within the ap window (off by default)
This commit is contained in:
AzaezelX 2024-11-26 08:51:43 -06:00
parent 43501127ec
commit de882b4024
2 changed files with 43 additions and 2 deletions

View file

@ -163,7 +163,8 @@ GuiCanvas::GuiCanvas(): GuiControl(),
mPlatformWindow(NULL),
mDisplayWindow(true),
mMenuBarCtrl(nullptr),
mMenuBackground(nullptr)
mMenuBackground(nullptr),
mConstrainMouse(false)
{
setBounds(0, 0, 640, 480);
mAwake = true;
@ -1749,6 +1750,36 @@ void GuiCanvas::setupFences()
mNextFenceIdx = 0;
}
void GuiCanvas::constrainMouseCoords(Point2I mousePoint)
{
if (mConstrainMouse == false) return;
Point2I windowPos = getPlatformWindow()->getPosition();//this is the offset
Point2I winSize = getWindowSize();//window size too!
S32 newDisplay = Con::getIntVariable("pref::Video::deviceId", 0);
SDL_DisplayMode displayM;
if (0 == SDL_GetDesktopDisplayMode(newDisplay, &displayM))
{
S32 width = displayM.w;
S32 height = displayM.h;
if (winSize.x < width || winSize.y < height)
{
//we must be windowed
//find the diference and half it
S32 offX = (width - winSize.x) * 0.5f;
S32 offY = (height - winSize.y) * 0.5f;
S32 maxX = winSize.x + offX;
S32 maxY = winSize.y + offY;
Point2I newPos; //using 8px as a safety margin
newPos.x = mClamp(mousePoint.x, 0, maxX);
newPos.y = mClamp(mousePoint.y, 0, maxY);
setCursorPos(windowPos + newPos);
}
}
}
void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */)
{
AssertISV(mPlatformWindow, "GuiCanvas::renderFrame - no window present!");
@ -1874,6 +1905,7 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */)
addUpdateRegion(pos - Point2I(2, 2), Point2I(cext.x + 4, cext.y + 4));
}
constrainMouseCoords(cursorPos);
mLastCursorEnabled = cursorVisible;
mLastCursor = mouseCursor;
@ -2956,6 +2988,11 @@ DefineEngineMethod(GuiCanvas, cursorNudge, void, (F32 x, F32 y), , "")
object->cursorNudge(x, y);
}
DefineEngineMethod(GuiCanvas, constrainMouse, void, (bool constrained), , "constrain Mouse to the window")
{
object->constrainMouse(constrained);
}
// This function allows resetting of the video-mode from script. It was motivated by
// the need to temporarily disable vsync during datablock cache load to avoid a
// significant slowdown.

View file

@ -84,6 +84,7 @@
/// you need to add your control to the dirty areas of the canvas.
///
class guiCanvas;
class Point2I;
typedef Signal<void(GuiCanvas* canvas)> CanvasSizeChangeSignal;
class GuiCanvas : public GuiControl, public IProcessInput
{
@ -212,7 +213,7 @@ protected:
GuiControl *mMenuBarCtrl;
GuiControl* mMenuBackground;
bool mConstrainMouse;
public:
DECLARE_CONOBJECT(GuiCanvas);
DECLARE_CATEGORY( "Gui Core" );
@ -233,12 +234,15 @@ public:
/// @name Rendering methods
///
/// @{
void constrainMouse(bool constrained) { mConstrainMouse = constrained; };
void constrainMouseCoords(Point2I mousePoint);
/// Repaints the dirty regions of the canvas
/// @param preRenderOnly If set to true, only the onPreRender methods of all the GuiControls will be called
/// @param bufferSwap If set to true, it will swap buffers at the end. This is to support canvas-subclassing.
virtual void renderFrame(bool preRenderOnly, bool bufferSwap = true);
/// Repaints the canvas by calling the platform window display event.
virtual void paint();