Sfoglia il codice sorgente

CSS Box Model

This adds margin and padding to the GuiBorderProfile. With these fields in place, the profiles now mimic the CSS Box Model.
Peter Robinson 7 anni fa
parent
commit
66b8d40455
39 ha cambiato i file con 291 aggiunte e 256 eliminazioni
  1. 1 1
      engine/source/2d/core/ImageFrameProviderCore.cc
  2. 1 1
      engine/source/2d/gui/SceneWindow.cc
  3. 1 1
      engine/source/2d/gui/guiImageButtonCtrl.cc
  4. 1 1
      engine/source/2d/gui/guiSceneObjectCtrl.cc
  5. 24 35
      engine/source/gui/buttons/guiButtonCtrl.cc
  6. 37 22
      engine/source/gui/buttons/guiCheckBoxCtrl.cc
  7. 1 0
      engine/source/gui/buttons/guiCheckBoxCtrl.h
  8. 7 70
      engine/source/gui/buttons/guiRadioCtrl.cc
  9. 1 1
      engine/source/gui/buttons/guiRadioCtrl.h
  10. 1 1
      engine/source/gui/containers/guiFormCtrl.cc
  11. 1 1
      engine/source/gui/containers/guiFrameCtrl.cc
  12. 1 1
      engine/source/gui/containers/guiPaneCtrl.cc
  13. 1 1
      engine/source/gui/containers/guiRolloutCtrl.cc
  14. 1 1
      engine/source/gui/containers/guiScrollCtrl.cc
  15. 2 1
      engine/source/gui/containers/guiTabBookCtrl.cc
  16. 13 13
      engine/source/gui/containers/guiTabBookCtrl.h
  17. 1 1
      engine/source/gui/containers/guiWindowCtrl.cc
  18. 1 1
      engine/source/gui/editor/guiEditCtrl.cc
  19. 1 1
      engine/source/gui/editor/guiFilterCtrl.cc
  20. 1 1
      engine/source/gui/editor/guiMenuBar.cc
  21. 1 1
      engine/source/gui/editor/guiSeparatorCtrl.cc
  22. 1 1
      engine/source/gui/guiArrayCtrl.cc
  23. 1 1
      engine/source/gui/guiBackgroundCtrl.cc
  24. 1 1
      engine/source/gui/guiBitmapBorderCtrl.cc
  25. 2 2
      engine/source/gui/guiBitmapCtrl.cc
  26. 2 2
      engine/source/gui/guiColorPicker.cc
  27. 1 1
      engine/source/gui/guiConsoleTextCtrl.cc
  28. 96 9
      engine/source/gui/guiControl.cc
  29. 15 3
      engine/source/gui/guiControl.h
  30. 6 6
      engine/source/gui/guiDefaultControlRender.cc
  31. 1 1
      engine/source/gui/guiMLTextCtrl.h
  32. 2 2
      engine/source/gui/guiProgressCtrl.cc
  33. 1 1
      engine/source/gui/guiSliderCtrl.cc
  34. 2 2
      engine/source/gui/guiTabPageCtrl.cc
  35. 3 3
      engine/source/gui/guiTabPageCtrl.h
  36. 1 1
      engine/source/gui/guiTextCtrl.cc
  37. 1 1
      engine/source/gui/guiTextEditCtrl.cc
  38. 40 50
      engine/source/gui/guiTypes.cc
  39. 16 13
      engine/source/gui/guiTypes.h

+ 1 - 1
engine/source/2d/core/ImageFrameProviderCore.cc

@@ -290,7 +290,7 @@ void ImageFrameProviderCore::renderGui( GuiControl& owner, Point2I offset, const
     }
 
     // Render child controls.
-    owner.renderChildControls(offset, updateRect);
+    owner.renderChildControls(offset, updateRect, updateRect);
 }
 
 //------------------------------------------------------------------------------

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

@@ -1720,7 +1720,7 @@ void SceneWindow::onRender( Point2I offset, const RectI& updateRect )
     renderMetricsOverlay( offset, updateRect );
 
     // Render Children.
-    renderChildControls( offset, updateRect );
+    renderChildControls( offset, mBounds, updateRect );
 
     // Update Window.
     setUpdate();

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

@@ -272,7 +272,7 @@ void GuiImageButtonCtrl::renderButton( ImageAsset* pImageAsset, const U32 frame,
         dglSetBitmapModulation( mProfile->mFillColor );
         dglDrawBitmapStretchSR( pImageAsset->getImageTexture(), destinationRegion, sourceRegion );
         dglClearBitmapModulation();
-        renderChildControls( offset, updateRect);
+        renderChildControls( offset, mBounds, updateRect);
     }
     else
     {

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

@@ -476,5 +476,5 @@ void GuiSceneObjectCtrl::onRender(Point2I offset, const RectI& updateRect)
    
 
    // Render Child Controls.
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }

+ 24 - 35
engine/source/gui/buttons/guiButtonCtrl.cc

