Ver Fonte

Gui Borders Rework

I reworked the way borders are drawn for GuiControls. The new system adds a border profile that can be applied to one or all of the borders for a control. This gives the programmer far greater control over how the control appears in different states.
Peter Robinson há 6 anos atrás
pai
commit
978c6bc927

+ 22 - 0
engine/source/graphics/dgl.cc

@@ -875,6 +875,28 @@ void dglDrawRectFill(const RectI &rect, const ColorI &color)
    dglDrawRectFill(rect.point, lowerR, color);
    dglDrawRectFill(rect.point, lowerR, color);
 }
 }
 
 
+void dglDrawQuadFill(const Point2I &point1, const Point2I &point2, const Point2I &point3, const Point2I &point4, const ColorI &color)
+{
+	glEnable(GL_BLEND);
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	glDisable(GL_TEXTURE_2D);
+
+	glColor4ub(color.red, color.green, color.blue, color.alpha);
+
+	//Points 3 and 4 are switched by design.
+	GLint vertices[] = {
+		(GLint)point1.x, (GLint)point1.y,
+		(GLint)point2.x, (GLint)point2.y,
+		(GLint)point4.x, (GLint)point4.y,
+		(GLint)point3.x, (GLint)point3.y,
+	};
+
+	glVertexPointer(2, GL_INT, 0, vertices);
+	glEnableClientState(GL_VERTEX_ARRAY);
+
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+}
+
 void dglDraw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle )
 void dglDraw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle )
 {
 {
    width *= 0.5;
    width *= 0.5;

+ 2 - 0
engine/source/graphics/dgl.h

@@ -185,6 +185,8 @@ void dglDrawRect(const RectI &rect, const ColorI &color, const float &lineWidth
 void dglDrawRectFill(const Point2I &upperL, const Point2I &lowerR, const ColorI &color);
 void dglDrawRectFill(const Point2I &upperL, const Point2I &lowerR, const ColorI &color);
 /// draws an UNTEXTURED filled rectangle in "rect" in specified color
 /// draws an UNTEXTURED filled rectangle in "rect" in specified color
 void dglDrawRectFill(const RectI &rect, const ColorI &color);
 void dglDrawRectFill(const RectI &rect, const ColorI &color);
+/// draws an UNTEXTURED filled quad in specified color
+void dglDrawQuadFill(const Point2I &point1, const Point2I &point2, const Point2I &point3, const Point2I &point4, const ColorI &color);
 /// draws a square, with center point "screenPoint", width of "width" on an angle of "spinAngle" in 2d
 /// draws a square, with center point "screenPoint", width of "width" on an angle of "spinAngle" in 2d
 void dglDraw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle );
 void dglDraw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle );
 /// draws a square, with center point "position", width of "width" on an angle of "spinAngle" in 3d
 /// draws a square, with center point "position", width of "width" on an angle of "spinAngle" in 3d

+ 40 - 25
engine/source/gui/buttons/guiButtonCtrl.cc

@@ -52,44 +52,59 @@ bool GuiButtonCtrl::onWake()
 }
 }
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 
 
-void GuiButtonCtrl::onRender(Point2I      offset,
-                             const RectI& updateRect)
+void GuiButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
 {
 {
-   bool highlight = mMouseOver;
-   bool depressed = mDepressed;
-
-   ColorI fontColor   = mActive ? (highlight ? mProfile->mFontColorHL : mProfile->mFontColor) : mProfile->mFontColorNA;
-   ColorI backColor   = mActive ? mProfile->mFillColor : mProfile->mFillColorNA;
-   ColorI borderColor = mActive ? mProfile->mBorderColor : mProfile->mBorderColorNA;
-
-   RectI boundsRect(offset, mBounds.extent);
-
-   if( mProfile->mBorder != 0 && !mHasTheme )
-   {
-      if (mDepressed || mStateOn)
-         renderFilledBorder( boundsRect, mProfile->mBorderColorHL, mProfile->mFillColorHL, mProfile->mBorderSize);
-      else
-         renderFilledBorder( boundsRect, mProfile->mBorderColor, mProfile->mFillColor, mProfile->mBorderSize);
-   }
+	GuiControlState currentState = GuiControlState::normal;
+	if (!mActive)
+	{
+		currentState = GuiControlState::disabled;
+	}
+	else if (mDepressed || mStateOn)
+	{
+		currentState = GuiControlState::selected;
+	}
+	else if(mMouseOver)
+	{
+		currentState = GuiControlState::highlight;
+	}
+
+	RectI boundsRect(offset, mBounds.extent);
+
+	if( !mHasTheme )
+	{
+		renderBorderedRect(boundsRect, mProfile, currentState);
+	}
    else if( mHasTheme )
    else if( mHasTheme )
    {
    {
       S32 indexMultiplier = 1;
       S32 indexMultiplier = 1;
-      if ( mDepressed || mStateOn ) 
+      if ( currentState == selected) 
          indexMultiplier = 3;
          indexMultiplier = 3;
-      else if ( mMouseOver )
+      else if ( currentState == highlight )
          indexMultiplier = 2;
          indexMultiplier = 2;
-      else if ( !mActive )
+      else if ( currentState == disabled )
          indexMultiplier = 4;
          indexMultiplier = 4;
 
 
       renderSizableBitmapBordersFilled( boundsRect, indexMultiplier, mProfile );
       renderSizableBitmapBordersFilled( boundsRect, indexMultiplier, mProfile );
    }
    }
 
 
-   Point2I textPos = offset;
-   if(depressed)
-      textPos += Point2I(1,1);
+	//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);
 
 
    dglSetBitmapModulation( fontColor );
    dglSetBitmapModulation( fontColor );
-   renderJustifiedText(textPos, mBounds.extent, mButtonText);
+   renderJustifiedText(innerRect.point, innerRect.extent, mButtonText);
 
 
    //render the children
    //render the children
    renderChildControls( offset, updateRect);
    renderChildControls( offset, updateRect);

+ 1 - 1
engine/source/gui/buttons/guiCheckBoxCtrl.cc

@@ -133,7 +133,7 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
    ColorI backColor = mActive ? mProfile->mFillColor : mProfile->mFillColorNA;
    ColorI backColor = mActive ? mProfile->mFillColor : mProfile->mFillColorNA;
    ColorI fontColor = mMouseOver ? mProfile->mFontColorHL : mProfile->mFontColor;
    ColorI fontColor = mMouseOver ? mProfile->mFontColorHL : mProfile->mFontColor;
-    ColorI insideBorderColor = isFirstResponder() ? mProfile->mBorderColorHL : mProfile->mBorderColor;
+    ColorI insideBorderColor = mProfile->mFillColor;//isFirstResponder() ? mProfile->mBorderColorHL : mProfile->mBorderColor;
 
 
    // just draw the check box and the text:
    // just draw the check box and the text:
    S32 xOffset = 0;
    S32 xOffset = 0;

+ 13 - 13
engine/source/gui/buttons/guiIconButtonCtrl.cc

@@ -197,13 +197,13 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
        if (highlight)
        if (highlight)
            fontColor = mProfile->mFontColorHL;
            fontColor = mProfile->mFontColorHL;
        else if (mStateOn)
        else if (mStateOn)
-           fontColor = mProfile->mFontColorSEL;
+           fontColor = mProfile->mFontColorSL;
        else
        else
            fontColor = mProfile->mFontColor;
            fontColor = mProfile->mFontColor;
    }
    }
 
 
    ColorI backColor   = mActive ? mProfile->mFillColor : mProfile->mFillColorNA; 
    ColorI backColor   = mActive ? mProfile->mFillColor : mProfile->mFillColorNA; 
-   ColorI borderColor = mActive ? mProfile->mBorderColor : mProfile->mBorderColorNA;
+   ColorI borderColor = mProfile->mFillColor;//mActive ? mProfile->mBorderColor : mProfile->mBorderColorNA;
 
 
    RectI boundsRect(offset, mBounds.extent);
    RectI boundsRect(offset, mBounds.extent);
 
 
@@ -214,7 +214,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
       if( mProfile->mBitmapArrayRects.size() )
       if( mProfile->mBitmapArrayRects.size() )
          renderBitmapArray(boundsRect, statePressed);
          renderBitmapArray(boundsRect, statePressed);
       else
       else
-         renderLoweredBox(boundsRect, mProfile);
+         renderBorderedRect(boundsRect, mProfile, normal);
    }
    }
    else if(mMouseOver && mActive)
    else if(mMouseOver && mActive)
    {
    {
@@ -223,7 +223,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
       if(mProfile->mBitmapArrayRects.size())
       if(mProfile->mBitmapArrayRects.size())
          renderBitmapArray(boundsRect, stateMouseOver);
          renderBitmapArray(boundsRect, stateMouseOver);
       else
       else
-         renderRaisedBox(boundsRect, mProfile);
+         renderBorderedRect(boundsRect, mProfile, GuiControlState::highlight);
    }
    }
    else
    else
    {
    {
@@ -239,7 +239,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
       else
       else
       {
       {
          dglDrawRectFill(boundsRect, mProfile->mFillColorNA);
          dglDrawRectFill(boundsRect, mProfile->mFillColorNA);
-         dglDrawRect(boundsRect, mProfile->mBorderColorNA);
+         dglDrawRect(boundsRect, mProfile->mFillColorNA);//mBorderColorNA);
       }
       }
    }
    }
 
 
