Prechádzať zdrojové kódy

Merge branch 'next' of https://github.com/blackberry/GamePlay into next

Conflicts:
	gameplay/src/lua/lua_ControlListenerEventType.cpp
	gameplay/src/lua/lua_ControlState.cpp
sgrenier 12 rokov pred
rodič
commit
c582e7e879
78 zmenil súbory, kde vykonal 1512 pridanie a 412 odobranie
  1. 4 3
      CMakeLists.txt
  2. 1 1
      gameplay/src/AnimationClip.cpp
  3. 1 1
      gameplay/src/AnimationClip.h
  4. 1 3
      gameplay/src/Button.cpp
  5. 128 36
      gameplay/src/Container.cpp
  6. 57 15
      gameplay/src/Container.h
  7. 58 2
      gameplay/src/Control.cpp
  8. 25 1
      gameplay/src/Control.h
  9. 29 31
      gameplay/src/Form.cpp
  10. 1 1
      gameplay/src/Form.h
  11. 2 2
      gameplay/src/Platform.cpp
  12. 1 1
      gameplay/src/Platform.h
  13. 1 1
      gameplay/src/PlatformBlackBerry.cpp
  14. 3 3
      gameplay/src/PlatformLinux.cpp
  15. 3 3
      gameplay/src/PlatformWindows.cpp
  16. 26 11
      gameplay/src/Slider.cpp
  17. 2 2
      gameplay/src/TextBox.cpp
  18. 27 8
      gameplay/src/Theme.cpp
  19. 8 3
      gameplay/src/ThemeStyle.cpp
  20. 2 1
      gameplay/src/ThemeStyle.h
  21. 4 4
      gameplay/src/lua/lua_AnimationClip.cpp
  22. 1 1
      gameplay/src/lua/lua_AnimationClip.h
  23. 36 0
      gameplay/src/lua/lua_Button.cpp
  24. 1 0
      gameplay/src/lua/lua_Button.h
  25. 36 0
      gameplay/src/lua/lua_CheckBox.cpp
  26. 1 0
      gameplay/src/lua/lua_CheckBox.h
  27. 255 0
      gameplay/src/lua/lua_Container.cpp
  28. 7 0
      gameplay/src/lua/lua_Container.h
  29. 36 0
      gameplay/src/lua/lua_Control.cpp
  30. 1 0
      gameplay/src/lua/lua_Control.h
  31. 12 0
      gameplay/src/lua/lua_ControlListenerEventType.cpp
  32. 7 0
      gameplay/src/lua/lua_ControlState.cpp
  33. 255 0
      gameplay/src/lua/lua_Form.cpp
  34. 7 0
      gameplay/src/lua/lua_Form.h
  35. 3 0
      gameplay/src/lua/lua_Global.cpp
  36. 36 0
      gameplay/src/lua/lua_ImageControl.cpp
  37. 1 0
      gameplay/src/lua/lua_ImageControl.h
  38. 36 0
      gameplay/src/lua/lua_Joystick.cpp
  39. 1 0
      gameplay/src/lua/lua_Joystick.h
  40. 36 0
      gameplay/src/lua/lua_Label.cpp
  41. 1 0
      gameplay/src/lua/lua_Label.h
  42. 36 0
      gameplay/src/lua/lua_RadioButton.cpp
  43. 1 0
      gameplay/src/lua/lua_RadioButton.h
  44. 36 0
      gameplay/src/lua/lua_Slider.cpp
  45. 1 0
      gameplay/src/lua/lua_Slider.h
  46. 36 0
      gameplay/src/lua/lua_TextBox.cpp
  47. 1 0
      gameplay/src/lua/lua_TextBox.h
  48. 1 1
      samples/browser/CMakeLists.txt
  49. 21 9
      samples/browser/res/common/default.theme
  50. 3 3
      samples/browser/res/common/forms/formBasicControls.form
  51. 1 1
      samples/browser/res/common/forms/formFlowLayout.form
  52. 1 1
      samples/browser/res/common/forms/formScrolling.form
  53. 1 1
      samples/browser/res/common/forms/formSelect.form
  54. 1 1
      samples/browser/res/common/forms/formVerticalLayout.form
  55. 1 1
      samples/browser/res/common/forms/formZOrder.form
  56. 1 0
      samples/browser/res/common/text.form
  57. 1 1
      samples/browser/src/FormsSample.cpp
  58. 1 1
      samples/browser/src/Sample.cpp
  59. 1 1
      samples/browser/src/Sample.h
  60. 10 1
      samples/browser/src/SamplesGame.cpp
  61. 2 2
      samples/character/CMakeLists.txt
  62. 2 2
      samples/longboard/CMakeLists.txt
  63. 2 2
      samples/lua/CMakeLists.txt
  64. 2 2
      samples/mesh/CMakeLists.txt
  65. 2 2
      samples/particles/CMakeLists.txt
  66. 2 2
      samples/racer/CMakeLists.txt
  67. 2 2
      samples/spaceship/CMakeLists.txt
  68. 93 93
      tools/encoder/CMakeLists.txt
  69. 3 49
      tools/encoder/README.md
  70. 48 43
      tools/encoder/src/EncoderArguments.cpp
  71. 34 28
      tools/encoder/src/FBXSceneEncoder.cpp
  72. 0 3
      tools/encoder/src/FBXSceneEncoder.h
  73. 0 4
      tools/encoder/src/FBXUtil.cpp
  74. 0 3
      tools/encoder/src/FBXUtil.h
  75. 1 1
      tools/encoder/src/Material.cpp
  76. 1 3
      tools/encoder/src/MeshSkin.cpp
  77. 0 5
      tools/encoder/src/main.cpp
  78. 10 10
      tools/luagen/CMakeLists.txt

+ 4 - 3
CMakeLists.txt

@@ -24,6 +24,7 @@ add_subdirectory(gameplay)
 # gameplay samples
 add_subdirectory(samples)
 
-
-
-
+# gameplay encoder
+# A pre-compiled executable can be found in 'gameplay/bin'
+# Uncomment out this line if you want to build the encoder instead of using the pre-compiled gameplay-encoder.
+#add_subdirectory(tools/encoder)

+ 1 - 1
gameplay/src/AnimationClip.cpp

@@ -93,7 +93,7 @@ unsigned long AnimationClip::getEndTime() const
     return _endTime;
 }
 
-float AnimationClip::getElaspedTime() const
+float AnimationClip::getElapsedTime() const
 {
     return _elapsedTime;
 }

+ 1 - 1
gameplay/src/AnimationClip.h

@@ -109,7 +109,7 @@ public:
      *
      * @return The elapsed time of the AnimationClip (in milliseconds).
      */
