瀏覽代碼

Changes to UseInput

UseInput was a better-named version of the old "modal" field which worked backwards of the way it probably should have worked. I've moved it into the actual GuiControl and improved event handling by causing events to "bubble up" correctly. Generally speaking, UseInput should not be needed. Previously I had to pay close attention to it. Now it should mostly work as expected.
Peter Robinson 3 年之前
父節點
當前提交
e0c7aeea1c

+ 1 - 0
editor/AssetAdmin/AssetDictionaryButton.cs

@@ -123,6 +123,7 @@ function AssetDictionaryButton::buildIcon(%this)
 		Position = "0 0";
 		constrainProportions = "1";
 		fullSize = "1";
+		UseInput = false;
 	};
 	ThemeManager.setProfile(%texture, "spriteProfile");
 	return %texture;

+ 1 - 0
editor/EditorCore/EditorIconButton.cs

@@ -17,6 +17,7 @@ function EditorIconButton::onAdd(%this)
 		ImageColor = ThemeManager.activeTheme.iconButtonProfile.FontColor;
 		Frame = %this.frame;
 		Tooltip = %this.Tooltip;
+		UseInput = false;
 	};
 	ThemeManager.setProfile(%this.icon, "spriteProfile");
 	%this.add(%this.icon);

+ 1 - 1
engine/source/2d/gui/SceneWindow.cc

@@ -1417,7 +1417,7 @@ void SceneWindow::onTouchDown( const GuiEvent& event )
 	if (mShowScrollBar)
 	{
 		mScrollBar->curHitRegion = mScrollBar->findHitRegion(mScrollBar->globalToLocalCoord(event.mousePoint));
-		if (mScrollBar->curHitRegion != GuiScrollCtrl::None)
+		if (mScrollBar->curHitRegion != GuiScrollCtrl::Content)
 		{
 			setUpdate();
 			mScrollBar->onTouchDown(event);

+ 2 - 2
engine/source/gui/containers/guiSceneScrollCtrl.cc

@@ -211,7 +211,7 @@ void GuiSceneScrollCtrl::scrollByRegion(Region reg)
 		case RightPage:
 		case VertThumb:
 		case HorizThumb:
-		case None:
+		case Content:
 			//Con::errorf("Unhandled case in GuiSceneScrollCtrl::scrollByRegion");
 			break;
 		}
@@ -239,7 +239,7 @@ void GuiSceneScrollCtrl::scrollByRegion(Region reg)
 		case DownPage:
 		case VertThumb:
 		case HorizThumb:
-		case None:
+		case Content:
 			//Con::errorf("Unhandled case in GuiSceneScrollCtrl::scrollByRegion");
 			break;
 		}

+ 45 - 9
engine/source/gui/containers/guiScrollCtrl.cc

@@ -52,7 +52,7 @@ GuiScrollCtrl::GuiScrollCtrl()
    mScrollBarThickness = 16;
    mScrollBarDragTolerance = 130;
    mDepressed = false;
-   curHitRegion = None;
+   curHitRegion = Content;
    mActive = true;
    mShowArrowButtons = true;
    mBaseThumbSize = (mScrollBarThickness * 2);
@@ -74,6 +74,8 @@ GuiScrollCtrl::GuiScrollCtrl()
    setField("arrowProfile", "GuiScrollArrowProfile");
    setField("trackProfile", "GuiScrollTrackProfile");
    setField("profile", "GuiScrollProfile");
+
+   mEventBubbled = false;
 }
 
 void GuiScrollCtrl::initPersistFields()
@@ -190,12 +192,12 @@ GuiControl* GuiScrollCtrl::findHitControl(const Point2I& pt, S32 initialLayer)
 			{
 				continue;
 			}
-			else if (ctrl->mVisible && ctrl->pointInControl(pt - ctrl->mRenderInsetLT))
+			else if (ctrl->mVisible && ctrl->pointInControl(pt - ctrl->mRenderInsetLT) && ctrl->mUseInput)
 			{
 				Point2I ptemp = pt - (ctrl->mBounds.point + ctrl->mRenderInsetLT);
 				GuiControl* hitCtrl = ctrl->findHitControl(ptemp);
 
-				if (hitCtrl->mProfile->mUseInput)
+				if (hitCtrl->mUseInput)
 					return hitCtrl;
 			}
 		}
@@ -239,7 +241,7 @@ GuiScrollCtrl::Region GuiScrollCtrl::findHitRegion(const Point2I& pt)
 				return RightPage;
 		}
 	}
-	return None;
+	return Content;
 }
 
 #pragma region CalculationFunctions