@@ -321,30 +321,30 @@ void GuiIconButtonCtrl::renderBitmapArray(RectI &bounds, S32 state)
    switch(state)
    switch(state)
    {
    {
    case stateNormal:
    case stateNormal:
-      if(mProfile->mBorder == -2)
+     /* if(mProfile->mBorder == -2)
          renderSizableBitmapBordersFilled(bounds, 1, mProfile);
          renderSizableBitmapBordersFilled(bounds, 1, mProfile);
-      else
+      else*/
          renderFixedBitmapBordersFilled(bounds, 1, mProfile);
          renderFixedBitmapBordersFilled(bounds, 1, mProfile);
       break;
       break;
 
 
    case stateMouseOver:
    case stateMouseOver:
-      if(mProfile->mBorder == -2)
+      /*if(mProfile->mBorder == -2)
          renderSizableBitmapBordersFilled(bounds, 2, mProfile);
          renderSizableBitmapBordersFilled(bounds, 2, mProfile);
-      else
+      else*/
          renderFixedBitmapBordersFilled(bounds, 2, mProfile);
          renderFixedBitmapBordersFilled(bounds, 2, mProfile);
       break;
       break;
 
 
    case statePressed:
    case statePressed:
-      if(mProfile->mBorder == -2)
+      /*if(mProfile->mBorder == -2)
          renderSizableBitmapBordersFilled(bounds, 3, mProfile);
          renderSizableBitmapBordersFilled(bounds, 3, mProfile);
-      else
+      else*/
          renderFixedBitmapBordersFilled(bounds, 3, mProfile);
          renderFixedBitmapBordersFilled(bounds, 3, mProfile);
       break;
       break;
 
 
    case stateDisabled:
    case stateDisabled:
-      if(mProfile->mBorder == -2)
+      /*if(mProfile->mBorder == -2)
          renderSizableBitmapBordersFilled(bounds, 4, mProfile);
          renderSizableBitmapBordersFilled(bounds, 4, mProfile);
-      else
+      else*/
          renderFixedBitmapBordersFilled(bounds, 4, mProfile);
          renderFixedBitmapBordersFilled(bounds, 4, mProfile);
       break;
       break;
    }
    }

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

@@ -236,8 +236,8 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
    if (mProfile->mOpaque)
    if (mProfile->mOpaque)
       dglDrawRectFill(boundsRect, mProfile->mFillColor);
       dglDrawRectFill(boundsRect, mProfile->mFillColor);
 
 
-   if (mProfile->mBorder)
-      renderBorder(boundsRect, mProfile);
+   //if (mProfile->mBorder)
+      //renderBorder(boundsRect, mProfile);
 
 
    // If we don't have a child (other than the menu), put some text in the child area
    // If we don't have a child (other than the menu), put some text in the child area
    if(size() <= 1)
    if(size() <= 1)
