Permalink
Browse files

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.
  • Loading branch information...
greenfire27 committed Jan 24, 2019
1 parent e8d027a commit 978c6bc927f59ea2ca69c164db94bf9778f289e2
@@ -875,6 +875,28 @@ void dglDrawRectFill(const RectI &rect, const ColorI &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 )
{
width *= 0.5;
@@ -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);
/// draws an UNTEXTURED filled rectangle in "rect" in specified 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
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
@@ -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 )
{
S32 indexMultiplier = 1;
if ( mDepressed || mStateOn )
if ( currentState == selected)
indexMultiplier = 3;
else if ( mMouseOver )
else if ( currentState == highlight )
indexMultiplier = 2;
else if ( !mActive )
else if ( currentState == disabled )
indexMultiplier = 4;

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 );
renderJustifiedText(textPos, mBounds.extent, mButtonText);
renderJustifiedText(innerRect.point, innerRect.extent, mButtonText);

//render the children
renderChildControls( offset, updateRect);
@@ -133,7 +133,7 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
{
ColorI backColor = mActive ? mProfile->mFillColor : mProfile->mFillColorNA;
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:
S32 xOffset = 0;
@@ -197,13 +197,13 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
if (highlight)
fontColor = mProfile->mFontColorHL;
else if (mStateOn)
fontColor = mProfile->mFontColorSEL;
fontColor = mProfile->mFontColorSL;
else
fontColor = mProfile->mFontColor;
}

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);

@@ -214,7 +214,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
if( mProfile->mBitmapArrayRects.size() )
renderBitmapArray(boundsRect, statePressed);
else
renderLoweredBox(boundsRect, mProfile);
renderBorderedRect(boundsRect, mProfile, normal);
}
else if(mMouseOver && mActive)
{
@@ -223,7 +223,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
if(mProfile->mBitmapArrayRects.size())
renderBitmapArray(boundsRect, stateMouseOver);
else
renderRaisedBox(boundsRect, mProfile);
renderBorderedRect(boundsRect, mProfile, GuiControlState::highlight);
}
else
{
@@ -239,7 +239,7 @@ void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
else
{
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)
{
case stateNormal:
if(mProfile->mBorder == -2)
/* if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 1, mProfile);
else
else*/
renderFixedBitmapBordersFilled(bounds, 1, mProfile);
break;

case stateMouseOver:
if(mProfile->mBorder == -2)
/*if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 2, mProfile);
else
else*/
renderFixedBitmapBordersFilled(bounds, 2, mProfile);
break;

case statePressed:
if(mProfile->mBorder == -2)
/*if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 3, mProfile);
else
else*/
renderFixedBitmapBordersFilled(bounds, 3, mProfile);
break;

case stateDisabled:
if(mProfile->mBorder == -2)
/*if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 4, mProfile);
else
else*/
renderFixedBitmapBordersFilled(bounds, 4, mProfile);
break;
}
@@ -236,8 +236,8 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
if (mProfile->mOpaque)
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(size() <= 1)
@@ -253,7 +253,7 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
{
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;

Point2I barOffset(barStart, barTop);
@@ -494,8 +494,8 @@ void GuiFrameSetCtrl::onRender(Point2I offset, const RectI &updateRect )

drawDividers(offset);

if (mProfile->mBorder)
dglDrawRect(r, mProfile->mBorderColor);
//if (mProfile->mBorder)
// dglDrawRect(r, mProfile->mBorderColor);

// draw the frame contents
renderChildControls(offset, updateRect);
@@ -226,17 +226,17 @@ void GuiScrollCtrl::addObject(SimObject *object)

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;
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()
{
S32 thickness = (mProfile ? mProfile->mBorderSize : 1);
S32 thickness = 0;//(mProfile ? mProfile->mBorderSize : 1);
Point2I borderExtent(thickness, thickness);
mContentPos = borderExtent + mChildMargin;
mContentExt = mBounds.extent - (mChildMargin * 2)
@@ -324,7 +324,7 @@ void GuiScrollCtrl::computeSizes()

void GuiScrollCtrl::calcScrollRects(void)
{
S32 thickness = ( mProfile ? mProfile->mBorderSize : 1 );
S32 thickness = 0;//( mProfile ? mProfile->mBorderSize : 1 );
if (mHasHScrollBar)
{
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);

if (mProfile->mOpaque)
dglDrawRectFill(r, mProfile->mFillColor);

if (mProfile->mBorder)
renderFilledBorder(r, mProfile);
renderBorderedRect(r, mProfile, normal);

// draw scroll bars
if (mHasVScrollBar)
@@ -71,11 +71,11 @@ bool GuiGraphCtrl::onWake()

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);
dglDrawRect(rect, mProfile->mBorderColor);
}
}*/

glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
@@ -959,8 +959,8 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
dglDrawRectFill(RectI(offset, mBounds.extent), mProfile->mFillColor);

//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)
{
@@ -981,10 +981,14 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect)
RectI highlightBounds = bounds;
highlightBounds.inset(1,1);
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?
if(walk->bitmapIndex != -1)
@@ -78,7 +78,7 @@ void GuiSeparatorCtrl::onRender(Point2I offset, const RectI &updateRect)
if(mTextLeftMargin > 0)
{
RectI rect(Point2I(posx,seppos),Point2I(mTextLeftMargin,2));
renderSlightlyLoweredBox(rect, mProfile);
renderBorderedRect(rect, mProfile, GuiControlState::highlight);
posx += mTextLeftMargin;
}

@@ -87,21 +87,21 @@ void GuiSeparatorCtrl::onRender(Point2I offset, const RectI &updateRect)
//posx += mProfile->mFont->getStrWidth(mText);

RectI rect(Point2I(posx,seppos),Point2I(mBounds.extent.x - posx + offset.x,2));
renderSlightlyLoweredBox(rect, mProfile, mActive);
renderBorderedRect(rect, mProfile, GuiControlState::highlight);

} else
{
if( mSeparatorType == separatorTypeHorizontal )
{
S32 seppos = mBounds.extent.y / 2 + offset.y;
RectI rect(Point2I(offset.x + mMargin ,seppos),Point2I(mBounds.extent.x - (mMargin * 2),2));
renderSlightlyLoweredBox(rect, mProfile);
renderBorderedRect(rect, mProfile, GuiControlState::normal);
}
else
{
S32 seppos = mBounds.extent.x / 2 + offset.x;
RectI rect(Point2I(seppos, offset.y + mMargin),Point2I(2, mBounds.extent.y - (mMargin * 2)));
renderSlightlyLoweredBox(rect, mProfile);
renderBorderedRect(rect, mProfile, GuiControlState::normal);
}
}

@@ -137,10 +137,10 @@ void GuiArrayCtrl::scrollCellVisible(Point2I cell)

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);
dglDrawRectFill(cellR, mProfile->mBorderColor);
dglDrawRectFill(cellR, mProfile->mBorderDefault->mBorderColor);
}
}

@@ -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);
dglDrawRect(rect, mProfile->mBorderColor);
dglDrawRect(rect, mProfile->mBorderDefault->mBorderColor);
}

renderChildControls(offset, updateRect);
Oops, something went wrong.

0 comments on commit 978c6bc

Please sign in to comment.