Sfoglia il codice sorgente

Merge pull request #249 from kcunney/next

Fixes multiple-input handling and scrolling problems.
Sean Paul Taylor 13 anni fa
parent
commit
9a9bf676a0

+ 1 - 0
gameplay/src/Button.h

@@ -26,6 +26,7 @@ namespace gameplay
          width       = <width>   // Can be used in place of 'size', e.g. with 'autoHeight = true'
          height      = <height>  // Can be used in place of 'size', e.g. with 'autoWidth = true'
          text        = <string>
+         consumeEvents = <bool>  // Whether the button propogates input events to the Game's input event handler. Defualt is true.
     }
  @endverbatim
  */

+ 1 - 0
gameplay/src/CheckBox.h

@@ -28,6 +28,7 @@ namespace gameplay
          text        = <string>
          checked     = <bool>
          iconSize    = <width, height>   // The size to draw the checkbox icon, if different from its size in the texture.
+         consumeEvents = <bool>  // Whether the checkbox propogates input events to the Game's input event handler. Default is true.
     }
  @endverbatim
  */

+ 76 - 60
gameplay/src/Container.cpp

@@ -730,22 +730,28 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
     switch(evt)
     {
     case Touch::TOUCH_PRESS:
-        _scrollingLastX = _scrollingFirstX = x;
-        _scrollingLastY = _scrollingFirstY = y;
-        _scrollingVelocity.set(0, 0);
-        _scrolling = true;
-        _scrollingStartTimeX = _scrollingStartTimeY = 0;
-        
-        if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
-        {
-            _scrollBarOpacityClip->stop();
-            _scrollBarOpacityClip = NULL;
-        }
-        _scrollBarOpacity = 1.0f;
-        return _consumeInputEvents;
-
+    	if (_contactIndex == INVALID_CONTACT_INDEX)
+    	{
+    		_contactIndex = (int) contactIndex;
+    		_contactIndices++;
+			_scrollingLastX = _scrollingFirstX = x;
+			_scrollingLastY = _scrollingFirstY = y;
+			_scrollingVelocity.set(0, 0);
+			_scrolling = true;
+			_scrollingStartTimeX = _scrollingStartTimeY = 0;
+
+			if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
+			{
+				_scrollBarOpacityClip->stop();
+				_scrollBarOpacityClip = NULL;
+			}
+			_scrollBarOpacity = 1.0f;
+
+			return _consumeInputEvents;
+    	}
+		break;
     case Touch::TOUCH_MOVE:
-        if (_scrolling)
+        if (_scrolling && _contactIndex == (int) contactIndex)
         {
             double gameTime = Game::getAbsoluteTime();
 
@@ -808,50 +814,57 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         break;
 
     case Touch::TOUCH_RELEASE:
-        _scrolling = false;
-        double gameTime = Game::getAbsoluteTime();
-        float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
-        if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
-        {
-            _scrollingVelocity.set(0, 0);
-            _scrollingMouseVertically = _scrollingMouseHorizontally = false;
-            return _consumeInputEvents;
-        }
-
-        int dx = _scrollingLastX - _scrollingFirstX;
-        int dy = _scrollingLastY - _scrollingFirstY;
-
-        float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
-        float elapsedSecsX = timeTakenX * 0.001f;
-        float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
-        float elapsedSecsY = timeTakenY * 0.001f;
-
-        float vx = dx;
-        float vy = dy;
-        if (elapsedSecsX > 0)
-            vx = (float)dx / elapsedSecsX;
-        if (elapsedSecsY > 0)
-            vy = (float)dy / elapsedSecsY;
-
-        if (_scrollingMouseVertically)
-        {
-            float yRatio = _totalHeight / _absoluteBounds.height;
-            vy *= yRatio;
-            _scrollingVelocity.set(0, -vy);
-        }
-        else if (_scrollingMouseHorizontally)
-        {
-            float xRatio = _totalWidth / _absoluteBounds.width;
-            vx *= xRatio;
-            _scrollingVelocity.set(-vx, 0);
-        }
-        else
-        {
-            _scrollingVelocity.set(vx, vy);
-        }
-
-        _scrollingMouseVertically = _scrollingMouseHorizontally = false;
-        return _consumeInputEvents;
+    	if (_contactIndex == (int) contactIndex)
+    	{
+    		_contactIndex = INVALID_CONTACT_INDEX;
+    		_contactIndices--;
+			_scrolling = false;
+			double gameTime = Game::getAbsoluteTime();
+			float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
+			if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
+			{
+				_scrollingVelocity.set(0, 0);
+				_scrollingMouseVertically = _scrollingMouseHorizontally = false;
+				return _consumeInputEvents;
+			}
+
+			int dx = _scrollingLastX - _scrollingFirstX;
+			int dy = _scrollingLastY - _scrollingFirstY;
+
+			float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
+			float elapsedSecsX = timeTakenX * 0.001f;
+			float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
+			float elapsedSecsY = timeTakenY * 0.001f;
+
+			float vx = dx;
+			float vy = dy;
+			if (elapsedSecsX > 0)
+				vx = (float)dx / elapsedSecsX;
+			if (elapsedSecsY > 0)
+				vy = (float)dy / elapsedSecsY;
+
+			if (_scrollingMouseVertically)
+			{
+				float yRatio = _totalHeight / _absoluteBounds.height;
+				vy *= yRatio;
+				_scrollingVelocity.set(0, -vy);
+			}
+			else if (_scrollingMouseHorizontally)
+			{
+				float xRatio = _totalWidth / _absoluteBounds.width;
+				vx *= xRatio;
+				_scrollingVelocity.set(-vx, 0);
+			}
+			else
+			{
+				_scrollingVelocity.set(vx, vy);
+			}
+
+			_scrollingMouseVertically = _scrollingMouseHorizontally = false;
+
+			return _consumeInputEvents;
+    	}
+    	break;
     }
 
     return false;
@@ -997,6 +1010,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         return (_consumeInputEvents | eventConsumed);
     }
     