-    float getElaspedTime() const;
+    float getElapsedTime() const;
 
     /**
      * Sets the AnimationClip's repeat count. Overrides repeat duration.

+ 1 - 3
gameplay/src/Button.cpp

@@ -81,9 +81,7 @@ bool Button::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contac
         }
         break;
     case Touch::TOUCH_MOVE:
-        if (_contactIndex == (int) contactIndex)
-            return _consumeInputEvents;
-        break;
+        return Control::touchEvent(evt, x, y, contactIndex);
     }
 
     return false;

+ 128 - 36
gameplay/src/Container.cpp

@@ -46,7 +46,7 @@ Container::Container()
       _scrollBarsAutoHide(false), _scrollBarOpacity(1.0f), _scrolling(false),
       _scrollingVeryFirstX(0), _scrollingVeryFirstY(0), _scrollingFirstX(0), _scrollingFirstY(0), _scrollingLastX(0), _scrollingLastY(0),
       _scrollingStartTimeX(0), _scrollingStartTimeY(0), _scrollingLastTime(0),
-      _scrollingVelocity(Vector2::zero()), _scrollingFriction(1.0f),
+      _scrollingVelocity(Vector2::zero()), _scrollingFriction(1.0f), _scrollWheelSpeed(400.0f),
       _scrollingRight(false), _scrollingDown(false),
       _scrollingMouseVertically(false), _scrollingMouseHorizontally(false),
       _scrollBarOpacityClip(NULL), _zIndexDefault(0), _focusIndexDefault(0), _focusIndexMax(0),
@@ -54,7 +54,7 @@ Container::Container()
       _lastFrameTime(0), _focusChangeRepeat(false),
       _focusChangeStartTime(0), _focusChangeRepeatDelay(FOCUS_CHANGE_REPEAT_DELAY), _focusChangeCount(0),
       _totalWidth(0), _totalHeight(0),
-      _contactIndices(0), _initializedWithScroll(false)
+      _contactIndices(0), _initializedWithScroll(false), _scrollWheelRequiresFocus(false)
 {
 }
 
@@ -114,6 +114,13 @@ Container* Container::create(Theme::Style* style, Properties* properties, Theme*
     {
         container->_scrollBarOpacity = 0.0f;
     }
+    
+    container->_scrollWheelRequiresFocus = properties->getBool("scrollWheelRequiresFocus");
+    if (properties->exists("scrollingFriction"))
+        container->_scrollingFriction = properties->getFloat("scrollingFriction");
+    if (properties->exists("scrollWheelSpeed"))
+        container->_scrollWheelSpeed = properties->getFloat("scrollWheelSpeed");
+
     container->addControls(theme, properties);
     container->_layout->update(container, container->_scrollPosition);
 
@@ -421,6 +428,16 @@ const char* Container::getType() const
     return "container";
 }
 
+bool Container::getScrollWheelRequiresFocus() const
+{
+    return _scrollWheelRequiresFocus;
+}
+
+void Container::setScrollWheelRequiresFocus(bool required)
+{
+    _scrollWheelRequiresFocus = required;
+}
+
 void Container::update(const Control* container, const Vector2& offset)
 {
     // Update this container's viewport.
@@ -504,7 +521,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
 
         spriteBatch->start();
 
-        if (_scrollBarBounds.height > 0 &&((_scroll & SCROLL_VERTICAL) == SCROLL_VERTICAL))
+        if (_scrollBarBounds.height > 0 && ((_scroll & SCROLL_VERTICAL) == SCROLL_VERTICAL))
         {
             const Rectangle& topRegion = _scrollBarTopCap->getRegion();
             const Theme::UVs& topUVs = _scrollBarTopCap->getUVs();
@@ -628,7 +645,7 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
             continue;
         }
 
-        if (control->getState() == Control::FOCUS && control->keyEvent(evt, key))
+        if (control->isInFocus() && control->keyEvent(evt, key))
         {
             release();
             return true;
@@ -660,7 +677,7 @@ void Container::guaranteeFocus(Control* inFocus)
         {
             ((Container*)control)->guaranteeFocus(inFocus);
         }
-        else if (control->getState() == Control::FOCUS)
+        else if (control->isInFocus())
         {
             control->setState(NORMAL);
             return;
@@ -680,7 +697,7 @@ bool Container::moveFocus(Direction direction, Control* outsideControl)
         {
             Control* control = *it;
             GP_ASSERT(control);
-            if (control->getState() == Control::FOCUS)
+            if (control->isInFocus())
             {
                 start = control;
                 break;
@@ -887,7 +904,7 @@ bool Container::moveFocus(Direction direction, Control* outsideControl)
 void Container::timeEvent(long timeDiff, void* cookie)
 {
     double time = Game::getAbsoluteTime();
-    if (_focusChangeRepeat && _state == FOCUS && _focusPressed &&
+    if (_focusChangeRepeat && isInFocus() && _focusPressed &&
         abs(time - timeDiff - _focusChangeRepeatDelay - _focusChangeStartTime) < 50)
     {
         ++_focusChangeCount;
@@ -944,7 +961,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
     {
         Control* control = *it;
         GP_ASSERT(control);
-        if (control->getState() == Control::FOCUS || control->getState() == Control::ACTIVE)
+        if (control->isInFocus() || control->getState() == Control::ACTIVE)
         {
             eventConsumed |= control->gamepadEvent(evt, gamepad, analogIndex);
             break;
@@ -986,7 +1003,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
                     gamepad->isButtonDown(Gamepad::BUTTON_DOWN))
                 {
                     _focusPressed |= DOWN;
-                    eventConsumed |= _consumeInputEvents;
+                    eventConsumed = true;
                     if (moveFocus(DOWN))
                         break;
                     else
@@ -997,7 +1014,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
                     gamepad->isButtonDown(Gamepad::BUTTON_RIGHT))
                 {
                     _focusPressed |= RIGHT;
-                    eventConsumed |= _consumeInputEvents;
+                    eventConsumed = true;
                     if (moveFocus(RIGHT))
                         break;
                     else
@@ -1008,7 +1025,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
                     gamepad->isButtonDown(Gamepad::BUTTON_UP))
                 {
                     _focusPressed |= UP;
-                    eventConsumed |= _consumeInputEvents;
+                    eventConsumed = true;
                     if (moveFocus(UP))
                         break;
                     else
@@ -1019,7 +1036,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
                     gamepad->isButtonDown(Gamepad::BUTTON_LEFT))
                 {
                     _focusPressed |= LEFT;
-                    eventConsumed |= _consumeInputEvents;
+                    eventConsumed = true;
                     if (moveFocus(LEFT))
                         break;
                     else
@@ -1033,7 +1050,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
                 {
                 case 0:
                     // The left analog stick can be used in the same way as the DPad.
-                    eventConsumed |= _consumeInputEvents;
+                    eventConsumed = true;
                     if (!(_focusPressed & RIGHT) &&
                         joystick.x > JOYSTICK_THRESHOLD)
                     {
@@ -1111,7 +1128,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
             joystick.y > -JOYSTICK_THRESHOLD)
         {
             _focusPressed &= ~DOWN;
-            eventConsumed |= _consumeInputEvents;
+            eventConsumed = true;
         }
 
         if ((_focusPressed & RIGHT) &&
@@ -1119,7 +1136,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
             joystick.x < JOYSTICK_THRESHOLD)
         {
             _focusPressed &= ~RIGHT;
-            eventConsumed |= _consumeInputEvents;
+            eventConsumed = true;
         }
     
         if ((_focusPressed & UP) &&
@@ -1127,7 +1144,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
             joystick.y < JOYSTICK_THRESHOLD)
         {
             _focusPressed &= ~UP;
-            eventConsumed |= _consumeInputEvents;
+            eventConsumed = true;
         }
 
         if ((_focusPressed & LEFT) &&
@@ -1135,7 +1152,7 @@ bool Container::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsign
             joystick.x > -JOYSTICK_THRESHOLD)
         {
             _focusPressed &= ~LEFT;
-            eventConsumed |= _consumeInputEvents;
+            eventConsumed = true;
         }
     }
 
@@ -1521,15 +1538,27 @@ bool Container::mouseEventScroll(Mouse::MouseEvent evt, int x, int y, int wheelD
             return touchEventScroll(Touch::TOUCH_RELEASE, x, y, 0);
 
         case Mouse::MOUSE_WHEEL:
-            _scrollPosition.y += (_totalHeight / 10.0f) * wheelDelta;
-            if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
+            if ((_state == HOVER && (!_scrollWheelRequiresFocus || _previousState == FOCUS)) ||
+                _state == FOCUS && _scrollWheelRequiresFocus)
             {
-                _scrollBarOpacityClip->stop();
-                _scrollBarOpacityClip = NULL;
+                if (_scrollingVelocity.isZero())
+                {
+                    _lastFrameTime = Game::getGameTime();
+                }
+                _scrolling = _scrollingMouseVertically = _scrollingMouseHorizontally = false;
+
+                _scrollingVelocity.y += _scrollWheelSpeed * wheelDelta;
+
+                if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
+                {
+                    _scrollBarOpacityClip->stop();
+                    _scrollBarOpacityClip = NULL;
+                }
+                _scrollBarOpacity = 1.0f;
+                _dirty = true;
+                return _consumeInputEvents;
             }
-            _scrollBarOpacity = 1.0f;
-            _dirty = true;
-            return _consumeInputEvents;
+            break;
     }
 
     return false;
@@ -1579,12 +1608,13 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         }
 
         Control::State currentState = control->getState();
-        if ((control->isContainer() && currentState == Control::FOCUS) ||
-            (currentState != Control::NORMAL) ||
+        if ((currentState != Control::NORMAL) ||
             ((evt == Touch::TOUCH_PRESS ||
               evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
               evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
-              evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON) &&
+              evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
+              evt == Mouse::MOUSE_MOVE ||
+              evt == Mouse::MOUSE_WHEEL) &&
                 x >= xPos + boundsX &&
                 x <= xPos + boundsX + bounds.width &&
                 y >= yPos + boundsY &&
@@ -1600,18 +1630,23 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
 
     if (!isEnabled() || !isVisible())
     {
+        _contactIndex = INVALID_CONTACT_INDEX;
+        _contactIndices = 0;
+        _scrolling = false;
+        _scrollingMouseVertically = _scrollingMouseHorizontally = false;
+
         release();
         return (_consumeInputEvents | eventConsumed);
     }
-    
-    bool withinClipBounds = false;
+
+    bool withinClipBounds = (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                             y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height);
     switch (evt)
     {
     case Touch::TOUCH_PRESS:
-        if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-            y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+        if (withinClipBounds)
         {
-            setState(Control::FOCUS);
+            setState(Control::ACTIVE);
             withinClipBounds = true;
             if (eventConsumed)
                 _contactIndices++;
@@ -1624,16 +1659,53 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
             return false;
         }
         break;
+    case Mouse::MOUSE_MOVE:
+        if (_state != ACTIVE)
+        {
+            if (_state != HOVER && withinClipBounds)
+            {
+                _previousState = _state;
+                setState(HOVER);
+                notifyListeners(Control::Listener::ENTER);
+            }
+            else if (_state == HOVER && !withinClipBounds)
+            {
+                setState(_previousState);
+                notifyListeners(Control::Listener::LEAVE);
+            }
+            else if (_state != HOVER)
+            {
+                release();
+                return false;
+            }
+        }
+        break;
+    case Mouse::MOUSE_WHEEL:
+        if (!withinClipBounds && !_scrollWheelRequiresFocus)
+        {
+            release();
+            return false;
+        }
+        break;
     case Touch::TOUCH_RELEASE:
-        if (eventConsumed)
+        if (eventConsumed && _contactIndices > 0)
         {
-            if (_contactIndices > 0)
-                _contactIndices--;
+            _contactIndices--;
+        }
+
+        if (_state == ACTIVE && withinClipBounds)
+        {
+            setState(FOCUS);
+        }
+        else
+        {
+            setState(NORMAL);
         }
         break;
     }
 
-    if (!eventConsumed && _scroll != SCROLL_NONE && getState() == Control::FOCUS && (evt != Touch::TOUCH_PRESS || withinClipBounds))
+    if (!eventConsumed && _scroll != SCROLL_NONE &&
+        (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)))
@@ -1675,6 +1747,26 @@ Container::Scroll Container::getScroll(const char* scroll)
     return Container::SCROLL_NONE;
 }
 
+float Container::getScrollingFriction() const
+{
+    return _scrollingFriction;
+}
+
+void Container::setScrollingFriction(float friction)
+{
+    _scrollingFriction = friction;
+}
+
+float Container::getScrollWheelSpeed() const
+{
+    return _scrollWheelSpeed;
+}
+
+void Container::setScrollWheelSpeed(float speed)
+{
+    _scrollWheelSpeed = speed;
+}
+
 static bool sortControlsByZOrder(Control* c1, Control* c2)
 {
     if (c1->getZIndex() < c2->getZIndex())

+ 57 - 15
gameplay/src/Container.h

@@ -27,7 +27,10 @@ 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'
          scroll      = <Container::Scroll constant> // Whether scrolling is allowed and in which directions.
-         scrollBarsAutoHide = <bool>    // Whether scrollbars fade out when not in use.
+         scrollBarsAutoHide = <bool>        // Whether scrollbars fade out when not in use.
+         scrollingFriction = <float>        // Friction applied to inertial scrolling.
+         scrollWheelRequiresFocus = <bool>  // Whether focus or hover state handles scroll-wheel events.
+         scrollWheelSpeed = <float>         // Speed to scroll at on a scroll-wheel event.
          consumeEvents = <bool>             // Whether the container propagates input events to the Game's input event handler. Default is true.
 
          // All the nested controls within this container.
@@ -183,6 +186,27 @@ public:
      */
     bool isScrolling() const;
 
+    /**
+     * Get the friction applied to scrolling velocity for this container.
+     */
+    float getScrollingFriction() const;
+
+    /**
+     * Get the friction applied to scrolling velocity for this container.
+     * A higher value will bring the viewport to a stop sooner.
+     */
+    void setScrollingFriction(float friction);
+
+    /**
+     * Get the speed added to scrolling velocity on a scroll-wheel event.
+     */
+    float getScrollWheelSpeed() const;
+
+    /**
+     * Set the speed added to scrolling velocity on a scroll-wheel event.
+     */
+    void setScrollWheelSpeed(float speed);
+
     /**
      * @see AnimationTarget::getAnimation
      */
@@ -198,6 +222,21 @@ public:
      */
     const char* getType() const;
 
+    /**
+     * Get whether this container requires focus in order to handle scroll-wheel events.
+     */
+    bool getScrollWheelRequiresFocus() const;
+
+    /**
+     * Set whether this container requires focus in order to handle scroll-wheel events.
+     * If this property is set to true, scroll-wheel events will only be handled when the container has focus.
+     * If this property is set tofalse, scroll-wheel events will only be handled
+     * when the container is in the HOVER state.
+     *
+     * @param required Whether focus is required in order to handle scroll-wheel events.
+     */
+    void setScrollWheelRequiresFocus(bool required);
+
     /**
      * @see AnimationTarget::getAnimationPropertyComponentCount
      */
@@ -422,7 +461,7 @@ protected:
      */
     Theme::ThemeImage* _scrollBarTopCap;
     /**
-     * Scrollbar vertical image.
+     * Scrollbar vertical track image.
      */
     Theme::ThemeImage* _scrollBarVertical;
     /**
@@ -434,7 +473,7 @@ protected:
      */
     Theme::ThemeImage* _scrollBarLeftCap;
     /**
-     * Scrollbar horizontal image.
+     * Scrollbar horizontal track image.
      */
     Theme::ThemeImage* _scrollBarHorizontal;
     /**
@@ -446,7 +485,7 @@ protected:
      */
     Scroll _scroll;
     /** 
-     * Scroll bar bounds
+     * Scroll bar bounds.
      */
     Rectangle _scrollBarBounds;
     /** 
@@ -454,7 +493,7 @@ protected:
      */
     Vector2 _scrollPosition;
     /** 
-     * Should the scrollbars auto hide. Default is false.
+     * Whether the scrollbars should auto-hide. Default is false.
      */
     bool _scrollBarsAutoHide;
     /** 
@@ -466,11 +505,11 @@ protected:
      */
     bool _scrolling;
     /** 
-     * First scrolling touch x position
+     * First scrolling touch x position.
      */
     int _scrollingVeryFirstX;
     /**
-     * First scrolling touch y position
+     * First scrolling touch y position.
      */
     int _scrollingVeryFirstY;
     /**
@@ -482,33 +521,37 @@ protected:
      */ 
     int _scrollingFirstY;
     /** 
-     * The last y position when scrolling
+     * The last y position when scrolling.
      */ 
     int _scrollingLastX;
     /** 
-     * The last x position when scrolling
+     * The last x position when scrolling.
      */ 
     int _scrollingLastY;
     /** 
-     * Time we started scrolling in the x
+     * Time we started scrolling horizontally.
      */ 
     double _scrollingStartTimeX;
     /** 
-     * Time we started scrolling in the y
+     * Time we started scrolling vertically.
      */ 
     double _scrollingStartTimeY;
     /** 
-     * The last time we were scrolling
+     * The last time we were scrolling.
      */
     double _scrollingLastTime;
     /** 
-     * Speed to continue scrolling at after touch release.
+     * Speed to continue scrolling at after touch release or a scroll-wheel event.
      */ 
     Vector2 _scrollingVelocity;
     /** 
      * Friction dampens velocity.
      */ 
     float _scrollingFriction;
+    /**
+     * Amount to add to scrolling velocity on a scroll-wheel event;
+     */
+    float _scrollWheelSpeed;
     /** 
      * Are we scrolling to the right?
      */ 
@@ -517,12 +560,10 @@ protected:
      * Are we scrolling down?
      */ 
     bool _scrollingDown;
-
     /**
      * Locked to scrolling vertically by grabbing the scrollbar with the mouse.
      */
     bool _scrollingMouseVertically;
-
     /**
      * Locked to scrolling horizontally by grabbing the scrollbar with the mouse.
      */
@@ -574,6 +615,7 @@ private:
     float _totalHeight;
     int _contactIndices;
     bool _initializedWithScroll;
+    bool _scrollWheelRequiresFocus;
 };
 
 }

+ 58 - 2
gameplay/src/Control.cpp

@@ -8,7 +8,7 @@ namespace gameplay
 Control::Control()
     : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
     _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(false), _alignment(ALIGN_TOP_LEFT), _isAlignmentSet(false), _autoWidth(false), _autoHeight(false), _listeners(NULL), _visible(true),
-    _zIndex(-1), _contactIndex(INVALID_CONTACT_INDEX), _focusIndex(-1), _parent(NULL), _styleOverridden(false), _skin(NULL)
+    _zIndex(-1), _contactIndex(INVALID_CONTACT_INDEX), _focusIndex(-1), _parent(NULL), _styleOverridden(false), _skin(NULL), _previousState(NORMAL)
 {
     addScriptEvent("controlEvent", "<Control>[Control::Listener::EventType]");
 }
@@ -115,6 +115,10 @@ void Control::initialize(Theme::Style* style, Properties* properties)
         {
             overrideThemedProperties(innerSpace, DISABLED);
         }
+        else if (spaceName == "STATEHOVER")
+        {
+            overrideThemedProperties(innerSpace, HOVER);
+        }
         else if (spaceName == "MARGIN")
         {
             setMargin(innerSpace->getFloat("top"), innerSpace->getFloat("bottom"),
@@ -271,6 +275,11 @@ bool Control::isVisible() const
     return _visible;
 }
 
+bool Control::isInFocus() const
+{
+    return (_state == FOCUS || (_state == HOVER && _previousState == FOCUS));
+}
+
 void Control::setOpacity(float opacity, unsigned char states)
 {
     overrideStyle();
@@ -653,6 +662,8 @@ Theme::Style::OverlayType Control::getOverlayType() const
         return Theme::Style::OVERLAY_ACTIVE;
     case Control::DISABLED:
         return Theme::Style::OVERLAY_DISABLED;
+    case Control::HOVER:
+        return Theme::Style::OVERLAY_HOVER;
     default:
         return Theme::Style::OVERLAY_NORMAL;
     }
@@ -789,6 +800,9 @@ bool Control::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int conta
         }
         break;
             