@@ -253,7 +253,7 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
    {
    {
       dglClearBitmapModulation();
       dglClearBitmapModulation();
 
 
-      S32 barStart = (mHasMenu ? mThumbSize.x : 1 + mProfile->mBorderSize) + offset.x + textWidth;
+      S32 barStart = 0;//(mHasMenu ? mThumbSize.x : 1 + mProfile->mBorderSize) + offset.x + textWidth;
       S32 barTop   = mThumbSize.y/2 + offset.y - mProfile->mBitmapArrayRects[3].extent.y /2;
       S32 barTop   = mThumbSize.y/2 + offset.y - mProfile->mBitmapArrayRects[3].extent.y /2;
 
 
       Point2I barOffset(barStart, barTop);
       Point2I barOffset(barStart, barTop);

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

@@ -494,8 +494,8 @@ void GuiFrameSetCtrl::onRender(Point2I offset, const RectI &updateRect )
 
 
    drawDividers(offset);
    drawDividers(offset);
 
 
-   if (mProfile->mBorder)
-      dglDrawRect(r, mProfile->mBorderColor);
+   //if (mProfile->mBorder)
+   //   dglDrawRect(r, mProfile->mBorderColor);
 
 
    // draw the frame contents
    // draw the frame contents
    renderChildControls(offset, updateRect);
    renderChildControls(offset, updateRect);

+ 8 - 12
engine/source/gui/containers/guiScrollCtrl.cc

@@ -226,17 +226,17 @@ void GuiScrollCtrl::addObject(SimObject *object)
 
 
 GuiControl* GuiScrollCtrl::findHitControl(const Point2I &pt, S32 initialLayer)
 GuiControl* GuiScrollCtrl::findHitControl(const Point2I &pt, S32 initialLayer)
 {
 {
-   if(pt.x < mProfile->mBorderSize || pt.y < mProfile->mBorderSize)
+   //if(pt.x < mProfile->mBorderSize || pt.y < mProfile->mBorderSize)
       return this;
       return this;
-   if(pt.x >= mBounds.extent.x - mProfile->mBorderSize - (mHasVScrollBar ? mScrollBarThickness : 0) ||
-      pt.y >= mBounds.extent.y - mProfile->mBorderSize - (mHasHScrollBar ? mScrollBarThickness : 0))
-      return this;
-   return Parent::findHitControl(pt, initialLayer);
+   //if(pt.x >= mBounds.extent.x - mProfile->mBorderSize - (mHasVScrollBar ? mScrollBarThickness : 0) ||
+   //   pt.y >= mBounds.extent.y - mProfile->mBorderSize - (mHasHScrollBar ? mScrollBarThickness : 0))
+   //   return this;
+   //return Parent::findHitControl(pt, initialLayer);
 }
 }
 
 
 void GuiScrollCtrl::computeSizes()
 void GuiScrollCtrl::computeSizes()
 {
 {
-   S32 thickness = (mProfile ? mProfile->mBorderSize : 1);
+   S32 thickness = 0;//(mProfile ? mProfile->mBorderSize : 1);
    Point2I borderExtent(thickness, thickness);
    Point2I borderExtent(thickness, thickness);
    mContentPos = borderExtent + mChildMargin;
    mContentPos = borderExtent + mChildMargin;
    mContentExt = mBounds.extent - (mChildMargin * 2)
    mContentExt = mBounds.extent - (mChildMargin * 2)
@@ -324,7 +324,7 @@ void GuiScrollCtrl::computeSizes()
 
 
 void GuiScrollCtrl::calcScrollRects(void)
 void GuiScrollCtrl::calcScrollRects(void)
 {
 {
-   S32 thickness = ( mProfile ? mProfile->mBorderSize : 1 );
+   S32 thickness = 0;//( mProfile ? mProfile->mBorderSize : 1 );
    if (mHasHScrollBar)
    if (mHasHScrollBar)
    {
    {
       mLeftArrowRect.set(thickness,
       mLeftArrowRect.set(thickness,
@@ -796,11 +796,7 @@ void GuiScrollCtrl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
    RectI r(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
    RectI r(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
 
 
-   if (mProfile->mOpaque)
-      dglDrawRectFill(r, mProfile->mFillColor);
-
-    if (mProfile->mBorder)
-        renderFilledBorder(r, mProfile);
+   renderBorderedRect(r, mProfile, normal);
 
 
    // draw scroll bars
    // draw scroll bars
    if (mHasVScrollBar)
    if (mHasVScrollBar)

+ 2 - 2
engine/source/gui/editor/guiGraphCtrl.cc

@@ -71,11 +71,11 @@ bool GuiGraphCtrl::onWake()
 
 
 void GuiGraphCtrl::onRender(Point2I offset, const RectI &updateRect)
 void GuiGraphCtrl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
-	if (mProfile->mBorder)
+	/*if (mProfile->mBorder)
 	{
 	{
 		RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
 		RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
 		dglDrawRect(rect, mProfile->mBorderColor);
 		dglDrawRect(rect, mProfile->mBorderColor);
-	}
+	}*/
 
 
 	glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
 	glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
 	glEnable(GL_BLEND);
 	glEnable(GL_BLEND);

+ 10 - 6
engine/source/gui/editor/guiMenuBar.cc

@@ -959,8 +959,8 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
       dglDrawRectFill(RectI(offset, mBounds.extent), mProfile->mFillColor);
       dglDrawRectFill(RectI(offset, mBounds.extent), mProfile->mFillColor);
 
 
    //if there's a border, draw the border
    //if there's a border, draw the border
-   if (mProfile->mBorder)
-      renderBorder(ctrlRect, mProfile);
+   //if (mProfile->mBorder)
+   //   renderBorder(ctrlRect, mProfile);
 
 
    for(Menu *walk = menuList; walk; walk = walk->nextMenu)
    for(Menu *walk = menuList; walk; walk = walk->nextMenu)
    {
    {
@@ -981,10 +981,14 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
         RectI highlightBounds = bounds;
         RectI highlightBounds = bounds;
         highlightBounds.inset(1,1);
         highlightBounds.inset(1,1);
          if(walk == mouseDownMenu)
          if(walk == mouseDownMenu)
-            renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL, mProfile->mBorderSize);
-         else if(walk == mouseOverMenu && mouseDownMenu == NULL)
-            renderFilledBorder(highlightBounds, mProfile->mBorderColor, mProfile->mFillColor, mProfile->mBorderSize);
-      }
+		 {
+			renderBorderedRect(highlightBounds, mProfile, GuiControlState::highlight);
+         }
+		 else if(walk == mouseOverMenu && mouseDownMenu == NULL)
+		 {
+			 renderBorderedRect(highlightBounds, mProfile, GuiControlState::normal);
+		 }
+	  }
 
 
       // Do we draw a bitmap?
       // Do we draw a bitmap?
       if(walk->bitmapIndex != -1)
       if(walk->bitmapIndex != -1)

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

@@ -78,7 +78,7 @@ void GuiSeparatorCtrl::onRender(Point2I offset, const RectI &updateRect)
       if(mTextLeftMargin > 0)
       if(mTextLeftMargin > 0)
       {
       {
          RectI rect(Point2I(posx,seppos),Point2I(mTextLeftMargin,2));
          RectI rect(Point2I(posx,seppos),Point2I(mTextLeftMargin,2));
-         renderSlightlyLoweredBox(rect, mProfile);
+         renderBorderedRect(rect, mProfile, GuiControlState::highlight);
          posx += mTextLeftMargin;
          posx += mTextLeftMargin;
       }
       }
 
 
@@ -87,7 +87,7 @@ void GuiSeparatorCtrl::onRender(Point2I offset, const RectI &updateRect)
       //posx += mProfile->mFont->getStrWidth(mText);
       //posx += mProfile->mFont->getStrWidth(mText);
 
 
       RectI rect(Point2I(posx,seppos),Point2I(mBounds.extent.x - posx + offset.x,2));
       RectI rect(Point2I(posx,seppos),Point2I(mBounds.extent.x - posx + offset.x,2));
-      renderSlightlyLoweredBox(rect, mProfile, mActive);
+	  renderBorderedRect(rect, mProfile, GuiControlState::highlight);
 
 
    } else
    } else
    {
    {
@@ -95,13 +95,13 @@ void GuiSeparatorCtrl::onRender(Point2I offset, const RectI &updateRect)
       {
       {
          S32 seppos = mBounds.extent.y / 2 + offset.y; 
          S32 seppos = mBounds.extent.y / 2 + offset.y; 
          RectI rect(Point2I(offset.x + mMargin ,seppos),Point2I(mBounds.extent.x - (mMargin * 2),2));
          RectI rect(Point2I(offset.x + mMargin ,seppos),Point2I(mBounds.extent.x - (mMargin * 2),2));
-         renderSlightlyLoweredBox(rect, mProfile);
+		 renderBorderedRect(rect, mProfile, GuiControlState::normal);
       }
       }
       else
       else
       {
       {
          S32 seppos = mBounds.extent.x / 2 + offset.x; 
          S32 seppos = mBounds.extent.x / 2 + offset.x; 
          RectI rect(Point2I(seppos, offset.y + mMargin),Point2I(2, mBounds.extent.y - (mMargin * 2)));
          RectI rect(Point2I(seppos, offset.y + mMargin),Point2I(2, mBounds.extent.y - (mMargin * 2)));
-         renderSlightlyLoweredBox(rect, mProfile);
+		 renderBorderedRect(rect, mProfile, GuiControlState::normal);
       }
       }
    }
    }
 
 

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

@@ -137,10 +137,10 @@ void GuiArrayCtrl::scrollCellVisible(Point2I cell)
 
 
 void GuiArrayCtrl::onRenderColumnHeaders(Point2I offset, Point2I parentOffset, Point2I headerDim)
 void GuiArrayCtrl::onRenderColumnHeaders(Point2I offset, Point2I parentOffset, Point2I headerDim)
 {
 {
-   if (mProfile->mBorder)
+   if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
    {
    {
       RectI cellR(offset.x + headerDim.x, parentOffset.y, mBounds.extent.x - headerDim.x, headerDim.y);
       RectI cellR(offset.x + headerDim.x, parentOffset.y, mBounds.extent.x - headerDim.x, headerDim.y);
-      dglDrawRectFill(cellR, mProfile->mBorderColor);
+      dglDrawRectFill(cellR, mProfile->mBorderDefault->mBorderColor);
    }
    }
 }
 }
 
 

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

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

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

@@ -472,8 +472,8 @@ void GuiColorPickerCtrl::renderColorBox(RectI &bounds)
    pickerBounds.extent.x = bounds.extent.x-1;
    pickerBounds.extent.x = bounds.extent.x-1;
    pickerBounds.extent.y = bounds.extent.y-1;
    pickerBounds.extent.y = bounds.extent.y-1;
    
    
-   if (mProfile->mBorder)
-      dglDrawRect(bounds, mProfile->mBorderColor);
+   if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
+      dglDrawRect(bounds, mProfile->mBorderDefault->mBorderColor);
       
       
    Point2I selectorPos = Point2I(bounds.point.x+mSelectorPos.x+1, bounds.point.y+mSelectorPos.y+1);
    Point2I selectorPos = Point2I(bounds.point.x+mSelectorPos.x+1, bounds.point.y+mSelectorPos.y+1);
 
 

+ 4 - 11
engine/source/gui/guiControl.cc

@@ -446,15 +446,9 @@ void GuiControl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
     RectI ctrlRect(offset, mBounds.extent);
     RectI ctrlRect(offset, mBounds.extent);
 
 
-    dglSetBitmapModulation( mProfile->mFontColor );
-    //if opaque, fill the update rect with the fill color and the border is not 5
-    if (mProfile->mOpaque && mProfile->mBorder != 5)
-        dglDrawRectFill( ctrlRect, mProfile->mFillColor );
-
-    //if there's a border, draw the border
-    if (mProfile->mBorder)
-        renderBorder(ctrlRect, mProfile);
+    renderBorderedRect(ctrlRect, mProfile, normal);
 
 
+	dglSetBitmapModulation(mProfile->mFontColor);
     renderChildControls(offset, updateRect);
     renderChildControls(offset, updateRect);
 }
 }
 
 
@@ -593,9 +587,8 @@ bool GuiControl::renderTooltip(Point2I cursorPos, const char* tipText )
     RectI rect(offset, textBounds);
     RectI rect(offset, textBounds);
     dglSetClipRect(rect);
     dglSetClipRect(rect);
 
 
-    // Draw Filler bit, then border on top of that
-    dglDrawRectFill(rect, mTooltipProfile->mFillColor );
-    dglDrawRect( rect, mTooltipProfile->mBorderColor );
+    // Draw body and border of the tool tip
+	renderBorderedRect(rect, mTooltipProfile, normal);
 
 
     // Draw the text centered in the tool tip box
     // Draw the text centered in the tool tip box
     dglSetBitmapModulation( mTooltipProfile->mFontColor );
     dglSetBitmapModulation( mTooltipProfile->mFontColor );

+ 61 - 263
engine/source/gui/guiDefaultControlRender.cc

@@ -26,270 +26,68 @@
 #include "graphics/color.h"
 #include "graphics/color.h"
 #include "math/mRect.h"
 #include "math/mRect.h"
 
 
-static ColorI colorLightGray(192, 192, 192);
-static ColorI colorGray(128, 128, 128);
-static ColorI colorDarkGray(64, 64, 64);
-static ColorI colorWhite(255,255,255);
-static ColorI colorBlack(0,0,0);
-
-void renderRaisedBox(RectI &bounds, GuiControlProfile *profile)
-{
-   S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
-   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
-
-   dglDrawRectFill( bounds, profile->mFillColor);
-   dglDrawLine(l, t, l, b - 1, profile->mBevelColorHL);
-   dglDrawLine(l, t, r - 1, t, profile->mBevelColorHL);
-
-   dglDrawLine(l, b, r, b, profile->mBevelColorLL);
-   dglDrawLine(r, b - 1, r, t, profile->mBevelColorLL);
-
-   dglDrawLine(l + 1, b - 1, r - 1, b - 1, profile->mBorderColor);
-   dglDrawLine(r - 1, b - 2, r - 1, t + 1, profile->mBorderColor);
-}
-
-void renderSlightlyRaisedBox(RectI &bounds, GuiControlProfile *profile)
-{
-   S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
-   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
-
-   dglDrawRectFill( bounds, profile->mFillColor);
-   dglDrawLine(l, t, l, b, profile->mBevelColorHL);
-   dglDrawLine(l, t, r, t, profile->mBevelColorHL);
-   dglDrawLine(l + 1, b, r, b, profile->mBorderColor);
-   dglDrawLine(r, t + 1, r, b - 1, profile->mBorderColor);
-}
-
-void renderLoweredBox(RectI &bounds, GuiControlProfile *profile)
-{
-   S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
-   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
-
-   dglDrawRectFill( bounds, profile->mFillColor);
-
-   dglDrawLine(l, b, r, b, profile->mBevelColorHL);
-   dglDrawLine(r, b - 1, r, t, profile->mBevelColorHL);
-
-   dglDrawLine(l, t, r - 1, t, profile->mBevelColorLL);
-   dglDrawLine(l, t + 1, l, b - 1, profile->mBevelColorLL);
-
-   dglDrawLine(l + 1, t + 1, r - 2, t + 1, profile->mBorderColor);
-   dglDrawLine(l + 1, t + 2, l + 1, b - 2, profile->mBorderColor);
-}
-
-//void renderSlightlyLoweredBox(RectI &bounds, GuiControlProfile *profile)
-//{
-//   S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
-//   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
-//
-//   dglDrawRectFill( bounds, profile->mFillColor);
-//   dglDrawLine(l, b, r, b, profile->mBevelColorHL);
-//   dglDrawLine(r, t, r, b - 1, profile->mBevelColorHL);
-//   dglDrawLine(l, t, l, b - 1, profile->mBorderColor);
-//   dglDrawLine(l + 1, t, r - 1, t, profile->mBorderColor);
-//}
-
-void renderSlightlyLoweredBox(RectI &bounds, GuiControlProfile *profile, bool active)
+void renderBorderedRect(RectI &bounds, GuiControlProfile *profile, GuiControlState state )
 {
 {
-    S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
-    S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
-
-    if (active)
-    {
-        dglDrawRectFill( bounds, profile->mFillColor);
-        dglDrawLine(l, b, r, b, profile->mBevelColorHL);
-        dglDrawLine(r, t, r, b - 1, profile->mBevelColorHL);
-        dglDrawLine(l, t, l, b - 1, profile->mBorderColor);
-        dglDrawLine(l + 1, t, r - 1, t, profile->mBorderColor);
-    }
-    else
-    {
-        dglDrawRectFill( bounds, profile->mFillColorNA);
-        dglDrawLine(l, b, r, b, profile->mBorderColorNA);
-        dglDrawLine(r, t, r, b - 1, profile->mBorderColorNA);
-        dglDrawLine(l, t, l, b - 1, profile->mBorderColorNA);
-        dglDrawLine(l + 1, t, r - 1, t, profile->mBorderColorNA);
-    }
-}
-
-void renderBorder(RectI &bounds, GuiControlProfile *profile)
-{
-   S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
-   S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
-
-   RectI centerRect = bounds;
-   centerRect.inset(profile->mBorderSize, profile->mBorderSize);
-
-   switch(profile->mBorder)
-   {
-   case 1://normal borders
-		renderFilledBorder(bounds, profile);
-		break;
-   case 2://pillow
-      dglDrawLine(l + 1, t + 1, l + 1, b - 1, profile->mBevelColorHL);
-      dglDrawLine(l + 2, t + 1, r - 1, t + 1, profile->mBevelColorHL);
-      dglDrawLine(r, t + 1, r, b + 1, profile->mBevelColorHL);
-      dglDrawLine(l + 1, b, r, b, profile->mBevelColorHL);
-      dglDrawLine(l, t, r, t, profile->mBevelColorLL);
-      dglDrawLine(l, t + 1, l, b, profile->mBevelColorLL);
-      dglDrawLine(l + 2, b - 1, r, b - 1, profile->mBevelColorLL);
-      dglDrawLine(r - 1, t + 2, r - 1, b - 1, profile->mBevelColorLL);
-      break;
-   case 3://inner bevel
-      dglDrawLine(l + 1, b, r + 1, b, profile->mBevelColorHL);
-      dglDrawLine(r, t + 1, r, b, profile->mBevelColorHL);
-      dglDrawLine(l + 2, b - 1, r, b - 1, profile->mBorderColor);
-      dglDrawLine(r - 1, t + 2, r - 1, b - 1, profile->mBorderColor);
-      dglDrawLine(l, t, l, b, profile->mBorderColorNA);
-      dglDrawLine(l + 1, t, r, t, profile->mBorderColorNA);
-      dglDrawLine(l + 1, t + 1, l + 1, b - 1, profile->mBevelColorLL);
-      dglDrawLine(l + 2, t + 1, r - 1, t + 1, profile->mBevelColorLL);
-      break;
-   case 4://outer bevel
-      dglDrawLine(l, t, l, b, profile->mBevelColorHL);
-      dglDrawLine(l + 1, t, r, t, profile->mBevelColorHL);
-      dglDrawLine(l + 1, b, r + 1, b, profile->mBevelColorLL);
-      dglDrawLine(r, t + 1, r, b, profile->mBevelColorLL);
-      dglDrawLine(l + 2, b - 1, r, b - 1, profile->mBorderColor);
-      dglDrawLine(r - 1, t + 2, r - 1, b - 1, profile->mBorderColor);
-      break;
-   case 5: //normal borders, but the fill is not drawn under the borders
-		dglDrawRectFill(centerRect, profile->mFillColor);
-		renderFilledBorder( bounds, profile );
-		break;
-    
-   case 6:// Draw boarder only on top and left
-       dglDrawLine(l, t, l, b + 1, profile->mBorderColor);
-       dglDrawLine(l + 1, t, r + 1, t, profile->mBorderColor);
-       break;
-   case 7:// Draw boarder only on bottom and right
-       dglDrawLine(r, t, r, b, profile->mBorderColor);
-       dglDrawLine(l, b, r, b, profile->mBorderColor);
-       break;
-      // DAW:
-   case -1:
-      // Draw a simple sizable border with corners
-      // Taken from the 'Skinnable GUI Controls in TGE' resource by Justin DuJardin       
-      if(profile->mBitmapArrayRects.size() >= 8)
-      {
-         dglClearBitmapModulation();
-
-         RectI destRect;
-         RectI stretchRect;
-         RectI* mBitmapBounds = profile->mBitmapArrayRects.address();
-
-         // DAW: Indices into the bitmap array
-         enum
-         {
-            BorderTopLeft = 0,
-            BorderTop,
-            BorderTopRight,
-            BorderLeft,
-            //Fill,
-            BorderRight,
-            BorderBottomLeft,
-            BorderBottom,
-            BorderBottomRight,
-            NumBitmaps
-         };
-
-         // Draw all corners first.
-
-         //top left border
-         dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y),mBitmapBounds[BorderTopLeft]);
-         //top right border
-         dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x + bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x,bounds.point.y),mBitmapBounds[BorderTopRight]);
-
-         //bottom left border
-         dglDrawBitmapSR(profile->mTextureHandle,Point2I(bounds.point.x,bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomLeft].extent.y),mBitmapBounds[BorderBottomLeft]);
-         //bottom right border
-         dglDrawBitmapSR(profile->mTextureHandle,Point2I(
-            bounds.point.x + bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x,
-            bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottomRight].extent.y),
-            mBitmapBounds[BorderBottomRight]);
-
-         // End drawing corners
-
-         // Begin drawing sides and top stretched borders
-
-         //start with top line stretch
-         destRect.point.x = bounds.point.x + mBitmapBounds[BorderTopRight].extent.x;
-         destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderTopRight].extent.x - mBitmapBounds[BorderTopLeft].extent.x;
-         destRect.extent.y = mBitmapBounds[BorderTop].extent.y;
-         destRect.point.y = bounds.point.y;
-         //stretch it
-         stretchRect = mBitmapBounds[BorderTop];
-         stretchRect.inset(1,0);
-         //draw it
-         dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
-         //bottom line stretch
-         destRect.point.x = bounds.point.x + mBitmapBounds[BorderBottomRight].extent.x;
-         destRect.extent.x = bounds.extent.x - mBitmapBounds[BorderBottomRight].extent.x - mBitmapBounds[BorderBottomLeft].extent.x;
-         destRect.extent.y = mBitmapBounds[BorderBottom].extent.y;
-         destRect.point.y = bounds.point.y + bounds.extent.y - mBitmapBounds[BorderBottom].extent.y;
-         //stretch it
-         stretchRect = mBitmapBounds[BorderBottom];
-         stretchRect.inset(1,0);
-         //draw it
-         dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
-         //left line stretch
-         destRect.point.x = bounds.point.x;
-         destRect.extent.x = mBitmapBounds[BorderLeft].extent.x;
-         destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopLeft].extent.y - mBitmapBounds[BorderBottomLeft].extent.y;
-         destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopLeft].extent.y;
-         //stretch it
-         stretchRect = mBitmapBounds[BorderLeft];
-         stretchRect.inset(0,1);
-         //draw it
-         dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
-         //left line stretch
-         destRect.point.x = bounds.point.x + bounds.extent.x - mBitmapBounds[BorderRight].extent.x;
-         destRect.extent.x = mBitmapBounds[BorderRight].extent.x;
-         destRect.extent.y = bounds.extent.y - mBitmapBounds[BorderTopRight].extent.y - mBitmapBounds[BorderBottomRight].extent.y;
-         destRect.point.y = bounds.point.y + mBitmapBounds[BorderTopRight].extent.y;
-         //stretch it
-         stretchRect = mBitmapBounds[BorderRight];
-         stretchRect.inset(0,1);
-         //draw it
-         dglDrawBitmapStretchSR(profile->mTextureHandle,destRect,stretchRect);
-
-         // End drawing sides and top stretched borders
-         break;
-      }
-   case -2:
-      // Draw a simple sizable border with corners that is filled in
-      renderSizableBitmapBordersFilled(bounds, 1, profile);
-      break;
-   case -3:
-      // Draw a simple fixed height border with center fill horizontally.
-      renderFixedBitmapBordersFilled( bounds, 1, profile );
-      break;
-
-   }
-}
-
-void renderFilledBorder( RectI &bounds, GuiControlProfile *profile )
-{
-   renderFilledBorder( bounds, profile->mBorderColor, profile->mFillColor, profile->mBorderSize );
-}
-
-void renderFilledBorder( RectI &bounds, ColorI &borderColor, ColorI &fillColor, S32 borderSize )
-{
-   RectI centerRect = bounds;
-   centerRect.inset( borderSize, borderSize );
-   dglDrawRectFill(centerRect, fillColor);
-
-   RectI leftRect = RectI(bounds.point.x, bounds.point.y, borderSize, bounds.extent.y - borderSize);
-   dglDrawRectFill(leftRect, borderColor);
-
-   RectI topRect = RectI(bounds.point.x + borderSize, bounds.point.y, bounds.extent.x, borderSize);
-   dglDrawRectFill(topRect, borderColor);
-
-   RectI rightRect = RectI(bounds.point.x + bounds.extent.x - borderSize, bounds.point.y + borderSize, borderSize, bounds.extent.y - borderSize);
-   dglDrawRectFill(rightRect, borderColor);
-
-   RectI bottomRect = RectI(bounds.point.x, bounds.point.y + bounds.extent.y - borderSize, bounds.extent.x - borderSize, borderSize);
-   dglDrawRectFill(bottomRect, borderColor);
+	//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;
+
+	//Get the colors
+	ColorI fillColor = profile->getFillColor(state);
+	ColorI leftColor = (leftProfile) ? leftProfile->getBorderColor(state) : ColorI();
+	ColorI rightColor = (rightProfile) ? rightProfile->getBorderColor(state) : ColorI();
+	ColorI topColor = (topProfile) ? topProfile->getBorderColor(state) : ColorI();
+	ColorI bottomColor = (bottomProfile) ? bottomProfile->getBorderColor(state) : ColorI();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getBorder(state) : 0;
+	S32 rightSize = (rightProfile) ? rightProfile->getBorder(state) : 0;
+	S32 topSize = (topProfile) ? topProfile->getBorder(state) : 0;
+	S32 bottomSize = (bottomProfile) ? bottomProfile->getBorder(state) : 0;
+	
+	//Get the inner rect
+	RectI innerRect = RectI(bounds.point.x + leftSize, bounds.point.y + topSize, (bounds.extent.x - leftSize) - rightSize, (bounds.extent.y - topSize) - bottomSize);
+
+	//Draw the fill
+	if(profile->mOpaque)
+	{
+		S32 fillWidth = innerRect.extent.x + ((leftProfile && leftProfile->mUnderfill) ? leftSize : 0) + ((rightProfile && rightProfile->mUnderfill) ? rightSize : 0);
+		S32 fillHeight = innerRect.extent.y + ((topProfile && topProfile->mUnderfill) ? topSize : 0) + ((bottomProfile && bottomProfile->mUnderfill) ? bottomSize : 0);
+		RectI fillRect = RectI((leftProfile && leftProfile->mUnderfill) ? bounds.point.x : innerRect.point.x,
+			(topProfile && topProfile->mUnderfill) ? bounds.point.y : innerRect.point.y, fillWidth, fillHeight);
+		dglDrawRectFill(fillRect, fillColor);
+	}
+	
+	//Draw the borders
+	//Points for outer bounds starting top left and traveling counter-clockwise
+	Point2I p1 = Point2I(bounds.point);
+	Point2I p2 = Point2I(bounds.point.x, bounds.point.y + bounds.extent.y);
+	Point2I p3 = Point2I(bounds.point.x + bounds.extent.x, bounds.point.y + bounds.extent.y);
+	Point2I p4 = Point2I(bounds.point.x + bounds.extent.x, bounds.point.y);
+
+	//Points for inner bounds starting top left and traveling counter-clockwise
+	Point2I p5 = Point2I(innerRect.point);
+	Point2I p6 = Point2I(innerRect.point.x, innerRect.point.y + innerRect.extent.y);
+	Point2I p7 = Point2I(innerRect.point.x + innerRect.extent.x, innerRect.point.y + innerRect.extent.y);
+	Point2I p8 = Point2I(innerRect.point.x + innerRect.extent.x, innerRect.point.y);
+
+	if (leftSize > 0)
+	{
+		dglDrawQuadFill(p1, p2, p6, p5, leftColor);
+	}
+	if (rightSize > 0)
+	{
+		dglDrawQuadFill(p8, p7, p3, p4, rightColor);
+	}
+	if (topSize > 0)
+	{
+		dglDrawQuadFill(p1, p5, p8, p4, topColor);
+	}
+	if (bottomSize > 0)
+	{
+		dglDrawQuadFill(p6, p2, p3, p7, bottomColor);
+	}
 }
 }
 
 
 // DAW: Render out the sizable bitmap borders based on a multiplier into the bitmap array
 // DAW: Render out the sizable bitmap borders based on a multiplier into the bitmap array