@@ -238,6 +238,7 @@ void GuiButtonCtrl::onAction()
 
 void GuiButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
 {
+
 	GuiControlState currentState = GuiControlState::NormalState;
 	if (!mActive)
 	{
@@ -252,46 +253,34 @@ void GuiButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
 		currentState = GuiControlState::HighlightState;
 	}
 
+	RectI ctrlRect = applyMargins(offset, mBounds.extent, currentState);
 	RectI boundsRect(offset, mBounds.extent);
 
-   if(mProfile->mBitmapName != NULL && mProfile->constructBitmapArray() >= 36)
-   {
-      S32 indexMultiplier = 1;
-      if ( currentState == HighlightState)
-         indexMultiplier = 2;
-      else if ( currentState == SelectedState )
-         indexMultiplier = 3;
-      else if ( currentState == DisabledState )
-         indexMultiplier = 4;
-
-      renderSizableBitmapBordersFilled( boundsRect, indexMultiplier, mProfile );
-   }
+	if(mProfile->mBitmapName != NULL && mProfile->constructBitmapArray() >= 36)
+	{
+		S32 indexMultiplier = 1;
+		if ( currentState == HighlightState)
+			indexMultiplier = 2;
+		else if ( currentState == SelectedState )
+			indexMultiplier = 3;
+		else if ( currentState == DisabledState )
+			indexMultiplier = 4;
+
+		renderSizableBitmapBordersFilled(ctrlRect, indexMultiplier, mProfile );
+	}
 	else
-   {
-	   renderBorderedRect(boundsRect, mProfile, currentState);
-   }
-
-	//Get the border profiles
-	GuiBorderProfile *leftProfile = (mProfile->mBorderLeft) ? mProfile->mBorderLeft : mProfile->mBorderDefault;
-	GuiBorderProfile *rightProfile = (mProfile->mBorderRight) ? mProfile->mBorderRight : mProfile->mBorderDefault;
-	GuiBorderProfile *topProfile = (mProfile->mBorderTop) ? mProfile->mBorderTop : mProfile->mBorderDefault;
-	GuiBorderProfile *bottomProfile = (mProfile->mBorderBottom) ? mProfile->mBorderBottom : mProfile->mBorderDefault;
-
-	S32 leftSize = (leftProfile) ? leftProfile->getBorder(currentState) : 0;
-	S32 rightSize = (rightProfile) ? rightProfile->getBorder(currentState) : 0;
-	S32 topSize = (topProfile) ? topProfile->getBorder(currentState) : 0;
-	S32 bottomSize = (bottomProfile) ? bottomProfile->getBorder(currentState) : 0;
-
-	//Get the inner rect
-	RectI innerRect = RectI(offset.x + leftSize, offset.y + topSize, (mBounds.extent.x - leftSize) - rightSize, (mBounds.extent.y - topSize) - bottomSize);
-
-	ColorI fontColor = mProfile->getFontColor(currentState);
+	{
+		renderBorderedRect(ctrlRect, mProfile, currentState);
+	}
 
-   dglSetBitmapModulation( fontColor );
-   renderJustifiedText(innerRect.point, innerRect.extent, mText);
+	//Render Text
+	dglSetBitmapModulation(mProfile->getFontColor(currentState));
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState);
+	renderJustifiedText(contentRect.point, contentRect.extent, mText);
 
-   //render the children
-   renderChildControls( offset, updateRect);
+	//Render the childen
+	renderChildControls(contentRect.point, contentRect, updateRect);
 }
 
 void GuiButtonCtrl::setScriptValue(const char *value)

+ 37 - 22
engine/source/gui/buttons/guiCheckBoxCtrl.cc

@@ -78,8 +78,20 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
 		currentState = GuiControlState::HighlightState;
 	}
 
-	RectI boundsRect(offset, mBounds.extent);
-	RectI boxRect(offset + mBoxOffset, mBoxExtent);
+	RectI ctrlRect = applyMargins(offset, mBounds.extent, currentState);
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState);
+	RectI boxRect(contentRect.point + mBoxOffset, mBoxExtent);
+
+	//Contrain the Box Rect. It must fit in the content Rect.
+	if ((boxRect.point.x + boxRect.extent.x) > (contentRect.point.x + contentRect.extent.x))
+	{
+		boxRect.extent.x = contentRect.point.x + contentRect.extent.x - boxRect.point.x;
+	}
+	if ((boxRect.point.y + boxRect.extent.y) > (contentRect.point.y + contentRect.extent.y))
+	{
+		boxRect.extent.y = contentRect.point.y + contentRect.extent.y - boxRect.point.y;
+	}
 
 	if(mProfile->mBitmapName != NULL && mProfile->constructBitmapArray() >= 6)
 	{
@@ -105,29 +117,32 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
 	else
 	{
 		//Draw the checkbox
-		renderBorderedRect(boxRect, mProfile, currentState);
+		renderInnerControl(boxRect, currentState);
 	}
-   
-    if(mText[0] != '\0')
-    {
-		ColorI fontColor = mProfile->getFontColor(currentState);
-		dglSetBitmapModulation( fontColor );
-
-		Point2I textArea = mTextExtent;
-		if ((textArea.x + mTextOffset.x) > mBounds.extent.x)
-		{
-			textArea.x = mBounds.extent.x;
-		}
-		if ((textArea.y + mTextOffset.y) > mBounds.extent.y)
-		{
-			textArea.y = mBounds.extent.y;
-		}
 
-		renderJustifiedText(Point2I(offset.x + mTextOffset.x, offset.y + mTextOffset.y), textArea, mText);
-    }
+	RectI textRect(contentRect.point + mTextOffset, mTextExtent);
 
-   //render the children
-   renderChildControls(offset, updateRect);
+	//Contrain the Text Rect. It must fit in the content Rect.
+	if ((textRect.point.x + textRect.extent.x) > (contentRect.point.x + contentRect.extent.x))
+	{
+		textRect.extent.x = contentRect.point.x + contentRect.extent.x - textRect.point.x;
+	}
+	if ((textRect.point.y + textRect.extent.y) > (contentRect.point.y + contentRect.extent.y))
+	{
+		textRect.extent.y = contentRect.point.y + contentRect.extent.y - textRect.point.y;
+	}
+
+	//Render Text
+	dglSetBitmapModulation(mProfile->getFontColor(currentState));
+	renderJustifiedText(textRect.point, textRect.extent, mText);
+
+	//Render the childen
+	renderChildControls(offset, contentRect, updateRect);
+}
+
+void GuiCheckBoxCtrl::renderInnerControl(RectI &boxRect, const GuiControlState currentState)
+{
+	renderBorderedRect(boxRect, mProfile, currentState);
 }
 
 void GuiCheckBoxCtrl::onAction()

+ 1 - 0
engine/source/gui/buttons/guiCheckBoxCtrl.h

@@ -61,6 +61,7 @@ public:
    void setTextExtent(const Point2I &newExtent) { mTextExtent = newExtent; }
 
    void onRender(Point2I offset, const RectI &updateRect);
+   virtual void renderInnerControl(RectI &boxRect, const GuiControlState currentState);
    void setScriptValue(const char *value);
    const char *getScriptValue();
 

+ 7 - 70
engine/source/gui/buttons/guiRadioCtrl.cc

@@ -41,79 +41,16 @@ void GuiRadioCtrl::initPersistFields()
 	addField("groupNum", TypeS32, Offset(mRadioGroup, GuiRadioCtrl));
 }
 