+    case Touch::TOUCH_MOVE:
+        break;
+
     case Touch::TOUCH_RELEASE:
         if (_contactIndex == (int)contactIndex)
         {
@@ -830,6 +844,25 @@ bool Control::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
         return touchEvent(Touch::TOUCH_RELEASE, x, y, 0);
 
     case Mouse::MOUSE_MOVE:
+        if (_state != ACTIVE)
+        {
+            if (_state != HOVER &&
+                x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+            {
+                _previousState = _state;
+                setState(HOVER);
+                notifyListeners(Control::Listener::ENTER);
+                return _consumeInputEvents;
+            }
+            else if (_state == HOVER && !(x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                        y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height))
+            {
+                setState(_previousState);
+                notifyListeners(Control::Listener::LEAVE);
+                return _consumeInputEvents;
+            }
+        }
         return touchEvent(Touch::TOUCH_MOVE, x, y, 0);
 
     default:
@@ -1130,6 +1163,10 @@ Control::State Control::getState(const char* state)
     {
         return DISABLED;
     }
+    else if (strcmp(state, "HOVER") == 0)
+    {
+        return HOVER;
+    }
 
     return NORMAL;
 }
@@ -1272,6 +1309,11 @@ Theme::Style::Overlay** Control::getOverlays(unsigned char overlayTypes, Theme::
         overlays[index++] = _style->getOverlay(Theme::Style::OVERLAY_DISABLED);
     }
 
+    if ((overlayTypes & HOVER) == HOVER)
+    {
+        overlays[index++] = _style->getOverlay(Theme::Style::OVERLAY_HOVER);
+    }
+
     return overlays;
 }
 
@@ -1286,9 +1328,23 @@ Theme::Style::Overlay* Control::getOverlay(State state) const
     case Control::FOCUS:
         return _style->getOverlay(Theme::Style::OVERLAY_FOCUS);
     case Control::ACTIVE:
-        return _style->getOverlay(Theme::Style::OVERLAY_ACTIVE);
+    {
+        Theme::Style::Overlay* activeOverlay = _style->getOverlay(Theme::Style::OVERLAY_ACTIVE);
+        if (activeOverlay)
+            return activeOverlay;
+        else
+            return getOverlay(_previousState);
+    }
     case Control::DISABLED:
         return _style->getOverlay(Theme::Style::OVERLAY_DISABLED);
+    case Control::HOVER:
+    {
+        Theme::Style::Overlay* hoverOverlay = _style->getOverlay(Theme::Style::OVERLAY_HOVER);
+        if (hoverOverlay)
+            return hoverOverlay;
+        else
+            return getOverlay(_previousState);
+    }
     default:
         return NULL;
     }

+ 25 - 1
gameplay/src/Control.h

@@ -57,6 +57,11 @@ public:
          * State of a control that has been disabled.
          */
         DISABLED = 0x08,
+
+        /**
+         * When a mouse is in use, the state of a control the cursor is over.
+         */
+        HOVER = 0x10,
     };
 
     /**
@@ -135,6 +140,16 @@ public:
              * Event triggered when a control is clicked with the right mouse button.
              */
             RIGHT_CLICK     = 0x40,
+
+            /**
+             * Event triggered when a mouse cursor enters a control.
+             */
+            ENTER           = 0x80,
+
+            /**
+             * Event triggered when a mouse cursor leaves a control.
+             */
+            LEAVE           = 0x100,
         };
     
         /*
@@ -155,7 +170,7 @@ public:
      * @script{ignore}
      * A constant used for setting themed attributes on all control states simultaneously.
      */
-    static const unsigned char STATE_ALL = NORMAL | FOCUS | ACTIVE | DISABLED;
+    static const unsigned char STATE_ALL = NORMAL | FOCUS | ACTIVE | DISABLED | HOVER;
 
     /**
      * Position animation property. Data = x, y
@@ -615,6 +630,14 @@ public:
      */
     bool isVisible() const;
 
+    /**
+     * Gets whether this control is in focus.
+     * Note that a control's state can be HOVER while the control is in focus.
+     * When the cursor leaves the control, it will return to the FOCUS state.
+     * This method will still return true in this case.
+     */
+    bool isInFocus() const;
+
     /**
      * Set the opacity of this control.
      *
@@ -1095,6 +1118,7 @@ private:
     
     bool _styleOverridden;
     Theme::Skin* _skin;
+    State _previousState;
 };
 
 }

+ 29 - 31
gameplay/src/Form.cpp

@@ -601,6 +601,16 @@ void Form::updateInternal(float elapsedTime)
     }
 }
 
+static bool shouldPropagateTouchEvent(Control::State state, Touch::TouchEvent evt, const Rectangle& bounds, int x, int y)
+{
+    return (state == Control::FOCUS ||
+            (evt == Touch::TOUCH_PRESS &&
+             x >= bounds.x &&
+             x <= bounds.x + bounds.width &&
+             y >= bounds.y &&
+             y <= bounds.y + bounds.height));
+}
+
 bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
 {
     // Check for a collision with each Form in __forms.
@@ -619,12 +629,7 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
                 if (form->projectPoint(x, y, &point))
                 {
                     const Rectangle& bounds = form->getBounds();
-                    if (form->getState() == Control::FOCUS ||
-                        (evt == Touch::TOUCH_PRESS &&
-                         point.x >= bounds.x &&
-                         point.x <= bounds.x + bounds.width &&
-                         point.y >= bounds.y &&
-                         point.y <= bounds.y + bounds.height))
+                    if (shouldPropagateTouchEvent(form->getState(), evt, bounds, point.x, point.y))
                     {
                         if (form->touchEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, contactIndex))
                             return true;
@@ -635,12 +640,7 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
             {
                 // Simply compare with the form's bounds.
                 const Rectangle& bounds = form->getBounds();
-                if (form->getState() == Control::FOCUS ||
-                    (evt == Touch::TOUCH_PRESS &&
-                        x >= bounds.x &&
-                        x <= bounds.x + bounds.width &&
-                        y >= bounds.y &&
-                        y <= bounds.y + bounds.height))
+                if (shouldPropagateTouchEvent(form->getState(), evt, bounds, x, y))
                 {
                     // Pass on the event's position relative to the form.
                     if (form->touchEvent(evt, x - bounds.x, y - bounds.y, contactIndex))
@@ -668,6 +668,20 @@ bool Form::keyEventInternal(Keyboard::KeyEvent evt, int key)
     return false;
 }
 
+static bool shouldPropagateMouseEvent(Control::State state, Mouse::MouseEvent evt, const Rectangle& bounds, int x, int y)
+{
+    return (state != Control::NORMAL ||
+            ((evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
+              evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
+              evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
+              evt == Mouse::MOUSE_MOVE ||
+              evt == Mouse::MOUSE_WHEEL) &&
+                x >= bounds.x &&
+                x <= bounds.x + bounds.width &&
+                y >= bounds.y &&
+                y <= bounds.y + bounds.height));
+}
+
 bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 {
     for (size_t i = 0; i < __forms.size(); ++i)
@@ -683,15 +697,7 @@ bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelt
                 if (form->projectPoint(x, y, &point))
                 {
                     const Rectangle& bounds = form->getBounds();
-                    if (form->getState() == Control::FOCUS ||
-                        ((evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
-                          evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
-                          evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
-                          evt == Mouse::MOUSE_WHEEL) &&
-                         point.x >= bounds.x &&
-                         point.x <= bounds.x + bounds.width &&
-                         point.y >= bounds.y &&
-                         point.y <= bounds.y + bounds.height))
+                    if (shouldPropagateMouseEvent(form->getState(), evt, bounds, point.x, point.y))
                     {
                         if (form->mouseEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, wheelDelta))
                             return true;
@@ -702,15 +708,7 @@ bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelt
             {
                 // Simply compare with the form's bounds.
                 const Rectangle& bounds = form->getBounds();
-                if (form->getState() == Control::FOCUS ||
-                    ((evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
-                      evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
-                      evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
-                      evt == Mouse::MOUSE_WHEEL) &&
-                        x >= bounds.x &&
-                        x <= bounds.x + bounds.width &&
-                        y >= bounds.y &&
-                        y <= bounds.y + bounds.height))
+                if (shouldPropagateMouseEvent(form->getState(), evt, bounds, x, y))
                 {
                     // Pass on the event's position relative to the form.
                     if (form->mouseEvent(evt, x - bounds.x, y - bounds.y, wheelDelta))
@@ -729,7 +727,7 @@ void Form::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, uns
         Form* form = __forms[i];
         GP_ASSERT(form);
 
-        if (form->isEnabled() && form->isVisible() && form->getState() == FOCUS)
+        if (form->isEnabled() && form->isVisible() && form->isInFocus())
         {
             if (form->gamepadEvent(evt, gamepad, analogIndex))
                 return;

+ 1 - 1
gameplay/src/Form.h

@@ -255,7 +255,7 @@ private:
     float _u2;
     float _v1;
     Matrix _projectionMatrix;           // Orthographic projection matrix to be set on SpriteBatch objects when rendering into the FBO.
-    Matrix _defaultProjectionMatrix;   
+    Matrix _defaultProjectionMatrix;
 };
 
 }

+ 2 - 2
gameplay/src/Platform.cpp

@@ -8,9 +8,9 @@
 namespace gameplay
 {
 
-void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse)
 {
-    if (!Form::touchEventInternal(evt, x, y, contactIndex))
+    if (actuallyMouse || !Form::touchEventInternal(evt, x, y, contactIndex))
     {
         Game::getInstance()->touchEvent(evt, x, y, contactIndex);
         Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);

+ 1 - 1
gameplay/src/Platform.h

@@ -281,7 +281,7 @@ public:
      *
      * @script{ignore}
      */