+ 5 - 7
engine/source/gui/guiDefaultControlRender.h

@@ -23,15 +23,13 @@
 #ifndef _H_GUIDEFAULTCONTROLRENDER_
 #ifndef _H_GUIDEFAULTCONTROLRENDER_
 #define _H_GUIDEFAULTCONTROLRENDER_
 #define _H_GUIDEFAULTCONTROLRENDER_
 
 
+#ifndef _GUITYPES_H_
+#include "gui/guiTypes.h"
+#endif
+
 class GuiControlProfile;
 class GuiControlProfile;
 
 
-void renderRaisedBox(RectI &bounds, GuiControlProfile *profile);
-void renderSlightlyRaisedBox(RectI &bounds, GuiControlProfile *profile);
-void renderLoweredBox(RectI &bounds, GuiControlProfile *profile);
-void renderSlightlyLoweredBox(RectI &bounds, GuiControlProfile *profile, bool active = true);
-void renderBorder(RectI &bounds, GuiControlProfile *profile);
-void renderFilledBorder( RectI &bounds, GuiControlProfile *profile );
-void renderFilledBorder( RectI &bounds, ColorI &borderColor, ColorI &fillColor, S32 borderSize);
+void renderBorderedRect(RectI &bounds, GuiControlProfile *profile, GuiControlState state);
 void renderSizableBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile); // DAW: Added
 void renderSizableBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile); // DAW: Added
 void renderSizableBitmapBordersFilledIndex(RectI &bounds, S32 startIndex, GuiControlProfile *profile);
 void renderSizableBitmapBordersFilledIndex(RectI &bounds, S32 startIndex, GuiControlProfile *profile);
 void renderFixedBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile); // DAW: Added
 void renderFixedBitmapBordersFilled(RectI &bounds, S32 baseMultiplier, GuiControlProfile *profile); // DAW: Added