-void GuiRadioCtrl::onRender(Point2I offset, const RectI &updateRect)
+void GuiRadioCtrl::renderInnerControl(RectI &boxRect, const GuiControlState currentState)
 {
-	GuiControlState currentState = GuiControlState::NormalState;
-	if (!mActive)
-	{
-		currentState = GuiControlState::DisabledState;
-	}
-	else if (mDepressed || mStateOn)
-	{
-		currentState = GuiControlState::SelectedState;
-	}
-	else if (mMouseOver)
-	{
-		currentState = GuiControlState::HighlightState;
-	}
-
-	RectI boundsRect(offset, mBounds.extent);
-	RectI boxRect(offset + mBoxOffset, mBoxExtent);
-
-	if (mProfile->mBitmapName != NULL && mProfile->constructBitmapArray() >= 6)
+	S32 radius = boxRect.extent.x;
+	if (boxRect.extent.y < radius)
 	{
-		//Use the bitmap to create the radio button
-		S32 index = 1;
-		if (mStateOn || mDepressed)
-		{
-			index = 2;
-		}
-		if (mMouseOver)
-		{
-			index += 2;
-		}
-		else if (!mActive)
-		{
-			index += 4;
-		}
-
-		RectI dest = RectI(offset + mBoxOffset, mBoxExtent);
-		dglClearBitmapModulation();
-		dglDrawBitmapStretchSR(mProfile->mTextureHandle, dest, mProfile->mBitmapArrayRects[index - 1]);
-	}
-	else
-	{
-		//Draw the radio button
-		S32 radius = mBoxExtent.x;
-		if (mBoxExtent.y < radius)
-		{
-			radius = mBoxExtent.y;
-		}
-		radius = (S32)round(radius/2);
-		Point2I center = Point2I(offset.x + mBoxOffset.x + (mBoxExtent.x/2), offset.y + mBoxOffset.y + (mBoxExtent.y / 2));
-		renderBorderedCircle(center, radius, mProfile, currentState);
+		radius = boxRect.extent.y;
 	}
-
-	if (mText[0] != '\0')
-	{
-		ColorI fontColor = mProfile->getFontColor(currentState);
-		dglSetBitmapModulation(fontColor);
-
-		Point2I textArea = mTextExtent;
-		if ((textArea.x + mTextOffset.x) > mBounds.extent.x)
-		{
-			textArea.x = mBounds.extent.x;
-		}
-		if ((textArea.y + mTextOffset.y) > mBounds.extent.y)
-		{
-			textArea.y = mBounds.extent.y;
-		}
-
-		renderJustifiedText(Point2I(offset.x + mTextOffset.x, offset.y + mTextOffset.y), textArea, mText);
-	}
-
-	//render the children
-	renderChildControls(offset, updateRect);
+	radius = (S32)round(radius / 2);
+	Point2I center = Point2I(boxRect.point.x + (boxRect.extent.x / 2), boxRect.point.y + (boxRect.extent.y / 2));
+	renderBorderedCircle(center, radius, mProfile, currentState);
 }
 
 void GuiRadioCtrl::onAction()

+ 1 - 1
engine/source/gui/buttons/guiRadioCtrl.h

@@ -38,7 +38,7 @@ public:
    DECLARE_CONOBJECT(GuiRadioCtrl);
    GuiRadioCtrl();
    static void initPersistFields();
-   void onRender(Point2I offset, const RectI &updateRect);
+   void renderInnerControl(RectI &boxRect, const GuiControlState currentState);
    void setStateOn(bool bStateOn);
    void onAction();
    void onMessage(GuiControl *, S32 msg);

+ 1 - 1
engine/source/gui/containers/guiFormCtrl.cc

@@ -291,7 +291,7 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
    }
 
    // Render the children
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 void GuiFormCtrl::onMouseDragged(const GuiEvent &event)

+ 1 - 1
engine/source/gui/containers/guiFrameCtrl.cc

@@ -498,7 +498,7 @@ void GuiFrameSetCtrl::onRender(Point2I offset, const RectI &updateRect )
    //   dglDrawRect(r, mProfile->mBorderColor);
 
    // draw the frame contents
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 1
engine/source/gui/containers/guiPaneCtrl.cc

@@ -220,7 +220,7 @@ void GuiPaneControl::onRender(Point2I offset, const RectI &updateRect)
 
    // Draw child controls if appropriate
    if(!mCollapsed)
-      renderChildControls(offset, updateRect);
+      renderChildControls(offset, mBounds, updateRect);
 }
 
 ConsoleMethod(GuiPaneControl, setCollapsed, void, 3, 3, "(bool collapsed) Sets the controls \"collapsed\" property\n"

+ 1 - 1
engine/source/gui/containers/guiRolloutCtrl.cc

@@ -367,7 +367,7 @@ void GuiRolloutCtrl::onRender(Point2I offset, const RectI &updateRect)
          else if( mIsExpanded && !pChild->isVisible())
             pChild->setVisible( true );
       }
-      renderChildControls(offset, updateRect);
+      renderChildControls(offset, mBounds, updateRect);
    }
 }
 

+ 1 - 1
engine/source/gui/containers/guiScrollCtrl.cc

@@ -813,7 +813,7 @@ void GuiScrollCtrl::onRender(Point2I offset, const RectI &updateRect)
    // create a rect to intersect with the updateRect
    RectI contentRect(mContentPos.x + offset.x, mContentPos.y + offset.y, mContentExt.x, mContentExt.y);
    if(contentRect.intersect(updateRect))
-      renderChildControls(offset, contentRect);
+      renderChildControls(offset, mBounds, contentRect);
 
    // Finally draw the last vis rect (debug aid, BJG)
    //RectI renderRect = lastVisRect;

+ 2 - 1
engine/source/gui/containers/guiTabBookCtrl.cc

@@ -64,6 +64,7 @@ GuiTabBookCtrl::GuiTabBookCtrl()
    mPages.reserve(12);
    mTabMargin = 7;
    mMinTabWidth = 64;
+   mTabWidth = 64;
    mIsContainer = true;
 
 
@@ -309,7 +310,7 @@ void GuiTabBookCtrl::onRender(Point2I offset, const RectI &updateRect)
    renderTabs( offset );
 
    // Render Children
-   renderChildControls( offset, updateRect );
+   renderChildControls( offset, mBounds, updateRect );
 
    // Restore old modulation
    dglSetBitmapModulation( oldModulation );

+ 13 - 13
engine/source/gui/containers/guiTabBookCtrl.h