@@ -483,7 +485,7 @@ void GuiScrollCtrl::scrollByRegion(Region reg)
 		case RightPage:
 		case VertThumb:
 		case HorizThumb:
-		case None:
+		case Content:
 			//Con::errorf("Unhandled case in GuiScrollCtrl::scrollByRegion");
 			break;
 		}
@@ -511,7 +513,7 @@ void GuiScrollCtrl::scrollByRegion(Region reg)
 		case DownPage:
 		case VertThumb:
 		case HorizThumb:
-		case None:
+		case Content:
 			//Con::errorf("Unhandled case in GuiScrollCtrl::scrollByRegion");
 			break;
 		}
@@ -561,13 +563,17 @@ void GuiScrollCtrl::scrollRectVisible(RectI rect)
 void GuiScrollCtrl::onTouchMove(const GuiEvent& event)
 {
 	curHitRegion = findHitRegion(globalToLocalCoord(event.mousePoint));
+
+	GuiControl* parent = getParent();
+	if (parent)
+		parent->onTouchMove(event);
 }
 
 void GuiScrollCtrl::onTouchLeave(const GuiEvent &event)
 {
 	if (!mDepressed)
 	{
-		curHitRegion = None;
+		curHitRegion = Content;
 	}
 }
 
@@ -611,6 +617,7 @@ void GuiScrollCtrl::onTouchDown(const GuiEvent &event)
    Point2I curMousePos = globalToLocalCoord(event.mousePoint);
    curHitRegion = findHitRegion(curMousePos);
    mDepressed = true;
+   mEventBubbled = false;
 
    // Set a 0.5 second delay before we start scrolling
    mLastUpdated = Platform::getVirtualMilliseconds() + 500;
@@ -627,15 +634,34 @@ void GuiScrollCtrl::onTouchDown(const GuiEvent &event)
 	   mScrollOffsetAnchor = mScrollOffset;
       mThumbMouseDelta = curMousePos.x - mHThumbPos;
    }
+   else if (curHitRegion == Content)
+   {
+	   GuiControl* parent = getParent();
+	   if (parent)
+	   {
+		   parent->onTouchDown(event);
+		   mEventBubbled = true;
+	   }
+   }
 }
 
-void GuiScrollCtrl::onTouchUp(const GuiEvent &)
+void GuiScrollCtrl::onTouchUp(const GuiEvent &event)
 {
    mouseUnlock();
 
    setUpdate();
 
-   curHitRegion = None;
+   if (mEventBubbled)
+   {
+	   GuiControl* parent = getParent();
+	   if (parent)
+	   {
+		   parent->onTouchUp(event);
+	   }
+		mEventBubbled = false;
+   }
+
+   curHitRegion = Content;
    mDepressed = false;
 }
 
@@ -644,6 +670,16 @@ void GuiScrollCtrl::onTouchDragged(const GuiEvent &event)
    Point2I curMousePos = globalToLocalCoord(event.mousePoint);
    setUpdate();
 
+   if (mEventBubbled)
+   {
+	   GuiControl* parent = getParent();
+	   if (parent)
+	   {
+		   parent->onTouchDragged(event);
+		   return;
+	   }
+   }
+
    if ( (curHitRegion != VertThumb) && (curHitRegion != HorizThumb) )
    {
       Region hit = findHitRegion(curMousePos);

+ 2 - 1
engine/source/gui/containers/guiScrollCtrl.h

@@ -31,6 +31,7 @@ class GuiScrollCtrl : public GuiControl
 {
 private:
    typedef GuiControl Parent;
+   bool mEventBubbled;
 
 protected:
 
@@ -84,7 +85,7 @@ public:
       RightPage,
       VertThumb,
       HorizThumb,
-      None
+      Content
    };
    enum {
       ScrollBarAlwaysOn = 0,

+ 4 - 64
engine/source/gui/containers/guiTabBookCtrl.cc

@@ -259,6 +259,10 @@ void GuiTabBookCtrl::onTouchDown(const GuiEvent &event)
         if( tab != NULL && tab->isActive() )
             selectPage( tab );
     }
+    else
+    {
+        Parent::onTouchDown(event);
+    }
 }
 
 void GuiTabBookCtrl::onTouchMove(const GuiEvent &event)
@@ -402,70 +406,6 @@ void GuiTabBookCtrl::renderTab( RectI tabRect, GuiTabPageCtrl *tab )
    }
 
    renderText(contentRect.point, contentRect.extent, text, mTabProfile, rot);
