ソースを参照

Hide the Cursor on Touch

This detects cursor behavior that could only be possible if the user has a touch screen and hides the cursor. Likewise, once the cursor is hidden, it detects behavior that could only be made by a mouse and shows the cursor again. The effect is that the cursor immediantly hides if the touch screen is used and shows again if the user grabs the mouse. Detection is necessary because in our experiments, windows 10 does not willing to tell us if the mouse or touch screen is used. This gives us a surefire way to recognize a touch screen even if the OS keeps it hidden. All of this can be controlled by a preference variable: $pref::Gui::hideCursorWhenTouchEventDetected.
Peter Robinson 4 年 前
コミット
88a77b6f24

+ 42 - 1
engine/source/gui/guiCanvas.cc

@@ -95,6 +95,10 @@ GuiCanvas::GuiCanvas()
    mDoubleClickHeight = Input::getDoubleClickHeight();
    mDoubleClickHeight = Input::getDoubleClickHeight();
    mDoubleClickTime = Input::getDoubleClickTime();
    mDoubleClickTime = Input::getDoubleClickTime();
 
 
+   mTouchDetectionSize = 100;
+   mPotentialTouchEvent = false;
+   mHideCursorBecauseOfTouch = false;
+
     /// Background color.
     /// Background color.
     mBackgroundColor.set( 0.0f, 0.0f, 0.0f, 0.0f );
     mBackgroundColor.set( 0.0f, 0.0f, 0.0f, 0.0f );
     mUseBackgroundColor = true;
     mUseBackgroundColor = true;
@@ -276,6 +280,32 @@ void GuiCanvas::processMouseMoveEvent(const MouseMoveEvent *event)
          mRightMouseLast = false;
          mRightMouseLast = false;
       }
       }
 
 
+		//should we try to detect a touch event pretending to be a mouse event?
+		if( Con::getBoolVariable( "$pref::Gui::hideCursorWhenTouchEventDetected", false ))
+		{
+			mPotentialTouchEvent = false;
+			Point2F jump = mPrevMouseMovePosition - cursorPt;
+			if ((mAbs((S32)jump.x) > mTouchDetectionSize) || (mAbs((S32)jump.y) > mTouchDetectionSize))
+			{
+				mPotentialTouchEvent = true;
+				mPotentialMouseEventCount = 0;
+			}
+			else if(mHideCursorBecauseOfTouch && !mMouseButtonDown)
+			{
+				if(mPotentialMouseEventCount > 20) 
+				{
+					//This is our 20th small movement with no click or drag so it must be a mouse!
+					mHideCursorBecauseOfTouch = false;
+					mPotentialMouseEventCount = 0;
+				}
+				else 
+				{
+					mPotentialMouseEventCount++;
+				}
+			}
+			mPrevMouseMovePosition.set(cursorPt.x, cursorPt.y);
+		}
+
         if (mMouseButtonDown)
         if (mMouseButtonDown)
             rootMouseDragged(mLastEvent);
             rootMouseDragged(mLastEvent);
         else if (mMouseRightButtonDown)
         else if (mMouseRightButtonDown)
@@ -475,6 +505,15 @@ bool GuiCanvas::processInputEvent(const InputEvent *event)
                mLastMouseDownTime = curTime;
                mLastMouseDownTime = curTime;
                mLastEvent.mouseClickCount = mLastMouseClickCount;
                mLastEvent.mouseClickCount = mLastMouseClickCount;
 
 
+			   if(mHideCursorBecauseOfTouch)
+			   {
+					mPotentialMouseEventCount = 0;
+				}
+			   if(mPotentialTouchEvent)
+			   {
+					mHideCursorBecauseOfTouch = true;
+			   }
+
                rootMouseDown(mLastEvent);
                rootMouseDown(mLastEvent);
             }
             }
             //else button was released
             //else button was released