-    static void touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+    static void touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse = false);
 
     /**
      * Internal method used only from static code in various platform implementation.

+ 1 - 1
gameplay/src/PlatformBlackBerry.cpp

@@ -1037,7 +1037,7 @@ void mouseOrTouchEvent(Mouse::MouseEvent mouseEvent, Touch::TouchEvent touchEven
 {
     if (!gameplay::Platform::mouseEventInternal(mouseEvent, x, y, 0))
     {
-        Platform::touchEventInternal(touchEvent, x, y, 0);
+        Platform::touchEventInternal(touchEvent, x, y, 0, true);
     }
 }
 

+ 3 - 3
gameplay/src/PlatformLinux.cpp

@@ -1243,7 +1243,7 @@ namespace gameplay
                             }
                             if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
                             {
-                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0);
+                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0, true);
                             }
                         }
                         break;
@@ -1267,7 +1267,7 @@ namespace gameplay
                             }
                             if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
                             {
-                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0);
+                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0, true);
                             }
                         }
                         break;
@@ -1298,7 +1298,7 @@ namespace gameplay
                             {
                                 if (evt.xmotion.state & Button1Mask)
                                 {
-                                    gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0);
+                                    gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
                                 }
                                 else if (evt.xmotion.state & Button3Mask)
                                 {

+ 3 - 3
gameplay/src/PlatformWindows.cpp

@@ -365,7 +365,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         UpdateCapture(wParam);
         if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON, x, y, 0))
         {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, x, y, 0);
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, x, y, 0, true);
         }
         return 0;
     }
@@ -376,7 +376,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
         if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON, x, y, 0))
         {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, x, y, 0);
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, x, y, 0, true);
         }
         UpdateCapture(wParam);
         return 0;
@@ -429,7 +429,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             if ((wParam & MK_LBUTTON) == MK_LBUTTON)
             {
                 // Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
-                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0);
+                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
                 return 0;
             }
             else if ((wParam & MK_RBUTTON) == MK_RBUTTON)

+ 26 - 11
gameplay/src/Slider.cpp

@@ -144,13 +144,22 @@ bool Slider::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contac
     case Touch::TOUCH_PRESS:
         if (_contactIndex != INVALID_CONTACT_INDEX)
             return false;
-        _state = Control::ACTIVE;
-        _originalX = x;
-        _originalValue = _value;
-        _originalConsumeInputEvents = _consumeInputEvents;
-        _moveCancelled = false;
-        
-        // Fall through to calculate new value.
+        else if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+            y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+        {
+            _state = Control::ACTIVE;
+            _originalX = x;
+            _originalValue = _value;
+            _originalConsumeInputEvents = _consumeInputEvents;
+            _moveCancelled = false;
+            // Fall through to calculate new value.
+        }
+        else
+        {
+            _state = NORMAL;
+            _dirty = true;
+            break;
+        }
     case Touch::TOUCH_MOVE:
     
         if (evt != Touch::TOUCH_PRESS && _contactIndex != (int)contactIndex)
@@ -246,14 +255,14 @@ bool Slider::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
             return touchEvent(Touch::TOUCH_PRESS, x, y, 0);
 
         case Mouse::MOUSE_MOVE:
-            return touchEvent(Touch::TOUCH_MOVE, x, y, 0);
+            return Control::mouseEvent(evt, x, y, 0);
 
         case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
             return touchEvent(Touch::TOUCH_RELEASE, x, y, 0);
 
         case Mouse::MOUSE_WHEEL:
         {
-            if (_state == FOCUS || _state == ACTIVE)
+            if ((isInFocus() && _state == HOVER) || _state == ACTIVE)
             {
                 float total = _max - _min;
                 float oldValue = _value;
@@ -264,13 +273,19 @@ bool Slider::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
                 else if (_value < _min)
                     _value = _min;
 
+                if (_step > 0.0f)
+                {            
+                    int numSteps = round(_value / _step);
+                    _value = _step * numSteps;
+                }
+
                 if (_value != oldValue)
                 {
                     notifyListeners(Control::Listener::VALUE_CHANGED);
                 }
 
                 _dirty = true;
-                return _consumeInputEvents;
+                return true;
             }
             break;
         }
@@ -351,7 +366,7 @@ bool Slider::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned
         {
             _selectButtonDown = false;
 
-            if (_state == FOCUS)
+            if (isInFocus())
                 setState(ACTIVE);
             else if (_state == ACTIVE)
                 setState(FOCUS);

+ 2 - 2
gameplay/src/TextBox.cpp

@@ -105,7 +105,7 @@ bool TextBox::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int conta
 
 bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
 {
-    if (_state == FOCUS)
+    if (isInFocus())
     {
         switch (evt)
         {
@@ -326,7 +326,7 @@ void TextBox::update(const Control* container, const Vector2& offset)
 
 void TextBox::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
-    if (_caretImage && (_state == ACTIVE || _state == FOCUS))
+    if (_caretImage && (_state == ACTIVE || isInFocus()))
     {
         // Draw the cursor at its current location.
         const Rectangle& region = _caretImage->getRegion();

+ 27 - 8
gameplay/src/Theme.cpp

@@ -161,6 +161,7 @@ Theme* Theme::create(const char* url)
             Theme::Style::Overlay* focus = NULL;
             Theme::Style::Overlay* active = NULL;
             Theme::Style::Overlay* disabled = NULL;
+            Theme::Style::Overlay* hover = NULL;
 
             // Need to load OVERLAY_NORMAL first so that the other overlays can inherit from it.
             Properties* innerSpace = space->getNextNamespace();
@@ -387,6 +388,26 @@ Theme* Theme::create(const char* url)
                         disabled->setTextRightToLeft(rightToLeft);
                         disabled->setOpacity(opacity);
 
+                        if (font)
+                        {
+                            theme->_fonts.insert(font);
+                            font->release();
+                        }
+                    }
+                    else if (strcmp(innerSpacename, "stateHover") == 0)
+                    {
+                        hover = Theme::Style::Overlay::create();
+                        GP_ASSERT(hover);
+                        hover->setSkin(skin);
+                        hover->setCursor(cursor);
+                        hover->setImageList(imageList);
+                        hover->setTextColor(textColor);
+                        hover->setFont(font);
+                        hover->setFontSize(fontSize);
+                        hover->setTextAlignment(textAlignment);
+                        hover->setTextRightToLeft(rightToLeft);
+                        hover->setOpacity(opacity);
+
                         if (font)
                         {
                             theme->_fonts.insert(font);
@@ -404,19 +425,16 @@ Theme* Theme::create(const char* url)
                 focus->addRef();
             }
 
-            if (!active)
-            {
-                active = normal;
-                active->addRef();
-            }
-
             if (!disabled)
             {
                 disabled = normal;
                 disabled->addRef();
             }
 
-            Theme::Style* s = new Theme::Style(theme, space->getId(), tw, th, margin, padding, normal, focus, active, disabled);
+            // Note: The hover and active states have their overlay left NULL if unspecified.
+            // Events will still be triggered, but a control's overlay will not be changed.
+
+            Theme::Style* s = new Theme::Style(theme, space->getId(), tw, th, margin, padding, normal, focus, active, disabled, hover);
             GP_ASSERT(s);
             theme->_styles.push_back(s);
         }
@@ -458,8 +476,9 @@ Theme::Style* Theme::getEmptyStyle()
         overlay->addRef();
         overlay->addRef();
         overlay->addRef();
+        overlay->addRef();
         emptyStyle = new Theme::Style(const_cast<Theme*>(this), "EMPTY_STYLE", 1.0f / _texture->getWidth(), 1.0f / _texture->getHeight(),
-            Theme::Margin::empty(), Theme::Border::empty(), overlay, overlay, overlay, overlay);
+            Theme::Margin::empty(), Theme::Border::empty(), overlay, overlay, NULL, overlay, NULL);
 
         _styles.push_back(emptyStyle);
     }

+ 8 - 3
gameplay/src/ThemeStyle.cpp

@@ -8,13 +8,16 @@ namespace gameplay
  ****************/
 Theme::Style::Style(Theme* theme, const char* id, float tw, float th,
         const Theme::Margin& margin, const Theme::Padding& padding,
-        Theme::Style::Overlay* normal, Theme::Style::Overlay* focus, Theme::Style::Overlay* active, Theme::Style::Overlay* disabled)
+        Theme::Style::Overlay* normal, Theme::Style::Overlay* focus,
+        Theme::Style::Overlay* active, Theme::Style::Overlay* disabled,
+        Theme::Style::Overlay* hover)
     : _theme(theme), _id(id), _tw(tw), _th(th), _margin(margin), _padding(padding)
 {
     _overlays[OVERLAY_NORMAL] = normal;
     _overlays[OVERLAY_FOCUS] = focus;
     _overlays[OVERLAY_ACTIVE] = active;
     _overlays[OVERLAY_DISABLED] = disabled;
+    _overlays[OVERLAY_HOVER] = hover;
 }
 
 Theme::Style::Style(const Style& copy)
@@ -27,8 +30,10 @@ Theme::Style::Style(const Style& copy)
 
     for (int i = 0; i < OVERLAY_MAX; i++)
     {
-        GP_ASSERT(copy._overlays[i]);
-        _overlays[i] = new Theme::Style::Overlay(*copy._overlays[i]);
+        if (copy._overlays[i])
+            _overlays[i] = new Theme::Style::Overlay(*copy._overlays[i]);
+        else
+            _overlays[i] = NULL;
     }
 }
 

+ 2 - 1
gameplay/src/ThemeStyle.h

@@ -45,6 +45,7 @@ private:
         OVERLAY_FOCUS,
         OVERLAY_ACTIVE,
         OVERLAY_DISABLED,
+        OVERLAY_HOVER,
         OVERLAY_MAX
     };
 