+ 8 - 8
engine/source/gui/guiPopUpCtrl.cc

@@ -879,8 +879,8 @@ void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
       {
       {
          dglDrawLine(l, t, l, b, colorWhite);
          dglDrawLine(l, t, l, b, colorWhite);
          dglDrawLine(l, t, r2, t, colorWhite);
          dglDrawLine(l, t, r2, t, colorWhite);
-         dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
-         dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
+         //dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
+         //dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
       }
       }
 
 
    }
    }
@@ -916,8 +916,8 @@ void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
          {
          {
             dglDrawLine(l, t, l, b, colorWhite);
             dglDrawLine(l, t, l, b, colorWhite);
             dglDrawLine(l, t, r2, t, colorWhite);
             dglDrawLine(l, t, r2, t, colorWhite);
-            dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
-            dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
+            //dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
+            //dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
          }
          }
       }
       }
       else
       else
@@ -946,7 +946,7 @@ void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
          // Do we render a bitmap border or lines?
          // Do we render a bitmap border or lines?
          if(!(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size()))
          if(!(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size()))
          {
          {
-            dglDrawRect(r, mProfile->mBorderColorNA);
+            //dglDrawRect(r, mProfile->mBorderColorNA);
          }
          }
       }
       }
       //      renderSlightlyRaisedBox(r, mProfile); // DAW: Used to be the only 'else' condition to mInAction above.
       //      renderSlightlyRaisedBox(r, mProfile); // DAW: Used to be the only 'else' condition to mInAction above.
