Skip to content

Commit

Permalink
add a canvas.constrainMouse(true/false);
Browse files Browse the repository at this point in the history
command keeps a mouse point within the ap window (off by default)
  • Loading branch information
Azaezel committed Nov 26, 2024
1 parent 4350112 commit de882b4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
39 changes: 38 additions & 1 deletion Engine/source/gui/core/guiCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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!");
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 5 additions & 1 deletion Engine/source/gui/core/guiCanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -212,7 +213,7 @@ class GuiCanvas : public GuiControl, public IProcessInput

GuiControl *mMenuBarCtrl;
GuiControl* mMenuBackground;

bool mConstrainMouse;
public:
DECLARE_CONOBJECT(GuiCanvas);
DECLARE_CATEGORY( "Gui Core" );
Expand All @@ -233,12 +234,15 @@ class GuiCanvas : public GuiControl, public IProcessInput
/// @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();

Expand Down

0 comments on commit de882b4

Please sign in to comment.