+    bool withinClipBounds = false;
     switch (evt)
     {
     case Touch::TOUCH_PRESS:
@@ -1004,12 +1018,14 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
             y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
         {
             setState(Control::FOCUS);
+            withinClipBounds = true;
             if (eventConsumed)
                 _contactIndices++;
         }
         else if (_contactIndices == 0)
         {
             setState(Control::NORMAL);
+            _contactIndex = INVALID_CONTACT_INDEX;
             return false;
         }
         break;
@@ -1024,7 +1040,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         break;
     }
 
-    if (!eventConsumed && _scroll != SCROLL_NONE && getState() == Control::FOCUS)
+    if (!eventConsumed && _scroll != SCROLL_NONE && getState() == Control::FOCUS && (evt != Touch::TOUCH_PRESS || withinClipBounds))
     {
         if ((mouse && mouseEventScroll((Mouse::MouseEvent)evt, x - xPos, y - yPos, data)) ||
             (!mouse && touchEventScroll((Touch::TouchEvent)evt, x - xPos, y - yPos, (unsigned int)data)))

+ 2 - 1
gameplay/src/Container.h

@@ -27,7 +27,8 @@ namespace gameplay
          height      = <height>  // Can be used in place of 'size', e.g. with 'autoWidth = true'
          scroll      = <Container::Scroll constant> // Whether scrolling is allowed and in which directions.
          scrollBarsAutoHide = <bool>    // Whether scrollbars fade out when not in use.
-  
+         consumeEvents = <bool>             // Whether the container propogates input events to the Game's input event handler. Default is true.
+
          // All the nested controls within this container.
          container 
          { 

+ 2 - 0
gameplay/src/Control.cpp

@@ -41,6 +41,8 @@ void Control::initialize(Theme::Style* style, Properties* properties)
     _autoWidth = properties->getBool("autoWidth");
     _autoHeight = properties->getBool("autoHeight");
 
+    _consumeInputEvents = properties->getBool("consumeEvents", true);
+
     if (properties->exists("zIndex"))
     {
         _zIndex = properties->getInt("zIndex");

+ 3 - 0
gameplay/src/Form.cpp

@@ -40,6 +40,7 @@ static std::vector<Form*> __forms;
 
 Form::Form() : _theme(NULL), _frameBuffer(NULL), _spriteBatch(NULL), _node(NULL), _nodeQuad(NULL), _nodeMaterial(NULL) , _u2(0), _v1(0)
 {
+	_consumeInputEvents = false;
 }
 
 Form::~Form()
@@ -167,6 +168,8 @@ Form* Form::create(const char* url)
     }
     form->initialize(style, formProperties);
 
+    form->_consumeInputEvents = formProperties->getBool("consumeInputs");
+
     // Alignment
     if ((form->_alignment & Control::ALIGN_BOTTOM) == Control::ALIGN_BOTTOM)
     {

+ 4 - 3
gameplay/src/Form.h

@@ -32,6 +32,7 @@ class Theme;
         size       = <width, height>       // Size of the form, measured in pixels.
         width      = <width>               // Can be used in place of 'size', e.g. with 'autoHeight = true'
         height     = <height>              // Can be used in place of 'size', e.g. with 'autoWidth = true'
+        consumeEvents = <bool>             // Whether the form propogates input events to the Game's input event handler. Default is false
       
         // All the nested controls within this form.
         container { }
@@ -197,9 +198,9 @@ private:
      * @param x The number to start with.
      *
      * @return The next highest power of two after x, or x if it is already a power of two.
-     */
+     */
     static unsigned int nextPowerOfTwo(unsigned int x);
-
+
     /**
      * Unproject a point (from a mouse or touch event) into the scene and then project it onto the form.
      *
@@ -209,7 +210,7 @@ private:
      *
      * @return True if the projected point lies within the form's plane, false otherwise.
      */
-    bool projectPoint(int x, int y, Vector3* point);
+    bool projectPoint(int x, int y, Vector3* point);
 
     Theme* _theme;                      // The Theme applied to this Form.
     FrameBuffer* _frameBuffer;          // FBO the Form is rendered into for texturing the quad. 

+ 0 - 2
gameplay/src/Joystick.cpp

@@ -114,8 +114,6 @@ void Joystick::addListener(Control::Listener* listener, int eventFlags)
         GP_ERROR("TEXT_CHANGED event is not applicable to this control.");
     }
 
-    _consumeInputEvents = true;
-
     Control::addListener(listener, eventFlags);
 }
 

+ 14 - 0
gameplay/src/Joystick.h

@@ -8,6 +8,20 @@ namespace gameplay
 
 /**
  * Defines a control representing a joystick (axis).
+ *
+  @verbatim
+    slider
+    {
+        style       = <styleID>                 // A Style from the Theme.
+        position    = <x, y>                    // Position of the Control on-screen, measured in pixels.
+        alignment   = <Control::Alignment constant> // Note: 'position' will be ignored.
+        size        = <width, height>           // Size of the Control, measured in pixels.
+        radius      = <float>                   // The value of the left- / bottom-most point on the slider.
+        consumeEvents = <bool>                  // Whether the slider propogates input events to the Game's input event handler. Default is true.
+        
+    }
+ @endverbatim
+ *
  */
 class Joystick : public Control
 {

+ 1 - 0
gameplay/src/Label.h

@@ -24,6 +24,7 @@ namespace gameplay
          width       = <width>   // Can be used in place of 'size', e.g. with 'autoHeight = true'
          height      = <height>  // Can be used in place of 'size', e.g. with 'autoWidth = true'
          text        = <string>
+         consumeEvents = <bool>  // Whether the label propogates input events to the Game's input event handler. Default is true.
     }
  @endverbatim
  */

+ 8 - 8
gameplay/src/Mouse.h

@@ -16,14 +16,14 @@ public:
      */
     enum MouseEvent
     {
-        MOUSE_PRESS_LEFT_BUTTON,
-        MOUSE_RELEASE_LEFT_BUTTON,
-        MOUSE_PRESS_MIDDLE_BUTTON,
-        MOUSE_RELEASE_MIDDLE_BUTTON,
-        MOUSE_PRESS_RIGHT_BUTTON,
-        MOUSE_RELEASE_RIGHT_BUTTON,
-        MOUSE_MOVE,
-        MOUSE_WHEEL
+        MOUSE_PRESS_LEFT_BUTTON = 3,
+        MOUSE_RELEASE_LEFT_BUTTON = 4,
+        MOUSE_PRESS_MIDDLE_BUTTON = 5,
+        MOUSE_RELEASE_MIDDLE_BUTTON = 6,
+        MOUSE_PRESS_RIGHT_BUTTON = 7,
+        MOUSE_RELEASE_RIGHT_BUTTON = 8,
+        MOUSE_MOVE = 9,
+        MOUSE_WHEEL = 10
     };
 
 

+ 2 - 2
gameplay/src/Properties.cpp

@@ -689,7 +689,7 @@ const char* Properties::getString(const char* name) const
     return NULL;
 }
 
