Browse Source

Added gameplay::strcmpnocase as a platform-independent case-insensitive ASCII string comparison function.
More work on adding support for default UI theme.

sgrenier 12 years ago
parent
commit
25e70f7088
65 changed files with 1877 additions and 388 deletions
  1. 25 13
      gameplay/src/Button.cpp
  2. 18 0
      gameplay/src/Button.h
  3. 20 8
      gameplay/src/CheckBox.cpp
  4. 16 0
      gameplay/src/CheckBox.h
  5. 24 48
      gameplay/src/Container.cpp
  6. 22 17
      gameplay/src/Container.h
  7. 57 8
      gameplay/src/Control.cpp
  8. 14 8
      gameplay/src/Control.h
  9. 27 17
      gameplay/src/ControlFactory.cpp
  10. 16 10
      gameplay/src/ControlFactory.h
  11. 56 80
      gameplay/src/Form.cpp
  12. 5 8
      gameplay/src/Form.h
  13. 3 0
      gameplay/src/Game.cpp
  14. 11 6
      gameplay/src/ImageControl.cpp
  15. 12 1
      gameplay/src/ImageControl.h
  16. 11 6
      gameplay/src/Joystick.cpp
  17. 13 2
      gameplay/src/Joystick.h
  18. 11 6
      gameplay/src/Label.cpp
  19. 14 3
      gameplay/src/Label.h
  20. 5 0
      gameplay/src/PlatformBlackBerry.cpp
  21. 5 0
      gameplay/src/PlatformLinux.cpp
  22. 5 0
      gameplay/src/PlatformMacOSX.mm
  23. 5 0
      gameplay/src/PlatformWindows.cpp
  24. 5 0
      gameplay/src/PlatformiOS.mm
  25. 34 18
      gameplay/src/RadioButton.cpp
  26. 16 0
      gameplay/src/RadioButton.h
  27. 29 17
      gameplay/src/Slider.cpp
  28. 16 0
      gameplay/src/Slider.h
  29. 11 4
      gameplay/src/TextBox.cpp
  30. 13 2
      gameplay/src/TextBox.h
  31. 25 32
      gameplay/src/Theme.cpp
  32. 6 3
      gameplay/src/Theme.h
  33. 1 0
      gameplay/src/ThemeStyle.cpp
  34. 112 1
      gameplay/src/lua/lua_Button.cpp
  35. 2 0
      gameplay/src/lua/lua_Button.h
  36. 112 1
      gameplay/src/lua/lua_CheckBox.cpp
  37. 2 0
      gameplay/src/lua/lua_CheckBox.h
  38. 150 1
      gameplay/src/lua/lua_Container.cpp
  39. 3 0
      gameplay/src/lua/lua_Container.h
  40. 83 0
      gameplay/src/lua/lua_Control.cpp
  41. 2 0
      gameplay/src/lua/lua_Control.h
  42. 1 0
      gameplay/src/lua/lua_ControlListener.cpp
  43. 75 0
      gameplay/src/lua/lua_Form.cpp
  44. 2 0
      gameplay/src/lua/lua_Form.h
  45. 2 0
      gameplay/src/lua/lua_Game.cpp
  46. 42 0
      gameplay/src/lua/lua_Global.cpp
  47. 3 0
      gameplay/src/lua/lua_Global.h
  48. 112 1
      gameplay/src/lua/lua_ImageControl.cpp
  49. 2 0
      gameplay/src/lua/lua_ImageControl.h
  50. 112 1
      gameplay/src/lua/lua_Joystick.cpp
  51. 2 0
      gameplay/src/lua/lua_Joystick.h
  52. 112 1
      gameplay/src/lua/lua_Label.cpp
  53. 2 0
      gameplay/src/lua/lua_Label.h
  54. 112 1
      gameplay/src/lua/lua_RadioButton.cpp
  55. 2 0
      gameplay/src/lua/lua_RadioButton.h
  56. 112 1
      gameplay/src/lua/lua_Slider.cpp
  57. 2 0
      gameplay/src/lua/lua_Slider.h
  58. 112 54
      gameplay/src/lua/lua_TextBox.cpp
  59. 2 1
      gameplay/src/lua/lua_TextBox.h
  60. 39 0
      gameplay/src/lua/lua_Theme.cpp
  61. 1 0
      gameplay/src/lua/lua_Theme.h
  62. 1 0
      gameplay/src/lua/lua_ThemeSideRegions.cpp
  63. 1 0
      gameplay/src/lua/lua_ThemeThemeImage.cpp
  64. 1 0
      gameplay/src/lua/lua_ThemeUVs.cpp
  65. 8 8
      samples/browser/src/SamplesGame.cpp

+ 25 - 13
gameplay/src/Button.cpp

@@ -14,25 +14,37 @@ Button::~Button()
 {
 }
 
-Control* Button::create(Theme::Style* style, Properties* properties)
+Button* Button::create(const char* id, Theme::Style* style)
 {
     Button* button = new Button();
-	button->initialize(style, properties);
-
-	if (properties)
-	{
-		// Different types of data bindings can be named differently in a button namespace.
-		// Gamepad button mappings have the name "mapping" and correspond to Gamepad::ButtonMapping enums.
-		const char* mapping = properties->getString("mapping");
-		if (mapping)
-		{
-			button->_dataBinding = Gamepad::getButtonMappingFromString(mapping);
-		}
-	}
+    button->_id = id ? id : "";
+    button->initialize("Button", style, NULL);
+    return button;
+}
 
+Control* Button::create(Theme::Style* style, Properties* properties)
+{
+    Button* button = new Button();
+	button->initialize("Button", style, properties);
     return button;
 }
 
+void Button::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Label::initialize(typeName, style, properties);
+
+    if (properties)
+    {
+        // Different types of data bindings can be named differently in a button namespace.
+        // Gamepad button mappings have the name "mapping" and correspond to Gamepad::ButtonMapping enums.
+        const char* mapping = properties->getString("mapping");
+        if (mapping)
+        {
+            _dataBinding = Gamepad::getButtonMappingFromString(mapping);
+        }
+    }
+}
+
 const char* Button::getType() const
 {
     return "button";

+ 18 - 0
gameplay/src/Button.h

@@ -37,6 +37,19 @@ class Button : public Label
     friend class Gamepad;
     friend class ControlFactory;
 
+public:
+
+    /**
+     * Creates a new Button.
+     *
+     * @param id The button ID.
+     * @param style The button style (optional).
+     *
+     * @return The new button.
+     * @script{create}
+     */
+    static Button* create(const char* id, Theme::Style* style = NULL);
+
 protected:
 
     /**
@@ -59,6 +72,11 @@ protected:
      */
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
+    /**
+     * @see Control::initialize
+     */
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
+
     /**
      * @see Control::getType
      */

+ 20 - 8
gameplay/src/CheckBox.cpp

@@ -14,18 +14,30 @@ CheckBox::~CheckBox()
 
 }
 
+CheckBox* CheckBox::create(const char* id, Theme::Style* style)
+{
+    CheckBox* cb = new CheckBox();
+    cb->_id = id ? id : "";
+    cb->initialize("CheckBox", style, NULL);
+    return cb;
+}
+
 Control* CheckBox::create(Theme::Style* style, Properties* properties)
 {
-    CheckBox* checkBox = new CheckBox();
-	checkBox->initialize(style, properties);
+    CheckBox* cb = new CheckBox();
+    cb->initialize("CheckBox", style, properties);
+    return cb;
+}
 
-	if (properties)
-	{
-		properties->getVector2("imageSize", &checkBox->_imageSize);
-		checkBox->_checked = properties->getBool("checked");
-	}
+void CheckBox::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Button::initialize(typeName, style, properties);
 
-    return checkBox;
+    if (properties)
+    {
+        properties->getVector2("imageSize", &_imageSize);
+        _checked = properties->getBool("checked");
+    }
 }
 
 bool CheckBox::isChecked()

+ 16 - 0
gameplay/src/CheckBox.h

@@ -39,6 +39,17 @@ class CheckBox : public Button
 
 public:
 
+    /**
+     * Creates a new CheckBox.
+     *
+     * @param id The checkbox ID.
+     * @param style The checkbox style (optional).
+     *
+     * @return The new checkbox.
+     * @script{create}
+     */
+    static CheckBox* create(const char* id, Theme::Style* style = NULL);
+
     /**
      * Gets whether this checkbox is checked.
      *
@@ -107,6 +118,11 @@ protected:
      */
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
+    /**
+    * @see Control::initialize
+    */
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
+
     /**
      * Keyboard callback on key events.
      *

+ 24 - 48
gameplay/src/Container.cpp

@@ -70,22 +70,25 @@ Container::~Container()
     SAFE_RELEASE(_layout);
 }
 
-Control* Container::create(Theme::Style* style, Properties* properties)
+Container* Container::create(const char* id, Theme::Style* style, Layout::Type layout)
 {
     Container* container = new Container();
-    container->initialize(style, properties);
-
-	if (container->_layout == NULL)
-		container->_layout = createLayout(Layout::LAYOUT_ABSOLUTE);
-
+    container->_id = id ? id : "";
+    container->_layout = createLayout(layout);
+    container->initialize("Container", style, NULL);
     return container;
 }
 
-void Container::initialize(Theme::Style* style, Properties* properties)
+Control* Container::create(Theme::Style* style, Properties* properties)
 {
-	GP_ASSERT(style);
+    Container* container = new Container();
+    container->initialize("Container", style, properties);
+    return container;
+}
 
-    Control::initialize(style, properties);
+void Container::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Control::initialize(typeName, style, properties);
 
 	if (properties)
 	{
@@ -122,7 +125,7 @@ void Container::initialize(Theme::Style* style, Properties* properties)
 		if (properties->exists("scrollWheelSpeed"))
 			_scrollWheelSpeed = properties->getFloat("scrollWheelSpeed");
 
-		addControls(style->getTheme(), properties);
+		addControls(properties);
 		_layout->update(this, _scrollPosition);
 
 		const char* activeControl = properties->getString("activeControl");
@@ -138,34 +141,25 @@ void Container::initialize(Theme::Style* style, Properties* properties)
 			}
 		}
 	}
+
+    // Create a default layout if one does not yet exist
+    if (_layout == NULL)
+        _layout = createLayout(Layout::LAYOUT_ABSOLUTE);
 }
 
-void Container::addControls(Theme* theme, Properties* properties)
+void Container::addControls(Properties* properties)
 {
-    GP_ASSERT(theme);
     GP_ASSERT(properties);
 
     // Add all the controls to this container.
     Properties* controlSpace = properties->getNextNamespace();
     while (controlSpace != NULL)
     {
-        Control* control = NULL;
-
-        const char* controlStyleName = controlSpace->getString("style");
-        Theme::Style* controlStyle = NULL;
-        if (controlStyleName)
-        {
-            controlStyle = theme->getStyle(controlStyleName);
-        }
-        else
-        {
-            controlStyle = theme->getEmptyStyle();
-        }
-
-        std::string controlName(controlSpace->getNamespace());
-        std::transform(controlName.begin(), controlName.end(), controlName.begin(), (int(*)(int))toupper);
+        const char* controlName = controlSpace->getNamespace();
 
-		control = ControlFactory::getInstance()->createControl(controlName.c_str(), controlStyle, controlSpace);
+        // Pass our own style into the creation of the child control.
+        // The child control's style will be looked up using the passed in style's theme.
+        Control* control = ControlFactory::getInstance()->createControl(controlName, _style, controlSpace);
 
         // Add the new control to the form.
         if (control)
@@ -199,27 +193,9 @@ void Container::setLayout(Layout::Type type)
 	}
 }
 
-unsigned int Container::addControl(const char* typeName, const char* styleName)
+unsigned int Container::addControl(Control* control)
 {
-	GP_ASSERT(typeName);
-
-	Form* form = getTopLevelForm();
-	if (!form)
-	{
-		GP_WARN("Attempted to add a new control to an orphaned container.");
-		return 0;
-	}
-
-	Theme* theme = form->getTheme();
-	GP_ASSERT(theme);
-
-	Theme::Style* style = NULL;
-	if (styleName)
-		style = theme->getStyle(styleName);
-	if (!style)
-		style = theme->getStyle(typeName);
-
-	Control* control = ControlFactory::getInstance()->createControl()
+	GP_ASSERT(control);
 
     // Remove the control from its current parent
     if (control->_parent && control->_parent != this)

+ 22 - 17
gameplay/src/Container.h

@@ -72,6 +72,18 @@ public:
         SCROLL_BOTH = SCROLL_HORIZONTAL | SCROLL_VERTICAL
     };
 
+    /**
+     * Creates a new container.
+     *
+     * @param id The container ID.
+     * @param style The container style (optional).
+     * @param layout The container layout (optional).
+     *
+     * @return The new container.
+     * @script{create}
+     */
+    static Container* create(const char* id, Theme::Style* style = NULL, Layout::Type layout = Layout::LAYOUT_ABSOLUTE);
+
     /**
      * Get this container's layout.
      *
@@ -87,23 +99,21 @@ public:
 	void setLayout(Layout::Type type);
 
     /**
-     * Creates and adds a new control to this container.
+     * Adds a new control to this container.
      *
-	 * @param type The type of the control to add.
-	 * @param style Name of the theme style to use for the new control (optional).
+	 * @param control The control to add.
      *
      * @return The index assigned to the new Control.
      */