@@ -62,10 +62,10 @@ class GuiTabBookCtrl : public GuiControl
 public:
     enum TabPosition
     {
-        AlignTop,   ///< Align the tabs on the top of the tab book control
-        AlignBottom,///< Align the tabs on the bottom of the tab book control
-      AlignLeft,  ///< Align the tabs on the left of the tab book control
-      AlignRight  ///< Align the tabs on the right of the tab book control
+		AlignTop,   ///< Align the tabs on the top of the tab book control
+		AlignBottom,///< Align the tabs on the bottom of the tab book control
+		AlignLeft,  ///< Align the tabs on the left of the tab book control
+		AlignRight  ///< Align the tabs on the right of the tab book control
     };
 
    struct TabHeaderInfo
@@ -97,14 +97,14 @@ private:
 
    enum
    {
-       TabSelected = 0,     ///< Index of selected tab texture
-      TabNormal,           ///< Index of normal tab texture
-      TabHover,            ///< Index of hover tab texture
-      TabSelectedVertical, ///< Index of selected tab texture
-      TabNormalVertical,   ///< Index of normal tab texture
-      TabHoverVertical,    ///< Index of hover tab texture
-      TabBackground = 19,       ///< Index of background texture (tiled)
-       NumBitmaps           ///< Number of bitmaps in this array
+		TabSelected = 0,		///< Index of selected tab texture
+		TabNormal,				///< Index of normal tab texture
+		TabHover,				///< Index of hover tab texture
+		TabSelectedVertical,	///< Index of selected tab texture
+		TabNormalVertical,		///< Index of normal tab texture
+		TabHoverVertical,		///< Index of hover tab texture
+		TabBackground = 19,     ///< Index of background texture (tiled)
+		NumBitmaps				///< Number of bitmaps in this array
    };
    bool  mHasTexture;   ///< Indicates whether we have a texture to render the tabs with
    RectI *mBitmapBounds;///< Array of rectangles identifying textures for tab book
@@ -228,7 +228,7 @@ private:
    /// Called when a child page is resized
    /// This method is overridden so that we may handle resizing of our child tab
    /// pages when one of them is resized.
-   /// This ensures we keep our sizing in sync when we our children are sized or moved.
+   /// This ensures we keep our sizing in sync when our children are sized or moved.
    ///
    /// @param   child   A pointer to the child control that has been resized
    void childResized(GuiControl *child);

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

@@ -694,7 +694,7 @@ void GuiWindowCtrl::onRender(Point2I offset, const RectI &updateRect)
    if( !mMinimized )
    {
       //render the children
-      renderChildControls( offset, updateRect );
+      renderChildControls( offset, mBounds, updateRect );
    }
 }
 

+ 1 - 1
engine/source/gui/editor/guiEditCtrl.cc

@@ -523,7 +523,7 @@ void GuiEditCtrl::onRender(Point2I offset, const RectI &updateRect)
       }
    }
 
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 
    if(mActive && mCurrentAddSet && (mGridSnap.x && mGridSnap.y) && 
        (mMouseDownMode == MovingSelection || mMouseDownMode == SizingSelection))

+ 1 - 1
engine/source/gui/editor/guiFilterCtrl.cc

@@ -231,7 +231,7 @@ void GuiFilterCtrl::onRender(Point2I offset, const RectI &updateRect)
       dglDrawRectFill(r, ColorI(255,0,0));
    }
 
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 

+ 1 - 1
engine/source/gui/editor/guiMenuBar.cc

@@ -1021,7 +1021,7 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
       }
    }
 
-   renderChildControls( offset, updateRect );
+   renderChildControls( offset, mBounds, updateRect );
 }
 
 void GuiMenuBar::buildAcceleratorMap()

+ 1 - 1
engine/source/gui/editor/guiSeparatorCtrl.cc

@@ -105,7 +105,7 @@ void GuiSeparatorCtrl::onRender(Point2I offset, const RectI &updateRect)
       }
    }
 
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 

+ 1 - 1
engine/source/gui/guiArrayCtrl.cc

@@ -140,7 +140,7 @@ void GuiArrayCtrl::onRenderColumnHeaders(Point2I offset, Point2I parentOffset, P
    if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
    {
       RectI cellR(offset.x + headerDim.x, parentOffset.y, mBounds.extent.x - headerDim.x, headerDim.y);
-      dglDrawRectFill(cellR, mProfile->mBorderDefault->mBorderColor);
+      dglDrawRectFill(cellR, mProfile->mBorderDefault->mBorderColor[0]);
    }
 }
 

+ 1 - 1
engine/source/gui/guiBackgroundCtrl.cc

@@ -38,7 +38,7 @@ void GuiBackgroundCtrl::onRender(Point2I offset, const RectI &updateRect)
    if ( mDraw )
       Parent::onRender( offset, updateRect );
 
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 

+ 1 - 1
engine/source/gui/guiBitmapBorderCtrl.cc

@@ -74,7 +74,7 @@ void GuiBitmapBorderCtrl::onSleep()
 
 void GuiBitmapBorderCtrl::onRender(Point2I offset, const RectI &updateRect)
 {
-   renderChildControls( offset, updateRect );
+   renderChildControls( offset, mBounds, updateRect );
    dglSetClipRect(updateRect);
 
    //draw the outline

+ 2 - 2
engine/source/gui/guiBitmapCtrl.cc

@@ -228,10 +228,10 @@ void GuiBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
    if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0 && !mTextureHandle)
    {
       RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
-      dglDrawRect(rect, mProfile->mBorderDefault->mBorderColor);
+      dglDrawRect(rect, mProfile->mBorderDefault->mBorderColor[0]);
    }
 
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 void GuiBitmapCtrl::setValue(S32 x, S32 y)

+ 2 - 2
engine/source/gui/guiColorPicker.cc

@@ -473,7 +473,7 @@ void GuiColorPickerCtrl::renderColorBox(RectI &bounds)
    pickerBounds.extent.y = bounds.extent.y-1;
    
    if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
-      dglDrawRect(bounds, mProfile->mBorderDefault->mBorderColor);
+      dglDrawRect(bounds, mProfile->mBorderDefault->mBorderColor[0]);
       
    Point2I selectorPos = Point2I(bounds.point.x+mSelectorPos.x+1, bounds.point.y+mSelectorPos.y+1);
 