@@ -1228,7 +1228,7 @@ void GuiPopUpMenuCtrl::onAction()
          textWidth = mFont->getStrWidth(mEntries[i].buf);
          textWidth = mFont->getStrWidth(mEntries[i].buf);
 
 
    //if(textWidth > mBounds.extent.x)
    //if(textWidth > mBounds.extent.x)
-   S32 sbWidth = mSc->mProfile->mBorderSize * 2 + mSc->scrollBarThickness(); // DAW: Calculate the scroll bar width
+   S32 sbWidth = 0;//mSc->mProfile->mBorderSize * 2 + mSc->scrollBarThickness(); // DAW: Calculate the scroll bar width
    if(textWidth > (mBounds.extent.x - sbWidth-mProfile->mTextOffset.x - mSc->getChildMargin().x * 2)) // DAW: The text draw area to test against is the width of the drop-down minus the scroll bar width, the text margin and the scroll bar child margins.
    if(textWidth > (mBounds.extent.x - sbWidth-mProfile->mTextOffset.x - mSc->getChildMargin().x * 2)) // DAW: The text draw area to test against is the width of the drop-down minus the scroll bar width, the text margin and the scroll bar child margins.
    {
    {
       //textWidth +=10;
       //textWidth +=10;
@@ -1252,7 +1252,7 @@ void GuiPopUpMenuCtrl::onAction()
 
 
    //Calc max Y distance, so Scroll Ctrl will fit on window 
    //Calc max Y distance, so Scroll Ctrl will fit on window 
    //S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - menuSpace; 
    //S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - menuSpace; 
-   S32 sbBorder = mSc->mProfile->mBorderSize * 2 + mSc->getChildMargin().y * 2; // DAW: Added to take into account the border thickness and the margin of the child controls of the scroll control when figuring out the size of the contained text list control
+   S32 sbBorder = 0;//TODO: mSc->mProfile->mBorderSize * 2 + mSc->getChildMargin().y * 2; // DAW: Added to take into account the border thickness and the margin of the child controls of the scroll control when figuring out the size of the contained text list control
    S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - sbBorder; // - menuSpace; // DAW: Need to remove the border thickness from the contained control maximum extent and got rid of the 'menuspace' variable
    S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - sbBorder; // - menuSpace; // DAW: Need to remove the border thickness from the contained control maximum extent and got rid of the 'menuspace' variable
 
 
    //If scroll bars need to be added
    //If scroll bars need to be added
@@ -1422,7 +1422,7 @@ bool GuiPopUpMenuCtrl::getFontColor( ColorI &fontColor, S32 id, bool selected, b
    }
    }
 
 
    // Default color scheme...
    // Default color scheme...
-   fontColor = selected ? mProfile->mFontColorSEL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColorNA; // DAW: Modified the final color choice from mProfile->mFontColor to mProfile->mFontColorNA
+   fontColor = selected ? mProfile->mFontColorSL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColorNA; // DAW: Modified the final color choice from mProfile->mFontColor to mProfile->mFontColorNA
 
 
    return( true );
    return( true );
 }
 }

+ 8 - 8
engine/source/gui/guiPopUpCtrlEx.cc

@@ -892,8 +892,8 @@ void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
 	  {
 	  {
          dglDrawLine(l, t, l, b, colorWhite);
          dglDrawLine(l, t, l, b, colorWhite);
          dglDrawLine(l, t, r2, t, colorWhite);
          dglDrawLine(l, t, r2, t, colorWhite);
-         dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
-         dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
+         //dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
+         //dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
 	  }
 	  }
 
 
    }
    }
@@ -928,8 +928,8 @@ void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
 	  {
 	  {
          dglDrawLine(l, t, l, b, colorWhite);
          dglDrawLine(l, t, l, b, colorWhite);
          dglDrawLine(l, t, r2, t, colorWhite);
          dglDrawLine(l, t, r2, t, colorWhite);
-         dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
-         dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
+         //dglDrawLine(l + 1, b, r2, b, mProfile->mBorderColor);
+         //dglDrawLine(r2, t + 1, r2, b - 1, mProfile->mBorderColor);
 	  }
 	  }
    }
    }
    else
    else
@@ -957,7 +957,7 @@ void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
       // Do we render a bitmap border or lines?
       // Do we render a bitmap border or lines?
       if(!(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size()))
       if(!(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size()))
 	  {
 	  {
-         dglDrawRect(r, mProfile->mBorderColorNA);
+         //dglDrawRect(r, mProfile->mBorderColorNA);
 	  }
 	  }
    }
    }
 //      renderSlightlyRaisedBox(r, mProfile); // DAW: Used to be the only 'else' condition to mInAction above.
 //      renderSlightlyRaisedBox(r, mProfile); // DAW: Used to be the only 'else' condition to mInAction above.
@@ -1213,7 +1213,7 @@ void GuiPopUpMenuCtrlEx::onAction()
          textWidth = mFont->getStrWidth(mEntries[i].buf);
          textWidth = mFont->getStrWidth(mEntries[i].buf);
 
 
    //if(textWidth > mBounds.extent.x)
    //if(textWidth > mBounds.extent.x)
-   S32 sbWidth = mSc->mProfile->mBorderSize * 2 + mSc->scrollBarThickness(); // DAW: Calculate the scroll bar width
+   S32 sbWidth = 0;//TODO: mSc->mProfile->mBorderSize * 2 + mSc->scrollBarThickness(); // DAW: Calculate the scroll bar width
    if(textWidth > (mBounds.extent.x - sbWidth-mProfile->mTextOffset.x - mSc->getChildMargin().x * 2)) // DAW: The text draw area to test against is the width of the drop-down minus the scroll bar width, the text margin and the scroll bar child margins.
    if(textWidth > (mBounds.extent.x - sbWidth-mProfile->mTextOffset.x - mSc->getChildMargin().x * 2)) // DAW: The text draw area to test against is the width of the drop-down minus the scroll bar width, the text margin and the scroll bar child margins.
    {
    {
       //textWidth +=10;
       //textWidth +=10;
@@ -1237,7 +1237,7 @@ void GuiPopUpMenuCtrlEx::onAction()
 
 
    //Calc max Y distance, so Scroll Ctrl will fit on window 
    //Calc max Y distance, so Scroll Ctrl will fit on window 
    //S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - menuSpace; 
    //S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - menuSpace; 
-   S32 sbBorder = mSc->mProfile->mBorderSize * 2 + mSc->getChildMargin().y * 2; // DAW: Added to take into account the border thickness and the margin of the child controls of the scroll control when figuring out the size of the contained text list control
+   S32 sbBorder = 0;//TODO: mSc->mProfile->mBorderSize * 2 + mSc->getChildMargin().y * 2; // DAW: Added to take into account the border thickness and the margin of the child controls of the scroll control when figuring out the size of the contained text list control
    S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - sbBorder; // - menuSpace; // DAW: Need to remove the border thickness from the contained control maximum extent and got rid of the 'menuspace' variable
    S32 maxYdis = windowExt.y - pointInGC.y - mBounds.extent.y - sbBorder; // - menuSpace; // DAW: Need to remove the border thickness from the contained control maximum extent and got rid of the 'menuspace' variable
                      
                      
    //If scroll bars need to be added
    //If scroll bars need to be added
@@ -1410,7 +1410,7 @@ bool GuiPopUpMenuCtrlEx::getFontColor( ColorI &fontColor, S32 id, bool selected,
       fontColor = mProfile->mFontColorHL;
       fontColor = mProfile->mFontColorHL;
    else
    else
    // Default color scheme...
    // Default color scheme...
-   fontColor = selected ? mProfile->mFontColorSEL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColorNA; // DAW: Modified the final color choice from mProfile->mFontColor to mProfile->mFontColorNA
+   fontColor = selected ? mProfile->mFontColorSL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColorNA; // DAW: Modified the final color choice from mProfile->mFontColor to mProfile->mFontColorNA
 
 
    return( true );
    return( true );
 }
 }

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

@@ -81,8 +81,8 @@ void GuiProgressCtrl::onRender(Point2I offset, const RectI &updateRect)
    }
    }
 
 
    //now draw the border
    //now draw the border
-   if (mProfile->mBorder)
-      dglDrawRect(ctrlRect, mProfile->mBorderColor);
+   if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
+      dglDrawRect(ctrlRect, mProfile->mBorderDefault->mBorderColor);
 
 
    Parent::onRender( offset, updateRect );
    Parent::onRender( offset, updateRect );
 
 

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

@@ -440,7 +440,7 @@ void GuiSliderCtrl::onRender(Point2I offset, const RectI &updateRect)
 
 
         // draw the thumb
         // draw the thumb
         thumb.point += pos;
         thumb.point += pos;
-        renderRaisedBox(thumb, mProfile);
+        renderBorderedRect(thumb, mProfile, normal);
     }
     }
 
 
     if (mDisplayValue)
     if (mDisplayValue)

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