-
-   /*
-   // Is this a skinned control?
-   if( mHasTexture && mProfile->mBitmapArrayRects.size() >= 9 )
-   {
-      S32 indexMultiplier = 1;
-      switch( mTabPosition )
-      {
-      case AlignTop:
-      case AlignBottom:
-         
-         if ( mActivePage == tab )
-            indexMultiplier += TabSelected;
-         else if( mHoverTab == tab )
-            indexMultiplier += TabHover;
-         else
-            indexMultiplier += TabNormal;
-         
-         //dglDrawBitmapStretchSR(mProfile->mTextureHandle,tabRect,stretchRect, ( mTabPosition == AlignBottom ) ? GFlip_Y : 0 );
-         break;
-      case AlignLeft:
-      case AlignRight:
-         if ( mActivePage == tab )
-            indexMultiplier += TabSelectedVertical;
-         else if( mHoverTab == tab )
-            indexMultiplier += TabHoverVertical;
-         else
-            indexMultiplier += TabNormalVertical;
-
-         //dglDrawBitmapStretchSR(mProfile->mTextureHandle,tabRect,stretchRect, ( mTabPosition == AlignRight ) ? GFlip_X : 0 );
-         break;
-      } 
-
-      renderFixedBitmapBordersFilled( tabRect, indexMultiplier, mProfile );
-   }
-   else
-   {
-      // If this isn't a skinned control or the bitmap is simply missing, handle it WELL
-      if ( mActivePage == tab )
-         dglDrawRectFill(tabRect, mProfile->mFillColor);
-      else if( mHoverTab == tab )
-         dglDrawRectFill(tabRect, mProfile->mFillColorHL);
-      else
-         dglDrawRectFill(tabRect, mProfile->mFillColorNA);
-
-   }
-
-
-   dglSetBitmapModulation(mProfile->mFontColor);
-
-   switch( mTabPosition )
-   {
-   case AlignTop:
-   case AlignBottom:
-      renderJustifiedTextRot( tabRect.point, tabRect.extent, text, 0);
-   break;
-   case AlignLeft:
-      renderJustifiedTextRot( tabRect.point, tabRect.extent, text, -90 );
-      break;
-   case AlignRight:
-      renderJustifiedTextRot( tabRect.point, tabRect.extent, text, -90 );
-      break;
-   }
-   */
 }
 
 // This is nothing but a clever hack to allow the tab page children

+ 1 - 0
engine/source/gui/containers/guiWindowCtrl.cc

@@ -180,6 +180,7 @@ void GuiWindowCtrl::resize(const Point2I &newPosition, const Point2I &newExtent)
 void GuiWindowCtrl::onTouchMove(const GuiEvent &event)
 {
 	curHitRegion = findHitRegion(globalToLocalCoord(event.mousePoint));
+	Parent::onTouchMove(event);
 }
 
 void GuiWindowCtrl::onTouchLeave(const GuiEvent &event)

+ 41 - 32
engine/source/gui/guiCanvas.cc

@@ -621,15 +621,18 @@ void GuiCanvas::rootMouseDown(const GuiEvent &event)
       {
          i--;
          GuiControl *ctrl = static_cast<GuiControl *>(*i);
-         GuiControl *controlHit = ctrl->findHitControl(event.mousePoint);
+         if (ctrl->mUseInput)
+         {
+             GuiControl* controlHit = ctrl->findHitControl(event.mousePoint);
 
-		 //Regardless of what the control does, it has the user's focus.
-		 controlHit->onFocus();
+             //Regardless of what the control does, it has the user's focus.
+             controlHit->onFocus();
 
-         if (controlHit->mProfile->mUseInput)
-         {
-            controlHit->onTouchDown(event);
-            break;
+             if (controlHit->mUseInput)
+             {
+                 controlHit->onTouchDown(event);
+                 break;
+             }
          }
       }
    }
@@ -671,23 +674,26 @@ void GuiCanvas::rootScreenTouchDown(const GuiEvent &event)
         {  
             i--;  
             GuiControl *ctrl = static_cast<GuiControl *>(*i);  
-            GuiControl *controlHit = ctrl->findHitControl(event.mousePoint);  
-              
-            //If the control we hit is not the same one that is locked,  
-            // then unlock the existing control.  
-            if (bool(mMouseCapturedControl) && mMouseCapturedControl->isMouseLocked() && mMouseCapturedControl != controlHit)  
-            {  
-                mMouseCapturedControl->onTouchLeave(event);   
-            } 
-			
-			//Regardless of what the control does, it has the user's focus.
-			controlHit->onFocus();
-              
-			if (controlHit->mProfile->mUseInput)
-			{
-				controlHit->onTouchDown(event);
-				break;
-			}
+            if (ctrl->mUseInput)
+            {
+                GuiControl* controlHit = ctrl->findHitControl(event.mousePoint);
+
+                //If the control we hit is not the same one that is locked,  
+                // then unlock the existing control.  
+                if (bool(mMouseCapturedControl) && mMouseCapturedControl->isMouseLocked() && mMouseCapturedControl != controlHit)
+                {
+                    mMouseCapturedControl->onTouchLeave(event);
+                }
+
+                //Regardless of what the control does, it has the user's focus.
+                controlHit->onFocus();
+
+                if (controlHit->mUseInput)
+                {
+                    controlHit->onTouchDown(event);
+                    break;
+                }
+            }
         }  
       
     if (bool(mMouseControl))  