@@ -607,7 +607,7 @@ void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect)
    }
    
    //render the children
-   renderChildControls( offset, updateRect);
+   renderChildControls( offset, mBounds, updateRect);
 }
 
 //--------------------------------------------------------------------------

+ 1 - 1
engine/source/gui/guiConsoleTextCtrl.cc

@@ -164,7 +164,7 @@ void GuiConsoleTextCtrl::onRender(Point2I offset, const RectI &updateRect)
    }
 
    //render the child controls
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //

+ 96 - 9
engine/source/gui/guiControl.cc

@@ -58,6 +58,8 @@ GuiControl::GuiControl()
 {
    mLayer = 0;
    mBounds.set(0, 0, 64, 64);
+   mRenderInsetLT.set(0, 0);
+   mRenderInsetRB.set(0, 0);
    mMinExtent.set(8, 2);			// Set to 8x2 so GuiControl can be used as a separator.
 
    mProfile = NULL;
@@ -339,8 +341,10 @@ void GuiControl::resize(const Point2I &newPosition, const Point2I &newExtent)
    Point2I actualNewExtent = Point2I(getMax(mMinExtent.x, newExtent.x),
       getMax(mMinExtent.y, newExtent.y));
 
+	Point2I oldExtent = mBounds.extent;
+
    // only do the child control resizing stuff if you really need to.
-   bool extentChanged = (actualNewExtent != mBounds.extent);
+   bool extentChanged = (actualNewExtent != oldExtent);
 
    if (extentChanged) {
       //call set update both before and after
@@ -349,7 +353,7 @@ void GuiControl::resize(const Point2I &newPosition, const Point2I &newExtent)
       for(i = begin(); i != end(); i++)
       {
          GuiControl *ctrl = static_cast<GuiControl *>(*i);
-         ctrl->parentResized(mBounds.extent, actualNewExtent);
+         ctrl->parentResized(oldExtent - (ctrl->mRenderInsetLT + ctrl->mRenderInsetRB), actualNewExtent - (ctrl->mRenderInsetLT + ctrl->mRenderInsetRB));
       }
       mBounds.set(newPosition, actualNewExtent);
 
@@ -451,12 +455,93 @@ void GuiControl::parentResized(const Point2I &oldParentExtent, const Point2I &ne
 
 void GuiControl::onRender(Point2I offset, const RectI &updateRect)
 {
-    RectI ctrlRect(offset, mBounds.extent);
+    RectI ctrlRect = applyMargins(offset, mBounds.extent, NormalState);
+
+	if (!ctrlRect.isValidRect())
+	{
+		return;
+	}
 
     renderBorderedRect(ctrlRect, mProfile, NormalState);
 
+	//Render Text
 	dglSetBitmapModulation(mProfile->mFontColor);
-    renderChildControls(offset, updateRect);
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, NormalState);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, NormalState);
+
+	if(contentRect.isValidRect())
+	{
+		renderJustifiedText(contentRect.point, contentRect.extent, mText);
+
+		//Render the childen
+		renderChildControls(offset, contentRect, updateRect);
+	}
+}
+
+RectI GuiControl::applyMargins(Point2I offset, Point2I extent, GuiControlState currentState)
+{
+	//Get the border profiles
+	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
+	GuiBorderProfile *rightProfile = mProfile->getRightBorder();
+	GuiBorderProfile *topProfile = mProfile->getTopBorder();
+	GuiBorderProfile *bottomProfile = mProfile->getBottomBorder();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getMargin(currentState) : 0;
+	S32 rightSize = (rightProfile) ? rightProfile->getMargin(currentState) : 0;
+	S32 topSize = (topProfile) ? topProfile->getMargin(currentState) : 0;
+	S32 bottomSize = (bottomProfile) ? bottomProfile->getMargin(currentState) : 0;
+
+	//Ensure positive values
+	leftSize = (leftSize >= 0) ? leftSize : 0;
+	rightSize = (rightSize >= 0) ? rightSize : 0;
+	topSize = (topSize >= 0) ? topSize : 0;
+	bottomSize = (bottomSize >= 0) ? bottomSize : 0;
+
+	return RectI(offset.x + leftSize, offset.y + topSize, (extent.x - leftSize) - rightSize, (extent.y - topSize) - bottomSize);
+}
+
+RectI GuiControl::applyBorders(Point2I offset, Point2I extent, GuiControlState currentState)
+{
+	//Get the border profiles
+	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
+	GuiBorderProfile *rightProfile = mProfile->getRightBorder();
+	GuiBorderProfile *topProfile = mProfile->getTopBorder();
+	GuiBorderProfile *bottomProfile = mProfile->getBottomBorder();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getBorder(currentState) : 0;
+	S32 rightSize = (rightProfile) ? rightProfile->getBorder(currentState) : 0;
+	S32 topSize = (topProfile) ? topProfile->getBorder(currentState) : 0;
+	S32 bottomSize = (bottomProfile) ? bottomProfile->getBorder(currentState) : 0;
+
+	//Ensure positive values
+	leftSize = (leftSize >= 0) ? leftSize : 0;
+	rightSize = (rightSize >= 0) ? rightSize : 0;
+	topSize = (topSize >= 0) ? topSize : 0;
+	bottomSize = (bottomSize >= 0) ? bottomSize : 0;
+
+	return RectI(offset.x + leftSize, offset.y + topSize, (extent.x - leftSize) - rightSize, (extent.y - topSize) - bottomSize);
+}
+
+RectI GuiControl::applyPadding(Point2I offset, Point2I extent, GuiControlState currentState)
+{
+	//Get the border profiles
+	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
+	GuiBorderProfile *rightProfile = mProfile->getRightBorder();
+	GuiBorderProfile *topProfile = mProfile->getTopBorder();
+	GuiBorderProfile *bottomProfile = mProfile->getBottomBorder();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getPadding(currentState) : 0;
+	S32 rightSize = (rightProfile) ? rightProfile->getPadding(currentState) : 0;
+	S32 topSize = (topProfile) ? topProfile->getPadding(currentState) : 0;
+	S32 bottomSize = (bottomProfile) ? bottomProfile->getPadding(currentState) : 0;
+
+	//Ensure positive values
+	leftSize = (leftSize >= 0) ? leftSize : 0;
+	rightSize = (rightSize >= 0) ? rightSize : 0;
+	topSize = (topSize >= 0) ? topSize : 0;
+	bottomSize = (bottomSize >= 0) ? bottomSize : 0;
+
+	return RectI(offset.x + leftSize, offset.y + topSize, (extent.x - leftSize) - rightSize, (extent.y - topSize) - bottomSize);
 }
 
 bool GuiControl::renderTooltip(Point2I cursorPos, const char* tipText )
@@ -611,7 +696,7 @@ bool GuiControl::renderTooltip(Point2I cursorPos, const char* tipText )
     return true;
 }
 