-    unsigned int addControl(const char* type, const char* style = NULL);
+    unsigned int addControl(Control* control);
 
     /**
-     * Creates and inserts a control at a specific index.
+     * Inserts a control at a specific index.
      *
-     * @param type The type of the control to add.
+     * @param control The control to insert.
      * @param index The index at which to insert the control.
-	 * @param style Name of the style to use for the new control (optional).
      */
-    void insertControl(const char* type, unsigned int index, const char* style = NULL);
+    void insertControl(Control* control, unsigned int index);
 
     /**
      * Remove a control at a specific index.
@@ -320,12 +330,9 @@ protected:
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
     /**
-     * Initialize properties common to all Containers from a Properties object.
-     *
-     * @param style The style to apply to this control.
-     * @param properties The properties to set on this control.
+     * @see Control::initialize
      */
-    void initialize(Theme::Style* style, Properties* properties);
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
 
     /**
      * Updates each control within this container,
@@ -360,13 +367,11 @@ protected:
     virtual bool isDirty();
 
     /**
-     * Adds controls nested within a properties object to this container,
-     * searching for styles within the given theme.
+     * Adds controls nested within a properties object to this container.
      *
-     * @param theme The them to add controls from
      * @param properties The properties to use.
      */
-    void addControls(Theme* theme, Properties* properties);
+    void addControls(Properties* properties);
 
     /**
      * Draws a sprite batch for the specified clipping rect.

+ 57 - 8
gameplay/src/Control.cpp

@@ -2,6 +2,7 @@
 #include "Game.h"
 #include "Control.h"
 #include "Form.h"
+#include "Theme.h"
 
 #define BOUNDS_X_PERCENTAGE_BIT 1
 #define BOUNDS_Y_PERCENTAGE_BIT 2
@@ -66,9 +67,15 @@ Control::~Control()
         SAFE_DELETE(_listeners);
     }
 
-    if (_styleOverridden)
+    if (_style)
     {
-        SAFE_DELETE(_style);
+        // Release the style's theme since we addRef'd it in initialize()
+        _style->getTheme()->release();
+
+        if (_styleOverridden)
+        {
+            SAFE_DELETE(_style);
+        }
     }
 }
 
@@ -83,12 +90,49 @@ static Control::AutoSize parseAutoSize(const char* str)
     return Control::AUTO_SIZE_NONE;
 }
 
-void Control::initialize(Theme::Style* style, Properties* properties)
+void Control::initialize(const char* typeName, Theme::Style* style, Properties* properties)
 {
-	_style = style;
+    // Load our theme style
+    if (properties)
+    {
+        // The style passed is in our parent control's style.
+        // Attempt to load our own style from our parent style's theme.
+        const char* styleName = properties->getString("style", typeName);
+        if (style)
+        {
+            // The passed in style is our parent control's style : attempt to load our style from it.
+            _style = style->getTheme()->getStyle(styleName);
+        }
 
-	if (properties)
-	{
+        if (!_style)
+        {
+            // Try loading a style from the default theme
+            _style = Theme::getDefault()->getStyle(styleName);
+        }
+    }
+    else
+    {
+        // No properties passed in - the style passed in was explicity for us.
+        _style = style;
+    }
+
+    if (!_style)
+    {
+        // Search for a style from the default theme that matches this control's name
+        _style = Theme::getDefault()->getStyle(typeName);
+
+        if (!_style)
+        {
+            // No style was found, use an empty style
+            _style = Theme::getDefault()->getEmptyStyle();
+        }
+    }
+
+    // Increase the reference count of the style's theme while we hold the style
+    _style->getTheme()->addRef();
+
+    if (properties)
+    {
 		// Properties not defined by the style.
 		const char * alignmentString = properties->getString("alignment");
 
@@ -827,6 +871,11 @@ bool Control::getTextRightToLeft(State state) const
     return overlay->getTextRightToLeft();
 }
 
+Theme::Style* Control::getStyle() const
+{
+    return _style;
+}
+
 void Control::setStyle(Theme::Style* style)
 {
     if (style != _style)
@@ -837,9 +886,9 @@ void Control::setStyle(Theme::Style* style)
     _style = style;
 }
 
-Theme::Style* Control::getStyle() const
+Theme* Control::getTheme() const
 {
-    return _style;
+    return _style ? _style->getTheme() : NULL;
 }
 
 Control::State Control::getState() const

+ 14 - 8
gameplay/src/Control.h

@@ -847,6 +847,13 @@ public:
      */
     bool getConsumeInputEvents();
 
+    /**
+     * Get this control's style.
+     *
+     * @return This control's style.
+     */
+    Theme::Style* getStyle() const;
+
     /**
      * Set the style this control will use when rendering.
      *
@@ -855,11 +862,9 @@ public:
     void setStyle(Theme::Style* style);
 
     /**
-     * Get this control's style.
-     *
-     * @return This control's style.
+     * Returns the theme for this control.
      */
-    Theme::Style* getStyle() const;
+    Theme* getTheme() const;
 
     /**
      * Get this control's z-index.
@@ -1123,12 +1128,13 @@ protected:
     virtual void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight);
 
     /**
-     * Initialize properties common to all Controls from a Properties object.
+     * Initializes the control.
      *
-     * @param style The style to apply to this control.
-     * @param properties The properties to set on this control.
+     * @param typeName The type name of the control being initalized.
+     * @param style The style to apply to this control (optional).
+     * @param properties The properties to set on this control (optional).
      */