@@ -705,13 +711,16 @@ void GuiCanvas::rootScreenTouchUp(const GuiEvent &event)
     {
         i--;    
         GuiControl *ctrl = static_cast<GuiControl *>(*i);
-        GuiControl *controlHit = ctrl->findHitControl(event.mousePoint);
-        
-		if (controlHit->mActive && controlHit->mProfile->mUseInput)
-		{
-			controlHit->onTouchUp(event);
-			break;
-		}
+        if (ctrl->mUseInput)
+        {
+            GuiControl* controlHit = ctrl->findHitControl(event.mousePoint);
+
+            if (controlHit->mActive && controlHit->mUseInput)
+            {
+                controlHit->onTouchUp(event);
+                break;
+            }
+        }
     }
 }
 
@@ -989,7 +998,7 @@ void GuiCanvas::setContentControl(GuiControl *gui)
       GuiControl *ctrl = static_cast<GuiControl *>(*i);
       ctrl->buildAcceleratorMap();
 
-	  if (ctrl->mProfile->mUseInput)
+	  if (ctrl->mUseInput)
 	  {
 		  break;
 	  }

+ 69 - 17
engine/source/gui/guiControl.cc

@@ -95,6 +95,7 @@ GuiControl::GuiControl()
    mIsContainer         = false;
    mTextWrap			= false;
    mTextExtend          = false;
+   mUseInput            = true;
 }
 
 GuiControl::~GuiControl()
@@ -177,8 +178,9 @@ void GuiControl::initPersistFields()
    addProtectedField("MinExtent",         TypePoint2I,		Offset(mMinExtent, GuiControl), &setMinExtentFn, &defaultProtectedGetFn, &writeMinExtentFn, "The extent will not shrink below this size.");
    addField("canSave",           TypeBool,			Offset(mCanSave, GuiControl));
    addField("Visible",           TypeBool,			Offset(mVisible, GuiControl));
+   addField("useInput",          TypeBool,          Offset(mUseInput, GuiControl));
    addDepricatedField("Modal");
-   addDepricatedField("SetFirstResponder");
+   addField("SetFirstResponder", TypeBool, Offset(mFirstResponder, GuiControl));
 
    addField("Variable",          TypeString,		Offset(mConsoleVariable, GuiControl));
    addField("Command",           TypeString,		Offset(mConsoleCommand, GuiControl));
@@ -1235,12 +1237,12 @@ GuiControl* GuiControl::findHitControl(const Point2I &pt, S32 initialLayer)
       {
          continue;
       }
-      else if (ctrl->mVisible && ctrl->pointInControl(pt - ctrl->mRenderInsetLT))
+      else if (ctrl->mVisible && ctrl->pointInControl(pt - ctrl->mRenderInsetLT) && ctrl->mUseInput)
       {
          Point2I ptemp = pt - (ctrl->mBounds.point + ctrl->mRenderInsetLT);
          GuiControl *hitCtrl = ctrl->findHitControl(ptemp);
 
-         if(hitCtrl->mProfile->mUseInput)
+         if(hitCtrl->mUseInput)
             return hitCtrl;
       }
    }