@@ -487,6 +526,7 @@ bool GuiCanvas::processInputEvent(const InputEvent *event)
          }
          }
          else if(event->objInst == KEY_BUTTON1) // right button
          else if(event->objInst == KEY_BUTTON1) // right button
          {
          {
+			mHideCursorBecauseOfTouch = false;
             if(event->action == SI_MAKE)
             if(event->action == SI_MAKE)
             {
             {
                U32 curTime = Platform::getVirtualMilliseconds();
                U32 curTime = Platform::getVirtualMilliseconds();
@@ -517,6 +557,7 @@ bool GuiCanvas::processInputEvent(const InputEvent *event)
          }
          }
          else if(event->objInst == KEY_BUTTON2) // middle button
          else if(event->objInst == KEY_BUTTON2) // middle button
          {
          {
+			 mHideCursorBecauseOfTouch = false;
             if(event->action == SI_MAKE)
             if(event->action == SI_MAKE)
             {
             {
                U32 curTime = Platform::getVirtualMilliseconds();
                U32 curTime = Platform::getVirtualMilliseconds();
@@ -1317,7 +1358,7 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */)
       //   helpCtrl->render(srf);
       //   helpCtrl->render(srf);
       //}
       //}
 
 
-      if (cursorON && mouseCursor && mShowCursor)
+      if (cursorON && mouseCursor && mShowCursor && !mHideCursorBecauseOfTouch)
       {
       {
          Point2I pos((S32)cursorPt.x, (S32)cursorPt.y);
          Point2I pos((S32)cursorPt.x, (S32)cursorPt.y);
          Point2I spot = mouseCursor->getHotSpot();
          Point2I spot = mouseCursor->getHotSpot();

+ 6 - 0
engine/source/gui/guiCanvas.h

@@ -136,6 +136,12 @@ protected:
    S32                        mDoubleClickHeight;
    S32                        mDoubleClickHeight;
    S32                        mDoubleClickTime;
    S32                        mDoubleClickTime;
 
 
+   Point2F					  mPrevMouseMovePosition; ///< Holds the previous position of the mouse the last time a mouse move event was processed.
+   S32						  mTouchDetectionSize; ///< Changes in the x or y position of the mouse greater than this value will could be touch events.
+   bool						  mPotentialTouchEvent; ///< True if the mouse made a jump that looks like a touch event.
+   U8						  mPotentialMouseEventCount; ///< Counts how many small mouse movements have occured in a row that to determine if touch has been abandoned.
+   bool						  mHideCursorBecauseOfTouch; ///< Touch event has been detected. Hide the cursor.
+
    virtual void findMouseControl(const GuiEvent &event);
    virtual void findMouseControl(const GuiEvent &event);
    virtual void refreshMouseControl();
    virtual void refreshMouseControl();
    /// @}
    /// @}

+ 5 - 1
toybox/AppCore/1/scripts/defaultPreferences.cs

@@ -32,7 +32,7 @@ $pref::iOS::UseMusic            = 0;
 $pref::iOS::UseMoviePlayer      = 0;
 $pref::iOS::UseMoviePlayer      = 0;
 $pref::iOS::UseAutoRotate       = 1;
 $pref::iOS::UseAutoRotate       = 1;
 $pref::iOS::EnableOrientationRotation = 1;
 $pref::iOS::EnableOrientationRotation = 1;
-$pref::iOS::EnableOtherOrientationRotation = 1;   
+$pref::iOS::EnableOtherOrientationRotation = 1;
 $pref::iOS::StatusBarType       = 0;
 $pref::iOS::StatusBarType       = 0;
 
 
 /// Audio
 /// Audio
@@ -69,3 +69,7 @@ $pref::OpenGL::gammaCorrection = 0.5;
 
 
 /// Fonts.
 /// Fonts.
 $Gui::fontCacheDirectory = expandPath( "^AppCore/fonts" );
 $Gui::fontCacheDirectory = expandPath( "^AppCore/fonts" );
+
+// Gui
+$pref::Gui::noClampTorqueCursorToWindow = 1;
+$pref::Gui::hideCursorWhenTouchEventDetected = 1;