-bool Properties::getBool(const char* name) const
+bool Properties::getBool(const char* name, bool defaultValue) const
 {
     const char* valueString = getString(name);
     if (valueString)
@@ -697,7 +697,7 @@ bool Properties::getBool(const char* name) const
         return (strcmp(valueString, "true") == 0);
     }
 
-    return false;
+    return defaultValue;
 }
 
 int Properties::getInt(const char* name) const

+ 3 - 2
gameplay/src/Properties.h

@@ -241,10 +241,11 @@ public:
      * Interpret the value of the given property as a boolean.
      *
      * @param name The name of the property to interpret, or NULL to return the current property's value.
+     * @param defaultValue the default value to return if the specified property does not exist within the properties file.
      * 
      * @return true if the property exists and its value is "true", otherwise false.
      */
-    bool getBool(const char* name = NULL) const;
+    bool getBool(const char* name = NULL, bool defaultValue = false) const;
 
     /**
      * Interpret the value of the given property as an integer.
@@ -416,4 +417,4 @@ private:
 
 }
 
-#endif
+#endif

+ 1 - 0
gameplay/src/RadioButton.h

@@ -30,6 +30,7 @@ namespace gameplay
          text        = <string>
          group       = <string>
          iconSize    = <width, height>   // The size to draw the radio button icon, if different from its size in the texture.
+         consumeEvents = <bool>          // Whether the radio button propogates input events to the Game's input event handler. Default is true.
     }
  @endverbatim
  */

+ 1 - 0
gameplay/src/Slider.h

@@ -25,6 +25,7 @@ namespace gameplay
         value       = <float>                   // The default position of the marker.
         step        = <float>                   // If greater than 0, force the marker to snap to discrete multiples of 'step'.
         text        = <string>                  // Text to display above, below or alongside the slider (depending on the style).
+        consumeEvents = <bool>                  // Whether the slider propogates input events to the Game's input event handler. Default is true.
         // TODO: orientation = <HORIZONTAL or VERTICAL>  // Determines whether a slider is stretched along its width or its height
     }
  @endverbatim