@@ -1284,19 +1286,29 @@ bool GuiControl::onInputEvent(const InputEvent &event)
 
 void GuiControl::onTouchUp(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onTouchUp(event);
 }
 
 void GuiControl::onTouchDown(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onTouchDown(event);
 }
 
 void GuiControl::onTouchMove(const GuiEvent &event)
 {
-   //if this control is a dead end, make sure the event stops here
    if ( !mVisible || !mAwake )
       return;
 
-   //pass the event to the parent
    GuiControl *parent = getParent();
    if ( parent )
       parent->onTouchMove( event );
@@ -1304,23 +1316,29 @@ void GuiControl::onTouchMove(const GuiEvent &event)
 
 void GuiControl::onTouchDragged(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onTouchDragged(event);
 }
 
-void GuiControl::onTouchEnter(const GuiEvent &)
+void GuiControl::onTouchEnter(const GuiEvent &event)
 {
+    //Entering a child means nothing to a parent
 }
 
-void GuiControl::onTouchLeave(const GuiEvent &)
+void GuiControl::onTouchLeave(const GuiEvent &event)
 {
+    //Leaving a child means nothing to a parent
 }
 
 bool GuiControl::onMouseWheelUp( const GuiEvent &event )
 {
-   //if this control is a dead end, make sure the event stops here
    if ( !mVisible || !mAwake )
       return true;
 
-   //pass the event to the parent
    GuiControl *parent = getParent();
    if ( parent )
       return parent->onMouseWheelUp( event );
@@ -1330,11 +1348,9 @@ bool GuiControl::onMouseWheelUp( const GuiEvent &event )
 
 bool GuiControl::onMouseWheelDown( const GuiEvent &event )
 {
-   //if this control is a dead end, make sure the event stops here
    if ( !mVisible || !mAwake )
       return true;
 
-   //pass the event to the parent
    GuiControl *parent = getParent();
    if ( parent )
       return parent->onMouseWheelDown( event );
@@ -1342,28 +1358,64 @@ bool GuiControl::onMouseWheelDown( const GuiEvent &event )
       return false;
 }
 
-void GuiControl::onRightMouseDown(const GuiEvent &)
+void GuiControl::onRightMouseDown(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onRightMouseDown(event);
 }
 
-void GuiControl::onRightMouseUp(const GuiEvent &)
+void GuiControl::onRightMouseUp(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onRightMouseUp(event);
 }
 
-void GuiControl::onRightMouseDragged(const GuiEvent &)
+void GuiControl::onRightMouseDragged(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onRightMouseDragged(event);
 }
 
-void GuiControl::onMiddleMouseDown(const GuiEvent &)
+void GuiControl::onMiddleMouseDown(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onMiddleMouseDown(event);
 }
 
-void GuiControl::onMiddleMouseUp(const GuiEvent &)
+void GuiControl::onMiddleMouseUp(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onMiddleMouseUp(event);
 }
 
-void GuiControl::onMiddleMouseDragged(const GuiEvent &)
+void GuiControl::onMiddleMouseDragged(const GuiEvent &event)
 {
+    if (!mVisible || !mAwake)
+        return;
+
+    GuiControl* parent = getParent();
+    if (parent)
+        parent->onMiddleMouseDragged(event);
 }
 
 

+ 1 - 0
engine/source/gui/guiControl.h

@@ -140,6 +140,7 @@ public:
     bool    mSetFirstResponder;
     bool    mCanSave;
     bool    mIsContainer; ///< if true, then the GuiEditor can drag other controls into this one.
+    bool    mUseInput; ///< True if input events like a click can be passed to this gui. False will pass events to the parent and this object and its children will not process input (touch and keyboard).
 
     S32     mLayer;
     static S32     smCursorChanged; ///< Has this control modified the cursor? -1 or type

+ 0 - 2
engine/source/gui/guiTypes.cc

@@ -309,7 +309,6 @@ GuiControlProfile::GuiControlProfile(void) :
 	
 	mTabable       = false;
 	mCanKeyFocus   = false;
-	mUseInput      = true;
 
 	mBorderDefault = NULL;
 
@@ -401,7 +400,6 @@ void GuiControlProfile::initPersistFields()
    addGroup("Behavior");
       addField("tab",           TypeBool,       Offset(mTabable, GuiControlProfile));
       addField("canKeyFocus",   TypeBool,       Offset(mCanKeyFocus, GuiControlProfile));
-      addField("useInput",      TypeBool,       Offset(mUseInput, GuiControlProfile));
       addField("mouseOverSelected", TypeBool,   Offset(mMouseOverSelected, GuiControlProfile));
    endGroup("Behavior");
 

+ 0 - 1
engine/source/gui/guiTypes.h

@@ -167,7 +167,6 @@ public:
    bool mTabable;                                  ///< True if this object is accessable from using the tab key
 
    bool mCanKeyFocus;                              ///< True if the object can be given keyboard focus (in other words, made a first responder @see GuiControl)
-   bool mUseInput;                                 ///< True if input events like a click can be passed to this object. False will pass events to the parent and this object and its children will not be evaluated.
 
    ColorI mFillColor; //Normal fill color used to fill the control area inside (and possibly under) the border.
    ColorI mFillColorHL; //The highlight fill color used when the cursor enters the control.