-void GuiControl::renderChildControls(Point2I offset, const RectI &updateRect)
+void GuiControl::renderChildControls(Point2I offset, RectI content, const RectI &updateRect)
 {
    // offset is the upper-left corner of this control in screen coordinates
    // updateRect is the intersection rectangle in screen coords of the control
@@ -631,12 +716,14 @@ void GuiControl::renderChildControls(Point2I offset, const RectI &updateRect)
       }
       if (ctrl->mVisible)
       {
-         Point2I childPosition = offset + ctrl->getPosition();
+		 ctrl->mRenderInsetLT = content.point - offset;
+		 ctrl->mRenderInsetRB = mBounds.extent - (ctrl->mRenderInsetLT + content.extent);
+         Point2I childPosition = content.point + ctrl->getPosition();
          RectI childClip(childPosition, ctrl->getExtent());
 
          if (childClip.intersect(clipRect))
          {
-            dglSetClipRect(childClip);
+            dglSetClipRect(content);
             glDisable(GL_CULL_FACE);
             ctrl->onRender(childPosition, childClip);
          }
@@ -1050,9 +1137,9 @@ GuiControl* GuiControl::findHitControl(const Point2I &pt, S32 initialLayer)
       {
          continue;
       }
-      else if (ctrl->mVisible && ctrl->pointInControl(pt))
+      else if (ctrl->mVisible && ctrl->pointInControl(pt - ctrl->mRenderInsetLT))
       {
-         Point2I ptemp = pt - ctrl->mBounds.point;
+         Point2I ptemp = pt - (ctrl->mBounds.point + ctrl->mRenderInsetLT);
          GuiControl *hitCtrl = ctrl->findHitControl(ptemp);
 
          if(hitCtrl->mProfile->mModal)

+ 15 - 3
engine/source/gui/guiControl.h

@@ -118,6 +118,8 @@ public:
     static S32     smCursorChanged; ///< Has this control modified the cursor? -1 or type
     RectI   mBounds;
     Point2I mMinExtent;
+	Point2I mRenderInsetLT;			///Add this to the mBounds and parent offset to get the true render location of the control
+	Point2I mRenderInsetRB;			///The actual rendered inset for the right and bottom sides.
     StringTableEntry mLangTableName;
     LangTable *mLangTable;
 
@@ -393,9 +395,10 @@ public:
     virtual bool renderTooltip(Point2I cursorPos, const char* tipText = NULL );
 
     /// Called when this control should render its children
-    /// @param   offset   The location this control is to begin rendering
+    /// @param   offset   The top left of the parent control
+    /// @param   contentOffset   The top left of the parent's content
     /// @param   updateRect   The screen area this control has drawing access to
-    void renderChildControls(Point2I offset, const RectI &updateRect);
+    void renderChildControls(Point2I offset, RectI content, const RectI &updateRect);
 
     /// Sets the area (local coordinates) this control wants refreshed each frame
     /// @param   pos   UpperLeft point on rectangle of refresh area
@@ -484,7 +487,7 @@ public:
     /// General input handler.
     virtual bool onInputEvent(const InputEvent &event);
 
-    /// @name Mouse Events
+    /// @name Touch/Mouse Events
     /// These functions are called when the input event which is
     /// in the name of the function occurs.
     /// @{
@@ -670,6 +673,15 @@ public:
     /// @note This should move into the graphics library at some point
     void renderJustifiedText(Point2I offset, Point2I extent, const char *text);
 
+	/// Returns a new rect based on the margins.
+	RectI GuiControl::applyMargins(Point2I offset, Point2I extent, GuiControlState currentState);
+
+	/// Returns the bounds of the rect after considering the borders.
+	RectI GuiControl::applyBorders(Point2I offset, Point2I extent, GuiControlState currentState);
+
+	/// Returns the bounds of the rect this time with padding.
+	RectI GuiControl::applyPadding(Point2I offset, Point2I extent, GuiControlState currentState);
+
     void inspectPostApply();
     void inspectPreApply();
 };

+ 6 - 6
engine/source/gui/guiDefaultControlRender.cc

@@ -29,10 +29,10 @@
 void renderBorderedRect(RectI &bounds, GuiControlProfile *profile, GuiControlState state )
 {
 	//Get the border profiles
-	GuiBorderProfile *leftProfile = (profile->mBorderLeft) ? profile->mBorderLeft : profile->mBorderDefault;
-	GuiBorderProfile *rightProfile = (profile->mBorderRight) ? profile->mBorderRight : profile->mBorderDefault;
-	GuiBorderProfile *topProfile = (profile->mBorderTop) ? profile->mBorderTop : profile->mBorderDefault;
-	GuiBorderProfile *bottomProfile = (profile->mBorderBottom) ? profile->mBorderBottom : profile->mBorderDefault;
+	GuiBorderProfile *leftProfile = profile->getLeftBorder();
+	GuiBorderProfile *rightProfile = profile->getRightBorder();
+	GuiBorderProfile *topProfile = profile->getTopBorder();
+	GuiBorderProfile *bottomProfile = profile->getBottomBorder();
 
 	//Get the colors
 	ColorI fillColor = profile->getFillColor(state);
@@ -104,11 +104,11 @@ void renderBorderedCircle(Point2I &center, S32 radius, GuiControlProfile *profil
 	if (profile->mOpaque)
 	{
 		S32 fillRadius = (profile->mBorderDefault && profile->mBorderDefault->mUnderfill) ? radius : radius - borderSize;
-		dglDrawCircleFill(center, fillRadius, fillColor);
+		dglDrawCircleFill(center, (F32)fillRadius, fillColor);
 	}
 
 	//Draw the border
-	dglDrawCircle(center, radius, borderColor, borderSize);
+	dglDrawCircle(center, (F32)radius, borderColor, (F32)borderSize);
 }
 
 // DAW: Render out the sizable bitmap borders based on a multiplier into the bitmap array

+ 1 - 1
engine/source/gui/guiMLTextCtrl.h

@@ -250,7 +250,7 @@ class GuiMLTextCtrl : public GuiControl
    bool  mAllowColorChars;
 
    // Too many chars sound:
-   AssetPtr<AudioAsset>  mDeniedSound;
+   AssetPtr<AudioAsset>  mDeniedSound; 
 
    //-------------------------------------- Protected interface
   protected:

+ 2 - 2
engine/source/gui/guiProgressCtrl.cc

@@ -82,11 +82,11 @@ void GuiProgressCtrl::onRender(Point2I offset, const RectI &updateRect)
 
    //now draw the border
    if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
-      dglDrawRect(ctrlRect, mProfile->mBorderDefault->mBorderColor);
+      dglDrawRect(ctrlRect, mProfile->mBorderDefault->mBorderColor[0]);
 
    Parent::onRender( offset, updateRect );
 
    //render the children
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 

+ 1 - 1
engine/source/gui/guiSliderCtrl.cc

@@ -463,6 +463,6 @@ void GuiSliderCtrl::onRender(Point2I offset, const RectI &updateRect)
         dglSetBitmapModulation(mProfile->mFontColor);
         dglDrawText(mProfile->mFont, textStart, buf, mProfile->mFontColors);
     }
-    renderChildControls(offset, updateRect);
+    renderChildControls(offset, mBounds, updateRect);
 }
 