-    virtual void initialize(Theme::Style* style, Properties* properties);
+    virtual void initialize(const char* typeName, Theme::Style* style, Properties* properties);
 
     /**
      * Returns whether this control has been modified and requires an update.

+ 27 - 17
gameplay/src/ControlFactory.cpp

@@ -40,43 +40,53 @@ ControlFactory* ControlFactory::getInstance()
 	return __controlFactory;
 }
 
-bool ControlFactory::registerCustomControl(const char* name, ControlActivator activator)
+bool ControlFactory::registerCustomControl(const char* typeName, ControlActivator activator)
 {
-	if (_registeredControls.find(name) != _registeredControls.end())
+    std::string upper(typeName);
+    std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
+
+	if (_registeredControls.find(upper) != _registeredControls.end())
 		return false;
 
-	_registeredControls[name] = activator;
+	_registeredControls[upper] = activator;
 	return true;
 }
 
-void ControlFactory::unregisterCustomControl(const char* controlName)
+void ControlFactory::unregisterCustomControl(const char* typeName)
 {
+    std::string upper(typeName);
+    std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
+
 	std::map<std::string, ControlActivator>::iterator it;
-	if ((it = _registeredControls.find(controlName)) != _registeredControls.end())
+	if ((it = _registeredControls.find(upper)) != _registeredControls.end())
 	{
 		_registeredControls.erase(it);
 	}
 }
 
-Control *ControlFactory::createControl(const char* controlName, Theme::Style* style, Properties* properties)
+Control *ControlFactory::createControl(const char* typeName, Theme::Style* style, Properties* properties)
 {
-	if (_registeredControls.find(controlName) == _registeredControls.end())
+    std::string upper(typeName);
+    std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
+
+    std::map<std::string, ControlActivator>::iterator it = _registeredControls.find(upper);
+    if (it == _registeredControls.end())
 		return NULL;
 
-	return (*_registeredControls[controlName])(style, properties);
+    return (*it->second)(style, properties);
 }
 
 void ControlFactory::registerStandardControls() 
 {
-	_registeredControls["LABEL"] = &Label::create;
-	_registeredControls["BUTTON"] = &Button::create;
-	_registeredControls["CHECKBOX"] = &CheckBox::create;
-	_registeredControls["RADIOBUTTON"] = &RadioButton::create;
-	_registeredControls["CONTAINER"] = &Container::create;
-	_registeredControls["SLIDER"] = &Slider::create;
-	_registeredControls["TEXTBOX"] = &TextBox::create;
-	_registeredControls["JOYSTICK"] = &Joystick::create;
-	_registeredControls["IMAGE"] = &ImageControl::create;
+    registerCustomControl("LABEL", &Label::create);
+    registerCustomControl("BUTTON", &Button::create);
+    registerCustomControl("CHECKBOX", &CheckBox::create);
+    registerCustomControl("RADIOBUTTON", &RadioButton::create);
+    registerCustomControl("CONTAINER", &Container::create);
+    registerCustomControl("SLIDER", &Slider::create);
+    registerCustomControl("TEXTBOX", &TextBox::create);
+    registerCustomControl("JOYSTICK", &Joystick::create);
+    registerCustomControl("IMAGE", &ImageControl::create);
 }
 
 }

+ 16 - 10
gameplay/src/ControlFactory.h

@@ -16,6 +16,7 @@ class Control;
  */
 class ControlFactory 
 {
+    friend class Game;
 	friend class Container;
 
 public:
@@ -35,19 +36,19 @@ public:
 	/**
 	 * Registers a custom control and specify the activator.
 	 *
-	 * @param controlName The name of the custom control to register.
+	 * @param typeName The name of the custom control type to register.
 	 * @param activator The activator for applying the style, properties and theme to the control.
 	 *
 	 * @return true if the control was successfully registered.
 	 */
-	bool registerCustomControl(const char* controlName, ControlActivator activator);
+    bool registerCustomControl(const char* typeName, ControlActivator activator);
 
 	/**
 	 * Unregisters a custom control and specify the activator.
 	 *
-	 * @param controlName The name of the custom control to unregister.
+	 * @param typeName The name of the custom control type to unregister.
 	 */
-	void unregisterCustomControl(const char* controlName);
+    void unregisterCustomControl(const char* typeName);
 
 private:
 
@@ -55,8 +56,8 @@ private:
 	 * Constructor.
 	 */
 	ControlFactory();
-		
-	/**
+
+    /**
 	 * Constructor.
 	 */
 	ControlFactory(const ControlFactory& copy);
@@ -66,6 +67,11 @@ private:
 	 */
 	~ControlFactory();
 
+    /**
+     * Cleans up resources allocated by the ControlFactory.
+     */
+    static void finalize();
+
 	/**
 	 * Assignment operator
 	 */
@@ -74,14 +80,14 @@ private:
 	/**
 	* Creates a controls from the set of core and custom controls registered.
 	*
-	* @param controlName The name of the control to create.
+	* @param typeName The type of the control to create.
 	* @param style The style to apply to the control.
 	* @param properties A Properties object describing the control (optional).
 	* @return The new control.
 	*/
-	Control* createControl(const char* controlName, Theme::Style *style, Properties *properties = NULL);
-	
-	/**
+    Control* createControl(const char* typeName, Theme::Style *style, Properties *properties = NULL);
+
+    /**
 	 * Registers the standard (built-in) controls
 	 */
 	void registerStandardControls();

+ 56 - 80
gameplay/src/Form.cpp

@@ -31,7 +31,7 @@ Control* Form::_activeControl = NULL;
 Control::State Form::_activeControlState = Control::NORMAL;
 static bool _shiftKeyDown = false;
 
-Form::Form() : _theme(NULL), _frameBuffer(NULL), _spriteBatch(NULL), _node(NULL),
+Form::Form() : _frameBuffer(NULL), _spriteBatch(NULL), _node(NULL),
     _nodeQuad(NULL), _nodeMaterial(NULL) , _u2(0), _v1(0)
 {
 }
@@ -40,7 +40,6 @@ Form::~Form()
 {
     SAFE_DELETE(_spriteBatch);
     SAFE_RELEASE(_frameBuffer);
-    SAFE_RELEASE(_theme);
 
     if (__formEffect)
     {
@@ -61,94 +60,72 @@ Form::~Form()
 
 Form* Form::create(const char* id, Theme::Style* style, Layout::Type layoutType)
 {
-	Theme* theme;
-	if (style)
-	{
-		theme = style->getTheme();
-	}
-	else
-	{
-		theme = Theme::getDefault();
-		style = theme->getStyle("form");
-	}
-
-	GP_ASSERT(style);
-
-    Layout* layout;
-    switch (layoutType)
-    {
-    case Layout::LAYOUT_ABSOLUTE:
-        layout = AbsoluteLayout::create();
-        break;
-    case Layout::LAYOUT_FLOW:
-        layout = FlowLayout::create();
-        break;
-    case Layout::LAYOUT_VERTICAL:
-        layout = VerticalLayout::create();
-        break;
-    default:
-		layout = AbsoluteLayout::create();
-        GP_WARN("Unsupported layout type '%d'.", layoutType);
-        break;
-    }
-
     Form* form = new Form();
-    if (id)
-        form->_id = id;
-    form->_style = style;
-    form->_layout = layout;
-	form->_theme = theme;
-    form->_theme->addRef();
-
-    form->updateFrameBuffer();
-
-    __forms.push_back(form);
-
+    form->_id = id ? id : "";
+    form->_layout = createLayout(layoutType);
+    form->initialize("Form", style, NULL);
     return form;
 }
 
 Form* Form::create(const char* url)
 {
+    Form* form = new Form();
+
     // Load Form from .form file.
     Properties* properties = Properties::create(url);
-    if (properties == NULL)
+    Properties* formProperties = NULL;
+    if (properties)
     {
-        GP_ASSERT(properties);
-        return NULL;
+        // Check if the Properties is valid and has a valid namespace.
+        formProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
+        if (!formProperties || !(strcmpnocase(formProperties->getNamespace(), "form") == 0))
+        {
+            GP_WARN("Invalid properties file for form: %s", url);
+            SAFE_DELETE(properties);
+        }
     }
-
-    // Check if the Properties is valid and has a valid namespace.
-    Properties* formProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
-    assert(formProperties);
-    if (!formProperties || !(strcmp(formProperties->getNamespace(), "form") == 0))
+    if (!properties)
     {
-        GP_ASSERT(formProperties);
-        SAFE_DELETE(properties);
-        return NULL;
+        GP_WARN("Failed to load properties file for Form.");
     }
 
-    // Parse theme
-    std::string themeFile;
-    formProperties->getPath("theme", &themeFile);
-    Theme* theme = Theme::create(themeFile.c_str());
-    GP_ASSERT(theme);
+    // Load the form's theme style.
+    Theme* theme = NULL;
+    Theme::Style* style = NULL;
+    if (formProperties->exists("theme"))
+    {
+        std::string themeFile;
+        if (formProperties->getPath("theme", &themeFile))
+        {
+            theme = Theme::create(themeFile.c_str());
+            if (theme)
+            {
+                // Load the form's style
+                const char* styleName = formProperties->getString("style", "Form");
+                style = theme->getStyle(styleName);
+                if (!style)
+                    style = theme->getEmptyStyle();
+            }
+        }
+    }
 
-    // Parse style
-    const char* styleName = formProperties->getString("style");
-    Theme::Style* style = styleName ? theme->getStyle(styleName) : theme->getEmptyStyle();
+    // Initialize the form and all of its child controls
+    form->initialize("Form", style, formProperties);
 
-    // Create new form
-    Form* form = new Form();
-    form->_theme = theme;
+    // Release the theme: its lifetime is controlled by addRef() and release() calls
+    // in initialize (above) and ~Control.
+    SAFE_RELEASE(theme);
 
-    // Initialize common container properties
-    form->initialize(style, formProperties);
+    return form;
+}
 
-    form->updateFrameBuffer();
+void Form::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Container::initialize(typeName, style, properties);
 
-    __forms.push_back(form);
+    updateFrameBuffer();
 
-    return form;
+    __forms.push_back(this);
 }
 
 Form* Form::getForm(const char* id)
@@ -180,11 +157,6 @@ bool Form::isForm() const
     return true;
 }
 
-Theme* Form::getTheme() const
-{
-    return _theme;
-}
-
 void Form::updateFrameBuffer()
 {
     float width = _absoluteClipBounds.width;
@@ -222,7 +194,7 @@ void Form::updateFrameBuffer()
         Rectangle previousViewport = game->getViewport();
 
         game->setViewport(Rectangle(0, 0, width, height));
-        _theme->setProjectionMatrix(_projectionMatrix);
+        //_theme->setProjectionMatrix(_projectionMatrix);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
 
         previousFrameBuffer->bind();
@@ -385,14 +357,18 @@ unsigned int Form::draw()
         Rectangle prevViewport = game->getViewport();
         game->setViewport(Rectangle(0, 0, _absoluteClipBounds.width, _absoluteClipBounds.height));
 
-        GP_ASSERT(_theme);
-        _theme->setProjectionMatrix(_projectionMatrix);
+        //_theme->setProjectionMatrix(_projectionMatrix);
+        _style->getTheme()->setProjectionMatrix(_projectionMatrix);
 
         // By setting needsClear to true here, an optimization meant to clear and redraw only areas of the form
         // that have changed is disabled.  Currently, repositioning controls can result in areas of the screen being cleared
         // after another control has been drawn there.  This should probably be done in two passes -- one to clear areas where
         // dirty controls were last frame, and another to draw them where they are now.
-        Container::draw(_theme->getSpriteBatch(), _absoluteClipBounds, /*_skin != NULL*/ true, false, _absoluteClipBounds.height);
+
+        // !!! TODO !!!
+        //
+        //Container::draw(_theme->getSpriteBatch(), _absoluteClipBounds, /*_skin != NULL*/ true, false, _absoluteClipBounds.height);
+        Container::draw(_style->getTheme()->getSpriteBatch(), _absoluteClipBounds, /*_skin != NULL*/ true, false, _absoluteClipBounds.height);
 
         // Restore the previous game viewport.
         game->setViewport(prevViewport);

+ 5 - 8
gameplay/src/Form.h

@@ -113,13 +113,6 @@ public:
      */
     bool isForm() const;
 
-    /**
-     * Gets the theme for the form.
-     *
-     * @return The theme for the form.
-     */
-    Theme* getTheme() const;
-
     /**
      * Attach this form to a node.
      *
@@ -178,6 +171,11 @@ private:
      */
     virtual ~Form();
 
+    /**
+     * @see Control::initialize
+     */
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
+
     /**
      * Initialize a quad for this form in order to draw it in 3D.
      *
@@ -275,7 +273,6 @@ private:
 
     static bool pollGamepad(Gamepad* gamepad);
 
-    Theme* _theme;                      // The Theme applied to this Form.
     FrameBuffer* _frameBuffer;          // FBO the Form is rendered into for texturing the quad. 
     SpriteBatch* _spriteBatch;
     Node* _node;                        // Node for transforming this Form in world-space.

+ 3 - 0
gameplay/src/Game.cpp

@@ -6,6 +6,7 @@
 #include "FrameBuffer.h"
 #include "SceneLoader.h"
 #include "ControlFactory.h"
+#include "Theme.h"
 
 /** @script{ignore} */
 GLenum __gl_error_code = GL_NO_ERROR;
@@ -203,6 +204,8 @@ void Game::shutdown()
 
         ControlFactory::finalize();
 
+        Theme::finalize();
+
         // Note: we do not clean up the script controller here
         // because users can call Game::exit() from a script.
 

+ 11 - 6
gameplay/src/ImageControl.cpp

@@ -15,19 +15,24 @@ ImageControl::~ImageControl()
     SAFE_DELETE(_batch);
 }
 
-Control* ImageControl::create(Theme::Style* style, Properties* properties)
+ImageControl* ImageControl::create(const char* id, Theme::Style* style)
 {
     ImageControl* imageControl = new ImageControl();
-    imageControl->initialize(style, properties);
-
-    imageControl->_focusIndex = -2;
+    imageControl->_id = id ? id : "";
+    imageControl->initialize("Image", style, NULL);
+    return imageControl;
+}
 
+Control* ImageControl::create(Theme::Style* style, Properties* properties)
+{
+    ImageControl* imageControl = new ImageControl();
+    imageControl->initialize("Image", style, properties);
     return imageControl;
 }
 
-void ImageControl::initialize(Theme::Style* style, Properties* properties)
+void ImageControl::initialize(const char* typeName, Theme::Style* style, Properties* properties)
 {
-	Control::initialize(style, properties);
+	Control::initialize(typeName, style, properties);
 
 	if (properties)
 	{

+ 12 - 1
gameplay/src/ImageControl.h

@@ -40,6 +40,17 @@ class ImageControl : public Control
 
 public:
 
+    /**
+     * Creates a new ImageControl.
+     *
+     * @param id The image control ID.
+     * @param style The image control style (optional).
+     *
+     * @return The new image control.
+     * @script{create}
+     */
+    static ImageControl* create(const char* id, Theme::Style* style = NULL);
+
     /**
      * Set the path of the image for this ImageControl to display.
      *
@@ -109,7 +120,7 @@ protected:
 
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
-    virtual void initialize(Theme::Style* style, Properties* properties);
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
 
     void drawImages(SpriteBatch* spriteBatch, const Rectangle& clip);
 

+ 11 - 6
gameplay/src/Joystick.cpp

@@ -16,19 +16,24 @@ Joystick::~Joystick()
         SAFE_DELETE(_outerSize);
 }
 
-Control* Joystick::create(Theme::Style* style, Properties* properties)
+Joystick* Joystick::create(const char* id, Theme::Style* style)
 {
     Joystick* joystick = new Joystick();
-    joystick->initialize(style, properties);
-
+    joystick->_id = id ? id : "";
+    joystick->initialize("Joystick", style, NULL);
     return joystick;
 }
 
-void Joystick::initialize(Theme::Style* style, Properties* properties)
+Control* Joystick::create(Theme::Style* style, Properties* properties)
 {
-    GP_ASSERT(properties);
+    Joystick* joystick = new Joystick();
+    joystick->initialize("Joystick", style, properties);
+    return joystick;
+}
 
-    Control::initialize(style, properties);
+void Joystick::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Control::initialize(typeName, style, properties);
 
 	if (!properties)
 	{

+ 13 - 2
gameplay/src/Joystick.h

@@ -29,6 +29,17 @@ class Joystick : public Control
 
 public:
 
+    /**
+     * Creates a new Joystick.
+     *
+     * @param id The joystick ID.
+     * @param style The joystick style.
+     *
+     * @return The new joystick.
+     * @script{create}
+     */
+    static Joystick* create(const char* id, Theme::Style* style = NULL);
+
     /**
      * Add a listener to be notified of specific events affecting
      * this control.  Event types can be OR'ed together.
@@ -133,9 +144,9 @@ protected:
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
     /**
-     * Initialize this joystick.
+     * @see Control::initialize
      */
-    virtual void initialize(Theme::Style* style, Properties* properties);
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.

+ 11 - 6
gameplay/src/Label.cpp

@@ -12,19 +12,24 @@ Label::~Label()
 {
 }
 
-Control* Label::create(Theme::Style* style, Properties* properties)
+Label* Label::create(const char* id, Theme::Style* style)
 {
     Label* label = new Label();
-	label->initialize(style, properties);
-
-	label->_focusIndex = -2;
+    label->_id = id ? id : "";
+    label->initialize("Label", style, NULL);
+    return label;
+}
 
+Control* Label::create(Theme::Style* style, Properties* properties)
+{
+    Label* label = new Label();
+	label->initialize("Label", style, properties);
     return label;
 }
 
-void Label::initialize(Theme::Style* style, Properties* properties)
+void Label::initialize(const char* typeName, Theme::Style* style, Properties* properties)
 {
-    Control::initialize(style, properties);
+    Control::initialize(typeName, style, properties);
 
 	if (properties)
 	{

+ 14 - 3
gameplay/src/Label.h

@@ -35,6 +35,17 @@ class Label : public Control
 
 public:
 
+    /**
+     * Creates a new label.
+     *
+     * @param id The label id.
+     * @param style The label style (optional).
+     *
+     * @return The new label.
+     * @script{create}
+     */
+    static Label* create(const char* id, Theme::Style* style = NULL);
+
     /**
      * Set the text for this label to display.
      *
@@ -87,12 +98,12 @@ protected:
 	* @return The new label.
 	* @script{create}
 	*/
-	static Control* create(Theme::Style* style, Properties* properties = NULL);
+	static Control* create(Theme::Style* style, Properties* properties);
 
     /**
-     * Initialize this label.
+     * @see Control::initialize
      */
-    virtual void initialize(Theme::Style* style, Properties* properties);
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
 
     /**
      * Called when a label's properties change. Updates this label's internal rendering

+ 5 - 0
gameplay/src/PlatformBlackBerry.cpp

@@ -427,6 +427,11 @@ extern void print(const char* format, ...)
     va_end(argptr);
 }
 
+extern int strcmpnocase(const char* s1, const char* s2)
+{
+    return strcasecmp(s1, s2);
+}
+
 EGLenum checkErrorEGL(const char* msg)
 {
     GP_ASSERT(msg);

+ 5 - 0
gameplay/src/PlatformLinux.cpp

@@ -542,6 +542,11 @@ namespace gameplay
         va_end(argptr);
     }
 
+    extern int strcmpnocase(const char* s1, const char* s2)
+    {
+        return strcasecmp(s1, s2);
+    }
+
     Platform::Platform(Game* game) : _game(game)
     {
     }

+ 5 - 0
gameplay/src/PlatformMacOSX.mm

@@ -1585,6 +1585,11 @@ extern void print(const char* format, ...)
     vfprintf(stderr, format, argptr);
     va_end(argptr);
 }
+
+extern int strcmpnocase(const char* s1, const char* s2)
+{
+    return strcasecmp(s1, s2);
+}
     
 Platform::Platform(Game* game)
 : _game(game)

+ 5 - 0
gameplay/src/PlatformWindows.cpp

@@ -507,6 +507,11 @@ extern void print(const char* format, ...)
     va_end(argptr);
 }
 
+extern int strcmpnocase(const char* s1, const char* s2)
+{
+    return _strcmpi(s1, s2);
+}
+
 Platform::Platform(Game* game)
     : _game(game)
 {

+ 5 - 0
gameplay/src/PlatformiOS.mm

@@ -1339,6 +1339,11 @@ extern void print(const char* format, ...)
     va_end(argptr);
 }
 
+extern int strcmpnocase(const char* s1, const char* s2)
+{
+    return strcasecmp(s1, s2);
+}
+
 Platform::Platform(Game* game) : _game(game)
 {
 }

+ 34 - 18
gameplay/src/RadioButton.cpp

@@ -19,31 +19,47 @@ RadioButton::~RadioButton()
     }
 }
 
+RadioButton* RadioButton::create(const char* id, Theme::Style* style)
+{
+    RadioButton* rb = new RadioButton();
+    rb->_id = id ? id : "";
+    rb->initialize("RadioButton", style, NULL);
+
+    __radioButtons.push_back(rb);
+
+    return rb;
+}
+
 Control* RadioButton::create(Theme::Style* style, Properties* properties)
 {
-    RadioButton* radioButton = new RadioButton();
-    radioButton->initialize(style, properties);
+    RadioButton* rb = new RadioButton();
+    rb->initialize("RadioButton", style, properties);
+
+    __radioButtons.push_back(rb);
 
-	if (properties)
-	{
-		properties->getVector2("imageSize", &radioButton->_imageSize);
+    return rb;
+}
 
-		if (properties->getBool("selected"))
-		{
-			RadioButton::clearSelected(radioButton->_groupId);
-			radioButton->_selected = true;
-		}
+void RadioButton::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Button::initialize(typeName, style, properties);
 
-		const char* groupId = properties->getString("group");
-		if (groupId)
-		{
-			radioButton->_groupId = groupId;
-		}
-	}
+    if (properties)
+    {
+        properties->getVector2("imageSize", &_imageSize);
 
-    __radioButtons.push_back(radioButton);
+        if (properties->getBool("selected"))
+        {
+            RadioButton::clearSelected(_groupId);
+            _selected = true;
+        }
 
-    return radioButton;
+        const char* groupId = properties->getString("group");
+        if (groupId)
+        {
+            _groupId = groupId;
+        }
+    }
 }
 
 bool RadioButton::isSelected() const

+ 16 - 0
gameplay/src/RadioButton.h

@@ -41,6 +41,17 @@ class RadioButton : public Button
 
 public:
 
+    /**
+     * Creates a new RadioButton.
+     *
+     * @param id The radio button ID.
+     * @param id The radio button style (optional).
+     *
+     * @return The new radio button.
+     * @script{create}
+     */
+    static RadioButton* create(const char* id, Theme::Style* style = NULL);
+
     /**
      * Get whether this radio button is currently selected.
      *
@@ -120,6 +131,11 @@ protected:
      */
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
+    /**
+     * @see Control::initialize
+     */
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
+
     /**
      * Keyboard callback on key events.
      *

+ 29 - 17
gameplay/src/Slider.cpp

@@ -24,29 +24,41 @@ Slider::~Slider()
 {
 }
 
-Control* Slider::create(Theme::Style* style, Properties* properties)
+Slider* Slider::create(const char* id, Theme::Style* style)
 {
     Slider* slider = new Slider();
-    slider->initialize(style, properties);
-
-	if (properties)
-	{
-		slider->_min = properties->getFloat("min");
-		slider->_max = properties->getFloat("max");
-		slider->_value = properties->getFloat("value");
-		slider->_step = properties->getFloat("step");
-		slider->_valueTextVisible = properties->getBool("valueTextVisible");
-		slider->_valueTextPrecision = properties->getInt("valueTextPrecision");
-
-		if (properties->exists("valueTextAlignment"))
-		{
-			slider->_valueTextAlignment = Font::getJustify(properties->getString("valueTextAlignment"));
-		}
-	}
+    slider->_id = id ? id : "";
+    slider->initialize("Slider", style, NULL);
+    return slider;
+}
 
+Control* Slider::create(Theme::Style* style, Properties* properties)
+{
+    Slider* slider = new Slider();
+    slider->initialize("Slider", style, properties);
     return slider;
 }
 
+void Slider::initialize(const char* typeName, Theme::Style* style, Properties* properties)
+{
+    Label::initialize(typeName, style, properties);
+
+    if (properties)
+    {
+        _min = properties->getFloat("min");
+        _max = properties->getFloat("max");
+        _value = properties->getFloat("value");
+        _step = properties->getFloat("step");
+        _valueTextVisible = properties->getBool("valueTextVisible");
+        _valueTextPrecision = properties->getInt("valueTextPrecision");
+
+        if (properties->exists("valueTextAlignment"))
+        {
+            _valueTextAlignment = Font::getJustify(properties->getString("valueTextAlignment"));
+        }
+    }
+}
+
 void Slider::setMin(float min)
 {
     if (_min != _min)

+ 16 - 0
gameplay/src/Slider.h

@@ -37,6 +37,17 @@ class Slider : public Label
 
 public:
 
+    /**
+     * Creates a new Slider.
+     *
+     * @param id The slider ID.
+     * @param style The slider style (optional).
+     *
+     * @return The new slider.
+     * @script{create}
+     */
+    static Slider* create(const char* id, Theme::Style* style = NULL);
+
     /**
      * Set the minimum value that can be set on this slider.
      *
@@ -176,6 +187,11 @@ protected:
      */
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
+    /**
+     * @see Control::initialize
+     */
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
+
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.
      *

+ 11 - 4
gameplay/src/TextBox.cpp

@@ -18,17 +18,24 @@ TextBox::~TextBox()
 {
 }
 
-Control* TextBox::create(Theme::Style* style, Properties* properties)
+TextBox* TextBox::create(const char* id, Theme::Style* style)
 {
     TextBox* textBox = new TextBox();
-    textBox->initialize(style, properties);
+    textBox->_id = id ? id : "";
+    textBox->initialize("TextBox", style, NULL);
+    return textBox;
+}
 
+Control* TextBox::create(Theme::Style* style, Properties* properties)
+{
+    TextBox* textBox = new TextBox();
+    textBox->initialize("TextBox", style, properties);
     return textBox;
 }
 
-void TextBox::initialize(Theme::Style* style, Properties* properties)
+void TextBox::initialize(const char* typeName, Theme::Style* style, Properties* properties)
 {
-    Label::initialize(style, properties);
+    Label::initialize(typeName, style, properties);
 
 	if (properties)
 	{

+ 13 - 2
gameplay/src/TextBox.h

@@ -58,9 +58,15 @@ public:
     };
 
     /**
-     * Initialize this textbox.
+     * Creates a new TextBox.
+     *
+     * @param id The textbox ID.
+     * @param style The textbox style (optional).
+     *
+     * @return The new textbox.
+     * @script{create}
      */
-    virtual void initialize(Theme::Style* style, Properties* properties);
+    static TextBox* create(const char* id, Theme::Style* style = NULL);
 
     /**
      * Returns the current location of the caret with the text of this TextBox.
@@ -138,6 +144,11 @@ protected:
      */
     static Control* create(Theme::Style* style, Properties* properties = NULL);
 
+    /**
+     * @see Control::initialize
+     */
+    void initialize(const char* typeName, Theme::Style* style, Properties* properties);
+
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.
      *

+ 25 - 32
gameplay/src/Theme.cpp

@@ -68,23 +68,18 @@ Theme* Theme::getDefault()
 				__defaultTheme = Theme::create(defaultTheme);
 		}
 
-		// Look for a default.theme file at the root of the resource directory
-		if (!__defaultTheme)
-		{
-			__defaultTheme = Theme::create("res/default.theme");
-		}
-
 		// TODO: Use a built-in (compiled-in) default theme resource as the final fallback so that
 		// UI still works even when no theme files are present.
 	}
-	else
-	{
-		__defaultTheme->addRef();
-	}
 
 	return __defaultTheme;
 }
 
+void Theme::finalize()
+{
+    SAFE_RELEASE(__defaultTheme);
+}
+
 Theme* Theme::create(const char* url)
 {
     GP_ASSERT(url);
@@ -113,7 +108,7 @@ Theme* Theme::create(const char* url)
     // Check if the Properties is valid and has a valid namespace.
     Properties* themeProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
     GP_ASSERT(themeProperties);
-    if (!themeProperties || !(strcmp(themeProperties->getNamespace(), "theme") == 0))
+    if (!themeProperties || !(strcmpnocase(themeProperties->getNamespace(), "theme") == 0))
     {
         SAFE_DELETE(properties);
         return NULL;
@@ -142,22 +137,22 @@ Theme* Theme::create(const char* url)
         // First load all cursors, checkboxes etc. that can be referred to by styles.
         const char* spacename = space->getNamespace();
             
-        if (strcmp(spacename, "image") == 0)
+        if (strcmpnocase(spacename, "image") == 0)
         {
             theme->_images.push_back(ThemeImage::create(tw, th, space, Vector4::one()));
         }
-        else if (strcmp(spacename, "imageList") == 0)
+        else if (strcmpnocase(spacename, "imageList") == 0)
         {
             theme->_imageLists.push_back(ImageList::create(tw, th, space));
         }
-        else if (strcmp(spacename, "skin") == 0)
+        else if (strcmpnocase(spacename, "skin") == 0)
         {
             Theme::Border border;
             Properties* innerSpace = space->getNextNamespace();
             if (innerSpace)
             {
                 const char* innerSpacename = innerSpace->getNamespace();
-                if (strcmp(innerSpacename, "border") == 0)
+                if (strcmpnocase(innerSpacename, "border") == 0)
                 {
                     border.top = innerSpace->getFloat("top");
                     border.bottom = innerSpace->getFloat("bottom");
@@ -189,7 +184,7 @@ Theme* Theme::create(const char* url)
     while (space != NULL)
     {
         const char* spacename = space->getNamespace();
-        if (strcmp(spacename, "style") == 0)
+        if (strcmpnocase(spacename, "style") == 0)
         {
             // Each style contains up to MAX_OVERLAYS overlays,
             // as well as Border and Padding namespaces.
@@ -206,7 +201,7 @@ Theme* Theme::create(const char* url)
             while (innerSpace != NULL)
             {
                 const char* innerSpacename = innerSpace->getNamespace();
-                if (strcmp(innerSpacename, "stateNormal") == 0)
+                if (strcmpnocase(innerSpacename, "stateNormal") == 0)
                 {
                     Vector4 textColor(0, 0, 0, 1);
                     if (innerSpace->exists("textColor"))
@@ -274,21 +269,21 @@ Theme* Theme::create(const char* url)
             while (innerSpace != NULL)
             {
                 const char* innerSpacename = innerSpace->getNamespace();
-                if (strcmp(innerSpacename, "margin") == 0)
+                if (strcmpnocase(innerSpacename, "margin") == 0)
                 {
                     margin.top = innerSpace->getFloat("top");
                     margin.bottom = innerSpace->getFloat("bottom");
                     margin.left = innerSpace->getFloat("left");
                     margin.right = innerSpace->getFloat("right");
                 }
-                else if (strcmp(innerSpacename, "padding") == 0)
+                else if (strcmpnocase(innerSpacename, "padding") == 0)
                 {
                     padding.top = innerSpace->getFloat("top");
                     padding.bottom = innerSpace->getFloat("bottom");
                     padding.left = innerSpace->getFloat("left");
                     padding.right = innerSpace->getFloat("right");
                 }
-                else if (strcmp(innerSpacename, "stateNormal") != 0)
+                else if (strcmpnocase(innerSpacename, "stateNormal") != 0)
                 {
                     // Either OVERLAY_FOCUS or OVERLAY_ACTIVE.
                     // If a property isn't specified, it inherits from OVERLAY_NORMAL.
@@ -372,7 +367,7 @@ Theme* Theme::create(const char* url)
                         skin = normal->getSkin();
                     }
 
-                    if (strcmp(innerSpacename, "stateFocus") == 0)
+                    if (strcmpnocase(innerSpacename, "stateFocus") == 0)
                     {
                         focus = Theme::Style::Overlay::create();
                         GP_ASSERT(focus);
@@ -392,7 +387,7 @@ Theme* Theme::create(const char* url)
                             font->release();
                         }
                     }
-                    else if (strcmp(innerSpacename, "stateActive") == 0)
+                    else if (strcmpnocase(innerSpacename, "stateActive") == 0)
                     {
                         active = Theme::Style::Overlay::create();
                         GP_ASSERT(active);
@@ -412,7 +407,7 @@ Theme* Theme::create(const char* url)
                             font->release();
                         }
                     }
-                    else if (strcmp(innerSpacename, "stateDisabled") == 0)
+                    else if (strcmpnocase(innerSpacename, "stateDisabled") == 0)
                     {
                         disabled = Theme::Style::Overlay::create();
                         GP_ASSERT(disabled);
@@ -432,7 +427,7 @@ Theme* Theme::create(const char* url)
                             font->release();
                         }
                     }
-                    else if (strcmp(innerSpacename, "stateHover") == 0)
+                    else if (strcmpnocase(innerSpacename, "stateHover") == 0)
                     {
                         hover = Theme::Style::Overlay::create();
                         GP_ASSERT(hover);
@@ -456,7 +451,7 @@ Theme* Theme::create(const char* url)
 
                 innerSpace = space->getNextNamespace();
             }
-                
+
             if (!focus)
             {
                 focus = normal;
@@ -488,8 +483,6 @@ Theme* Theme::create(const char* url)
     return theme;
 }
 
-strcmpi
-
 Theme::Style* Theme::getStyle(const char* name) const
 {
     GP_ASSERT(name);
@@ -497,7 +490,7 @@ Theme::Style* Theme::getStyle(const char* name) const
     for (size_t i = 0, count = _styles.size(); i < count; ++i)
     {
         GP_ASSERT(_styles[i]);
-        if (strcmp(name, _styles[i]->getId()) == 0)
+        if (strcmpnocase(name, _styles[i]->getId()) == 0)
         {
             return _styles[i];
         }
@@ -704,7 +697,7 @@ Theme::ThemeImage* Theme::ImageList::getImage(const char* imageId) const
         ThemeImage* image = *it;
         GP_ASSERT(image);
         GP_ASSERT(image->getId());
-        if (strcmp(image->getId(), imageId) == 0)
+        if (strcmpnocase(image->getId(), imageId) == 0)
         {
             return image;
         }
@@ -846,7 +839,7 @@ void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList,
         {
             GP_ASSERT(_imageLists[i]);
             GP_ASSERT(_imageLists[i]->getId());
-            if (strcmp(_imageLists[i]->getId(), imageListString) == 0)
+            if (strcmpnocase(_imageLists[i]->getId(), imageListString) == 0)
             {
                 GP_ASSERT(imageList);
                 *imageList = _imageLists[i];
@@ -862,7 +855,7 @@ void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList,
         {
             GP_ASSERT(_images[i]);
             GP_ASSERT(_images[i]->getId());
-            if (strcmp(_images[i]->getId(), cursorString) == 0)
+            if (strcmpnocase(_images[i]->getId(), cursorString) == 0)
             {
                 GP_ASSERT(cursor);
                 *cursor = _images[i];
@@ -878,7 +871,7 @@ void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList,
         {
             GP_ASSERT(_skins[i]);
             GP_ASSERT(_skins[i]->getId());
-            if (strcmp(_skins[i]->getId(), skinString) == 0)
+            if (strcmpnocase(_skins[i]->getId(), skinString) == 0)
             {
                 GP_ASSERT(skin);
                 *skin = _skins[i];

+ 6 - 3
gameplay/src/Theme.h

@@ -137,6 +137,7 @@ class Theme: public Ref
     friend class Control;
     friend class Form;
     friend class Skin;
+    friend class Game;
 
 public:
 
@@ -310,9 +311,6 @@ public:
 
     /**
      * Returns the default theme.
-	 *
-	 * Calling this method increases the reference count of the returned theme,
-	 * so you must ensure you call release() on it when you are finished with it.
      *
      * @return The default theme.
      */
@@ -460,6 +458,11 @@ private:
      */
     ~Theme();
 
+    /**
+     * Cleans up any theme related resources when the game shuts down.
+     */
+    static void finalize();
+
     /**
      * Hidden copy assignment operator.
      */

+ 1 - 0
gameplay/src/ThemeStyle.cpp

@@ -22,6 +22,7 @@ Theme::Style::Style(Theme* theme, const char* id, float tw, float th,
 
 Theme::Style::Style(const Style& copy)
 {
+    _theme = copy._theme;
     _id = copy._id;
     _margin = copy._margin;
     _padding = copy._padding;

+ 112 - 1
gameplay/src/lua/lua_Button.cpp

@@ -14,6 +14,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -72,6 +73,7 @@ void luaRegister_Button()
         {"getTextAlignment", lua_Button_getTextAlignment},
         {"getTextColor", lua_Button_getTextColor},
         {"getTextRightToLeft", lua_Button_getTextRightToLeft},
+        {"getTheme", lua_Button_getTheme},
         {"getTopLevelForm", lua_Button_getTopLevelForm},
         {"getWidth", lua_Button_getWidth},
         {"getX", lua_Button_getX},
@@ -107,6 +109,7 @@ void luaRegister_Button()
         {"setFont", lua_Button_setFont},
         {"setFontSize", lua_Button_setFontSize},
         {"setHeight", lua_Button_setHeight},
+        {"setId", lua_Button_setId},
         {"setImageColor", lua_Button_setImageColor},
         {"setImageRegion", lua_Button_setImageRegion},
         {"setMargin", lua_Button_setMargin},
@@ -2487,6 +2490,50 @@ int lua_Button_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_Button_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -3983,6 +4030,42 @@ int lua_Button_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Button_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Button* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setId - 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_Button_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5150,6 +5233,34 @@ int lua_Button_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)Button::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Button");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5190,7 +5301,7 @@ int lua_Button_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -50,6 +50,7 @@ int lua_Button_getText(lua_State* state);
 int lua_Button_getTextAlignment(lua_State* state);
 int lua_Button_getTextColor(lua_State* state);
 int lua_Button_getTextRightToLeft(lua_State* state);
+int lua_Button_getTheme(lua_State* state);
 int lua_Button_getTopLevelForm(lua_State* state);
 int lua_Button_getWidth(lua_State* state);
 int lua_Button_getX(lua_State* state);
@@ -85,6 +86,7 @@ int lua_Button_setFocusIndex(lua_State* state);
 int lua_Button_setFont(lua_State* state);
 int lua_Button_setFontSize(lua_State* state);
 int lua_Button_setHeight(lua_State* state);
+int lua_Button_setId(lua_State* state);
 int lua_Button_setImageColor(lua_State* state);
 int lua_Button_setImageRegion(lua_State* state);
 int lua_Button_setMargin(lua_State* state);

+ 112 - 1
gameplay/src/lua/lua_CheckBox.cpp

@@ -15,6 +15,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -74,6 +75,7 @@ void luaRegister_CheckBox()
         {"getTextAlignment", lua_CheckBox_getTextAlignment},
         {"getTextColor", lua_CheckBox_getTextColor},
         {"getTextRightToLeft", lua_CheckBox_getTextRightToLeft},
+        {"getTheme", lua_CheckBox_getTheme},
         {"getTopLevelForm", lua_CheckBox_getTopLevelForm},
         {"getType", lua_CheckBox_getType},
         {"getWidth", lua_CheckBox_getWidth},
@@ -112,6 +114,7 @@ void luaRegister_CheckBox()
         {"setFont", lua_CheckBox_setFont},
         {"setFontSize", lua_CheckBox_setFontSize},
         {"setHeight", lua_CheckBox_setHeight},
+        {"setId", lua_CheckBox_setId},
         {"setImageColor", lua_CheckBox_setImageColor},
         {"setImageRegion", lua_CheckBox_setImageRegion},
         {"setImageSize", lua_CheckBox_setImageSize},
@@ -2537,6 +2540,50 @@ int lua_CheckBox_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_CheckBox_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4139,6 +4186,42 @@ int lua_CheckBox_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_CheckBox_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                CheckBox* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setId - 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_CheckBox_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5346,6 +5429,34 @@ int lua_CheckBox_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)CheckBox::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "CheckBox");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5386,7 +5497,7 @@ int lua_CheckBox_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -51,6 +51,7 @@ int lua_CheckBox_getText(lua_State* state);
 int lua_CheckBox_getTextAlignment(lua_State* state);
 int lua_CheckBox_getTextColor(lua_State* state);
 int lua_CheckBox_getTextRightToLeft(lua_State* state);
+int lua_CheckBox_getTheme(lua_State* state);
 int lua_CheckBox_getTopLevelForm(lua_State* state);
 int lua_CheckBox_getType(lua_State* state);
 int lua_CheckBox_getWidth(lua_State* state);
@@ -89,6 +90,7 @@ int lua_CheckBox_setFocusIndex(lua_State* state);
 int lua_CheckBox_setFont(lua_State* state);
 int lua_CheckBox_setFontSize(lua_State* state);
 int lua_CheckBox_setHeight(lua_State* state);
+int lua_CheckBox_setId(lua_State* state);
 int lua_CheckBox_setImageColor(lua_State* state);
 int lua_CheckBox_setImageRegion(lua_State* state);
 int lua_CheckBox_setImageSize(lua_State* state);

+ 150 - 1
gameplay/src/lua/lua_Container.cpp

@@ -9,6 +9,7 @@
 #include "CheckBox.h"
 #include "Container.h"
 #include "Control.h"
+#include "ControlFactory.h"
 #include "FlowLayout.h"
 #include "Form.h"
 #include "Game.h"
@@ -23,6 +24,7 @@
 #include "ScriptTarget.h"
 #include "Slider.h"
 #include "TextBox.h"
+#include "Theme.h"
 #include "VerticalLayout.h"
 #include "lua_ContainerScroll.h"
 #include "lua_ControlAlignment.h"
@@ -93,6 +95,7 @@ void luaRegister_Container()
         {"getTextAlignment", lua_Container_getTextAlignment},
         {"getTextColor", lua_Container_getTextColor},
         {"getTextRightToLeft", lua_Container_getTextRightToLeft},
+        {"getTheme", lua_Container_getTheme},
         {"getTopLevelForm", lua_Container_getTopLevelForm},
         {"getType", lua_Container_getType},
         {"getWidth", lua_Container_getWidth},
@@ -135,8 +138,10 @@ void luaRegister_Container()
         {"setFont", lua_Container_setFont},
         {"setFontSize", lua_Container_setFontSize},
         {"setHeight", lua_Container_setHeight},
+        {"setId", lua_Container_setId},
         {"setImageColor", lua_Container_setImageColor},
         {"setImageRegion", lua_Container_setImageRegion},
+        {"setLayout", lua_Container_setLayout},
         {"setMargin", lua_Container_setMargin},
         {"setOpacity", lua_Container_setOpacity},
         {"setPadding", lua_Container_setPadding},
@@ -2916,6 +2921,50 @@ int lua_Container_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_Container_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4712,6 +4761,42 @@ int lua_Container_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Container_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Container* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setId - 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_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -4868,6 +4953,42 @@ int lua_Container_setImageRegion(lua_State* state)
     return 0;
 }
 
+int lua_Container_setLayout(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Layout::Type param1 = (Layout::Type)lua_enumFromString_LayoutType(luaL_checkstring(state, 2));
+
+                Container* instance = getInstance(state);
+                instance->setLayout(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setLayout - 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_setMargin(lua_State* state)
 {
     // Get the number of parameters.
@@ -6082,6 +6203,34 @@ int lua_Container_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)Container::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Container");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -6164,7 +6313,7 @@ int lua_Container_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1, 2 or 3).");
             lua_error(state);
             break;
         }

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

@@ -59,6 +59,7 @@ int lua_Container_getStyle(lua_State* state);
 int lua_Container_getTextAlignment(lua_State* state);
 int lua_Container_getTextColor(lua_State* state);
 int lua_Container_getTextRightToLeft(lua_State* state);
+int lua_Container_getTheme(lua_State* state);
 int lua_Container_getTopLevelForm(lua_State* state);
 int lua_Container_getType(lua_State* state);
 int lua_Container_getWidth(lua_State* state);
@@ -101,8 +102,10 @@ int lua_Container_setFocusIndex(lua_State* state);
 int lua_Container_setFont(lua_State* state);
 int lua_Container_setFontSize(lua_State* state);
 int lua_Container_setHeight(lua_State* state);
+int lua_Container_setId(lua_State* state);
 int lua_Container_setImageColor(lua_State* state);
 int lua_Container_setImageRegion(lua_State* state);
+int lua_Container_setLayout(lua_State* state);
 int lua_Container_setMargin(lua_State* state);
 int lua_Container_setOpacity(lua_State* state);
 int lua_Container_setPadding(lua_State* state);

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

@@ -11,6 +11,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -68,6 +69,7 @@ void luaRegister_Control()
         {"getTextAlignment", lua_Control_getTextAlignment},
         {"getTextColor", lua_Control_getTextColor},
         {"getTextRightToLeft", lua_Control_getTextRightToLeft},
+        {"getTheme", lua_Control_getTheme},
         {"getTopLevelForm", lua_Control_getTopLevelForm},
         {"getType", lua_Control_getType},
         {"getWidth", lua_Control_getWidth},
@@ -104,6 +106,7 @@ void luaRegister_Control()
         {"setFont", lua_Control_setFont},
         {"setFontSize", lua_Control_setFontSize},
         {"setHeight", lua_Control_setHeight},
+        {"setId", lua_Control_setId},
         {"setImageColor", lua_Control_setImageColor},
         {"setImageRegion", lua_Control_setImageRegion},
         {"setMargin", lua_Control_setMargin},
@@ -2447,6 +2450,50 @@ int lua_Control_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_Control_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Control_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -3978,6 +4025,42 @@ int lua_Control_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Control_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Control* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setId - 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_Control_setImageColor(lua_State* state)
 {
     // Get the number of parameters.

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

@@ -49,6 +49,7 @@ int lua_Control_getStyle(lua_State* state);
 int lua_Control_getTextAlignment(lua_State* state);
 int lua_Control_getTextColor(lua_State* state);
 int lua_Control_getTextRightToLeft(lua_State* state);
+int lua_Control_getTheme(lua_State* state);
 int lua_Control_getTopLevelForm(lua_State* state);
 int lua_Control_getType(lua_State* state);
 int lua_Control_getWidth(lua_State* state);
@@ -85,6 +86,7 @@ int lua_Control_setFocusIndex(lua_State* state);
 int lua_Control_setFont(lua_State* state);
 int lua_Control_setFontSize(lua_State* state);
 int lua_Control_setHeight(lua_State* state);
+int lua_Control_setId(lua_State* state);
 int lua_Control_setImageColor(lua_State* state);
 int lua_Control_setImageRegion(lua_State* state);
 int lua_Control_setMargin(lua_State* state);

+ 1 - 0
gameplay/src/lua/lua_ControlListener.cpp

@@ -11,6 +11,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"

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

@@ -9,6 +9,7 @@
 #include "CheckBox.h"
 #include "Container.h"
 #include "Control.h"
+#include "ControlFactory.h"
 #include "FlowLayout.h"
 #include "Form.h"
 #include "Game.h"
@@ -139,8 +140,10 @@ void luaRegister_Form()
         {"setFont", lua_Form_setFont},
         {"setFontSize", lua_Form_setFontSize},
         {"setHeight", lua_Form_setHeight},
+        {"setId", lua_Form_setId},
         {"setImageColor", lua_Form_setImageColor},
         {"setImageRegion", lua_Form_setImageRegion},
+        {"setLayout", lua_Form_setLayout},
         {"setMargin", lua_Form_setMargin},
         {"setNode", lua_Form_setNode},
         {"setOpacity", lua_Form_setOpacity},
@@ -4801,6 +4804,42 @@ int lua_Form_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Form_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Form* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setId - 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_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -4957,6 +4996,42 @@ int lua_Form_setImageRegion(lua_State* state)
     return 0;
 }
 
+int lua_Form_setLayout(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Layout::Type param1 = (Layout::Type)lua_enumFromString_LayoutType(luaL_checkstring(state, 2));
+
+                Form* instance = getInstance(state);
+                instance->setLayout(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setLayout - 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_setMargin(lua_State* state)
 {
     // Get the number of parameters.

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

@@ -103,8 +103,10 @@ int lua_Form_setFocusIndex(lua_State* state);
 int lua_Form_setFont(lua_State* state);
 int lua_Form_setFontSize(lua_State* state);
 int lua_Form_setHeight(lua_State* state);
+int lua_Form_setId(lua_State* state);
 int lua_Form_setImageColor(lua_State* state);
 int lua_Form_setImageRegion(lua_State* state);
+int lua_Form_setLayout(lua_State* state);
 int lua_Form_setMargin(lua_State* state);
 int lua_Form_setNode(lua_State* state);
 int lua_Form_setOpacity(lua_State* state);

+ 2 - 0
gameplay/src/lua/lua_Game.cpp

@@ -2,12 +2,14 @@
 #include "ScriptController.h"
 #include "lua_Game.h"
 #include "Base.h"
+#include "ControlFactory.h"
 #include "FileSystem.h"
 #include "FrameBuffer.h"
 #include "Game.h"
 #include "Platform.h"
 #include "RenderState.h"
 #include "SceneLoader.h"
+#include "Theme.h"
 #include "lua_GameClearFlags.h"
 #include "lua_GameState.h"
 #include "lua_GamepadGamepadEvent.h"

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

@@ -6,6 +6,7 @@ namespace gameplay
 
 void luaRegister_lua_Global()
 {
+    gameplay::ScriptUtil::registerFunction("strcmpnocase", lua__strcmpnocase);
     gameplay::ScriptUtil::setGlobalHierarchyPair("AnimationTarget", "Button");
     gameplay::ScriptUtil::setGlobalHierarchyPair("AnimationTarget", "CheckBox");
     gameplay::ScriptUtil::setGlobalHierarchyPair("AnimationTarget", "Container");
@@ -917,6 +918,47 @@ void luaRegister_lua_Global()
     }
 }
 
+int lua__strcmpnocase(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_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = gameplay::ScriptUtil::getString(2, false);
+
+                int result = strcmpnocase(param1, param2);
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua__strcmpnocase - 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;
+}
+
 static const char* enumStringEmpty = "";
 
 const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value)

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

@@ -55,6 +55,9 @@
 namespace gameplay
 {
 
+// Lua bindings for global functions.
+int lua__strcmpnocase(lua_State* state);
+
 // Global enum to string conversion function (used to pass enums to Lua from C++).
 const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value);
 

+ 112 - 1
gameplay/src/lua/lua_ImageControl.cpp

@@ -12,6 +12,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -71,6 +72,7 @@ void luaRegister_ImageControl()
         {"getTextAlignment", lua_ImageControl_getTextAlignment},
         {"getTextColor", lua_ImageControl_getTextColor},
         {"getTextRightToLeft", lua_ImageControl_getTextRightToLeft},
+        {"getTheme", lua_ImageControl_getTheme},
         {"getTopLevelForm", lua_ImageControl_getTopLevelForm},
         {"getType", lua_ImageControl_getType},
         {"getWidth", lua_ImageControl_getWidth},
@@ -107,6 +109,7 @@ void luaRegister_ImageControl()
         {"setFont", lua_ImageControl_setFont},
         {"setFontSize", lua_ImageControl_setFontSize},
         {"setHeight", lua_ImageControl_setHeight},
+        {"setId", lua_ImageControl_setId},
         {"setImage", lua_ImageControl_setImage},
         {"setImageColor", lua_ImageControl_setImageColor},
         {"setImageRegion", lua_ImageControl_setImageRegion},
@@ -2542,6 +2545,50 @@ int lua_ImageControl_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_ImageControl_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_ImageControl_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4073,6 +4120,42 @@ int lua_ImageControl_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_ImageControl_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                ImageControl* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_ImageControl_setId - 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_ImageControl_setImage(lua_State* state)
 {
     // Get the number of parameters.
@@ -5390,6 +5473,34 @@ int lua_ImageControl_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)ImageControl::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "ImageControl");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_ImageControl_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5430,7 +5541,7 @@ int lua_ImageControl_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -51,6 +51,7 @@ int lua_ImageControl_getStyle(lua_State* state);
 int lua_ImageControl_getTextAlignment(lua_State* state);
 int lua_ImageControl_getTextColor(lua_State* state);
 int lua_ImageControl_getTextRightToLeft(lua_State* state);
+int lua_ImageControl_getTheme(lua_State* state);
 int lua_ImageControl_getTopLevelForm(lua_State* state);
 int lua_ImageControl_getType(lua_State* state);
 int lua_ImageControl_getWidth(lua_State* state);
@@ -87,6 +88,7 @@ int lua_ImageControl_setFocusIndex(lua_State* state);
 int lua_ImageControl_setFont(lua_State* state);
 int lua_ImageControl_setFontSize(lua_State* state);
 int lua_ImageControl_setHeight(lua_State* state);
+int lua_ImageControl_setId(lua_State* state);
 int lua_ImageControl_setImage(lua_State* state);
 int lua_ImageControl_setImageColor(lua_State* state);
 int lua_ImageControl_setImageRegion(lua_State* state);

+ 112 - 1
gameplay/src/lua/lua_Joystick.cpp

@@ -12,6 +12,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -72,6 +73,7 @@ void luaRegister_Joystick()
         {"getTextAlignment", lua_Joystick_getTextAlignment},
         {"getTextColor", lua_Joystick_getTextColor},
         {"getTextRightToLeft", lua_Joystick_getTextRightToLeft},
+        {"getTheme", lua_Joystick_getTheme},
         {"getTopLevelForm", lua_Joystick_getTopLevelForm},
         {"getType", lua_Joystick_getType},
         {"getValue", lua_Joystick_getValue},
@@ -110,6 +112,7 @@ void luaRegister_Joystick()
         {"setFont", lua_Joystick_setFont},
         {"setFontSize", lua_Joystick_setFontSize},
         {"setHeight", lua_Joystick_setHeight},
+        {"setId", lua_Joystick_setId},
         {"setImageColor", lua_Joystick_setImageColor},
         {"setImageRegion", lua_Joystick_setImageRegion},
         {"setInnerRegionSize", lua_Joystick_setInnerRegionSize},
@@ -2580,6 +2583,50 @@ int lua_Joystick_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_Joystick_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Joystick_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4190,6 +4237,42 @@ int lua_Joystick_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Joystick_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Joystick* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Joystick_setId - 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_Joystick_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5441,6 +5524,34 @@ int lua_Joystick_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)Joystick::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Joystick");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Joystick_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5481,7 +5592,7 @@ int lua_Joystick_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -52,6 +52,7 @@ int lua_Joystick_getStyle(lua_State* state);
 int lua_Joystick_getTextAlignment(lua_State* state);
 int lua_Joystick_getTextColor(lua_State* state);
 int lua_Joystick_getTextRightToLeft(lua_State* state);
+int lua_Joystick_getTheme(lua_State* state);
 int lua_Joystick_getTopLevelForm(lua_State* state);
 int lua_Joystick_getType(lua_State* state);
 int lua_Joystick_getValue(lua_State* state);
@@ -90,6 +91,7 @@ int lua_Joystick_setFocusIndex(lua_State* state);
 int lua_Joystick_setFont(lua_State* state);
 int lua_Joystick_setFontSize(lua_State* state);
 int lua_Joystick_setHeight(lua_State* state);
+int lua_Joystick_setId(lua_State* state);
 int lua_Joystick_setImageColor(lua_State* state);
 int lua_Joystick_setImageRegion(lua_State* state);
 int lua_Joystick_setInnerRegionSize(lua_State* state);

+ 112 - 1
gameplay/src/lua/lua_Label.cpp

@@ -12,6 +12,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -70,6 +71,7 @@ void luaRegister_Label()
         {"getTextAlignment", lua_Label_getTextAlignment},
         {"getTextColor", lua_Label_getTextColor},
         {"getTextRightToLeft", lua_Label_getTextRightToLeft},
+        {"getTheme", lua_Label_getTheme},
         {"getTopLevelForm", lua_Label_getTopLevelForm},
         {"getType", lua_Label_getType},
         {"getWidth", lua_Label_getWidth},
@@ -106,6 +108,7 @@ void luaRegister_Label()
         {"setFont", lua_Label_setFont},
         {"setFontSize", lua_Label_setFontSize},
         {"setHeight", lua_Label_setHeight},
+        {"setId", lua_Label_setId},
         {"setImageColor", lua_Label_setImageColor},
         {"setImageRegion", lua_Label_setImageRegion},
         {"setMargin", lua_Label_setMargin},
@@ -2486,6 +2489,50 @@ int lua_Label_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_Label_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Label_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4017,6 +4064,42 @@ int lua_Label_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Label_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Label* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Label_setId - 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_Label_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5184,6 +5267,34 @@ int lua_Label_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)Label::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Label");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Label_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5224,7 +5335,7 @@ int lua_Label_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -50,6 +50,7 @@ int lua_Label_getText(lua_State* state);
 int lua_Label_getTextAlignment(lua_State* state);
 int lua_Label_getTextColor(lua_State* state);
 int lua_Label_getTextRightToLeft(lua_State* state);
+int lua_Label_getTheme(lua_State* state);
 int lua_Label_getTopLevelForm(lua_State* state);
 int lua_Label_getType(lua_State* state);
 int lua_Label_getWidth(lua_State* state);
@@ -86,6 +87,7 @@ int lua_Label_setFocusIndex(lua_State* state);
 int lua_Label_setFont(lua_State* state);
 int lua_Label_setFontSize(lua_State* state);
 int lua_Label_setHeight(lua_State* state);
+int lua_Label_setId(lua_State* state);
 int lua_Label_setImageColor(lua_State* state);
 int lua_Label_setImageRegion(lua_State* state);
 int lua_Label_setMargin(lua_State* state);

+ 112 - 1
gameplay/src/lua/lua_RadioButton.cpp

@@ -15,6 +15,7 @@
 #include "Ref.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -75,6 +76,7 @@ void luaRegister_RadioButton()
         {"getTextAlignment", lua_RadioButton_getTextAlignment},
         {"getTextColor", lua_RadioButton_getTextColor},
         {"getTextRightToLeft", lua_RadioButton_getTextRightToLeft},
+        {"getTheme", lua_RadioButton_getTheme},
         {"getTopLevelForm", lua_RadioButton_getTopLevelForm},
         {"getType", lua_RadioButton_getType},
         {"getWidth", lua_RadioButton_getWidth},
@@ -113,6 +115,7 @@ void luaRegister_RadioButton()
         {"setFontSize", lua_RadioButton_setFontSize},
         {"setGroupId", lua_RadioButton_setGroupId},
         {"setHeight", lua_RadioButton_setHeight},
+        {"setId", lua_RadioButton_setId},
         {"setImageColor", lua_RadioButton_setImageColor},
         {"setImageRegion", lua_RadioButton_setImageRegion},
         {"setImageSize", lua_RadioButton_setImageSize},
@@ -2574,6 +2577,50 @@ int lua_RadioButton_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_RadioButton_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_RadioButton_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4176,6 +4223,42 @@ int lua_RadioButton_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_RadioButton_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                RadioButton* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_RadioButton_setId - 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_RadioButton_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5419,6 +5502,34 @@ int lua_RadioButton_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)RadioButton::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "RadioButton");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_RadioButton_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5459,7 +5570,7 @@ int lua_RadioButton_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -52,6 +52,7 @@ int lua_RadioButton_getText(lua_State* state);
 int lua_RadioButton_getTextAlignment(lua_State* state);
 int lua_RadioButton_getTextColor(lua_State* state);
 int lua_RadioButton_getTextRightToLeft(lua_State* state);
+int lua_RadioButton_getTheme(lua_State* state);
 int lua_RadioButton_getTopLevelForm(lua_State* state);
 int lua_RadioButton_getType(lua_State* state);
 int lua_RadioButton_getWidth(lua_State* state);
@@ -90,6 +91,7 @@ int lua_RadioButton_setFont(lua_State* state);
 int lua_RadioButton_setFontSize(lua_State* state);
 int lua_RadioButton_setGroupId(lua_State* state);
 int lua_RadioButton_setHeight(lua_State* state);
+int lua_RadioButton_setId(lua_State* state);
 int lua_RadioButton_setImageColor(lua_State* state);
 int lua_RadioButton_setImageRegion(lua_State* state);
 int lua_RadioButton_setImageSize(lua_State* state);

+ 112 - 1
gameplay/src/lua/lua_Slider.cpp

@@ -13,6 +13,7 @@
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "Slider.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -74,6 +75,7 @@ void luaRegister_Slider()
         {"getTextAlignment", lua_Slider_getTextAlignment},
         {"getTextColor", lua_Slider_getTextColor},
         {"getTextRightToLeft", lua_Slider_getTextRightToLeft},
+        {"getTheme", lua_Slider_getTheme},
         {"getTopLevelForm", lua_Slider_getTopLevelForm},
         {"getType", lua_Slider_getType},
         {"getValue", lua_Slider_getValue},
@@ -114,6 +116,7 @@ void luaRegister_Slider()
         {"setFont", lua_Slider_setFont},
         {"setFontSize", lua_Slider_setFontSize},
         {"setHeight", lua_Slider_setHeight},
+        {"setId", lua_Slider_setId},
         {"setImageColor", lua_Slider_setImageColor},
         {"setImageRegion", lua_Slider_setImageRegion},
         {"setMargin", lua_Slider_setMargin},
@@ -2606,6 +2609,50 @@ int lua_Slider_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_Slider_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Slider_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -4277,6 +4324,42 @@ int lua_Slider_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_Slider_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                Slider* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Slider_setId - 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_Slider_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5696,6 +5779,34 @@ int lua_Slider_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)Slider::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Slider");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Slider_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5736,7 +5847,7 @@ int lua_Slider_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -53,6 +53,7 @@ int lua_Slider_getText(lua_State* state);
 int lua_Slider_getTextAlignment(lua_State* state);
 int lua_Slider_getTextColor(lua_State* state);
 int lua_Slider_getTextRightToLeft(lua_State* state);
+int lua_Slider_getTheme(lua_State* state);
 int lua_Slider_getTopLevelForm(lua_State* state);
 int lua_Slider_getType(lua_State* state);
 int lua_Slider_getValue(lua_State* state);
@@ -93,6 +94,7 @@ int lua_Slider_setFocusIndex(lua_State* state);
 int lua_Slider_setFont(lua_State* state);
 int lua_Slider_setFontSize(lua_State* state);
 int lua_Slider_setHeight(lua_State* state);
+int lua_Slider_setId(lua_State* state);
 int lua_Slider_setImageColor(lua_State* state);
 int lua_Slider_setImageRegion(lua_State* state);
 int lua_Slider_setMargin(lua_State* state);

+ 112 - 54
gameplay/src/lua/lua_TextBox.cpp

@@ -13,6 +13,7 @@
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "TextBox.h"
+#include "Theme.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
@@ -76,6 +77,7 @@ void luaRegister_TextBox()
         {"getTextAlignment", lua_TextBox_getTextAlignment},
         {"getTextColor", lua_TextBox_getTextColor},
         {"getTextRightToLeft", lua_TextBox_getTextRightToLeft},
+        {"getTheme", lua_TextBox_getTheme},
         {"getTopLevelForm", lua_TextBox_getTopLevelForm},
         {"getType", lua_TextBox_getType},
         {"getWidth", lua_TextBox_getWidth},
@@ -83,7 +85,6 @@ void luaRegister_TextBox()
         {"getY", lua_TextBox_getY},
         {"getZIndex", lua_TextBox_getZIndex},
         {"hasFocus", lua_TextBox_hasFocus},
-        {"initialize", lua_TextBox_initialize},
         {"isChild", lua_TextBox_isChild},
         {"isContainer", lua_TextBox_isContainer},
         {"isEnabled", lua_TextBox_isEnabled},
@@ -114,6 +115,7 @@ void luaRegister_TextBox()
         {"setFont", lua_TextBox_setFont},
         {"setFontSize", lua_TextBox_setFontSize},
         {"setHeight", lua_TextBox_setHeight},
+        {"setId", lua_TextBox_setId},
         {"setImageColor", lua_TextBox_setImageColor},
         {"setImageRegion", lua_TextBox_setImageRegion},
         {"setInputMode", lua_TextBox_setInputMode},
@@ -2636,6 +2638,50 @@ int lua_TextBox_getTextRightToLeft(lua_State* state)
     return 0;
 }
 
+int lua_TextBox_getTheme(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);
+                void* returnPtr = (void*)instance->getTheme();
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Theme");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_TextBox_getTheme - 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_getTopLevelForm(lua_State* state)
 {
     // Get the number of parameters.
@@ -2890,58 +2936,6 @@ int lua_TextBox_hasFocus(lua_State* state)
     return 0;
 }
 
-int lua_TextBox_initialize(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 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
-                (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                gameplay::ScriptUtil::LuaArray<Theme::Style> param1 = gameplay::ScriptUtil::getObjectPointer<Theme::Style>(2, "ThemeStyle", false, &param1Valid);
-                if (!param1Valid)
-                {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Theme::Style'.");
-                    lua_error(state);
-                }
-
-                // Get parameter 2 off the stack.
-                bool param2Valid;
-                gameplay::ScriptUtil::LuaArray<Properties> param2 = gameplay::ScriptUtil::getObjectPointer<Properties>(3, "Properties", false, &param2Valid);
-                if (!param2Valid)
-                {
-                    lua_pushstring(state, "Failed to convert parameter 2 to type 'Properties'.");
-                    lua_error(state);
-                }
-
-                TextBox* instance = getInstance(state);
-                instance->initialize(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_TextBox_initialize - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
 int lua_TextBox_isChild(lua_State* state)
 {
     // Get the number of parameters.
@@ -4255,6 +4249,42 @@ int lua_TextBox_setHeight(lua_State* state)
     return 0;
 }
 
+int lua_TextBox_setId(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(2, false);
+
+                TextBox* instance = getInstance(state);
+                instance->setId(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_TextBox_setId - 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_TextBox_setImageColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -5494,6 +5524,34 @@ int lua_TextBox_static_create(lua_State* state)
     // Attempt to match the parameters to a valid binding.
     switch (paramCount)
     {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)TextBox::create(param1);
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "TextBox");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_TextBox_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 2:
         {
             if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
@@ -5534,7 +5592,7 @@ int lua_TextBox_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

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

@@ -54,6 +54,7 @@ int lua_TextBox_getText(lua_State* state);
 int lua_TextBox_getTextAlignment(lua_State* state);
 int lua_TextBox_getTextColor(lua_State* state);
 int lua_TextBox_getTextRightToLeft(lua_State* state);
+int lua_TextBox_getTheme(lua_State* state);
 int lua_TextBox_getTopLevelForm(lua_State* state);
 int lua_TextBox_getType(lua_State* state);
 int lua_TextBox_getWidth(lua_State* state);
@@ -61,7 +62,6 @@ int lua_TextBox_getX(lua_State* state);
 int lua_TextBox_getY(lua_State* state);
 int lua_TextBox_getZIndex(lua_State* state);
 int lua_TextBox_hasFocus(lua_State* state);
-int lua_TextBox_initialize(lua_State* state);
 int lua_TextBox_isChild(lua_State* state);
 int lua_TextBox_isContainer(lua_State* state);
 int lua_TextBox_isEnabled(lua_State* state);
@@ -92,6 +92,7 @@ int lua_TextBox_setFocusIndex(lua_State* state);
 int lua_TextBox_setFont(lua_State* state);
 int lua_TextBox_setFontSize(lua_State* state);
 int lua_TextBox_setHeight(lua_State* state);
+int lua_TextBox_setId(lua_State* state);
 int lua_TextBox_setImageColor(lua_State* state);
 int lua_TextBox_setImageRegion(lua_State* state);
 int lua_TextBox_setInputMode(lua_State* state);

+ 39 - 0
gameplay/src/lua/lua_Theme.cpp

@@ -2,6 +2,7 @@
 #include "ScriptController.h"
 #include "lua_Theme.h"
 #include "Base.h"
+#include "FileSystem.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Theme.h"
@@ -24,6 +25,7 @@ void luaRegister_Theme()
     const luaL_Reg lua_statics[] = 
     {
         {"create", lua_Theme_static_create},
+        {"getDefault", lua_Theme_static_getDefault},
         {NULL, NULL}
     };
     std::vector<std::string> scopePath;
@@ -313,4 +315,41 @@ int lua_Theme_static_create(lua_State* state)
     return 0;
 }
 
+int lua_Theme_static_getDefault(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 0:
+        {
+            void* returnPtr = (void*)Theme::getDefault();
+            if (returnPtr)
+            {
+                gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "Theme");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }

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

@@ -12,6 +12,7 @@ int lua_Theme_getRefCount(lua_State* state);
 int lua_Theme_getStyle(lua_State* state);
 int lua_Theme_release(lua_State* state);
 int lua_Theme_static_create(lua_State* state);
+int lua_Theme_static_getDefault(lua_State* state);
 
 void luaRegister_Theme();
 

+ 1 - 0
gameplay/src/lua/lua_ThemeSideRegions.cpp

@@ -2,6 +2,7 @@
 #include "ScriptController.h"
 #include "lua_ThemeSideRegions.h"
 #include "Base.h"
+#include "FileSystem.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Theme.h"

+ 1 - 0
gameplay/src/lua/lua_ThemeThemeImage.cpp

@@ -2,6 +2,7 @@
 #include "ScriptController.h"
 #include "lua_ThemeThemeImage.h"
 #include "Base.h"
+#include "FileSystem.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Theme.h"

+ 1 - 0
gameplay/src/lua/lua_ThemeUVs.cpp

@@ -2,6 +2,7 @@
 #include "ScriptController.h"
 #include "lua_ThemeUVs.h"
 #include "Base.h"
+#include "FileSystem.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Theme.h"

+ 8 - 8
samples/browser/src/SamplesGame.cpp

@@ -27,14 +27,14 @@ void SamplesGame::initialize()
     getScriptController()->loadScript("res/common/camera.lua");
 
     // Construct a form for selecting which sample to run.
-    //Theme* theme = Theme::create("res/common/default.theme");
-    //Theme::Style* formStyle = theme->getStyle("basicContainer");
-    //Theme::Style* buttonStyle = theme->getStyle("buttonStyle");
-    //Theme::Style* titleStyle = theme->getStyle("title");
+    Theme* theme = Theme::create("res/common/default.theme");
+    Theme::Style* formStyle = theme->getStyle("basicContainer");
+    Theme::Style* buttonStyle = theme->getStyle("buttonStyle");
+    Theme::Style* titleStyle = theme->getStyle("title");
 
     // Note: this calls addRef() on formStyle's Theme, which we created above.
-    _sampleSelectForm = Form::create("sampleSelect", NULL, Layout::LAYOUT_VERTICAL);
-    //theme->release();   // So we can release it once we're done creating forms with it.
+    _sampleSelectForm = Form::create("sampleSelect", formStyle, Layout::LAYOUT_VERTICAL);
+    theme->release();   // So we can release it once we're done creating forms with it.
 
     _sampleSelectForm->setAutoHeight(true);
     _sampleSelectForm->setWidth(200.0f);
@@ -44,7 +44,7 @@ void SamplesGame::initialize()
     const size_t size = _samples->size();
     for (size_t i = 0; i < size; ++i)
     {
-        Label* categoryLabel = Label::create((*_categories)[i].c_str());// titleStyle);
+        Label* categoryLabel = Label::create((*_categories)[i].c_str(), titleStyle);
         categoryLabel->setAutoWidth(true);
         categoryLabel->setTextAlignment(Font::ALIGN_BOTTOM_LEFT);
         categoryLabel->setHeight(40);
@@ -58,7 +58,7 @@ void SamplesGame::initialize()
         for (size_t j = 0; j < listSize; ++j)
         {
             SampleRecord sampleRecord = list[j];
-            Button* sampleButton = Button::create(sampleRecord.title.c_str());// buttonStyle);
+            Button* sampleButton = Button::create(sampleRecord.title.c_str(), buttonStyle);
             sampleButton->setText(sampleRecord.title.c_str());
             sampleButton->setAutoWidth(true);
             sampleButton->setHeight(60);      // Tall enough to touch easily on a BB10 device.