@@ -179,7 +180,7 @@ private:
      */
     Style(Theme* theme, const char* id, float tw, float th,
           const Theme::Margin& margin, const Theme::Padding& padding,
-          Overlay* normal, Overlay* focus, Overlay* active, Overlay* disabled);
+          Overlay* normal, Overlay* focus, Overlay* active, Overlay* disabled, Overlay* hover);
 
     /**
      * Constructor.

+ 4 - 4
gameplay/src/lua/lua_AnimationClip.cpp

@@ -27,7 +27,7 @@ void luaRegister_AnimationClip()
         {"getAnimation", lua_AnimationClip_getAnimation},
         {"getBlendWeight", lua_AnimationClip_getBlendWeight},
         {"getDuration", lua_AnimationClip_getDuration},
-        {"getElaspedTime", lua_AnimationClip_getElaspedTime},
+        {"getElapsedTime", lua_AnimationClip_getElapsedTime},
         {"getEndTime", lua_AnimationClip_getEndTime},
         {"getId", lua_AnimationClip_getId},
         {"getLoopBlendTime", lua_AnimationClip_getLoopBlendTime},
@@ -508,7 +508,7 @@ int lua_AnimationClip_getDuration(lua_State* state)
     return 0;
 }
 
-int lua_AnimationClip_getElaspedTime(lua_State* state)
+int lua_AnimationClip_getElapsedTime(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -521,7 +521,7 @@ int lua_AnimationClip_getElaspedTime(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 AnimationClip* instance = getInstance(state);
-                float result = instance->getElaspedTime();
+                float result = instance->getElapsedTime();
 
                 // Push the return value onto the stack.
                 lua_pushnumber(state, result);
@@ -529,7 +529,7 @@ int lua_AnimationClip_getElaspedTime(lua_State* state)
                 return 1;
             }
 
-            lua_pushstring(state, "lua_AnimationClip_getElaspedTime - Failed to match the given parameters to a valid function signature.");
+            lua_pushstring(state, "lua_AnimationClip_getElapsedTime - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             break;
         }

+ 1 - 1
gameplay/src/lua/lua_AnimationClip.h

@@ -15,7 +15,7 @@ int lua_AnimationClip_getActiveDuration(lua_State* state);
 int lua_AnimationClip_getAnimation(lua_State* state);
 int lua_AnimationClip_getBlendWeight(lua_State* state);
 int lua_AnimationClip_getDuration(lua_State* state);
-int lua_AnimationClip_getElaspedTime(lua_State* state);
+int lua_AnimationClip_getElapsedTime(lua_State* state);
 int lua_AnimationClip_getEndTime(lua_State* state);
 int lua_AnimationClip_getId(lua_State* state);
 int lua_AnimationClip_getLoopBlendTime(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_Button.cpp

@@ -74,6 +74,7 @@ void luaRegister_Button()
         {"getZIndex", lua_Button_getZIndex},
         {"isContainer", lua_Button_isContainer},
         {"isEnabled", lua_Button_isEnabled},
+        {"isInFocus", lua_Button_isInFocus},
         {"isVisible", lua_Button_isVisible},
         {"release", lua_Button_release},
         {"removeListener", lua_Button_removeListener},
@@ -2602,6 +2603,41 @@ int lua_Button_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Button_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Button* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Button_isVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_Button.h

@@ -54,6 +54,7 @@ int lua_Button_getY(lua_State* state);
 int lua_Button_getZIndex(lua_State* state);
 int lua_Button_isContainer(lua_State* state);
 int lua_Button_isEnabled(lua_State* state);
+int lua_Button_isInFocus(lua_State* state);
 int lua_Button_isVisible(lua_State* state);
 int lua_Button_release(lua_State* state);
 int lua_Button_removeListener(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_CheckBox.cpp

@@ -78,6 +78,7 @@ void luaRegister_CheckBox()
         {"isChecked", lua_CheckBox_isChecked},
         {"isContainer", lua_CheckBox_isContainer},
         {"isEnabled", lua_CheckBox_isEnabled},
+        {"isInFocus", lua_CheckBox_isInFocus},
         {"isVisible", lua_CheckBox_isVisible},
         {"release", lua_CheckBox_release},
         {"removeListener", lua_CheckBox_removeListener},
@@ -2722,6 +2723,41 @@ int lua_CheckBox_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_CheckBox_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                CheckBox* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_CheckBox_isVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_CheckBox.h

@@ -57,6 +57,7 @@ int lua_CheckBox_getZIndex(lua_State* state);
 int lua_CheckBox_isChecked(lua_State* state);
 int lua_CheckBox_isContainer(lua_State* state);
 int lua_CheckBox_isEnabled(lua_State* state);
+int lua_CheckBox_isInFocus(lua_State* state);
 int lua_CheckBox_isVisible(lua_State* state);
 int lua_CheckBox_release(lua_State* state);
 int lua_CheckBox_removeListener(lua_State* state);

+ 255 - 0
gameplay/src/lua/lua_Container.cpp

@@ -76,6 +76,9 @@ void luaRegister_Container()
         {"getPadding", lua_Container_getPadding},
         {"getRefCount", lua_Container_getRefCount},
         {"getScroll", lua_Container_getScroll},
+        {"getScrollWheelRequiresFocus", lua_Container_getScrollWheelRequiresFocus},
+        {"getScrollWheelSpeed", lua_Container_getScrollWheelSpeed},
+        {"getScrollingFriction", lua_Container_getScrollingFriction},
         {"getSkinColor", lua_Container_getSkinColor},
         {"getSkinRegion", lua_Container_getSkinRegion},
         {"getState", lua_Container_getState},
@@ -91,6 +94,7 @@ void luaRegister_Container()
         {"insertControl", lua_Container_insertControl},
         {"isContainer", lua_Container_isContainer},
         {"isEnabled", lua_Container_isEnabled},
+        {"isInFocus", lua_Container_isInFocus},
         {"isScrollBarsAutoHide", lua_Container_isScrollBarsAutoHide},
         {"isScrolling", lua_Container_isScrolling},
         {"isVisible", lua_Container_isVisible},
@@ -120,6 +124,9 @@ void luaRegister_Container()
         {"setPosition", lua_Container_setPosition},
         {"setScroll", lua_Container_setScroll},
         {"setScrollBarsAutoHide", lua_Container_setScrollBarsAutoHide},
+        {"setScrollWheelRequiresFocus", lua_Container_setScrollWheelRequiresFocus},
+        {"setScrollWheelSpeed", lua_Container_setScrollWheelSpeed},
+        {"setScrollingFriction", lua_Container_setScrollingFriction},
         {"setSize", lua_Container_setSize},
         {"setSkinColor", lua_Container_setSkinColor},
         {"setSkinRegion", lua_Container_setSkinRegion},
@@ -2168,6 +2175,111 @@ int lua_Container_getScroll(lua_State* state)
     return 0;
 }
 
+int lua_Container_getScrollWheelRequiresFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                bool result = instance->getScrollWheelRequiresFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_getScrollWheelRequiresFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_getScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                float result = instance->getScrollWheelSpeed();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_getScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_getScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                float result = instance->getScrollingFriction();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_getScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_getSkinColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -2872,6 +2984,41 @@ int lua_Container_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Container_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_isScrollBarsAutoHide(lua_State* state)
 {
     // Get the number of parameters.
@@ -4259,6 +4406,114 @@ int lua_Container_setScrollBarsAutoHide(lua_State* state)
     return 0;
 }
 
+int lua_Container_setScrollWheelRequiresFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setScrollWheelRequiresFocus(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setScrollWheelRequiresFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_setScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setScrollWheelSpeed(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_setScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setScrollingFriction(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_setSize(lua_State* state)
 {
     // Get the number of parameters.

+ 7 - 0
gameplay/src/lua/lua_Container.h

@@ -44,6 +44,9 @@ int lua_Container_getOpacity(lua_State* state);
 int lua_Container_getPadding(lua_State* state);
 int lua_Container_getRefCount(lua_State* state);
 int lua_Container_getScroll(lua_State* state);
+int lua_Container_getScrollWheelRequiresFocus(lua_State* state);
+int lua_Container_getScrollWheelSpeed(lua_State* state);
+int lua_Container_getScrollingFriction(lua_State* state);
 int lua_Container_getSkinColor(lua_State* state);
 int lua_Container_getSkinRegion(lua_State* state);
 int lua_Container_getState(lua_State* state);
@@ -59,6 +62,7 @@ int lua_Container_getZIndex(lua_State* state);
 int lua_Container_insertControl(lua_State* state);
 int lua_Container_isContainer(lua_State* state);
 int lua_Container_isEnabled(lua_State* state);
+int lua_Container_isInFocus(lua_State* state);
 int lua_Container_isScrollBarsAutoHide(lua_State* state);
 int lua_Container_isScrolling(lua_State* state);
 int lua_Container_isVisible(lua_State* state);
@@ -88,6 +92,9 @@ int lua_Container_setPadding(lua_State* state);
 int lua_Container_setPosition(lua_State* state);
 int lua_Container_setScroll(lua_State* state);
 int lua_Container_setScrollBarsAutoHide(lua_State* state);
+int lua_Container_setScrollWheelRequiresFocus(lua_State* state);
+int lua_Container_setScrollWheelSpeed(lua_State* state);
+int lua_Container_setScrollingFriction(lua_State* state);
 int lua_Container_setSize(lua_State* state);
 int lua_Container_setSkinColor(lua_State* state);
 int lua_Container_setSkinRegion(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_Control.cpp

@@ -71,6 +71,7 @@ void luaRegister_Control()
         {"getZIndex", lua_Control_getZIndex},
         {"isContainer", lua_Control_isContainer},
         {"isEnabled", lua_Control_isEnabled},
+        {"isInFocus", lua_Control_isInFocus},
         {"isVisible", lua_Control_isVisible},
         {"release", lua_Control_release},
         {"removeListener", lua_Control_removeListener},
@@ -2597,6 +2598,41 @@ int lua_Control_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Control_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Control* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Control_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Control_isVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_Control.h

@@ -54,6 +54,7 @@ int lua_Control_getY(lua_State* state);
 int lua_Control_getZIndex(lua_State* state);
 int lua_Control_isContainer(lua_State* state);
 int lua_Control_isEnabled(lua_State* state);
+int lua_Control_isInFocus(lua_State* state);
 int lua_Control_isVisible(lua_State* state);
 int lua_Control_release(lua_State* state);
 int lua_Control_removeListener(lua_State* state);

+ 12 - 0
gameplay/src/lua/lua_ControlListenerEventType.cpp

@@ -13,6 +13,8 @@ static const char* luaEnumString_ControlListenerEventType_VALUE_CHANGED = "VALUE
 static const char* luaEnumString_ControlListenerEventType_TEXT_CHANGED = "TEXT_CHANGED";
 static const char* luaEnumString_ControlListenerEventType_MIDDLE_CLICK = "MIDDLE_CLICK";
 static const char* luaEnumString_ControlListenerEventType_RIGHT_CLICK = "RIGHT_CLICK";
+static const char* luaEnumString_ControlListenerEventType_ENTER = "ENTER";
+static const char* luaEnumString_ControlListenerEventType_LEAVE = "LEAVE";
 
 Control::Listener::EventType lua_enumFromString_ControlListenerEventType(const char* s)
 {
@@ -30,6 +32,11 @@ Control::Listener::EventType lua_enumFromString_ControlListenerEventType(const c
         return Control::Listener::MIDDLE_CLICK;
     if (strcmp(s, luaEnumString_ControlListenerEventType_RIGHT_CLICK) == 0)
         return Control::Listener::RIGHT_CLICK;
+    if (strcmp(s, luaEnumString_ControlListenerEventType_ENTER) == 0)
+        return Control::Listener::ENTER;
+    if (strcmp(s, luaEnumString_ControlListenerEventType_LEAVE) == 0)
+        return Control::Listener::LEAVE;
+    GP_ERROR("Invalid enumeration value '%s' for enumeration Control::Listener::EventType.", s);
     return Control::Listener::PRESS;
 }
 
@@ -49,6 +56,11 @@ const char* lua_stringFromEnum_ControlListenerEventType(Control::Listener::Event
         return luaEnumString_ControlListenerEventType_MIDDLE_CLICK;
     if (e == Control::Listener::RIGHT_CLICK)
         return luaEnumString_ControlListenerEventType_RIGHT_CLICK;
+    if (e == Control::Listener::ENTER)
+        return luaEnumString_ControlListenerEventType_ENTER;
+    if (e == Control::Listener::LEAVE)
+        return luaEnumString_ControlListenerEventType_LEAVE;
+    GP_ERROR("Invalid enumeration value '%d' for enumeration Control::Listener::EventType.", e);
     return enumStringEmpty;
 }
 

+ 7 - 0
gameplay/src/lua/lua_ControlState.cpp

@@ -10,6 +10,7 @@ static const char* luaEnumString_ControlState_NORMAL = "NORMAL";
 static const char* luaEnumString_ControlState_FOCUS = "FOCUS";
 static const char* luaEnumString_ControlState_ACTIVE = "ACTIVE";
 static const char* luaEnumString_ControlState_DISABLED = "DISABLED";
+static const char* luaEnumString_ControlState_HOVER = "HOVER";
 
 Control::State lua_enumFromString_ControlState(const char* s)
 {
@@ -21,6 +22,9 @@ Control::State lua_enumFromString_ControlState(const char* s)
         return Control::ACTIVE;
     if (strcmp(s, luaEnumString_ControlState_DISABLED) == 0)
         return Control::DISABLED;
+    if (strcmp(s, luaEnumString_ControlState_HOVER) == 0)
+        return Control::HOVER;
+    GP_ERROR("Invalid enumeration value '%s' for enumeration Control::State.", s);
     return Control::NORMAL;
 }
 
@@ -34,6 +38,9 @@ const char* lua_stringFromEnum_ControlState(Control::State e)
         return luaEnumString_ControlState_ACTIVE;
     if (e == Control::DISABLED)
         return luaEnumString_ControlState_DISABLED;
+    if (e == Control::HOVER)
+        return luaEnumString_ControlState_HOVER;
+    GP_ERROR("Invalid enumeration value '%d' for enumeration Control::State.", e);
     return enumStringEmpty;
 }
 

+ 255 - 0
gameplay/src/lua/lua_Form.cpp

@@ -80,6 +80,9 @@ void luaRegister_Form()
         {"getPadding", lua_Form_getPadding},
         {"getRefCount", lua_Form_getRefCount},
         {"getScroll", lua_Form_getScroll},
+        {"getScrollWheelRequiresFocus", lua_Form_getScrollWheelRequiresFocus},
+        {"getScrollWheelSpeed", lua_Form_getScrollWheelSpeed},
+        {"getScrollingFriction", lua_Form_getScrollingFriction},
         {"getSkinColor", lua_Form_getSkinColor},
         {"getSkinRegion", lua_Form_getSkinRegion},
         {"getState", lua_Form_getState},
@@ -96,6 +99,7 @@ void luaRegister_Form()
         {"insertControl", lua_Form_insertControl},
         {"isContainer", lua_Form_isContainer},
         {"isEnabled", lua_Form_isEnabled},
+        {"isInFocus", lua_Form_isInFocus},
         {"isScrollBarsAutoHide", lua_Form_isScrollBarsAutoHide},
         {"isScrolling", lua_Form_isScrolling},
         {"isVisible", lua_Form_isVisible},
@@ -126,6 +130,9 @@ void luaRegister_Form()
         {"setPosition", lua_Form_setPosition},
         {"setScroll", lua_Form_setScroll},
         {"setScrollBarsAutoHide", lua_Form_setScrollBarsAutoHide},
+        {"setScrollWheelRequiresFocus", lua_Form_setScrollWheelRequiresFocus},
+        {"setScrollWheelSpeed", lua_Form_setScrollWheelSpeed},
+        {"setScrollingFriction", lua_Form_setScrollingFriction},
         {"setSize", lua_Form_setSize},
         {"setSkinColor", lua_Form_setSkinColor},
         {"setSkinRegion", lua_Form_setSkinRegion},
@@ -2208,6 +2215,111 @@ int lua_Form_getScroll(lua_State* state)
     return 0;
 }
 
+int lua_Form_getScrollWheelRequiresFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                bool result = instance->getScrollWheelRequiresFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_getScrollWheelRequiresFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_getScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                float result = instance->getScrollWheelSpeed();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_getScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_getScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                float result = instance->getScrollingFriction();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_getScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_getSkinColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -2956,6 +3068,41 @@ int lua_Form_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Form_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_isScrollBarsAutoHide(lua_State* state)
 {
     // Get the number of parameters.
@@ -4385,6 +4532,114 @@ int lua_Form_setScrollBarsAutoHide(lua_State* state)
     return 0;
 }
 
+int lua_Form_setScrollWheelRequiresFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setScrollWheelRequiresFocus(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setScrollWheelRequiresFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_setScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setScrollWheelSpeed(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_setScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setScrollingFriction(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_setSize(lua_State* state)
 {
     // Get the number of parameters.

+ 7 - 0
gameplay/src/lua/lua_Form.h

@@ -45,6 +45,9 @@ int lua_Form_getOpacity(lua_State* state);
 int lua_Form_getPadding(lua_State* state);
 int lua_Form_getRefCount(lua_State* state);
 int lua_Form_getScroll(lua_State* state);
+int lua_Form_getScrollWheelRequiresFocus(lua_State* state);
+int lua_Form_getScrollWheelSpeed(lua_State* state);
+int lua_Form_getScrollingFriction(lua_State* state);
 int lua_Form_getSkinColor(lua_State* state);
 int lua_Form_getSkinRegion(lua_State* state);
 int lua_Form_getState(lua_State* state);
@@ -61,6 +64,7 @@ int lua_Form_getZIndex(lua_State* state);
 int lua_Form_insertControl(lua_State* state);
 int lua_Form_isContainer(lua_State* state);
 int lua_Form_isEnabled(lua_State* state);
+int lua_Form_isInFocus(lua_State* state);
 int lua_Form_isScrollBarsAutoHide(lua_State* state);
 int lua_Form_isScrolling(lua_State* state);
 int lua_Form_isVisible(lua_State* state);
@@ -91,6 +95,9 @@ int lua_Form_setPadding(lua_State* state);
 int lua_Form_setPosition(lua_State* state);
 int lua_Form_setScroll(lua_State* state);
 int lua_Form_setScrollBarsAutoHide(lua_State* state);
+int lua_Form_setScrollWheelRequiresFocus(lua_State* state);
+int lua_Form_setScrollWheelSpeed(lua_State* state);
+int lua_Form_setScrollingFriction(lua_State* state);
 int lua_Form_setSize(lua_State* state);
 int lua_Form_setSkinColor(lua_State* state);
 int lua_Form_setSkinRegion(lua_State* state);

+ 3 - 0
gameplay/src/lua/lua_Global.cpp

@@ -225,6 +225,8 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerConstantString("TEXT_CHANGED", "TEXT_CHANGED", scopePath);
         gameplay::ScriptUtil::registerConstantString("MIDDLE_CLICK", "MIDDLE_CLICK", scopePath);
         gameplay::ScriptUtil::registerConstantString("RIGHT_CLICK", "RIGHT_CLICK", scopePath);
+        gameplay::ScriptUtil::registerConstantString("ENTER", "ENTER", scopePath);
+        gameplay::ScriptUtil::registerConstantString("LEAVE", "LEAVE", scopePath);
     }
 
     // Register enumeration Control::State.
@@ -235,6 +237,7 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerConstantString("FOCUS", "FOCUS", scopePath);
         gameplay::ScriptUtil::registerConstantString("ACTIVE", "ACTIVE", scopePath);
         gameplay::ScriptUtil::registerConstantString("DISABLED", "DISABLED", scopePath);
+        gameplay::ScriptUtil::registerConstantString("HOVER", "HOVER", scopePath);
     }
 
     // Register enumeration Curve::InterpolationType.

+ 36 - 0
gameplay/src/lua/lua_ImageControl.cpp

@@ -78,6 +78,7 @@ void luaRegister_ImageControl()
         {"getZIndex", lua_ImageControl_getZIndex},
         {"isContainer", lua_ImageControl_isContainer},
         {"isEnabled", lua_ImageControl_isEnabled},
+        {"isInFocus", lua_ImageControl_isInFocus},
         {"isVisible", lua_ImageControl_isVisible},
         {"release", lua_ImageControl_release},
         {"removeListener", lua_ImageControl_removeListener},
@@ -2732,6 +2733,41 @@ int lua_ImageControl_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_ImageControl_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                ImageControl* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_ImageControl_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_ImageControl_isVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_ImageControl.h

@@ -57,6 +57,7 @@ int lua_ImageControl_getY(lua_State* state);
 int lua_ImageControl_getZIndex(lua_State* state);
 int lua_ImageControl_isContainer(lua_State* state);
 int lua_ImageControl_isEnabled(lua_State* state);
+int lua_ImageControl_isInFocus(lua_State* state);
 int lua_ImageControl_isVisible(lua_State* state);
 int lua_ImageControl_release(lua_State* state);
 int lua_ImageControl_removeListener(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_Joystick.cpp

@@ -76,6 +76,7 @@ void luaRegister_Joystick()
         {"getZIndex", lua_Joystick_getZIndex},
         {"isContainer", lua_Joystick_isContainer},
         {"isEnabled", lua_Joystick_isEnabled},
+        {"isInFocus", lua_Joystick_isInFocus},
         {"isRelative", lua_Joystick_isRelative},
         {"isVisible", lua_Joystick_isVisible},
         {"release", lua_Joystick_release},
@@ -2774,6 +2775,41 @@ int lua_Joystick_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Joystick_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Joystick* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Joystick_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Joystick_isRelative(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_Joystick.h

@@ -58,6 +58,7 @@ int lua_Joystick_getY(lua_State* state);
 int lua_Joystick_getZIndex(lua_State* state);
 int lua_Joystick_isContainer(lua_State* state);
 int lua_Joystick_isEnabled(lua_State* state);
+int lua_Joystick_isInFocus(lua_State* state);
 int lua_Joystick_isRelative(lua_State* state);
 int lua_Joystick_isVisible(lua_State* state);
 int lua_Joystick_release(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_Label.cpp

@@ -73,6 +73,7 @@ void luaRegister_Label()
         {"getZIndex", lua_Label_getZIndex},
         {"isContainer", lua_Label_isContainer},
         {"isEnabled", lua_Label_isEnabled},
+        {"isInFocus", lua_Label_isInFocus},
         {"isVisible", lua_Label_isVisible},
         {"release", lua_Label_release},
         {"removeListener", lua_Label_removeListener},
@@ -2636,6 +2637,41 @@ int lua_Label_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Label_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Label* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Label_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Label_isVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_Label.h

@@ -55,6 +55,7 @@ int lua_Label_getY(lua_State* state);
 int lua_Label_getZIndex(lua_State* state);
 int lua_Label_isContainer(lua_State* state);
 int lua_Label_isEnabled(lua_State* state);
+int lua_Label_isInFocus(lua_State* state);
 int lua_Label_isVisible(lua_State* state);
 int lua_Label_release(lua_State* state);
 int lua_Label_removeListener(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_RadioButton.cpp

@@ -78,6 +78,7 @@ void luaRegister_RadioButton()
         {"getZIndex", lua_RadioButton_getZIndex},
         {"isContainer", lua_RadioButton_isContainer},
         {"isEnabled", lua_RadioButton_isEnabled},
+        {"isInFocus", lua_RadioButton_isInFocus},
         {"isSelected", lua_RadioButton_isSelected},
         {"isVisible", lua_RadioButton_isVisible},
         {"release", lua_RadioButton_release},
@@ -2724,6 +2725,41 @@ int lua_RadioButton_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_RadioButton_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                RadioButton* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_RadioButton_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_RadioButton_isSelected(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_RadioButton.h

@@ -57,6 +57,7 @@ int lua_RadioButton_getY(lua_State* state);
 int lua_RadioButton_getZIndex(lua_State* state);
 int lua_RadioButton_isContainer(lua_State* state);
 int lua_RadioButton_isEnabled(lua_State* state);
+int lua_RadioButton_isInFocus(lua_State* state);
 int lua_RadioButton_isSelected(lua_State* state);
 int lua_RadioButton_isVisible(lua_State* state);
 int lua_RadioButton_release(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_Slider.cpp

@@ -80,6 +80,7 @@ void luaRegister_Slider()
         {"getZIndex", lua_Slider_getZIndex},
         {"isContainer", lua_Slider_isContainer},
         {"isEnabled", lua_Slider_isEnabled},
+        {"isInFocus", lua_Slider_isInFocus},
         {"isValueTextVisible", lua_Slider_isValueTextVisible},
         {"isVisible", lua_Slider_isVisible},
         {"release", lua_Slider_release},
@@ -2861,6 +2862,41 @@ int lua_Slider_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Slider_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Slider* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Slider_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Slider_isValueTextVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_Slider.h

@@ -61,6 +61,7 @@ int lua_Slider_getY(lua_State* state);
 int lua_Slider_getZIndex(lua_State* state);
 int lua_Slider_isContainer(lua_State* state);
 int lua_Slider_isEnabled(lua_State* state);
+int lua_Slider_isInFocus(lua_State* state);
 int lua_Slider_isValueTextVisible(lua_State* state);
 int lua_Slider_isVisible(lua_State* state);
 int lua_Slider_release(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_TextBox.cpp

@@ -75,6 +75,7 @@ void luaRegister_TextBox()
         {"getZIndex", lua_TextBox_getZIndex},
         {"isContainer", lua_TextBox_isContainer},
         {"isEnabled", lua_TextBox_isEnabled},
+        {"isInFocus", lua_TextBox_isInFocus},
         {"isVisible", lua_TextBox_isVisible},
         {"release", lua_TextBox_release},
         {"removeListener", lua_TextBox_removeListener},
@@ -2673,6 +2674,41 @@ int lua_TextBox_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_TextBox_isInFocus(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                TextBox* instance = getInstance(state);
+                bool result = instance->isInFocus();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_TextBox_isInFocus - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_TextBox_isVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_TextBox.h

@@ -56,6 +56,7 @@ int lua_TextBox_getY(lua_State* state);
 int lua_TextBox_getZIndex(lua_State* state);
 int lua_TextBox_isContainer(lua_State* state);
 int lua_TextBox_isEnabled(lua_State* state);
+int lua_TextBox_isInFocus(lua_State* state);
 int lua_TextBox_isVisible(lua_State* state);
 int lua_TextBox_release(lua_State* state);
 int lua_TextBox_removeListener(lua_State* state);

+ 1 - 1
samples/browser/CMakeLists.txt

@@ -53,7 +53,7 @@ set(GAME_SRC
     src/BillboardSample.cpp
     src/BillboardSample.h
     src/CreateSceneSample.cpp
-    src/CreateSceneSample.h	
+    src/CreateSceneSample.h    
     src/CreateSceneSample.h
     src/FirstPersonCamera.cpp
     src/FirstPersonCamera.h

+ 21 - 9
samples/browser/res/common/default.theme

@@ -231,10 +231,10 @@ theme mainMenu
             textAlignment = ALIGN_TOP_LEFT
         }
     }
-
-    style basic
-    {
-        stateNormal
+	
+	style basicContainer
+	{
+		stateNormal
         {
             skin = mainNormal
             imageList = normalImages
@@ -244,22 +244,26 @@ theme mainMenu
             fontSize = 18
             textAlignment = ALIGN_VCENTER_HCENTER
         }
-		
-        stateActive
-        {
-            imageList = activeImages
-        }
 
 		stateFocus
 		{
 			skin = mainFocus
 			imageList = focusImages
+			textColor = #aaa000ff
 		}
 		
 		stateDisabled
 		{
 			opacity = 0.6
 		}
+	}
+
+    style basic : basicContainer
+    {
+        stateActive
+        {
+            imageList = activeImages
+        }
     }
 
     style topLeftAlignedEntry : basic
@@ -295,6 +299,14 @@ theme mainMenu
             skin = mainActive
         }
     }
+	
+	style buttonHover : buttonStyle
+	{
+		stateHover
+		{
+			textColor = #ff0000ff
+		}
+	}
 
     style noBorder
     {

+ 3 - 3
samples/browser/res/common/forms/formBasicControls.form

@@ -2,7 +2,7 @@ form basicControls
 {
     theme = res/common/default.theme
     layout = LAYOUT_ABSOLUTE
-    style = basic
+    style = basicContainer
     size = 600, 600
 	consumeInputEvents = true
     	
@@ -16,10 +16,10 @@ form basicControls
 		
 	button testButton
 	{
-		style = buttonStyle
+		style = buttonHover
 		position = 20, 80
 		size = 200, 100
-		text = This is a button.
+		text = This is a button with a hover state.
 	}
 
 	checkbox testCheckbox

+ 1 - 1
samples/browser/res/common/forms/formFlowLayout.form

@@ -2,7 +2,7 @@ form flowLayout
 {
     theme = res/common/default.theme
     layout = LAYOUT_FLOW
-    style = basic
+    style = basicContainer
     size = 600, 600
     scroll = SCROLL_BOTH
 	consumeInputEvents = true

+ 1 - 1
samples/browser/res/common/forms/formScrolling.form

@@ -2,7 +2,7 @@ form scrolling
 {
     theme = res/common/default.theme
     layout = LAYOUT_VERTICAL
-    style = basic
+    style = basicContainer
     size = 600, 600
     scroll = SCROLL_BOTH
     scrollBarsAutoHide = true

+ 1 - 1
samples/browser/res/common/forms/formSelect.form

@@ -2,7 +2,7 @@ form formSelect
 {
     theme = res/common/default.theme
     layout = LAYOUT_VERTICAL
-    style = basic
+    style = basicContainer
     alignment = ALIGN_TOP_LEFT
     width = 200
     autoHeight = true

+ 1 - 1
samples/browser/res/common/forms/formVerticalLayout.form

@@ -2,7 +2,7 @@ form verticalLayout
 {
     theme = res/common/default.theme
     layout = LAYOUT_VERTICAL
-    style = basic
+    style = basicContainer
     size = 600, 600
     scroll = SCROLL_BOTH
 	consumeInputEvents = true

+ 1 - 1
samples/browser/res/common/forms/formZOrder.form

@@ -1,7 +1,7 @@
 form zOrder
 {
     theme = res/common/default.theme
-    style = basic
+    style = basicContainer
     size = 600, 600
     scroll = SCROLL_BOTH
 	consumeInputEvents = true

+ 1 - 0
samples/browser/res/common/text.form

@@ -6,6 +6,7 @@ form textTest
     width = 240
     layout = LAYOUT_VERTICAL
     scroll = SCROLL_VERTICAL
+	consumeInputEvents = true
 
     label topLabel
     {

+ 1 - 1
samples/browser/src/FormsSample.cpp

@@ -158,7 +158,7 @@ void FormsSample::formChanged()
 
 void FormsSample::createSampleForm(Theme* theme)
 {
-    Form* form = Form::create("testForm", theme->getStyle("buttonStyle"));
+    Form* form = Form::create("testForm", theme->getStyle("basicContainer"));
     form->setSize(600, 600);
 
     Label* label = Label::create("testLabel", theme->getStyle("iconNoBorder"));

+ 1 - 1
samples/browser/src/Sample.cpp

@@ -227,7 +227,7 @@ void Sample::gestureTapEvent(int x, int y)
 {
 }
 
-void Sample::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+void Sample::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
 {
 }
 

+ 1 - 1
samples/browser/src/Sample.h

@@ -70,7 +70,7 @@ public:
     virtual void gestureSwipeEvent(int x, int y, int direction);
     virtual void gesturePinchEvent(int x, int y, float scale);
     virtual void gestureTapEvent(int x, int y);
-    virtual void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex = 0);
+    virtual void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad);
     unsigned int getGamepadCount() const;
     Gamepad* getGamepad(unsigned int index, bool preferPhysical = true) const;
 

+ 10 - 1
samples/browser/src/SamplesGame.cpp

@@ -28,7 +28,7 @@ void SamplesGame::initialize()
 
     // Construct a form for selecting which sample to run.
     Theme* theme = Theme::create("res/common/default.theme");
-    Theme::Style* formStyle = theme->getStyle("basic");
+    Theme::Style* formStyle = theme->getStyle("basicContainer");
     Theme::Style* buttonStyle = theme->getStyle("buttonStyle");
     Theme::Style* titleStyle = theme->getStyle("title");
 
@@ -39,6 +39,7 @@ void SamplesGame::initialize()
     _sampleSelectForm->setAutoHeight(true);
     _sampleSelectForm->setWidth(200.0f);
     _sampleSelectForm->setScroll(Container::SCROLL_VERTICAL);
+    _sampleSelectForm->setConsumeInputEvents(true);
 
     const size_t size = _samples->size();
     for (size_t i = 0; i < size; ++i)
@@ -97,6 +98,13 @@ void SamplesGame::update(float elapsedTime)
 {
     if (_activeSample)
     {
+        Gamepad* gamepad = getGamepad(0);
+        if (gamepad && gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
+        {
+            exitActiveSample();
+            return;
+        }
+
         getScriptController()->executeFunction<void>("camera_update", "f", elapsedTime);
         _activeSample->update(elapsedTime);
         return;
@@ -249,6 +257,7 @@ void SamplesGame::exitActiveSample()
         SAFE_DELETE(_activeSample);
 
         _sampleSelectForm->setEnabled(true);
+        _sampleSelectForm->setState(Control::FOCUS);
     }
 
     // Reset some game options

+ 2 - 2
samples/character/CMakeLists.txt

@@ -1,8 +1,8 @@
 set(GAME_NAME sample-character)
 
 set(GAME_SRC
-	src/CharacterGame.cpp
-	src/CharacterGame.h
+    src/CharacterGame.cpp
+    src/CharacterGame.h
 )
 
 add_executable(${GAME_NAME}

+ 2 - 2
samples/longboard/CMakeLists.txt

@@ -1,8 +1,8 @@
 set( GAME_NAME sample-longboard )
 
 set(GAME_SRC
-	src/LongboardGame.cpp
-	src/LongboardGame.h
+    src/LongboardGame.cpp
+    src/LongboardGame.h
 )
 
 add_executable(${GAME_NAME}

+ 2 - 2
samples/lua/CMakeLists.txt

@@ -1,8 +1,8 @@
 set(GAME_NAME sample-lua)
 
 set(GAME_SRC
-	src/LuaGame.cpp
-	src/LuaGame.h
+    src/LuaGame.cpp
+    src/LuaGame.h
 )
 
 add_executable(${GAME_NAME}

+ 2 - 2
samples/mesh/CMakeLists.txt

@@ -1,8 +1,8 @@
 set( GAME_NAME sample-mesh )
 
 set(GAME_SRC
-	src/MeshGame.cpp
-	src/MeshGame.h
+    src/MeshGame.cpp
+    src/MeshGame.h
 )
 
 add_executable(${GAME_NAME}

+ 2 - 2
samples/particles/CMakeLists.txt

@@ -1,8 +1,8 @@
 set(GAME_NAME sample-particles)
 
 set(GAME_SRC
-	src/ParticlesGame.cpp
-	src/ParticlesGame.h
+    src/ParticlesGame.cpp
+    src/ParticlesGame.h
 )
 
 add_executable(${GAME_NAME}

+ 2 - 2
samples/racer/CMakeLists.txt

@@ -1,8 +1,8 @@
 set(GAME_NAME sample-racer)
 
 set(GAME_SRC
-	src/RacerGame.cpp
-	src/RacerGame.h
+    src/RacerGame.cpp
+    src/RacerGame.h
 )
 
 add_executable(${GAME_NAME}

+ 2 - 2
samples/spaceship/CMakeLists.txt

@@ -1,8 +1,8 @@
 set(GAME_NAME sample-spaceship)
 
 set(GAME_SRC
-	src/SpaceshipGame.cpp
-	src/SpaceshipGame.h
+    src/SpaceshipGame.cpp
+    src/SpaceshipGame.h
 )
 
 add_executable(${GAME_NAME}

+ 93 - 93
tools/encoder/CMakeLists.txt

@@ -32,101 +32,101 @@ add_definitions(-lstdc++ -ldl -lfbxsdk-2013.3-static -lpng -lz -lfreetype -lpthr
 set( APP_NAME gameplay-encoder )
 
 set(APP_SRC
-	src/AnimationChannel.cpp
-	src/AnimationChannel.h
-	src/Animation.cpp
-	src/Animation.h
-	src/Animations.cpp
-	src/Animations.h
-	src/Base.cpp
-	src/Base.h
-	src/BoundingVolume.cpp
-	src/BoundingVolume.h
-	src/Camera.cpp
-	src/Camera.h
+    src/AnimationChannel.cpp
+    src/AnimationChannel.h
+    src/Animation.cpp
+    src/Animation.h
+    src/Animations.cpp
+    src/Animations.h
+    src/Base.cpp
+    src/Base.h
+    src/BoundingVolume.cpp
+    src/BoundingVolume.h
+    src/Camera.cpp
+    src/Camera.h
     src/Constants.cpp
     src/Constants.h
-	src/Curve.cpp
-	src/Curve.h
-	src/Curve.inl
-	src/Effect.cpp
-	src/Effect.h
-	src/EncoderArguments.cpp
-	src/EncoderArguments.h
-	src/FBXSceneEncoder.cpp
-	src/FBXSceneEncoder.h
-	src/FBXUtil.cpp
-	src/FBXUtil.h
-	src/FileIO.cpp
-	src/FileIO.h
-	src/Font.cpp
-	src/Font.h
-	src/Glyph.cpp
-	src/Glyph.h
-	src/GPBDecoder.cpp
-	src/GPBDecoder.h
-	src/GPBFile.cpp
-	src/GPBFile.h
-	src/Heightmap.cpp
-	src/Heightmap.h
-	src/Image.cpp
-	src/Image.h
-	src/Light.cpp
-	src/Light.h
-	src/main.cpp
-	src/Material.cpp
-	src/Material.h
-	src/MaterialParameter.cpp
-	src/MaterialParameter.h
-	src/Matrix.cpp
-	src/Matrix.h
-	src/Mesh.cpp
-	src/Mesh.h
-	src/MeshPart.cpp
-	src/MeshPart.h
-	src/MeshSkin.cpp
-	src/MeshSkin.h
-	src/MeshSubSet.cpp
-	src/MeshSubSet.h
-	src/Model.cpp
-	src/Model.h
-	src/Node.cpp
-	src/Node.h
-	src/NormalMapGenerator.cpp
-	src/NormalMapGenerator.h
-	src/Object.cpp
-	src/Object.h
-	src/Quaternion.cpp
-	src/Quaternion.h
-	src/Quaternion.inl
-	src/Reference.cpp
-	src/Reference.h
-	src/ReferenceTable.cpp
-	src/ReferenceTable.h
-	src/Sampler.cpp
-	src/Sampler.h
-	src/Scene.cpp
-	src/Scene.h
-	src/StringUtil.cpp
-	src/StringUtil.h
-	src/Thread.h
-	src/Transform.cpp
-	src/Transform.h
-	src/TTFFontEncoder.cpp
-	src/TTFFontEncoder.h
-	src/Vector2.cpp
-	src/Vector2.h
-	src/Vector2.inl
-	src/Vector3.cpp
-	src/Vector3.h
-	src/Vector3.inl
-	src/Vector4.cpp
-	src/Vector4.h
-	src/Vector4.inl
-	src/Vertex.cpp
-	src/VertexElement.cpp
-	src/VertexElement.h
-	src/Vertex.h
+    src/Curve.cpp
+    src/Curve.h
+    src/Curve.inl
+    src/Effect.cpp
+    src/Effect.h
+    src/EncoderArguments.cpp
+    src/EncoderArguments.h
+    src/FBXSceneEncoder.cpp
+    src/FBXSceneEncoder.h
+    src/FBXUtil.cpp
+    src/FBXUtil.h
+    src/FileIO.cpp
+    src/FileIO.h
+    src/Font.cpp
+    src/Font.h
+    src/Glyph.cpp
+    src/Glyph.h
+    src/GPBDecoder.cpp
+    src/GPBDecoder.h
+    src/GPBFile.cpp
+    src/GPBFile.h
+    src/Heightmap.cpp
+    src/Heightmap.h
+    src/Image.cpp
+    src/Image.h
+    src/Light.cpp
+    src/Light.h
+    src/main.cpp
+    src/Material.cpp
+    src/Material.h
+    src/MaterialParameter.cpp
+    src/MaterialParameter.h
+    src/Matrix.cpp
+    src/Matrix.h
+    src/Mesh.cpp
+    src/Mesh.h
+    src/MeshPart.cpp
+    src/MeshPart.h
+    src/MeshSkin.cpp
+    src/MeshSkin.h
+    src/MeshSubSet.cpp
+    src/MeshSubSet.h
+    src/Model.cpp
+    src/Model.h
+    src/Node.cpp
+    src/Node.h
+    src/NormalMapGenerator.cpp
+    src/NormalMapGenerator.h
+    src/Object.cpp
+    src/Object.h
+    src/Quaternion.cpp
+    src/Quaternion.h
+    src/Quaternion.inl
+    src/Reference.cpp
+    src/Reference.h
+    src/ReferenceTable.cpp
+    src/ReferenceTable.h
+    src/Sampler.cpp
+    src/Sampler.h
+    src/Scene.cpp
+    src/Scene.h
+    src/StringUtil.cpp
+    src/StringUtil.h
+    src/Thread.h
+    src/Transform.cpp
+    src/Transform.h
+    src/TTFFontEncoder.cpp
+    src/TTFFontEncoder.h
+    src/Vector2.cpp
+    src/Vector2.h
+    src/Vector2.inl
+    src/Vector3.cpp
+    src/Vector3.h
+    src/Vector3.inl
+    src/Vector4.cpp
+    src/Vector4.h
+    src/Vector4.inl
+    src/Vertex.cpp
+    src/VertexElement.cpp
+    src/VertexElement.h
+    src/Vertex.h
 )
 
 add_executable(${APP_NAME}

+ 3 - 49
tools/encoder/README.md

@@ -26,60 +26,14 @@ Note: On Linux Ubuntu 12 (64-bit), you must first install the required 32-bit li
 `sudo apt-get install ia32-libs`
 
 ## Building gameplay-encoder
-The gameplay-encoder comes pre-built for Windows 7, MacOS X and Linux Ubuntu 12 (32-bit) in the 'bin' folder.
-However, to build the gameplay-encoder yourself just open either the 
-Visual Studio 2010 project "gameplay-encoder.vccproj" on Windows 7 or
-XCode project "gameplay-encoder.xcodeproj" on MacOSX.
-Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake .. from build then make.
 
-### Building with FBX Support on Windows 7 using Visual Studio 2010
-- Download and install the FBX SDK for Window VS2010. (http://www.autodesk.com/fbx)
-- Edit the project properties of "gameplay-encoder" for Debug
-- Add Preprocessor Definition "USE_FBX" (C++/Preprocessor)
-- Add the FBX SDK include directory to Additional Include Directories (C++/General)
-  * Example: C:/Program Files/Autodesk/FBX/FBX SDK/2013.3/include
-- Add the FBX lib directory to the Additional Library Directories (Linker/General)
-  * Example: C:/Program Files/Autodesk/FBX/FBX SDK/2013.3/lib/vs2010/x86
-- Add "fbxsdk-2013.3-md.lib"(Release) to the Additional Dependencies (Linker/Input)
-  * Example: fbxsdk-2013.3-md.lib
-- Build gameplay-encoder
-
-### Building with FBX Support on MacOS X using XCode 4
-- Download and install the FBX SDK for MacOS X (http://www.autodesk.com/fbx)
-- Edit the project properties of target "gameplay-encoder".
-- Add Preprocessor Macro "USE_FBX" to both Debug/Release sections. (Build Settings)
-- Add the FBX include directory to Header Search Paths: (Build Settings)
-  * Example: "/Applications/Autodesk/FBX SDK/2013.3/include" (Use quotes due to additional space in path)
-- Add the FBX library and dependency Library/Frameworks: (Build Phases -> Link Binary with Libraries)
-  * Example: /Applications/Autodesk/FBX SDK/2013.3/lib/gcc4/ub/libfbxsdk-2013.3-static.a  (Add Other)
-- Build gameplay-encoder
-
-### Building with FBX Support on Linux Ubuntu 12 (32-bit) using CMake
-- Download and install the FBX SDK for MacOS X (http://www.autodesk.com/fbx)
-- Edit the gameplay-encoder/CMakeLists.txt adding the following:
-- Add the FBX include directory to Header Search Paths: (Build Settings)
-  * Example: /usr/include/fbxsdk
-- Add Preprocessor Macro to the add"-DUSE_FBX" to the end of the add_definitions(...) section of the CMakeLists.txt
-- Add the FBX library path to the link_directories(...) section of the CMakeLists.txt
-  * Example: /usr/lib/gcc4
-- Add the FBX library to the set(APP_LIBRARIES {...} )
-  * Example: fbxsdk-2013.3-static
-- Add the FBX library to the library to the add_definitions(-l...) section of the CMakeLists.txt
-  * Example -lfbxsdk-2013.3-static
-- Build gameplay-encoder by uncommenting the last line in the gameplay/CMakeLists.txt and running the CMake build via:
-
-```
-mkdir build
-cd build
-cmake ..
-make
- ```
+See [Building gameplay-encoder](https://github.com/blackberry/GamePlay/wiki/Building-gameplay-encoder) on the wiki.
 
 ## Bundle File Format
-The gameplay bundle file format is well defined in the gameplay-encoder/gameplay-bundle.txt file.
+The gameplay bundle file format is defined in the [tools/encoder/gameplay-bundle.txt](gameplay-bundle.txt) file.
 
 ## Bundle File Loading
-Bundle files can easily be loaded using the gameplay/Bundle.h which is part of the gameplay runtime framework.
+Bundle files can easily be loaded using the `gameplay/Bundle.h` which is part of the gameplay runtime framework.
 
 ## Disclaimer
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 

+ 48 - 43
tools/encoder/src/EncoderArguments.cpp

@@ -233,55 +233,60 @@ void splitString(const char* str, std::vector<std::string>* tokens)
 
 void EncoderArguments::printUsage() const
 {
-    LOG(1, "Usage: gameplay-encoder [options] <input filepath> <output filepath>\n\n");
-    LOG(1, "Supported file extensions:\n");
-    LOG(1, "  .fbx\t(FBX)\n");
-    LOG(1, "  .ttf\t(TrueType Font)\n");
-    LOG(1, "\n");
-    LOG(1, "General Options:\n");
-    LOG(1, "  -v <verbosity>\tVerbosity level (0-4).\n");
-    LOG(1, "\n");
-    LOG(1, "FBX file options:\n");
-    LOG(1, "  -i <id>\tFilter by node ID.\n");
-    LOG(1, "  -t\t\tWrite text/xml.\n");
-    LOG(1, "  -g:auto\tAutomatically group animation channels into a new animation.\n");
-    LOG(1, "  -g:none\tDo not prompt to group animations.\n");
-    LOG(1, "  -g <node id> <animation id>\n" \
-        "\t\tGroup all animation channels targeting the nodes into a new animation.\n");
-    LOG(1, "  -m\t\tOutput material file for scene.\n");
-    LOG(1, "  -tb <node id>\n" \
-        "\t\tGenerates tangents and binormals for the given node.\n");
-    LOG(1, "  -oa\n" \
+    LOG(1, "Usage: gameplay-encoder [options] <input filepath> <output filepath>\n\n" \
+    "Supported file extensions:\n" \
+    "  .fbx\t(FBX)\n" \
+    "  .ttf\t(TrueType Font)\n" \
+    "\n" \
+    "General Options:\n" \
+    "  -v <verbosity>\tVerbosity level (0-4).\n" \
+    "\n" \
+    "FBX file options:\n" \
+    "  -i <id>\tFilter by node ID.\n" \
+    "  -t\t\tWrite text/xml.\n" \
+    "  -g:auto\tAutomatically group animation channels into a new animation.\n" \
+    "  -g:none\tDo not prompt to group animations.\n" \
+    "  -g <node id> <animation id>\n" \
+        "\t\tGroup all animation channels targeting the nodes into a \n" \
+        "\t\tnew animation.\n" \
+    "  -m\t\tOutput material file for scene.\n" \
+    "  -tb <node id>\n" \
+        "\t\tGenerates tangents and binormals for the given node.\n" \
+    "  -oa\n" \
         "\t\tOptimizes animations by analyzing animation channel data and\n" \
         "\t\tremoving any channels that contain default/identity values\n" \
-        "\t\tand removing any duplicate contiguous keyframes, which are common\n" \
-        "\t\twhen exporting baked animation data.\n");
-    LOG(1, "  -h <size> \"<node ids>\" <filename>\n" \
-        "\t\tGenerates a single heightmap image using meshes from the specified\n" \
-        "\t\tnodes. <size> should be two comma-separated numbers in the format\n" \
-        "\t\t\"X,Y\", indicating the dimensions of the produced heightmap image.\n" \
+        "\t\tand removing any duplicate contiguous keyframes, which are \n" \
+        "\t\tcommon when exporting baked animation data.\n" \
+    "  -h <size> \"<node ids>\" <filename>\n" \
+        "\t\tGenerates a single heightmap image using meshes from the \n" \
+        "\t\tspecified nodes. \n" \
+        "\t\t<size> is two comma-separated numbers in the format \"X,Y\", \n" \
+        "\t\tindicating the dimensions of the produced heightmap image.\n" \
         "\t\t<node ids> should be in quotes with a space between each id.\n" \
         "\t\tFilename is the name of the image (PNG) to be saved.\n" \
-        "\t\tMultiple -h arguments can be supplied to generate more than one heightmap.\n" \
-        "\t\tFor 24-bit packed height data use -hp instead of -h.\n");
-    LOG(1, "\n");
-    LOG(1, "Normal map generation options:\n" \
+        "\t\tMultiple -h arguments can be supplied to generate more than one \n" \
+        "\t\theightmap. For 24-bit packed height data use -hp instead of -h.\n" \
+    "\n" \
+    "Normal map generation options:\n" \
         "  -n\t\tGenerate normal map (requires input file of type PNG or RAW)\n" \
-        "  -s\t\tSize/resolution of the input heightmap image (requried for RAW files)\n" \
-        "  -w <size>\tSpecifies the size of an input terran heightmap file in world\n" \
-        "\t\tunits, along the X, Y and Z axes. <size> should be three comma-separated\n" \
-        "\t\tnumbers in the format \"X,Y,Z\". The Y value represents the maximum\n" \
-        "\t\tpossible height value of a full intensity heightmap pixel.\n" \
+        "  -s\t\tSize/resolution of the input heightmap image \n" \
+        "    \t\t(required for RAW files)\n" \
+        "  -w <size>\tSpecifies the size of an input terrain heightmap file in world\n" \
+        "\t\tunits, along the X, Y and Z axes. <size> should be three \n" \
+        "\t\tcomma-separated numbers in the format \"X,Y,Z\". The Y value \n" \
+        "\t\trepresents the maximum possible height value of a full \n" \
+        "\t\tintensity heightmap pixel.\n" \
         "\n" \
-        "  Normal map generation can be used to create object-space normal maps from heightmap\n" \
-        "  images. Heightmaps must be in either PNG format (where the intensity of each pixel\n" \
-        "  represents a height value), or in RAW format (8 or 16-bit), which is a common\n" \
-        "  headerless format supported by most terran generation tools.\n");
-    LOG(1, "\n");
-    LOG(1, "TTF file options:\n");
-    LOG(1, "  -s <size>\tSize of the font.\n");
-    LOG(1, "  -p\t\tOutput font preview.\n");
-    LOG(1, "\n");
+        "  Normal map generation can be used to create object-space normal maps from \n" \
+        "  heightmap images. Heightmaps must be in either PNG format (where the \n" \
+        "  intensity of each pixel represents a height value), or in RAW format \n" \
+        "  (8 or 16-bit), which is a common headerless format supported by most \n" \
+        "  terrain generation tools.\n" \
+    "\n" \
+    "TTF file options:\n" \
+    "  -s <size>\tSize of the font.\n" \
+    "  -p\t\tOutput font preview.\n" \
+    "\n");
     exit(8);
 }
 

+ 34 - 28
tools/encoder/src/FBXSceneEncoder.cpp

@@ -1,5 +1,3 @@
-#ifdef USE_FBX
-
 #include <algorithm>
 #include <string>
 #include <sstream>
@@ -14,6 +12,9 @@ using std::vector;
 using std::map;
 using std::ostringstream;
 
+// Fix bad material names
+static void fixMaterialName(string& name);
+
 FBXSceneEncoder::FBXSceneEncoder()
     : _groupAnimation(NULL), _autoGroupAnimations(false)
 {
@@ -60,11 +61,8 @@ void FBXSceneEncoder::write(const string& filepath, const EncoderArguments& argu
 
     print("Loading Scene.");
     loadScene(fbxScene);
-    if (arguments.outputMaterialEnabled())
-    {
-        print("Load materials");
-        loadMaterials(fbxScene);
-    }
+    print("Load materials");
+    loadMaterials(fbxScene);
     print("Loading animations.");
     loadAnimations(fbxScene, arguments);
     sdkManager->Destroy();
@@ -913,25 +911,6 @@ void FBXSceneEncoder::loadMaterials(FbxScene* fbxScene)
     }
 }
 
-// Fix bad material names
-void fixMaterialName(string& name)
-{
-    static int unnamedCount = 0;
-
-    for (string::size_type i = 0, len = name.length(); i < len; ++i)
-    {
-        if (!isalnum(name[i]))
-            name[i] = '_';
-    }
-
-    if (name.length() == 0)
-    {
-        ostringstream stream;
-        stream << "unnamed_" << (++unnamedCount);
-        name = stream.str();
-    }
-}
-
 void FBXSceneEncoder::loadMaterial(FbxNode* fbxNode)
 {
     Node* node = findNode(fbxNode);
@@ -952,7 +931,16 @@ void FBXSceneEncoder::loadMaterial(FbxNode* fbxNode)
         }
         else
         {
-            material = createMaterial(materialName, fbxMaterial, node);
+            if (EncoderArguments::getInstance()->outputMaterialEnabled())
+            {
+                material = createMaterial(materialName, fbxMaterial, node);
+            }
+            else
+            {
+                // If outputMaterialEnabled() is not enabled then only create the materials for the purpose of writing 
+                // the material name in the GPB file. There is no need to load uniforms and samplers for the material.
+                material = new Material(materialName);
+            }
             _materials[materialName] = material;
         }
 
@@ -1381,4 +1369,22 @@ void FBXSceneEncoder::triangulateRecursive(FbxNode* fbxNode)
     }
 }
 
-#endif
+// Functions
+
+void fixMaterialName(string& name)
+{
+    static int unnamedCount = 0;
+
+    for (string::size_type i = 0, len = name.length(); i < len; ++i)
+    {
+        if (!isalnum(name[i]))
+            name[i] = '_';
+    }
+
+    if (name.length() == 0)
+    {
+        ostringstream stream;
+        stream << "unnamed_" << (++unnamedCount);
+        name = stream.str();
+    }
+}

+ 0 - 3
tools/encoder/src/FBXSceneEncoder.h

@@ -1,8 +1,6 @@
 #ifndef FBXSCENEEENCODER_H_
 #define FBXSCENEEENCODER_H_
 
-#ifdef USE_FBX
-
 #define FBXSDK_NEW_API
 
 #include <iostream>
@@ -295,4 +293,3 @@ private:
 };
 
 #endif
-#endif

+ 0 - 4
tools/encoder/src/FBXUtil.cpp

@@ -1,5 +1,3 @@
-#ifdef USE_FBX
-
 #include <algorithm>
 #include <string>
 #include <sstream>
@@ -805,5 +803,3 @@ std::string toString(double value)
     stream << value;
     return stream.str();
 }
-
-#endif

+ 0 - 3
tools/encoder/src/FBXUtil.h

@@ -1,8 +1,6 @@
 #ifndef FBXUTIL_H_
 #define FBXUTIL_H_
 
-#ifdef USE_FBX
-
 #define FBXSDK_NEW_API
 
 #include <iostream>
@@ -203,4 +201,3 @@ std::string toString(const FbxDouble3& fbxDouble, double d);
 std::string toString(double value);
 
 #endif
-#endif

+ 1 - 1
tools/encoder/src/Material.cpp

@@ -16,7 +16,7 @@ Material::Material(const std::string& id) :
 
 Material::Material(const Material& c) :
     _parent(c._parent),
-    _id(c._id),
+    _id(c._id), _lit(false),
     _vertexShader(c._vertexShader),
     _fragmentShader(c._fragmentShader),
     _defines(c._defines),

+ 1 - 3
tools/encoder/src/MeshSkin.cpp

@@ -170,8 +170,6 @@ void MeshSkin::computeBounds()
 
     LOG(2, "Computing bounds for skin of mesh: %s\n", _mesh->getId().c_str());
 
-    Node* joint;
-
     // Get the root joint
     Node* rootJoint = _joints[0];
     Node* parent = rootJoint->getParent();
@@ -210,7 +208,7 @@ void MeshSkin::computeBounds()
     LOG(3, "  0%%\r");
     for (unsigned int i = 0; i < jointCount; ++i)
     {
-        joint = _joints[i];
+        Node* joint = _joints[i];
 
         // Find all animations that target this joint
         Animations* animations = GPBFile::getInstance()->getAnimations();

+ 0 - 5
tools/encoder/src/main.cpp

@@ -72,15 +72,10 @@ int main(int argc, const char** argv)
         }
     case EncoderArguments::FILEFORMAT_FBX:
         {
-#ifdef USE_FBX
             std::string realpath(arguments.getFilePath());
             FBXSceneEncoder fbxEncoder;
             fbxEncoder.write(realpath, arguments);
             break;
-#else
-            LOG(1, "Error: FBX not enabled. Install the FBX SDK and use the preprocessor definition USE_FBX.\n");
-            return -1;
-#endif
         }
     case EncoderArguments::FILEFORMAT_TTF:
         {

+ 10 - 10
tools/luagen/CMakeLists.txt

@@ -23,16 +23,16 @@ add_definitions(-lstdc++ -llua -ltinyxml2)
 set( APP_NAME gameplay-luagen )
 
 set(APP_SRC
-	src/Base.h
-	src/ClassBinding.cpp
-	src/ClassBinding.h
-	src/DebugNew.cpp
-	src/DebugNew.h
-	src/EnumBinding.h
-	src/FunctionBinding.cpp
-	src/FunctionBinding.h
-	src/Generator.cpp
-	src/Generator.h
+    src/Base.h
+    src/ClassBinding.cpp
+    src/ClassBinding.h
+    src/DebugNew.cpp
+    src/DebugNew.h
+    src/EnumBinding.h
+    src/FunctionBinding.cpp
+    src/FunctionBinding.h
+    src/Generator.cpp
+    src/Generator.h
     src/main.cpp
     src/TypedefBinding.h
 )