+ 2 - 2
engine/source/gui/guiTabPageCtrl.cc

@@ -34,7 +34,7 @@ GuiTabPageCtrl::GuiTabPageCtrl(void)
 {
    mBounds.extent.set(100, 200);
    mMinSize.set(50, 50);
-   dStrcpy(mText,(UTF8*)"TabPage");
+   //dStrcpy(mText,(UTF8*)"TabPage");
    mActive = true;
    mIsContainer = true;
 }
@@ -62,7 +62,7 @@ GuiControl* GuiTabPageCtrl::findHitControl(const Point2I &pt, S32 initialLayer)
    return Parent::findHitControl(pt, initialLayer);
 }
 
-void GuiTabPageCtrl::onMouseDown(const GuiEvent &event)
+void GuiTabPageCtrl::onTouchDown(const GuiEvent &event)
 {
    setUpdate();
    Point2I localPoint = globalToLocalCoord( event.mousePoint );

+ 3 - 3
engine/source/gui/guiTabPageCtrl.h

@@ -27,10 +27,10 @@
 #include "gui/guiTextCtrl.h"
 #endif
 
-class GuiTabPageCtrl : public GuiTextCtrl
+class GuiTabPageCtrl : public GuiControl
 {
    private:
-      typedef GuiTextCtrl Parent;
+      typedef GuiControl Parent;
 
       Point2I        mMinSize;
       S32            mTabIndex;
@@ -45,7 +45,7 @@ class GuiTabPageCtrl : public GuiTextCtrl
 
       GuiControl* findHitControl(const Point2I &pt, S32 initialLayer = -1); ///< Find which control is hit by the mouse starting at a specified layer
 
-      void onMouseDown(const GuiEvent &event);  ///< Called when a mouseDown event occurs
+      void onTouchDown(const GuiEvent &event);  ///< Called when a mouseDown event occurs
       bool onMouseDownEditor(const GuiEvent &event, Point2I offset );   ///< Called when a mouseDown event occurs and the GUI editor is active
 
       S32 getTabIndex(void) { return mTabIndex; }  ///< Get the tab index of this control

+ 1 - 1
engine/source/gui/guiTextCtrl.cc

@@ -224,7 +224,7 @@ void GuiTextCtrl::onRender(Point2I offset, const RectI &updateRect)
 	}
 
     //render the child controls
-    renderChildControls(offset, updateRect);
+    renderChildControls(offset, mBounds, updateRect);
 }
 
 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //

+ 1 - 1
engine/source/gui/guiTextEditCtrl.cc

@@ -1129,7 +1129,7 @@ void GuiTextEditCtrl::onRender(Point2I offset, const RectI & updateRect)
 
    drawText( ctrlRect, isFirstResponder() );
    
-   renderChildControls(offset, updateRect);
+   renderChildControls(offset, mBounds, updateRect);
 }
 
 void GuiTextEditCtrl::onPreRender()

+ 40 - 50
engine/source/gui/guiTypes.cc

@@ -96,15 +96,14 @@ IMPLEMENT_CONOBJECT(GuiBorderProfile);
 
 GuiBorderProfile::GuiBorderProfile()
 {
-	mBorder = 0;
-	mBorderHL = 0;
-	mBorderSL = 0;
-	mBorderNA = 0;
-
-	mBorderColor.set(255, 255, 255, 255);
-	mBorderColorHL.set(255, 255, 255, 255);
-	mBorderColorSL.set(255, 255, 255, 255);
-	mBorderColorNA.set(255, 255, 255, 255);
+	S32 stateCount = static_cast<S32>(StateCount);
+	for(S32 i = 0; i < stateCount; i++)
+	{
+		mMargin[i] = 0;
+		mBorder[i] = 0;
+		mBorderColor[i].set(255, 255, 255, 255);
+		mPadding[i] = 0;
+	}
 
 	mUnderfill = true;
 }
