Bläddra i källkod

add a canvas.constrainMouse(true/false);
command keeps a mouse point within the ap window (off by default)

AzaezelX 9 månader sedan
förälder
incheckning
de882b4024
2 ändrade filer med 43 tillägg och 2 borttagningar
  1. 38 1
      Engine/source/gui/core/guiCanvas.cpp
  2. 5 1
      Engine/source/gui/core/guiCanvas.h

+ 38 - 1
Engine/source/gui/core/guiCanvas.cpp

@@ -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.

+ 5 - 1
Engine/source/gui/core/guiCanvas.h

@@ -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();