@@ -1121,10 +1121,10 @@ void GuiTextEditCtrl::onRender(Point2I offset, const RectI & updateRect)
    }
    }
 
 
    //if there's a border, draw the border
    //if there's a border, draw the border
-   if ( mProfile->mBorder )
+   if (mProfile->mBorderDefault && mProfile->mBorderDefault->mBorder > 0)
    {
    {
       dglSetBitmapModulation( mActive ? mProfile->mFillColor : mProfile->mFillColorNA );
       dglSetBitmapModulation( mActive ? mProfile->mFillColor : mProfile->mFillColorNA );
-      renderBorder( ctrlRect, mProfile );
+      //renderBorder( ctrlRect, mProfile );
    }
    }
 
 
    drawText( ctrlRect, isFirstResponder() );
    drawText( ctrlRect, isFirstResponder() );

+ 2 - 1
engine/source/gui/guiTextListCtrl.cc

@@ -335,7 +335,8 @@ void GuiTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected,
       {
       {
          RectI highlightRect = RectI(offset.x, offset.y, mCellSize.x, mCellSize.y);
          RectI highlightRect = RectI(offset.x, offset.y, mCellSize.x, mCellSize.y);
          highlightRect.inset( 0, -1 );
          highlightRect.inset( 0, -1 );
-         renderFilledBorder( highlightRect, mProfile->mBorderColorHL, mProfile->mFillColorHL, mProfile->mBorderSize);
+		 //renderBody(highlightRect, mProfile, mProfile->mFillColorHL);
+         //renderBorder( highlightRect, mProfile->mBorderColorHL, mProfile->mBorderSize);
          dglSetBitmapModulation(mProfile->mFontColorHL);
          dglSetBitmapModulation(mProfile->mFontColorHL);
       }
       }
       else
       else

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

@@ -3199,7 +3199,7 @@ void GuiTreeViewCtrl::onRenderCell(Point2I offset, Point2I cell, bool, bool )
    // Determine what color the font should be.
    // Determine what color the font should be.
    ColorI fontColor;
    ColorI fontColor;
 
 
-   fontColor = item->mState.test( Item::Selected ) ? mProfile->mFontColorSEL :
+   fontColor = item->mState.test( Item::Selected ) ? mProfile->mFontColorSL :
              ( item->mState.test( Item::MouseOverText ) ? mProfile->mFontColorHL : mProfile->mFontColor );
              ( item->mState.test( Item::MouseOverText ) ? mProfile->mFontColorHL : mProfile->mFontColor );
 
 
    if (item->mState.test(Item::Selected))
    if (item->mState.test(Item::Selected))

+ 147 - 25
engine/source/gui/guiTypes.cc

@@ -91,6 +91,99 @@ void GuiCursor::render(const Point2I &pos)
    dglDrawBitmap(mTextureHandle, renderPos);
    dglDrawBitmap(mTextureHandle, renderPos);
 }
 }
 
 
+//------------------------------------------------------------------------------
+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);
+
+	mUnderfill = true;
+}
+
+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("underfill", TypeBool, Offset(mUnderfill, GuiBorderProfile));
+}
+
+bool GuiBorderProfile::onAdd()
+{
+	if (!Parent::onAdd())
+		return false;
+
+	Sim::getGuiDataGroup()->addObject(this);
+
+	return true;
+}
+
+void GuiBorderProfile::onRemove()
+{
+	Parent::onRemove();
+}
+
+const ColorI& GuiBorderProfile::getBorderColor(const GuiControlState state)
+{
+	switch (state)
+	{
+	default:
+	case normal:
+		return mBorderColor;
+		break;
+	case highlight:
+		return mBorderColorHL;
+		break;
+	case selected:
+		return mBorderColorSL;
+		break;
+	case disabled:
+		return mBorderColorNA;
+		break;
+	}
+}
+
+S32 GuiBorderProfile::getBorder(const GuiControlState state)
+{
+	switch (state)
+	{
+	default:
+	case normal:
+		return mBorder;
+		break;
+	case highlight:
+		return mBorderHL;
+		break;
+	case selected:
+		return mBorderSL;
+		break;
+	case disabled:
+		return mBorderNA;
+		break;
+	}
+}
+
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 IMPLEMENT_CONOBJECT(GuiControlProfile);
 IMPLEMENT_CONOBJECT(GuiControlProfile);
 
 
@@ -135,7 +228,7 @@ GuiControlProfile::GuiControlProfile(void) :
    mFontColor(mFontColors[BaseColor]),
    mFontColor(mFontColors[BaseColor]),
    mFontColorHL(mFontColors[ColorHL]),
    mFontColorHL(mFontColors[ColorHL]),
    mFontColorNA(mFontColors[ColorNA]),
    mFontColorNA(mFontColors[ColorNA]),
-   mFontColorSEL(mFontColors[ColorSEL])
+   mFontColorSL(mFontColors[ColorSL])
 {
 {
     mRefCount = 0;
     mRefCount = 0;
     mBitmapArrayRects.clear();
     mBitmapArrayRects.clear();
@@ -145,9 +238,12 @@ GuiControlProfile::GuiControlProfile(void) :
     mCanKeyFocus   = false;
     mCanKeyFocus   = false;
     
     
     mOpaque        = false;
     mOpaque        = false;
-    
-    mBorder        = 0;
-    mBorderSize = 1;
+
+	mBorderDefault = NULL;
+	mBorderLeft = NULL;
+	mBorderRight = NULL;
+	mBorderTop = NULL;
+	mBorderBottom = NULL;
     
     
     // default font
     // default font
     mFontType      = StringTable->EmptyString;
     mFontType      = StringTable->EmptyString;
@@ -180,15 +276,6 @@ GuiControlProfile::GuiControlProfile(void) :
       mFillColorHL   = def->mFillColorHL;
       mFillColorHL   = def->mFillColorHL;
       mFillColorNA   = def->mFillColorNA;
       mFillColorNA   = def->mFillColorNA;
 
 
-      mBorder        = def->mBorder;
-      mBorderSize    = def->mBorderSize;
-      mBorderColor   = def->mBorderColor;
-      mBorderColorHL = def->mBorderColorHL;
-      mBorderColorNA = def->mBorderColorNA;
-
-      mBevelColorHL = def->mBevelColorHL;
-      mBevelColorLL = def->mBevelColorLL;
-
       // default font
       // default font
       mFontType      = def->mFontType;
       mFontType      = def->mFontType;
       mFontSize      = def->mFontSize;
       mFontSize      = def->mFontSize;
@@ -230,15 +317,14 @@ void GuiControlProfile::initPersistFields()
    addField("opaque",        TypeBool,       Offset(mOpaque, GuiControlProfile));
    addField("opaque",        TypeBool,       Offset(mOpaque, GuiControlProfile));
    addField("fillColor",     TypeColorI,     Offset(mFillColor, GuiControlProfile));
    addField("fillColor",     TypeColorI,     Offset(mFillColor, GuiControlProfile));
    addField("fillColorHL",   TypeColorI,     Offset(mFillColorHL, GuiControlProfile));
    addField("fillColorHL",   TypeColorI,     Offset(mFillColorHL, GuiControlProfile));
+   addField("fillColorSL",   TypeColorI,     Offset(mFillColorSL, GuiControlProfile));
    addField("fillColorNA",   TypeColorI,     Offset(mFillColorNA, GuiControlProfile));
    addField("fillColorNA",   TypeColorI,     Offset(mFillColorNA, GuiControlProfile));
-   addField("border",        TypeS32,        Offset(mBorder, GuiControlProfile));
-   addField("borderSize",    TypeS32,        Offset(mBorderSize, GuiControlProfile));
-   addField("borderColor",   TypeColorI,     Offset(mBorderColor, GuiControlProfile));
-   addField("borderColorHL", TypeColorI,     Offset(mBorderColorHL, GuiControlProfile));
-   addField("borderColorNA", TypeColorI,     Offset(mBorderColorNA, GuiControlProfile));
 
 
-   addField("bevelColorHL", TypeColorI,     Offset(mBevelColorHL, GuiControlProfile));
-   addField("bevelColorLL", TypeColorI,     Offset(mBevelColorLL, GuiControlProfile));
+   addField("borderDefault", TypeSimObjectPtr, Offset(mBorderDefault, GuiControlProfile));
+   addField("borderLeft",    TypeSimObjectPtr, Offset(mBorderLeft, GuiControlProfile));
+   addField("borderRight",   TypeSimObjectPtr, Offset(mBorderRight, GuiControlProfile));
+   addField("borderTop",     TypeSimObjectPtr, Offset(mBorderTop, GuiControlProfile));
+   addField("borderBottom",  TypeSimObjectPtr, Offset(mBorderBottom, GuiControlProfile));
 
 
    addField("fontType",      TypeString,     Offset(mFontType, GuiControlProfile));
    addField("fontType",      TypeString,     Offset(mFontType, GuiControlProfile));
    addField("fontSize",      TypeS32,        Offset(mFontSize, GuiControlProfile));
    addField("fontSize",      TypeS32,        Offset(mFontSize, GuiControlProfile));
@@ -247,7 +333,7 @@ void GuiControlProfile::initPersistFields()
    addField("fontColor",     TypeColorI,     Offset(mFontColors[BaseColor], GuiControlProfile));
    addField("fontColor",     TypeColorI,     Offset(mFontColors[BaseColor], GuiControlProfile));
    addField("fontColorHL",   TypeColorI,     Offset(mFontColors[ColorHL], GuiControlProfile));
    addField("fontColorHL",   TypeColorI,     Offset(mFontColors[ColorHL], GuiControlProfile));
    addField("fontColorNA",   TypeColorI,     Offset(mFontColors[ColorNA], GuiControlProfile));
    addField("fontColorNA",   TypeColorI,     Offset(mFontColors[ColorNA], GuiControlProfile));
-   addField("fontColorSEL",  TypeColorI,     Offset(mFontColors[ColorSEL], GuiControlProfile));
+   addField("fontColorSL",  TypeColorI,     Offset(mFontColors[ColorSL], GuiControlProfile));
    addField("fontColorLink", TypeColorI,     Offset(mFontColors[ColorUser0], GuiControlProfile));
    addField("fontColorLink", TypeColorI,     Offset(mFontColors[ColorUser0], GuiControlProfile));
    addField("fontColorLinkHL", TypeColorI,     Offset(mFontColors[ColorUser1], GuiControlProfile));
    addField("fontColorLinkHL", TypeColorI,     Offset(mFontColors[ColorUser1], GuiControlProfile));
 
 
@@ -367,10 +453,6 @@ void GuiControlProfile::incRefCount()
           mTextureHandle = TextureHandle(mBitmapName, TextureHandle::BitmapKeepTexture);
           mTextureHandle = TextureHandle(mBitmapName, TextureHandle::BitmapKeepTexture);
           if (!(bool)mTextureHandle)
           if (!(bool)mTextureHandle)
              Con::errorf("Failed to load profile bitmap (%s)",mBitmapName);
              Con::errorf("Failed to load profile bitmap (%s)",mBitmapName);
-
-          // If we've got a special border, make sure it's usable.
-          if( mBorder == -1 || mBorder == -2 )
-             constructBitmapArray();
       }
       }
    }
    }
 }
 }