@@ -116,15 +115,26 @@ GuiBorderProfile::~GuiBorderProfile()
 void GuiBorderProfile::initPersistFields()
 {
 	Parent::initPersistFields();
-	addField("border", TypeS32, Offset(mBorder, GuiBorderProfile));
-	addField("borderHL", TypeS32, Offset(mBorderHL, GuiBorderProfile));
-	addField("borderSL", TypeS32, Offset(mBorderSL, GuiBorderProfile));
-	addField("borderNA", TypeS32, Offset(mBorderNA, GuiBorderProfile));
 
-	addField("borderColor", TypeColorI, Offset(mBorderColor, GuiBorderProfile));
-	addField("borderColorHL", TypeColorI, Offset(mBorderColorHL, GuiBorderProfile));
-	addField("borderColorSL", TypeColorI, Offset(mBorderColorSL, GuiBorderProfile));
-	addField("borderColorNA", TypeColorI, Offset(mBorderColorNA, GuiBorderProfile));
+	addField("margin", TypeS32, Offset(mMargin[0], GuiBorderProfile));
+	addField("marginHL", TypeS32, Offset(mMargin[1], GuiBorderProfile));
+	addField("marginSL", TypeS32, Offset(mMargin[2], GuiBorderProfile));
+	addField("marginNA", TypeS32, Offset(mMargin[3], GuiBorderProfile));
+
+	addField("border", TypeS32, Offset(mBorder[0], GuiBorderProfile));
+	addField("borderHL", TypeS32, Offset(mBorder[1], GuiBorderProfile));
+	addField("borderSL", TypeS32, Offset(mBorder[2], GuiBorderProfile));
+	addField("borderNA", TypeS32, Offset(mBorder[3], GuiBorderProfile));
+
+	addField("borderColor", TypeColorI, Offset(mBorderColor[0], GuiBorderProfile));
+	addField("borderColorHL", TypeColorI, Offset(mBorderColor[1], GuiBorderProfile));
+	addField("borderColorSL", TypeColorI, Offset(mBorderColor[2], GuiBorderProfile));
+	addField("borderColorNA", TypeColorI, Offset(mBorderColor[3], GuiBorderProfile));
+
+	addField("padding", TypeS32, Offset(mPadding[0], GuiBorderProfile));
+	addField("paddingHL", TypeS32, Offset(mPadding[1], GuiBorderProfile));
+	addField("paddingSL", TypeS32, Offset(mPadding[2], GuiBorderProfile));
+	addField("paddingNA", TypeS32, Offset(mPadding[3], GuiBorderProfile));
 
 	addField("underfill", TypeBool, Offset(mUnderfill, GuiBorderProfile));
 }
@@ -144,44 +154,24 @@ void GuiBorderProfile::onRemove()
 	Parent::onRemove();
 }
 
-const ColorI& GuiBorderProfile::getBorderColor(const GuiControlState state)
+S32 GuiBorderProfile::getMargin(const GuiControlState state)
 {
-	switch (state)
-	{
-	default:
-	case NormalState:
-		return mBorderColor;
-		break;
-	case HighlightState:
-		return mBorderColorHL;
-		break;
-	case SelectedState:
-		return mBorderColorSL;
-		break;
-	case DisabledState:
-		return mBorderColorNA;
-		break;
-	}
+	return mMargin[static_cast<S32>(state)];
 }
 
 S32 GuiBorderProfile::getBorder(const GuiControlState state)
 {
-	switch (state)
-	{
-	default:
-	case NormalState:
-		return mBorder;
-		break;
-	case HighlightState:
-		return mBorderHL;
-		break;
-	case SelectedState:
-		return mBorderSL;
-		break;
-	case DisabledState:
-		return mBorderNA;
-		break;
-	}
+	return mBorder[static_cast<S32>(state)];
+}
+
+const ColorI& GuiBorderProfile::getBorderColor(const GuiControlState state)
+{
+	return mBorderColor[static_cast<S32>(state)];
+}
+
+S32 GuiBorderProfile::getPadding(const GuiControlState state)
+{
+	return mPadding[static_cast<S32>(state)];
 }
 
 //------------------------------------------------------------------------------

+ 16 - 13
engine/source/gui/guiTypes.h

@@ -73,7 +73,8 @@ enum GuiControlState
 	NormalState = 0,				//Control renders with default look
 	HighlightState,				//Control is highlighted
 	SelectedState,				//Control has been selected
-	DisabledState				//Control cannot be used
+	DisabledState,				//Control cannot be used
+	StateCount					//Not an actual state! Should always be at the end of the list.
 };
 
 class GuiCursor : public SimObject
@@ -109,17 +110,11 @@ private:
 	typedef SimObject Parent;
 
 public:
-	S32 mBorder;								//Width of this border
-	S32 mBorderHL;
-	S32 mBorderSL;
-	S32 mBorderNA;
-
-	ColorI mBorderColor;						//The color of the border
-	ColorI mBorderColorHL;
-	ColorI mBorderColorSL;
-	ColorI mBorderColorNA;
-
-	bool mUnderfill;							//True if the control's fill color should appear under the border.
+	S32 mMargin[static_cast<S32>(StateCount)];					//The distance between the edge and the start of the border. Margin is outside of the control.
+	S32 mBorder[static_cast<S32>(StateCount)];					//Width of the border.
+	ColorI mBorderColor[static_cast<S32>(StateCount)];			//The color of the border.
+	S32 mPadding[static_cast<S32>(StateCount)];					//The distance between the border and content of the control.
+	bool mUnderfill;											//True if the control's fill color should appear under the border.
 public:
 	DECLARE_CONOBJECT(GuiBorderProfile);
 	GuiBorderProfile();
@@ -127,8 +122,11 @@ public:
 	static void initPersistFields();
 	bool onAdd();
 	void onRemove();
-	const ColorI& getBorderColor(const GuiControlState state); //Returns the correct border color based on the control's state.
+
+	S32 getMargin(const GuiControlState state); //Returns the margin based on the control's state.
 	S32 getBorder(const GuiControlState state); //Returns the size of the border based on the control's state.
+	const ColorI& getBorderColor(const GuiControlState state); //Returns the correct border color based on the control's state.
+	S32 getPadding(const GuiControlState state); //Returns the padding based on the control's state.
 };
 
 /// A GuiControlProfile is used by every GuiObject and is akin to a
@@ -232,6 +230,11 @@ public:
 
    const ColorI& getFillColor(const GuiControlState state); //Returns the fill color based on the state.
    const ColorI& getFontColor(const GuiControlState state); //Returns the font color based on the state.
+
+   GuiBorderProfile* getLeftBorder() { return ((mBorderLeft) ? mBorderLeft : mBorderDefault); };
+   GuiBorderProfile* getRightBorder() { return ((mBorderRight) ? mBorderRight : mBorderDefault); };
+   GuiBorderProfile* getTopBorder() { return ((mBorderTop) ? mBorderTop : mBorderDefault); };
+   GuiBorderProfile* getBottomBorder() { return ((mBorderBottom) ? mBorderBottom : mBorderDefault); };
 };
 DefineConsoleType( TypeGuiProfile)