@@ -388,6 +470,46 @@ void GuiControlProfile::decRefCount()
    }
    }
 }
 }
 
 
+const ColorI& GuiControlProfile::getFillColor(const GuiControlState state)
+{
+	switch (state)
+	{
+	default:
+	case normal:
+		return mFillColor;
+		break;
+	case highlight:
+		return mFillColorHL;
+		break;
+	case selected:
+		return mFillColorSL;
+		break;
+	case disabled:
+		return mFillColorNA;
+		break;
+	}
+}
+
+const ColorI& GuiControlProfile::getFontColor(const GuiControlState state)
+{
+	switch (state)
+	{
+	default:
+	case normal:
+		return mFontColor;
+		break;
+	case highlight:
+		return mFontColorHL;
+		break;
+	case selected:
+		return mFontColorSL;
+		break;
+	case disabled:
+		return mFontColorNA;
+		break;
+	}
+}
+
 ConsoleType( GuiProfile, TypeGuiProfile, sizeof(GuiControlProfile*), "" )
 ConsoleType( GuiProfile, TypeGuiProfile, sizeof(GuiControlProfile*), "" )
 
 
 ConsoleSetType( TypeGuiProfile )
 ConsoleSetType( TypeGuiProfile )

+ 50 - 11
engine/source/gui/guiTypes.h

@@ -68,6 +68,14 @@ struct GuiEvent
    S32		eventID;		   ///< assigns mouse or touch ID to the event
    S32		eventID;		   ///< assigns mouse or touch ID to the event
 };
 };
 
 
+enum GuiControlState
+{
+	normal = 0,				//Control renders with default look
+	highlight,				//Control is highlighted
+	selected,				//Control has been selected
+	disabled				//Control cannot be used
+};
+
 class GuiCursor : public SimObject
 class GuiCursor : public SimObject
 {
 {
 private:
 private:
@@ -93,6 +101,36 @@ public:
    void render(const Point2I &pos);
    void render(const Point2I &pos);
 };
 };
 
 
+/// A GuiBorderProfile holds on the information needed for a single border of a GuiControl.
+/// GuiBorderProfiles can be assigned to a GuiControlProfile to cover one or all of the borders.
+class GuiBorderProfile : public SimObject
+{
+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.
+public:
+	DECLARE_CONOBJECT(GuiBorderProfile);
+	GuiBorderProfile();
+	~GuiBorderProfile();
+	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 getBorder(const GuiControlState state); //Returns the size of the border based on the control's state.
+};
+
 /// A GuiControlProfile is used by every GuiObject and is akin to a
 /// A GuiControlProfile is used by every GuiObject and is akin to a
 /// datablock. It is used to control information that does not change
 /// datablock. It is used to control information that does not change
 /// or is unlikely to change during execution of a program. It is also
 /// or is unlikely to change during execution of a program. It is also
@@ -112,19 +150,17 @@ public:
    bool mCanKeyFocus;                              ///< True if the object can be given keyboard focus (in other words, made a first responder @see GuiControl)
    bool mCanKeyFocus;                              ///< True if the object can be given keyboard focus (in other words, made a first responder @see GuiControl)
    bool mModal;                                    ///< True if this is a Modeless dialog meaning it will pass input through instead of taking it all
    bool mModal;                                    ///< True if this is a Modeless dialog meaning it will pass input through instead of taking it all
 
 
-   bool mOpaque;                                   ///< True if this object is not translucent
+   bool mOpaque;                                   ///< True if this object should render its fill color
    ColorI mFillColor;                              ///< Fill color, this is used to fill the bounds of the control if it is opaque
    ColorI mFillColor;                              ///< Fill color, this is used to fill the bounds of the control if it is opaque
    ColorI mFillColorHL;                            ///< This is used insetead of mFillColor if the object is highlited
    ColorI mFillColorHL;                            ///< This is used insetead of mFillColor if the object is highlited
+   ColorI mFillColorSL;								//Color used when the control is selected.
    ColorI mFillColorNA;                            ///< This is used to instead of mFillColor if the object is not active or disabled
    ColorI mFillColorNA;                            ///< This is used to instead of mFillColor if the object is not active or disabled
 
 
-   S32 mBorder;                                    ///< For most controls, if mBorder is > 0 a border will be drawn, some controls use this to draw different types of borders however @see guiDefaultControlRender.cc
-   S32 mBorderSize;								   ///< Border thickness
-   ColorI mBorderColor;                            ///< Border color, used to draw a border around the bounds if border is enabled
-   ColorI mBorderColorHL;                          ///< Used instead of mBorderColor when the object is highlited
-   ColorI mBorderColorNA;                          ///< Used instead of mBorderColor when the object is not active or disabled
-
-   ColorI mBevelColorHL;                          ///< Used for the high-light part of the bevel
-   ColorI mBevelColorLL;                          ///< Used for the low-light part of the bevel
+   GuiBorderProfile *mBorderDefault;					//The default border settings.
+   GuiBorderProfile *mBorderTop;
+   GuiBorderProfile *mBorderBottom;
+   GuiBorderProfile *mBorderLeft;
+   GuiBorderProfile *mBorderRight;
 
 
    // font members
    // font members
    StringTableEntry  mFontType;                    ///< Font face name for the control
    StringTableEntry  mFontType;                    ///< Font face name for the control
@@ -133,7 +169,7 @@ public:
       BaseColor = 0,
       BaseColor = 0,
       ColorHL,
       ColorHL,
       ColorNA,
       ColorNA,
-      ColorSEL,
+      ColorSL,
       ColorUser0,
       ColorUser0,
       ColorUser1,
       ColorUser1,
       ColorUser2,
       ColorUser2,
@@ -145,7 +181,7 @@ public:
    ColorI& mFontColor;                             ///< Main font color
    ColorI& mFontColor;                             ///< Main font color
    ColorI& mFontColorHL;                           ///< Highlited font color
    ColorI& mFontColorHL;                           ///< Highlited font color
    ColorI& mFontColorNA;                           ///< Font color when object is not active/disabled
    ColorI& mFontColorNA;                           ///< Font color when object is not active/disabled
-   ColorI& mFontColorSEL;                          ///< Font color when object/text is selected
+   ColorI& mFontColorSL;                          ///< Font color when object/text is selected
    FontCharset mFontCharset;                       ///< Font character set
    FontCharset mFontCharset;                       ///< Font character set
 
 
    Resource<GFont>   mFont;                        ///< Font resource
    Resource<GFont>   mFont;                        ///< Font resource
@@ -193,6 +229,9 @@ public:
 
 
    void incRefCount();
    void incRefCount();
    void decRefCount();
    void decRefCount();
+
+   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.
 };
 };
 DefineConsoleType( TypeGuiProfile)
 DefineConsoleType( TypeGuiProfile)