瀏覽代碼

Tab Book Update

Previously the tab book was barely functional. Positioning the tabs to the right, left, or bottom did not work and there was no option to have the tabs draw without images. These changes fix that, but leave off support (for now) of image skinned tabs. It makes heavy use of the new border model.
Peter Robinson 6 年之前
父節點
當前提交
50a31984d9
共有 30 個文件被更改,包括 407 次插入328 次删除
  1. 二進制
      engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db
  2. 二進制
      engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db-shm
  3. 0 0
      engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db-wal
  4. 二進制
      engine/compilers/VisualStudio 2017/Torque 2D.aps
  5. 5 5
      engine/compilers/VisualStudio 2017/Torque 2D.rc
  6. 1 0
      engine/compilers/VisualStudio 2017/Torque 2D.vcxproj
  7. 3 0
      engine/compilers/VisualStudio 2017/Torque 2D.vcxproj.filters
  8. 2 2
      engine/source/2d/gui/guiSceneObjectCtrl.cc
  9. 4 4
      engine/source/gui/buttons/guiButtonCtrl.cc
  10. 4 4
      engine/source/gui/buttons/guiCheckBoxCtrl.cc
  11. 2 2
      engine/source/gui/containers/guiFormCtrl.cc
  12. 1 1
      engine/source/gui/containers/guiRolloutCtrl.cc
  13. 145 179
      engine/source/gui/containers/guiTabBookCtrl.cc
  14. 6 7
      engine/source/gui/containers/guiTabBookCtrl.h
  15. 41 0
      engine/source/gui/containers/guiTabBookCtrl_ScriptBinding.h
  16. 3 3
      engine/source/gui/containers/guiWindowCtrl.cc
  17. 3 3
      engine/source/gui/guiConsoleTextCtrl.cc
  18. 111 65
      engine/source/gui/guiControl.cc
  19. 16 4
      engine/source/gui/guiControl.h
  20. 1 1
      engine/source/gui/guiListBoxCtrl.cc
  21. 8 8
      engine/source/gui/guiMLTextCtrl.cc
  22. 3 3
      engine/source/gui/guiMLTextCtrl.h
  23. 4 4
      engine/source/gui/guiPopUpCtrl.cc
  24. 3 3
      engine/source/gui/guiPopUpCtrlEx.cc
  25. 0 5
      engine/source/gui/guiTabPageCtrl.cc
  26. 0 2
      engine/source/gui/guiTabPageCtrl.h
  27. 2 2
      engine/source/gui/guiTextCtrl.cc
  28. 5 5
      engine/source/gui/guiTextEditCtrl.cc
  29. 22 12
      engine/source/gui/guiTypes.cc
  30. 12 4
      engine/source/gui/guiTypes.h

二進制
engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db


二進制
engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db-shm


+ 0 - 0
engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db-wal


二進制
engine/compilers/VisualStudio 2017/Torque 2D.aps


+ 5 - 5
engine/compilers/VisualStudio 2017/Torque 2D.rc

@@ -62,8 +62,8 @@ END
 //
 //
 
 
 VS_VERSION_INFO VERSIONINFO
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,0,0,0
- PRODUCTVERSION 2,0,0,0
+ FILEVERSION 4,0,0,0
+ PRODUCTVERSION 4,0,0,0
  FILEFLAGSMASK 0x17L
  FILEFLAGSMASK 0x17L
 #ifdef _DEBUG
 #ifdef _DEBUG
  FILEFLAGS 0x1L
  FILEFLAGS 0x1L
@@ -80,12 +80,12 @@ BEGIN
         BEGIN
         BEGIN
             VALUE "CompanyName", "GarageGames LLC"
             VALUE "CompanyName", "GarageGames LLC"
             VALUE "FileDescription", "Torque 2D MIT"
             VALUE "FileDescription", "Torque 2D MIT"
-            VALUE "FileVersion", "2, 0, 0, 0"
+            VALUE "FileVersion", "4, 0, 0, 0"
             VALUE "InternalName", "Torque 2D"
             VALUE "InternalName", "Torque 2D"
-            VALUE "LegalCopyright", "Copyright (c) 2013 GarageGames, LLC"
+            VALUE "LegalCopyright", "Copyright (c) 2019 GarageGames, LLC"
             VALUE "OriginalFilename", "Torque2D.exe"
             VALUE "OriginalFilename", "Torque2D.exe"
             VALUE "ProductName", "Torque 2D MIT"
             VALUE "ProductName", "Torque 2D MIT"
-            VALUE "ProductVersion", "2, 0, 0, 0"
+            VALUE "ProductVersion", "4, 0, 0, 0"
         END
         END
     END
     END
     BLOCK "VarFileInfo"
     BLOCK "VarFileInfo"

+ 1 - 0
engine/compilers/VisualStudio 2017/Torque 2D.vcxproj

@@ -890,6 +890,7 @@
     <ClInclude Include="..\..\source\graphics\TextureObject.h" />
     <ClInclude Include="..\..\source\graphics\TextureObject.h" />
     <ClInclude Include="..\..\source\gui\buttons\guiCheckBoxCtrl_ScriptBinding.h" />
     <ClInclude Include="..\..\source\gui\buttons\guiCheckBoxCtrl_ScriptBinding.h" />
     <ClInclude Include="..\..\source\gui\containers\guiGridCtrl.h" />
     <ClInclude Include="..\..\source\gui\containers\guiGridCtrl.h" />
+    <ClInclude Include="..\..\source\gui\containers\guiTabBookCtrl_ScriptBinding.h" />
     <ClInclude Include="..\..\source\gui\guiArrayCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiArrayCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiBackgroundCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiBackgroundCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiBitmapCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiBitmapCtrl.h" />

+ 3 - 0
engine/compilers/VisualStudio 2017/Torque 2D.vcxproj.filters

@@ -3156,6 +3156,9 @@
     <ClInclude Include="..\..\source\gui\buttons\guiCheckBoxCtrl_ScriptBinding.h">
     <ClInclude Include="..\..\source\gui\buttons\guiCheckBoxCtrl_ScriptBinding.h">
       <Filter>gui\buttons</Filter>
       <Filter>gui\buttons</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\source\gui\containers\guiTabBookCtrl_ScriptBinding.h">
+      <Filter>gui\containers</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">

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

@@ -468,10 +468,10 @@ void GuiSceneObjectCtrl::onRender(Point2I offset, const RectI& updateRect)
 
 
    captionRect.inset(1, 1);
    captionRect.inset(1, 1);
    dglSetBitmapModulation( ColorI(0,0,0,255) );
    dglSetBitmapModulation( ColorI(0,0,0,255) );
-   renderJustifiedText(captionRect.point, captionRect.extent, mCaption);
+   renderText(captionRect.point, captionRect.extent, mCaption, mProfile);
    captionRect.inset(1, 1);   
    captionRect.inset(1, 1);   
    dglSetBitmapModulation( mProfile->mFontColor );
    dglSetBitmapModulation( mProfile->mFontColor );
-   renderJustifiedText(captionRect.point, captionRect.extent, mCaption);
+   renderText(captionRect.point, captionRect.extent, mCaption, mProfile);
 
 
    
    
 
 

+ 4 - 4
engine/source/gui/buttons/guiButtonCtrl.cc

@@ -253,7 +253,7 @@ void GuiButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
 		currentState = GuiControlState::HighlightState;
 		currentState = GuiControlState::HighlightState;
 	}
 	}
 
 
-	RectI ctrlRect = applyMargins(offset, mBounds.extent, currentState);
+	RectI ctrlRect = applyMargins(offset, mBounds.extent, currentState, mProfile);
 	RectI boundsRect(offset, mBounds.extent);
 	RectI boundsRect(offset, mBounds.extent);
 
 
 	if(mProfile->mBitmapName != NULL && mProfile->constructBitmapArray() >= 36)
 	if(mProfile->mBitmapName != NULL && mProfile->constructBitmapArray() >= 36)
@@ -275,9 +275,9 @@ void GuiButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
 
 
 	//Render Text
 	//Render Text
 	dglSetBitmapModulation(mProfile->getFontColor(currentState));
 	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);
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState, mProfile);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState, mProfile);
+	renderText(contentRect.point, contentRect.extent, mText, mProfile);
 
 
 	//Render the childen
 	//Render the childen
 	renderChildControls(contentRect.point, contentRect, updateRect);
 	renderChildControls(contentRect.point, contentRect, updateRect);

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

@@ -78,9 +78,9 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
 		currentState = GuiControlState::HighlightState;
 		currentState = GuiControlState::HighlightState;
 	}
 	}
 
 
-	RectI ctrlRect = applyMargins(offset, mBounds.extent, currentState);
-	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState);
-	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState);
+	RectI ctrlRect = applyMargins(offset, mBounds.extent, currentState, mProfile);
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState, mProfile);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState, mProfile);
 	RectI boxRect(contentRect.point + mBoxOffset, mBoxExtent);
 	RectI boxRect(contentRect.point + mBoxOffset, mBoxExtent);
 
 
 	//Contrain the Box Rect. It must fit in the content Rect.
 	//Contrain the Box Rect. It must fit in the content Rect.
@@ -134,7 +134,7 @@ void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
 
 
 	//Render Text
 	//Render Text
 	dglSetBitmapModulation(mProfile->getFontColor(currentState));
 	dglSetBitmapModulation(mProfile->getFontColor(currentState));
-	renderJustifiedText(textRect.point, textRect.extent, mText);
+	renderText(textRect.point, textRect.extent, mText, mProfile);
 
 
 	//Render the childen
 	//Render the childen
 	renderChildControls(offset, contentRect, updateRect);
 	renderChildControls(offset, contentRect, updateRect);

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

@@ -243,7 +243,7 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
    if(size() <= 1)
    if(size() <= 1)
    {
    {
       dglSetBitmapModulation(ColorI(0,0,0));
       dglSetBitmapModulation(ColorI(0,0,0));
-      renderJustifiedText(boundsRect.point, boundsRect.extent, "[none]");
+      renderText(boundsRect.point, boundsRect.extent, "[none]", mProfile);
    }
    }
 
 
    S32 textWidth = 0;
    S32 textWidth = 0;
@@ -286,7 +286,7 @@ void GuiFormCtrl::onRender(Point2I offset, const RectI &updateRect)
          mProfile->mBitmapArrayRects[4]);
          mProfile->mBitmapArrayRects[4]);
 
 
       dglSetBitmapModulation((mMouseOver ? mProfile->mFontColorHL : mProfile->mFontColor));
       dglSetBitmapModulation((mMouseOver ? mProfile->mFontColorHL : mProfile->mFontColor));
-      renderJustifiedText(Point2I(mThumbSize.x, 0) + offset, Point2I(mBounds.extent.x - mThumbSize.x - mProfile->mBitmapArrayRects[4].extent.x, mThumbSize.y), (mUseSmallCaption ? mSmallCaption : mCaption) );
+      renderText(Point2I(mThumbSize.x, 0) + offset, Point2I(mBounds.extent.x - mThumbSize.x - mProfile->mBitmapArrayRects[4].extent.x, mThumbSize.y), (mUseSmallCaption ? mSmallCaption : mCaption), mProfile);
 
 
    }
    }
 
 

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

@@ -352,7 +352,7 @@ void GuiRolloutCtrl::onRender(Point2I offset, const RectI &updateRect)
       dglGetBitmapModulation( &currColor );
       dglGetBitmapModulation( &currColor );
       Point2I textPosition = mHeader.point + offset + mProfile->mTextOffset;
       Point2I textPosition = mHeader.point + offset + mProfile->mTextOffset;
       dglSetBitmapModulation( mProfile->mFontColor );
       dglSetBitmapModulation( mProfile->mFontColor );
-      renderJustifiedText( textPosition, mHeader.extent, mCaption );
+      renderText( textPosition, mHeader.extent, mCaption, mProfile);
       dglSetBitmapModulation( currColor );
       dglSetBitmapModulation( currColor );
 
 
       // If we're collapsed we contain the first child as our content
       // If we're collapsed we contain the first child as our content

+ 145 - 179
engine/source/gui/containers/guiTabBookCtrl.cc

@@ -32,6 +32,7 @@
 #include "gui/guiPopUpCtrl.h"
 #include "gui/guiPopUpCtrl.h"
 #include "gui/guiDefaultControlRender.h"
 #include "gui/guiDefaultControlRender.h"
 
 
+#include "guiTabBookCtrl_ScriptBinding.h"
 
 
 // So we can set tab alignment via gui editor
 // So we can set tab alignment via gui editor
 static EnumTable::Enums tabAlignEnums[] =
 static EnumTable::Enums tabAlignEnums[] =
@@ -49,8 +50,7 @@ IMPLEMENT_CONOBJECT(GuiTabBookCtrl);
 GuiTabBookCtrl::GuiTabBookCtrl()
 GuiTabBookCtrl::GuiTabBookCtrl()
 {
 {
    VECTOR_SET_ASSOCIATION(mPages);
    VECTOR_SET_ASSOCIATION(mPages);
-   mTabHeight = 24;
-   mLastTabHeight = mTabHeight;
+   mLastFontHeight = 0;
    mTabPosition = GuiTabBookCtrl::AlignTop;
    mTabPosition = GuiTabBookCtrl::AlignTop;
    mLastTabPosition = mTabPosition;
    mLastTabPosition = mTabPosition;
    mActivePage = NULL;
    mActivePage = NULL;
@@ -62,21 +62,19 @@ GuiTabBookCtrl::GuiTabBookCtrl()
    mTabRect = RectI(0,0,0,0);
    mTabRect = RectI(0,0,0,0);
 
 
    mPages.reserve(12);
    mPages.reserve(12);
-   mTabMargin = 7;
    mMinTabWidth = 64;
    mMinTabWidth = 64;
    mTabWidth = 64;
    mTabWidth = 64;
    mIsContainer = true;
    mIsContainer = true;
 
 
-
+   mTabProfile = NULL;
 }
 }
 
 
 void GuiTabBookCtrl::initPersistFields()
 void GuiTabBookCtrl::initPersistFields()
 {
 {
    Parent::initPersistFields();
    Parent::initPersistFields();
    addField("TabPosition",		TypeEnum,		Offset(mTabPosition,GuiTabBookCtrl), 1, &gTabAlignEnums );
    addField("TabPosition",		TypeEnum,		Offset(mTabPosition,GuiTabBookCtrl), 1, &gTabAlignEnums );
-   addField("TabHeight",		TypeS32,		Offset(mTabHeight,GuiTabBookCtrl) );
-   addField("TabMargin",   TypeS32,    Offset(mTabMargin,GuiTabBookCtrl));
    addField("MinTabWidth", TypeS32,    Offset(mMinTabWidth,GuiTabBookCtrl));
    addField("MinTabWidth", TypeS32,    Offset(mMinTabWidth,GuiTabBookCtrl));
+   addField("TabProfile", TypeGuiProfile, Offset(mTabProfile, GuiTabBookCtrl));
 }
 }
 
 
 // Empty for now, will implement for handling design time context menu for manipulating pages
 // Empty for now, will implement for handling design time context menu for manipulating pages
@@ -220,12 +218,29 @@ void GuiTabBookCtrl::childResized(GuiControl *child)
    child->resize( mPageRect.point, mPageRect.extent );
    child->resize( mPageRect.point, mPageRect.extent );
 }
 }
 
 
+Point2I GuiTabBookCtrl::getTabLocalCoord(const Point2I &src)
+{
+	//Get the border profiles
+	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
+	GuiBorderProfile *topProfile = mProfile->getTopBorder();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getMargin(NormalState) + leftProfile->getBorder(NormalState) + leftProfile->getPadding(NormalState) : 0;
+	S32 topSize = (topProfile) ? topProfile->getMargin(NormalState) + topProfile->getBorder(NormalState) + topProfile->getPadding(NormalState) : 0;
+
+	Point2I ret = Point2I(src.x - leftSize, src.y - topSize);
+	ret.x -= mTabRect.point.x;
+	ret.y -= mTabRect.point.y;
+
+	return ret;
+}
+
 void GuiTabBookCtrl::onTouchDown(const GuiEvent &event)
 void GuiTabBookCtrl::onTouchDown(const GuiEvent &event)
 {
 {
     Point2I localMouse = globalToLocalCoord( event.mousePoint );
     Point2I localMouse = globalToLocalCoord( event.mousePoint );
     if( mTabRect.pointInRect( localMouse ) )
     if( mTabRect.pointInRect( localMouse ) )
     {
     {
-        GuiTabPageCtrl *tab = findHitTab( localMouse );
+		Point2I tabLocalMouse = getTabLocalCoord(localMouse);
+        GuiTabPageCtrl *tab = findHitTab(tabLocalMouse);
         if( tab != NULL && tab->isActive() )
         if( tab != NULL && tab->isActive() )
             selectPage( tab );
             selectPage( tab );
     }
     }
@@ -233,17 +248,20 @@ void GuiTabBookCtrl::onTouchDown(const GuiEvent &event)
 
 
 void GuiTabBookCtrl::onTouchMove(const GuiEvent &event)
 void GuiTabBookCtrl::onTouchMove(const GuiEvent &event)
 {
 {
-
    Point2I localMouse = globalToLocalCoord( event.mousePoint );
    Point2I localMouse = globalToLocalCoord( event.mousePoint );
    if( mTabRect.pointInRect( localMouse ) )
    if( mTabRect.pointInRect( localMouse ) )
    {
    {
-
-      GuiTabPageCtrl *tab = findHitTab( localMouse );
+	   Point2I tabLocalMouse = getTabLocalCoord(localMouse);
+      GuiTabPageCtrl *tab = findHitTab(tabLocalMouse);
       if( tab != NULL && mHoverTab != tab )
       if( tab != NULL && mHoverTab != tab )
          mHoverTab = tab;
          mHoverTab = tab;
       else if ( !tab )
       else if ( !tab )
          mHoverTab = NULL;
          mHoverTab = NULL;
    }
    }
+   else
+   {
+	   mHoverTab = NULL;
+   }
    Parent::onTouchMove( event );
    Parent::onTouchMove( event );
 }
 }
 
 
@@ -291,50 +309,33 @@ void GuiTabBookCtrl::onPreRender()
 
 
 void GuiTabBookCtrl::onRender(Point2I offset, const RectI &updateRect)
 void GuiTabBookCtrl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
-   RectI tabRect = mTabRect;
-   tabRect.point += offset;
-   RectI pageRect = mPageRect;
-   pageRect.point += offset;
-
-   // We're so nice we'll store the old modulation before we clear it for our rendering! :)
-   ColorI oldModulation;
-   dglGetBitmapModulation( &oldModulation );
-
-   // Wipe it out
-   dglClearBitmapModulation();
-
-   // Render background
-   renderBackground( offset, updateRect );
-
-   // Render our tabs
-   renderTabs( offset );
-
-   // Render Children
-   renderChildControls( offset, mBounds, updateRect );
+	RectI ctrlRect = applyMargins(offset + mTabRect.point, mTabRect.extent, NormalState, mProfile);
 
 
-   // Restore old modulation
-   dglSetBitmapModulation( oldModulation );
-}
-
-void GuiTabBookCtrl::renderBackground( Point2I offset, const RectI& updateRect )
-{
-   RectI winRect;
-   winRect.point = offset;
-   winRect.extent = mBounds.extent;
+	if (!ctrlRect.isValidRect())
+	{
+		return;
+	}
 
 
-   if( mHasTexture && mProfile->mBitmapArrayRects.size() >= NumBitmaps)
-      renderSizableBitmapBordersFilledIndex( winRect, TabBackground, mProfile );
-   else
-      dglDrawRectFill(winRect, mProfile->mFillColor);
+	renderBorderedRect(ctrlRect, mProfile, NormalState);
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, NormalState, mProfile);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, NormalState, mProfile);
+	if (contentRect.isValidRect())
+	{
+		renderTabs(contentRect.point);
+	}
 
 
+	if(mPageRect.isValidRect())
+	{
+		// Render Children
+		renderChildControls(offset, mBounds, updateRect);
+	}
 }
 }
 
 
-
 void GuiTabBookCtrl::renderTabs( const Point2I &offset )
 void GuiTabBookCtrl::renderTabs( const Point2I &offset )
 {
 {
    // If the tab size is zero, don't render tabs,
    // If the tab size is zero, don't render tabs,
    //  and assume it's a tab-less tab-book - JDD
    //  and assume it's a tab-less tab-book - JDD
-   if( mPages.empty() || mTabHeight <= 0 )
+   if( mPages.empty())
       return;
       return;
 
 
    for( S32 i = 0; i < mPages.size(); i++ )
    for( S32 i = 0; i < mPages.size(); i++ )
@@ -350,10 +351,43 @@ void GuiTabBookCtrl::renderTabs( const Point2I &offset )
 void GuiTabBookCtrl::renderTab( RectI tabRect, GuiTabPageCtrl *tab )
 void GuiTabBookCtrl::renderTab( RectI tabRect, GuiTabPageCtrl *tab )
 {
 {
    StringTableEntry text = tab->getText();
    StringTableEntry text = tab->getText();
-   ColorI oldColor;
 
 
-   dglGetBitmapModulation( &oldColor );
+   GuiControlState currentState = GuiControlState::NormalState;
+   if (mActivePage == tab)
+   {
+	   currentState = SelectedState;
+   }
+   else if (mHoverTab == tab)
+   {
+	   currentState = HighlightState;
+   }
+
+   RectI ctrlRect = applyMargins(tabRect.point, tabRect.extent, currentState, mTabProfile);
+   if (!ctrlRect.isValidRect())
+   {
+	   return;
+   }
 
 
+   renderBorderedRect(ctrlRect, mTabProfile, currentState);
+
+   //Render Text
+   dglSetBitmapModulation(mTabProfile->getFontColor(currentState));
+   RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, currentState, mTabProfile);
+   RectI contentRect = applyPadding(fillRect.point, fillRect.extent, currentState, mTabProfile);
+
+   TextRotationOptions rot = tRotateNone;
+   if (mTabPosition == AlignLeft)
+   {
+		rot = tRotateLeft;
+   }
+   else if(mTabPosition == AlignRight)
+   {
+		rot = tRotateRight;
+   }
+
+   renderText(contentRect.point, contentRect.extent, text, mTabProfile, rot);
+
+   /*
    // Is this a skinned control?
    // Is this a skinned control?
    if( mHasTexture && mProfile->mBitmapArrayRects.size() >= 9 )
    if( mHasTexture && mProfile->mBitmapArrayRects.size() >= 9 )
    {
    {
@@ -415,64 +449,7 @@ void GuiTabBookCtrl::renderTab( RectI tabRect, GuiTabPageCtrl *tab )
       renderJustifiedTextRot( tabRect.point, tabRect.extent, text, -90 );
       renderJustifiedTextRot( tabRect.point, tabRect.extent, text, -90 );
       break;
       break;
    }
    }
-
-   dglSetBitmapModulation( oldColor);
-
-}
-
-void GuiTabBookCtrl::renderJustifiedTextRot(Point2I offset, Point2I extent, const char *text, F32 rot )
-{
-   GFont *font = mProfile->mFont;
-   S32 textWidth = font->getStrWidth(text);
-   Point2I start;
-
-   offset += mProfile->mTextOffset;
-
-   if( mTabPosition == AlignLeft || mTabPosition == AlignRight )
-   {
-      switch( mProfile->mAlignment )
-      {
-      case GuiControlProfile::RightJustify:
-         start.set( 0, extent.y - textWidth);
-         break;
-      case GuiControlProfile::CenterJustify:
-         start.set( 0, ( extent.y - textWidth) / 2);
-         break;
-      default:
-         // GuiControlProfile::LeftJustify
-         start.set( 0, 0 );
-         break;
-      }
-
-      if( textWidth > extent.y )
-         start.set( 0, 0 );
-      start.x = ( ( extent.x - font->getHeight() ) / 2 ) + font->getHeight();
-
-   }
-   else
-   {
-      // align the horizontal
-      switch( mProfile->mAlignment )
-      {
-      case GuiControlProfile::RightJustify:
-         start.set( extent.x - textWidth, 0 );
-         break;
-      case GuiControlProfile::CenterJustify:
-         start.set( ( extent.x - textWidth) / 2, 0 );
-         break;
-      default:
-         // GuiControlProfile::LeftJustify
-         start.set( 0, 0 );
-         break;
-      }
-
-      if( textWidth > extent.x )
-         start.set( 0, 0 );
-      start.y = ( extent.y - font->getHeight() ) / 2;
-
-   }
-
-   dglDrawText( font, start + offset, text, mProfile->mFontColors,9,rot );
+   */
 }
 }
 
 
 // This is nothing but a clever hack to allow the tab page children
 // This is nothing but a clever hack to allow the tab page children
@@ -496,9 +473,9 @@ void GuiTabBookCtrl::solveDirty()
       dirty = true;
       dirty = true;
    }
    }
 
 
-   if( mTabHeight != mLastTabHeight )
+   if( mTabProfile != NULL && mTabProfile->mFont != NULL && mTabProfile->mFont->getHeight() != mLastFontHeight )
    {
    {
-      mLastTabHeight = mTabHeight;
+	   mLastFontHeight = mTabProfile->mFont->getHeight();
       dirty = true;
       dirty = true;
    }
    }
 
 
@@ -510,7 +487,6 @@ void GuiTabBookCtrl::solveDirty()
 
 
    if( dirty )
    if( dirty )
    {
    {
-      calculatePageTabs();
       resize( mBounds.point, mBounds.extent );
       resize( mBounds.point, mBounds.extent );
    }
    }
 
 
@@ -523,13 +499,21 @@ S32 GuiTabBookCtrl::calculatePageTabWidth( GuiTabPageCtrl *page )
 
 
    StringTableEntry text = page->getText();
    StringTableEntry text = page->getText();
 
 
-   if( !text || dStrlen(text) == 0 || mProfile->mFont == '\0' )
+   if( !text || dStrlen(text) == 0 || !mTabProfile || !mTabProfile->mFont || mTabProfile->mFont == '\0' )
       return mTabWidth;
       return mTabWidth;
 
 
-   GFont *font = mProfile->mFont;
+	S32 textLength = mTabProfile->mFont->getStrNWidth(text, dStrlen(text));
 
 
-   return font->getStrNWidth( text, dStrlen(text) );
+	Point2I outerExtent = getOuterExtent(Point2I(textLength, textLength), NormalState, mTabProfile);
 
 
+	if (mTabPosition == AlignTop || mTabPosition == AlignBottom)
+	{
+		return outerExtent.x;
+	}
+	else
+	{
+		return outerExtent.y;
+	}
 }
 }
 
 
 void GuiTabBookCtrl::calculatePageTabs()
 void GuiTabBookCtrl::calculatePageTabs()
@@ -538,19 +522,30 @@ void GuiTabBookCtrl::calculatePageTabs()
    //
    //
    // If the tab size is zero, don't render tabs,
    // If the tab size is zero, don't render tabs,
    //  and assume it's a tab-less tab-book - JDD
    //  and assume it's a tab-less tab-book - JDD
-   if( mPages.empty() || mTabHeight <= 0 )
+   if( mPages.empty())
       return;
       return;
 
 
    S32 currRow    = 0;
    S32 currRow    = 0;
    S32 currColumn = 0;
    S32 currColumn = 0;
    S32 currX      = 0;
    S32 currX      = 0;
    S32 currY      = 0;
    S32 currY      = 0;
-   S32 maxWidth   = 0;
+   S32 tabHeight  = 0;
+   RectI innerRect = getInnerRect(mBounds.point, mBounds.extent, NormalState, mProfile);
+   Point2I fontBasedBounds = getOuterExtent(Point2I(mTabProfile->mFont->getHeight(), mTabProfile->mFont->getHeight()), NormalState, mProfile);
+
+   if (mTabPosition == AlignTop || mTabPosition == AlignBottom)
+   {
+	   tabHeight = fontBasedBounds.y;
+   }
+   else
+   {
+	   tabHeight = fontBasedBounds.x;
+   }
 
 
    for( S32 i = 0; i < mPages.size(); i++ )
    for( S32 i = 0; i < mPages.size(); i++ )
    {
    {
       // Fetch Tab Width
       // Fetch Tab Width
-      S32 tabWidth = calculatePageTabWidth( mPages[i].Page ) + ( mTabMargin * 2 );
+      S32 tabWidth = calculatePageTabWidth( mPages[i].Page );
       tabWidth = getMax( tabWidth, mMinTabWidth );
       tabWidth = getMax( tabWidth, mMinTabWidth );
       TabHeaderInfo &info = mPages[i];
       TabHeaderInfo &info = mPages[i];
       switch( mTabPosition )
       switch( mTabPosition )
@@ -559,14 +554,13 @@ void GuiTabBookCtrl::calculatePageTabs()
       case AlignBottom:
       case AlignBottom:
          // If we're going to go outside our bounds
          // If we're going to go outside our bounds
          // with this tab move it down a row
          // with this tab move it down a row
-         if( currX + tabWidth > mBounds.extent.x )
+         if( currX + tabWidth > innerRect.extent.x )
          {
          {
             // Calculate and Advance State.
             // Calculate and Advance State.
-            maxWidth = getMax( tabWidth, maxWidth );
             balanceRow( currRow, currX );
             balanceRow( currRow, currX );
             info.TabRow = ++currRow;
             info.TabRow = ++currRow;
             // Reset Necessaries
             // Reset Necessaries
-            info.TabColumn = currColumn = maxWidth = currX = 0;
+            info.TabColumn = currColumn = currX = 0;
          }
          }
          else
          else
          {
          {
@@ -576,14 +570,9 @@ void GuiTabBookCtrl::calculatePageTabs()
 
 
          // Calculate Tabs Bounding Rect
          // Calculate Tabs Bounding Rect
          info.TabRect.point.x  = currX;
          info.TabRect.point.x  = currX;
+		 info.TabRect.point.y = (info.TabRow * tabHeight);
          info.TabRect.extent.x = tabWidth;
          info.TabRect.extent.x = tabWidth;
-         info.TabRect.extent.y = mTabHeight;
-
-         // Adjust Y Point based on alignment
-         if( mTabPosition == AlignTop )
-            info.TabRect.point.y  = ( info.TabRow * mTabHeight );
-         else 
-            info.TabRect.point.y  = mBounds.extent.y - ( ( 1 + info.TabRow ) * mTabHeight );
+         info.TabRect.extent.y = tabHeight;
 
 
          currX += tabWidth;
          currX += tabWidth;
          break;
          break;
@@ -591,9 +580,8 @@ void GuiTabBookCtrl::calculatePageTabs()
       case AlignRight:
       case AlignRight:
          // If we're going to go outside our bounds
          // If we're going to go outside our bounds
          // with this tab move it down a row
          // with this tab move it down a row
-         if( currY + tabWidth > mBounds.extent.y )
+         if( currY + tabWidth > innerRect.extent.y )
          {
          {
-
             // Balance Tab Column.
             // Balance Tab Column.
             balanceColumn( currColumn, currY );
             balanceColumn( currColumn, currY );
 
 
@@ -608,15 +596,10 @@ void GuiTabBookCtrl::calculatePageTabs()
          }
          }
 
 
          // Calculate Tabs Bounding Rect
          // Calculate Tabs Bounding Rect
+		 info.TabRect.point.x = (info.TabColumn * tabHeight);
          info.TabRect.point.y  = currY;
          info.TabRect.point.y  = currY;
+		 info.TabRect.extent.x = tabHeight;
          info.TabRect.extent.y = tabWidth;
          info.TabRect.extent.y = tabWidth;
-         info.TabRect.extent.x = mTabHeight;
-
-         // Adjust Y Point based on alignment
-         if( mTabPosition == AlignLeft )
-            info.TabRect.point.x  = ( info.TabColumn * mTabHeight );
-         else 
-            info.TabRect.point.x  = mBounds.extent.x - ( (1 + info.TabColumn) * mTabHeight );
 
 
          currY += tabWidth;
          currY += tabWidth;
          break;
          break;
@@ -626,19 +609,16 @@ void GuiTabBookCtrl::calculatePageTabs()
    currRow++;
    currRow++;
    currColumn++;
    currColumn++;
 
 
-   Point2I localPoint = mBounds.extent;
+   Point2I outerExtent = getOuterExtent(Point2I(currColumn * tabHeight, currRow * tabHeight), NormalState, mProfile);
 
 
    // Calculate 
    // Calculate 
    switch( mTabPosition )
    switch( mTabPosition )
    {
    {
    case AlignTop:
    case AlignTop:
-
-      localPoint.y -= mBounds.point.y;
-
-      mTabRect.point.x = 0;
-      mTabRect.extent.x = localPoint.x;
-      mTabRect.point.y = 0;
-      mTabRect.extent.y = currRow * mTabHeight;
+   	  mTabRect.point.x = 0;
+	  mTabRect.point.y = 0;
+      mTabRect.extent.x = mBounds.extent.x;
+      mTabRect.extent.y = outerExtent.y;
 
 
       mPageRect.point.x = 0;
       mPageRect.point.x = 0;
       mPageRect.point.y = mTabRect.extent.y;
       mPageRect.point.y = mTabRect.extent.y;
@@ -648,42 +628,38 @@ void GuiTabBookCtrl::calculatePageTabs()
       break;
       break;
    case AlignBottom:
    case AlignBottom:
       mTabRect.point.x = 0;
       mTabRect.point.x = 0;
-      mTabRect.extent.x = localPoint.x;
-      mTabRect.extent.y = currRow * mTabHeight;
-      mTabRect.point.y = mBounds.extent.y - mTabRect.extent.y;
+	  mTabRect.point.y = mBounds.extent.y - mTabRect.extent.y;
+      mTabRect.extent.x = mBounds.extent.x;
+      mTabRect.extent.y = outerExtent.y;
 
 
       mPageRect.point.x = 0;
       mPageRect.point.x = 0;
       mPageRect.point.y = 0;
       mPageRect.point.y = 0;
       mPageRect.extent.x = mTabRect.extent.x;
       mPageRect.extent.x = mTabRect.extent.x;
-      mPageRect.extent.y = localPoint.y - mTabRect.extent.y;
+      mPageRect.extent.y = mBounds.extent.y - mTabRect.extent.y;
 
 
       break;
       break;
    case AlignLeft:
    case AlignLeft:
-      
-
+	  mTabRect.point.x = 0;
       mTabRect.point.y = 0;
       mTabRect.point.y = 0;
+	  mTabRect.extent.x = outerExtent.x;
       mTabRect.extent.y = mBounds.extent.y;
       mTabRect.extent.y = mBounds.extent.y;
-      mTabRect.point.x = 0;
-      mTabRect.extent.x = currColumn * mTabHeight;
 
 
+	  mPageRect.point.x = mTabRect.extent.x;
       mPageRect.point.y = 0;
       mPageRect.point.y = 0;
-      mPageRect.point.x = mTabRect.extent.x;
-      mPageRect.extent.y = localPoint.y;
-      mPageRect.extent.x = localPoint.x - mTabRect.extent.x;
+	  mPageRect.extent.x = mBounds.extent.x - mTabRect.extent.x;
+      mPageRect.extent.y = mBounds.extent.y;
 
 
       break;
       break;
    case AlignRight:
    case AlignRight:
-
-
-      mTabRect.extent.x = currColumn * mTabHeight;
+	  mTabRect.point.x = mBounds.extent.x - mTabRect.extent.x;
       mTabRect.point.y = 0;
       mTabRect.point.y = 0;
-      mTabRect.extent.y = localPoint.y;
-      mTabRect.point.x = localPoint.x - mTabRect.extent.x;
-      
+	  mTabRect.extent.x = outerExtent.x;
+      mTabRect.extent.y = mBounds.extent.y;
+
+	  mPageRect.point.x = 0;
       mPageRect.point.y = 0;
       mPageRect.point.y = 0;
-      mPageRect.point.x = 0;
-      mPageRect.extent.y = localPoint.y;
-      mPageRect.extent.x = localPoint.x - mTabRect.extent.x;
+	  mPageRect.extent.x = mBounds.extent.x - mTabRect.extent.x;
+      mPageRect.extent.y = mTabRect.extent.y;
 
 
       break;
       break;
    };
    };
@@ -697,7 +673,7 @@ void GuiTabBookCtrl::balanceColumn( S32 column , S32 totalTabWidth )
    //
    //
    // If the tab size is zero, don't render tabs,
    // If the tab size is zero, don't render tabs,
    //  and assume it's a tab-less tab-book - JDD
    //  and assume it's a tab-less tab-book - JDD
-   if( mPages.empty() || mTabHeight <= 0 )
+   if( mPages.empty())
       return;
       return;
 
 
    Vector<TabHeaderInfo*> rowTemp;
    Vector<TabHeaderInfo*> rowTemp;
@@ -715,7 +691,8 @@ void GuiTabBookCtrl::balanceColumn( S32 column , S32 totalTabWidth )
       return;
       return;
 
 
    // Balance the tabs across the remaining space
    // Balance the tabs across the remaining space
-   S32 spaceToDivide = mBounds.extent.y - totalTabWidth;
+   RectI innerRect = getInnerRect(mBounds.point, mBounds.extent, NormalState, mProfile);
+   S32 spaceToDivide = innerRect.extent.y - totalTabWidth;
    S32 pointDelta    = 0;
    S32 pointDelta    = 0;
    for( S32 i = 0; i < rowTemp.size(); i++ )
    for( S32 i = 0; i < rowTemp.size(); i++ )
    {
    {
@@ -733,7 +710,7 @@ void GuiTabBookCtrl::balanceRow( S32 row, S32 totalTabWidth )
    //
    //
    // If the tab size is zero, don't render tabs,
    // If the tab size is zero, don't render tabs,
    //  and assume it's a tab-less tab-book - JDD
    //  and assume it's a tab-less tab-book - JDD
-   if( mPages.empty() || mTabHeight <= 0 )
+   if( mPages.empty())
       return;
       return;
 
 
    Vector<TabHeaderInfo*> rowTemp;
    Vector<TabHeaderInfo*> rowTemp;
@@ -751,7 +728,8 @@ void GuiTabBookCtrl::balanceRow( S32 row, S32 totalTabWidth )
       return;
       return;
 
 
    // Balance the tabs across the remaining space
    // Balance the tabs across the remaining space
-   S32 spaceToDivide = mBounds.extent.x - totalTabWidth;
+   RectI innerRect = getInnerRect(mBounds.point, mBounds.extent, NormalState, mProfile);
+   S32 spaceToDivide = innerRect.extent.x - totalTabWidth;
    S32 pointDelta    = 0;
    S32 pointDelta    = 0;
    for( S32 i = 0; i < rowTemp.size(); i++ )
    for( S32 i = 0; i < rowTemp.size(); i++ )
    {
    {
@@ -775,7 +753,7 @@ GuiTabPageCtrl *GuiTabBookCtrl::findHitTab( Point2I hitPoint )
    //
    //
    // If the tab size is zero, don't render tabs,
    // If the tab size is zero, don't render tabs,
    //  and assume it's a tab-less tab-book - JDD
    //  and assume it's a tab-less tab-book - JDD
-   if( mPages.empty() || mTabHeight <= 0 )
+   if( mPages.empty())
       return NULL;
       return NULL;
 
 
    for( S32 i = 0; i < mPages.size(); i++ )
    for( S32 i = 0; i < mPages.size(); i++ )
@@ -788,7 +766,7 @@ GuiTabPageCtrl *GuiTabBookCtrl::findHitTab( Point2I hitPoint )
 
 
 void GuiTabBookCtrl::selectPage( S32 index )
 void GuiTabBookCtrl::selectPage( S32 index )
 {
 {
-   if( mPages.size() < index )
+   if( index < 0 || index >= mPages.size())
       return;
       return;
 
 
    // Select the page
    // Select the page
@@ -924,15 +902,3 @@ void GuiTabBookCtrl::selectPrevPage()
    }
    }
 
 
 }
 }
-
-ConsoleMethod( GuiTabBookCtrl, selectPage, void, 3, 3, "(int pageIndex)")
-{
-   S32 pageIndex = dAtoi(argv[2]);
-
-   object->selectPage(pageIndex);
-}
-
-ConsoleMethod( GuiTabBookCtrl, selectPageName, void, 3, 3, "(pageName)")
-{
-   object->selectPage(argv[2]);
-}

+ 6 - 7
engine/source/gui/containers/guiTabBookCtrl.h

@@ -77,6 +77,8 @@ public:
       RectI           TabRect;
       RectI           TabRect;
    };
    };
 
 
+   GuiControlProfile *mTabProfile; //Used to render the tabs
+
 private:
 private:
 
 
    typedef GuiControl Parent;                ///< typedef for parent class access
    typedef GuiControl Parent;                ///< typedef for parent class access
@@ -89,11 +91,9 @@ private:
    S32                     mMinTabWidth;     ///< Minimum Width a tab will display as.
    S32                     mMinTabWidth;     ///< Minimum Width a tab will display as.
    TabPosition             mTabPosition;     ///< Current tab position (see alignment)
    TabPosition             mTabPosition;     ///< Current tab position (see alignment)
    TabPosition             mLastTabPosition; ///< Last known tab position, stored to compare to tabPosition to know when to resize children
    TabPosition             mLastTabPosition; ///< Last known tab position, stored to compare to tabPosition to know when to resize children
-   S32                     mTabHeight;       ///< Current tab height
-   S32                     mLastTabHeight;   ///< Last known tab height, stored to compare to current tabHeight to know when to resize children
+   S32                     mLastFontHeight;  ///< Last known font height
    S32                     mTabWidth;        ///< Current tab width
    S32                     mTabWidth;        ///< Current tab width
    S32                     mLastTabWidth;    ///< Last know tab width, stored to compare to current tabWidth to know when to resize children
    S32                     mLastTabWidth;    ///< Last know tab width, stored to compare to current tabWidth to know when to resize children
-   S32                     mTabMargin;       ///< Margin left/right of tab text in tab
 
 
    enum
    enum
    {
    {
@@ -144,10 +144,6 @@ private:
    /// @param   tab   pointer to the tab page control for which to render the tab
    /// @param   tab   pointer to the tab page control for which to render the tab
    void renderTab( RectI tabRect, GuiTabPageCtrl* tab );
    void renderTab( RectI tabRect, GuiTabPageCtrl* tab );
 
 
-   /// Page Rendering Routine
-   void renderBackground( Point2I offset, const RectI &updateRect );
-
-
    void renderJustifiedTextRot(Point2I offset, Point2I extent, const char *text, F32 rot );
    void renderJustifiedTextRot(Point2I offset, Point2I extent, const char *text, F32 rot );
 
 
 
 
@@ -211,6 +207,9 @@ private:
    /// @param    hitPoint   A Point2I that specifies where to search for a tab hit
    /// @param    hitPoint   A Point2I that specifies where to search for a tab hit
    GuiTabPageCtrl *findHitTab( Point2I hitPoint );
    GuiTabPageCtrl *findHitTab( Point2I hitPoint );
 
 
+   /// Changes a local point to a point in the inner rect of the tab section.
+   Point2I GuiTabBookCtrl::getTabLocalCoord(const Point2I &src);
+
    /// @}
    /// @}
 
 
    /// @name Sizing
    /// @name Sizing

+ 41 - 0
engine/source/gui/containers/guiTabBookCtrl_ScriptBinding.h

@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+ConsoleMethodGroupBeginWithDocs(GuiTabBookCtrl, GuiControl)
+
+/*! Selects the active tab by index.
+	@param pageIndex The zero-based index of the tab to make active.
+*/
+ConsoleMethodWithDocs(GuiTabBookCtrl, selectPage, void, 3, 3, "(pageIndex)")
+{
+	S32 pageIndex = dAtoi(argv[2]);
+
+	object->selectPage(pageIndex);
+}
+
+/*! Selects the active tab by name.
+	@param pageName The name that appears on the tab to make active.
+*/
+ConsoleMethodWithDocs(GuiTabBookCtrl, selectPageName, void, 3, 3, "(pageName)")
+{
+	object->selectPage(argv[2]);
+}

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

@@ -634,11 +634,11 @@ void GuiWindowCtrl::onRender(Point2I offset, const RectI &updateRect)
    S32 textWidth = mProfile->mFont->getStrWidth((const UTF8 *)mText);
    S32 textWidth = mProfile->mFont->getStrWidth((const UTF8 *)mText);
    Point2I start(0,0);
    Point2I start(0,0);
    // align the horizontal
    // align the horizontal
-   if ( mProfile->mAlignment == GuiControlProfile::RightJustify )
+   if ( mProfile->mAlignment == GuiControlProfile::RightAlign )
       start.set( winRect.extent.x - textWidth, 0 );
       start.set( winRect.extent.x - textWidth, 0 );
-   else if ( mProfile->mAlignment == GuiControlProfile::CenterJustify )
+   else if ( mProfile->mAlignment == GuiControlProfile::CenterAlign )
       start.set( ( winRect.extent.x - textWidth) / 2, 0 );
       start.set( ( winRect.extent.x - textWidth) / 2, 0 );
-   else // GuiControlProfile::LeftJustify or garbage... ;)
+   else // GuiControlProfile::LeftAlign or garbage... ;)
       start.set( 0, 0 );
       start.set( 0, 0 );
    // If the text is longer then the box size, (it'll get clipped) so force Left Justify
    // If the text is longer then the box size, (it'll get clipped) so force Left Justify
    if( textWidth > winRect.extent.x ) start.set( 0, 0 );
    if( textWidth > winRect.extent.x ) start.set( 0, 0 );

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

@@ -144,14 +144,14 @@ void GuiConsoleTextCtrl::onRender(Point2I offset, const RectI &updateRect)
       Point2I localStart;
       Point2I localStart;
       switch (mProfile->mAlignment)
       switch (mProfile->mAlignment)
       {
       {
-         case GuiControlProfile::RightJustify:
+         case GuiControlProfile::RightAlign:
             localStart.set(mBounds.extent.x - txt_w-2, 0);
             localStart.set(mBounds.extent.x - txt_w-2, 0);
             break;
             break;
-         case GuiControlProfile::CenterJustify:
+         case GuiControlProfile::CenterAlign:
             localStart.set((mBounds.extent.x - txt_w) / 2, 0);
             localStart.set((mBounds.extent.x - txt_w) / 2, 0);
             break;
             break;
          default:
          default:
-            // GuiControlProfile::LeftJustify
+            // GuiControlProfile::LeftAlign
             localStart.set(2,0);
             localStart.set(2,0);
             break;
             break;
       }
       }

+ 111 - 65
engine/source/gui/guiControl.cc

@@ -312,11 +312,11 @@ void GuiControl::inspectPostApply()
 Point2I GuiControl::localToGlobalCoord(const Point2I &src)
 Point2I GuiControl::localToGlobalCoord(const Point2I &src)
 {
 {
    Point2I ret = src;
    Point2I ret = src;
-   ret += mBounds.point;
+   ret += (mBounds.point + mRenderInsetLT);
    GuiControl *walk = getParent();
    GuiControl *walk = getParent();
    while(walk)
    while(walk)
    {
    {
-      ret += walk->getPosition();
+      ret += (walk->getPosition() + mRenderInsetLT);
       walk = walk->getParent();
       walk = walk->getParent();
    }
    }
    return ret;
    return ret;
@@ -325,11 +325,11 @@ Point2I GuiControl::localToGlobalCoord(const Point2I &src)
 Point2I GuiControl::globalToLocalCoord(const Point2I &src)
 Point2I GuiControl::globalToLocalCoord(const Point2I &src)
 {
 {
    Point2I ret = src;
    Point2I ret = src;
-   ret -= mBounds.point;
+   ret -= (mBounds.point + mRenderInsetLT);
    GuiControl *walk = getParent();
    GuiControl *walk = getParent();
    while(walk)
    while(walk)
    {
    {
-      ret -= walk->getPosition();
+      ret -= (walk->getPosition() + mRenderInsetLT);
       walk = walk->getParent();
       walk = walk->getParent();
    }
    }
    return ret;
    return ret;
@@ -455,7 +455,7 @@ void GuiControl::parentResized(const Point2I &oldParentExtent, const Point2I &ne
 
 
 void GuiControl::onRender(Point2I offset, const RectI &updateRect)
 void GuiControl::onRender(Point2I offset, const RectI &updateRect)
 {
 {
-    RectI ctrlRect = applyMargins(offset, mBounds.extent, NormalState);
+    RectI ctrlRect = applyMargins(offset, mBounds.extent, NormalState, mProfile);
 
 
 	if (!ctrlRect.isValidRect())
 	if (!ctrlRect.isValidRect())
 	{
 	{
@@ -466,84 +466,98 @@ void GuiControl::onRender(Point2I offset, const RectI &updateRect)
 
 
 	//Render Text
 	//Render Text
 	dglSetBitmapModulation(mProfile->mFontColor);
 	dglSetBitmapModulation(mProfile->mFontColor);
-	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, NormalState);
-	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, NormalState);
+	RectI fillRect = applyBorders(ctrlRect.point, ctrlRect.extent, NormalState, mProfile);
+	RectI contentRect = applyPadding(fillRect.point, fillRect.extent, NormalState, mProfile);
 
 
 	if(contentRect.isValidRect())
 	if(contentRect.isValidRect())
 	{
 	{
-		renderJustifiedText(contentRect.point, contentRect.extent, mText);
+		renderText(contentRect.point, contentRect.extent, mText, mProfile);
 
 
 		//Render the childen
 		//Render the childen
 		renderChildControls(offset, contentRect, updateRect);
 		renderChildControls(offset, contentRect, updateRect);
 	}
 	}
 }
 }
 
 
-RectI GuiControl::applyMargins(Point2I offset, Point2I extent, GuiControlState currentState)
+RectI GuiControl::applyMargins(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile)
 {
 {
 	//Get the border profiles
 	//Get the border profiles
-	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
-	GuiBorderProfile *rightProfile = mProfile->getRightBorder();
-	GuiBorderProfile *topProfile = mProfile->getTopBorder();
-	GuiBorderProfile *bottomProfile = mProfile->getBottomBorder();
+	GuiBorderProfile *leftProfile = profile->getLeftBorder();
+	GuiBorderProfile *rightProfile = profile->getRightBorder();
+	GuiBorderProfile *topProfile = profile->getTopBorder();
+	GuiBorderProfile *bottomProfile = profile->getBottomBorder();
 
 
 	S32 leftSize = (leftProfile) ? leftProfile->getMargin(currentState) : 0;
 	S32 leftSize = (leftProfile) ? leftProfile->getMargin(currentState) : 0;
 	S32 rightSize = (rightProfile) ? rightProfile->getMargin(currentState) : 0;
 	S32 rightSize = (rightProfile) ? rightProfile->getMargin(currentState) : 0;
 	S32 topSize = (topProfile) ? topProfile->getMargin(currentState) : 0;
 	S32 topSize = (topProfile) ? topProfile->getMargin(currentState) : 0;
 	S32 bottomSize = (bottomProfile) ? bottomProfile->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);
 	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)
+RectI GuiControl::applyBorders(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile)
 {
 {
 	//Get the border profiles
 	//Get the border profiles
-	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
-	GuiBorderProfile *rightProfile = mProfile->getRightBorder();
-	GuiBorderProfile *topProfile = mProfile->getTopBorder();
-	GuiBorderProfile *bottomProfile = mProfile->getBottomBorder();
+	GuiBorderProfile *leftProfile = profile->getLeftBorder();
+	GuiBorderProfile *rightProfile = profile->getRightBorder();
+	GuiBorderProfile *topProfile = profile->getTopBorder();
+	GuiBorderProfile *bottomProfile = profile->getBottomBorder();
 
 
 	S32 leftSize = (leftProfile) ? leftProfile->getBorder(currentState) : 0;
 	S32 leftSize = (leftProfile) ? leftProfile->getBorder(currentState) : 0;
 	S32 rightSize = (rightProfile) ? rightProfile->getBorder(currentState) : 0;
 	S32 rightSize = (rightProfile) ? rightProfile->getBorder(currentState) : 0;
 	S32 topSize = (topProfile) ? topProfile->getBorder(currentState) : 0;
 	S32 topSize = (topProfile) ? topProfile->getBorder(currentState) : 0;
 	S32 bottomSize = (bottomProfile) ? bottomProfile->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);
 	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)
+RectI GuiControl::applyPadding(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile)
 {
 {
 	//Get the border profiles
 	//Get the border profiles
-	GuiBorderProfile *leftProfile = mProfile->getLeftBorder();
-	GuiBorderProfile *rightProfile = mProfile->getRightBorder();
-	GuiBorderProfile *topProfile = mProfile->getTopBorder();
-	GuiBorderProfile *bottomProfile = mProfile->getBottomBorder();
+	GuiBorderProfile *leftProfile = profile->getLeftBorder();
+	GuiBorderProfile *rightProfile = profile->getRightBorder();
+	GuiBorderProfile *topProfile = profile->getTopBorder();
+	GuiBorderProfile *bottomProfile = profile->getBottomBorder();
 
 
 	S32 leftSize = (leftProfile) ? leftProfile->getPadding(currentState) : 0;
 	S32 leftSize = (leftProfile) ? leftProfile->getPadding(currentState) : 0;
 	S32 rightSize = (rightProfile) ? rightProfile->getPadding(currentState) : 0;
 	S32 rightSize = (rightProfile) ? rightProfile->getPadding(currentState) : 0;
 	S32 topSize = (topProfile) ? topProfile->getPadding(currentState) : 0;
 	S32 topSize = (topProfile) ? topProfile->getPadding(currentState) : 0;
 	S32 bottomSize = (bottomProfile) ? bottomProfile->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);
+}
+
+RectI GuiControl::getInnerRect(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile)
+{
+	//Get the border profiles
+	GuiBorderProfile *leftProfile = profile->getLeftBorder();
+	GuiBorderProfile *rightProfile = profile->getRightBorder();
+	GuiBorderProfile *topProfile = profile->getTopBorder();
+	GuiBorderProfile *bottomProfile = profile->getBottomBorder();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getMargin(currentState) + leftProfile->getBorder(currentState) + leftProfile->getPadding(currentState) : 0;
+	S32 rightSize = (rightProfile) ? rightProfile->getMargin(currentState) + rightProfile->getBorder(currentState) + rightProfile->getPadding(currentState) : 0;
+	S32 topSize = (topProfile) ? topProfile->getMargin(currentState) + topProfile->getBorder(currentState) + topProfile->getPadding(currentState) : 0;
+	S32 bottomSize = (bottomProfile) ? bottomProfile->getMargin(currentState) + bottomProfile->getBorder(currentState) + bottomProfile->getPadding(currentState) : 0;
 
 
 	return RectI(offset.x + leftSize, offset.y + topSize, (extent.x - leftSize) - rightSize, (extent.y - topSize) - bottomSize);
 	return RectI(offset.x + leftSize, offset.y + topSize, (extent.x - leftSize) - rightSize, (extent.y - topSize) - bottomSize);
 }
 }
 
 
+Point2I GuiControl::getOuterExtent(Point2I innerExtent, GuiControlState currentState, GuiControlProfile *profile)
+{
+	//Get the border profiles
+	GuiBorderProfile *leftProfile = profile->getLeftBorder();
+	GuiBorderProfile *rightProfile = profile->getRightBorder();
+	GuiBorderProfile *topProfile = profile->getTopBorder();
+	GuiBorderProfile *bottomProfile = profile->getBottomBorder();
+
+	S32 leftSize = (leftProfile) ? leftProfile->getMargin(currentState) + leftProfile->getBorder(currentState) + leftProfile->getPadding(currentState) : 0;
+	S32 rightSize = (rightProfile) ? rightProfile->getMargin(currentState) + rightProfile->getBorder(currentState) + rightProfile->getPadding(currentState) : 0;
+	S32 topSize = (topProfile) ? topProfile->getMargin(currentState) + topProfile->getBorder(currentState) + topProfile->getPadding(currentState) : 0;
+	S32 bottomSize = (bottomProfile) ? bottomProfile->getMargin(currentState) + bottomProfile->getBorder(currentState) + bottomProfile->getPadding(currentState) : 0;
+
+	return Point2I(innerExtent.x + leftSize + rightSize, innerExtent.y + topSize + bottomSize);
+}
+
 bool GuiControl::renderTooltip(Point2I cursorPos, const char* tipText )
 bool GuiControl::renderTooltip(Point2I cursorPos, const char* tipText )
 {
 {
 #if !defined(TORQUE_OS_IOS) && !defined(TORQUE_OS_ANDROID) && !defined(TORQUE_OS_EMSCRIPTEN)
 #if !defined(TORQUE_OS_IOS) && !defined(TORQUE_OS_ANDROID) && !defined(TORQUE_OS_EMSCRIPTEN)
@@ -1592,40 +1606,72 @@ void GuiControl::getScrollLineSizes(U32 *rowHeight, U32 *columnWidth)
     *rowHeight = 30;
     *rowHeight = 30;
 }
 }
 
 
-void GuiControl::renderJustifiedText(Point2I offset, Point2I extent, const char *text)
+void GuiControl::renderText(Point2I offset, Point2I extent, const char *text, GuiControlProfile *profile, TextRotationOptions rot)
 {
 {
-   GFont *font = mProfile->mFont;
+   GFont *font = profile->mFont;
    S32 textWidth = font->getStrWidth((const UTF8*)text);
    S32 textWidth = font->getStrWidth((const UTF8*)text);
-   Point2I start;
+   S32 textHeight = font->getHeight();
+   S32 totalWidth = extent.x;
+   S32 totalHeight = extent.y;
 
 
-   // align the horizontal
-   switch( mProfile->mAlignment )
+   if (rot != tRotateNone)
    {
    {
-      case GuiControlProfile::RightJustify:
-         start.set( extent.x - textWidth, 0 );
-         break;
-      case GuiControlProfile::CenterJustify:
-         start.set( ( extent.x - textWidth) / 2, 0 );
-         break;
-      default:
-         // GuiControlProfile::LeftJustify
-         start.set( 0, 0 );
-         break;
+	   totalWidth = extent.y;
+	   totalHeight = extent.x;
    }
    }
 
 
-   // If the text is longer then the box size, (it'll get clipped) so
-   // force Left Justify
+   Point2I startOffset = Point2I(0,0);
+   // align the horizontal
+   if(textWidth < totalWidth)
+   {
+	   if (profile->mAlignment == GuiControlProfile::RightAlign)
+	   {
+		   startOffset.x = totalWidth - textWidth;
+	   }
+	   else if (profile->mAlignment == GuiControlProfile::CenterAlign)
+	   {
+		   startOffset.x = (totalWidth - textWidth) / 2;
+	   }
+   }
 
 
-   if( textWidth > extent.x )
-      start.set( 0, 0 );
+	// align the vertical
+	if (textHeight < totalHeight)
+	{
+		if (profile->mVAlignment == GuiControlProfile::MiddleVAlign)
+		{
+			startOffset.y = (totalHeight - textHeight) / 2;
+		}
+		else if (profile->mVAlignment == GuiControlProfile::BottomVAlign)
+		{
+			startOffset.y = (totalHeight - textHeight);
+		}
+	}
+	else
+	{
+		startOffset.y = -((textHeight - totalHeight) / 2);
+	}
 
 
-   // center the vertical
-   if(font->getHeight() > (U32)extent.y)
-      start.y = 0 - ((font->getHeight() - extent.y) / 2) ;
-   else
-      start.y = ( extent.y - font->getHeight() ) / 2;
+	Point2I start = Point2I(0, 0);
+	F32 rotation;
+	if (rot == tRotateNone)
+	{
+		start += startOffset;
+		rotation = 0.0f;
+	}
+	else if (rot == tRotateLeft)
+	{
+		start.x = startOffset.y;
+		start.y = extent.y + startOffset.x;
+		rotation = 90.0f;
+	}
+	else if (rot == tRotateRight)
+	{
+		start.x = extent.x - startOffset.y;
+		start.y = startOffset.x;
+		rotation = -90.0f;
+	}
 
 
-   dglDrawText( font, start + offset, text, mProfile->mFontColors );
+	dglDrawText( font, start + offset, text, profile->mFontColors, 9, rotation );
 }
 }
 
 
 void GuiControl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent)
 void GuiControl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent)

+ 16 - 4
engine/source/gui/guiControl.h

@@ -154,6 +154,12 @@ public:
         vertResizeCenter,
         vertResizeCenter,
         vertResizeRelative      ///< resize relative
         vertResizeRelative      ///< resize relative
     };
     };
+	enum TextRotationOptions
+	{
+		tRotateNone = 0,
+		tRotateLeft, 
+		tRotateRight
+	};
 
 
 protected:
 protected:
     /// @name Control State
     /// @name Control State
@@ -671,16 +677,22 @@ public:
     /// Renders justified text using the profile.
     /// Renders justified text using the profile.
     ///
     ///
     /// @note This should move into the graphics library at some point
     /// @note This should move into the graphics library at some point
-    void renderJustifiedText(Point2I offset, Point2I extent, const char *text);
+    void renderText(Point2I offset, Point2I extent, const char *text, GuiControlProfile *profile, TextRotationOptions rot = tRotateNone);
 
 
 	/// Returns a new rect based on the margins.
 	/// Returns a new rect based on the margins.
-	RectI GuiControl::applyMargins(Point2I offset, Point2I extent, GuiControlState currentState);
+	RectI GuiControl::applyMargins(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile);
 
 
 	/// Returns the bounds of the rect after considering the borders.
 	/// Returns the bounds of the rect after considering the borders.
-	RectI GuiControl::applyBorders(Point2I offset, Point2I extent, GuiControlState currentState);
+	RectI GuiControl::applyBorders(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile);
 
 
 	/// Returns the bounds of the rect this time with padding.
 	/// Returns the bounds of the rect this time with padding.
-	RectI GuiControl::applyPadding(Point2I offset, Point2I extent, GuiControlState currentState);
+	RectI GuiControl::applyPadding(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile);
+
+	/// Returns the bounds of the rect with margin, borders, and padding applied.
+	RectI GuiControl::getInnerRect(Point2I offset, Point2I extent, GuiControlState currentState, GuiControlProfile *profile);
+
+	/// Returns the extent of the outer rect given the extent of the inner rect.
+	Point2I GuiControl::getOuterExtent(Point2I innerExtent, GuiControlState currentState, GuiControlProfile *profile);
 
 
     void inspectPostApply();
     void inspectPostApply();
     void inspectPreApply();
     void inspectPreApply();

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

@@ -746,7 +746,7 @@ void GuiListBoxCtrl::onRenderItem( RectI itemRect, LBItem *item )
       dglDrawRectFill( itemRect, mProfile->mFillColor );
       dglDrawRectFill( itemRect, mProfile->mFillColor );
 
 
    dglSetBitmapModulation(mProfile->mFontColor);
    dglSetBitmapModulation(mProfile->mFontColor);
-   renderJustifiedText(itemRect.point + Point2I( 2, 0 ), itemRect.extent, item->itemText);
+   renderText(itemRect.point + Point2I( 2, 0 ), itemRect.extent, item->itemText, mProfile);
 }
 }
 
 
 void GuiListBoxCtrl::drawBox(const Point2I &box, S32 size, ColorI &outlineColor, ColorI &boxColor)
 void GuiListBoxCtrl::drawBox(const Point2I &box, S32 size, ColorI &outlineColor, ColorI &boxColor)

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

@@ -1100,9 +1100,9 @@ void GuiMLTextCtrl::emitBitmapToken(GuiMLTextCtrl::Bitmap *bmp, U32 textStart, b
             {
             {
                // insert it:
                // insert it:
                U32 x = minx;
                U32 x = minx;
-               if(mCurJustify == CenterJustify)
+               if(mCurJustify == CenterAlign)
                   x += (width - ref->extent.x) >> 1;
                   x += (width - ref->extent.x) >> 1;
-               else if(mCurJustify == RightJustify)
+               else if(mCurJustify == RightAlign)
                   x += width - ref->extent.x;
                   x += width - ref->extent.x;
                ref->point.x = x;
                ref->point.x = x;
                ref->point.y = mCurY;
                ref->point.y = mCurY;
@@ -1348,12 +1348,12 @@ GuiMLTextCtrl::Atom *GuiMLTextCtrl::splitAtomListEmit(Atom *list, U32 width)
    *emitPtr = 0;
    *emitPtr = 0;
    // now emit it:
    // now emit it:
    // going from mCurX to mCurX + width:
    // going from mCurX to mCurX + width:
-   if(mCurJustify == CenterJustify)
+   if(mCurJustify == CenterAlign)
    {
    {
       if ( width > totalWidth )
       if ( width > totalWidth )
          mCurX += (width - totalWidth) >> 1;
          mCurX += (width - totalWidth) >> 1;
    }
    }
-   else if(mCurJustify == RightJustify)
+   else if(mCurJustify == RightAlign)
    {
    {
       if ( width > totalWidth )
       if ( width > totalWidth )
          mCurX += width - totalWidth;
          mCurX += width - totalWidth;
@@ -1440,7 +1440,7 @@ void GuiMLTextCtrl::reflow()
 
 
    mCurLMargin = 0;
    mCurLMargin = 0;
    mCurRMargin = width;
    mCurRMargin = width;
-   mCurJustify = LeftJustify;
+   mCurJustify = LeftAlign;
    mCurDiv = 0;
    mCurDiv = 0;
    mCurY = 0;
    mCurY = 0;
    mCurX = 0;
    mCurX = 0;
@@ -1746,7 +1746,7 @@ void GuiMLTextCtrl::reflow()
          if(!dStrnicmp(str +1, "just:left>", 10))
          if(!dStrnicmp(str +1, "just:left>", 10))
          {
          {
             processEmitAtoms();
             processEmitAtoms();
-            mCurJustify = LeftJustify;
+            mCurJustify = LeftAlign;
             mScanPos += 11;
             mScanPos += 11;
             continue;
             continue;
          }
          }
@@ -1754,7 +1754,7 @@ void GuiMLTextCtrl::reflow()
          if(!dStrnicmp(str +1, "just:right>", 11))
          if(!dStrnicmp(str +1, "just:right>", 11))
          {
          {
             processEmitAtoms();
             processEmitAtoms();
-            mCurJustify = RightJustify;
+            mCurJustify = RightAlign;
             mScanPos += 12;
             mScanPos += 12;
             continue;
             continue;
          }
          }
@@ -1762,7 +1762,7 @@ void GuiMLTextCtrl::reflow()
          if(!dStrnicmp(str +1, "just:center>", 12))
          if(!dStrnicmp(str +1, "just:center>", 12))
          {
          {
             processEmitAtoms();
             processEmitAtoms();
-            mCurJustify = CenterJustify;
+            mCurJustify = CenterAlign;
             mScanPos += 13;
             mScanPos += 13;
             continue;
             continue;
          }
          }

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

@@ -41,9 +41,9 @@ class GuiMLTextCtrl : public GuiControl
   public:
   public:
    enum Justification
    enum Justification
    {
    {
-      LeftJustify,
-      RightJustify,
-      CenterJustify,
+      LeftAlign,
+      RightAlign,
+      CenterAlign,
    };
    };
 
 
    struct Font {
    struct Font {

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

@@ -963,7 +963,7 @@ void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
       // align the horizontal
       // align the horizontal
       switch (mProfile->mAlignment)
       switch (mProfile->mAlignment)
       {
       {
-      case GuiControlProfile::RightJustify:
+      case GuiControlProfile::RightAlign:
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
          {
          {
             // We're making use of a bitmap border, so take into account the
             // We're making use of a bitmap border, so take into account the
@@ -976,13 +976,13 @@ void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
             localStart.x = mBounds.extent.x - txt_w;  
             localStart.x = mBounds.extent.x - txt_w;  
          }
          }
          break;
          break;
-      case GuiControlProfile::CenterJustify:
+      case GuiControlProfile::CenterAlign:
 
 
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
          {
          {
             RectI* mBitmapBounds = mProfile->mBitmapArrayRects.address();
             RectI* mBitmapBounds = mProfile->mBitmapArrayRects.address();
 
 
-             // GuiControlProfile::LeftJustify
+             // GuiControlProfile::LeftAlign
              if(txt_w > (mBounds.extent.x - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x) )
              if(txt_w > (mBounds.extent.x - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x) )
              {
              {
                 // We're making use of a bitmap border, so take into account the
                 // We're making use of a bitmap border, so take into account the
@@ -1009,7 +1009,7 @@ void GuiPopUpMenuCtrl::onRender(Point2I offset, const RectI &updateRect)
         {
         {
             RectI* mBitmapBounds = mProfile->mBitmapArrayRects.address();
             RectI* mBitmapBounds = mProfile->mBitmapArrayRects.address();
 
 
-             // GuiControlProfile::LeftJustify
+             // GuiControlProfile::LeftAlign
              if(txt_w > (mBounds.extent.x - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x) )
              if(txt_w > (mBounds.extent.x - mBitmapBounds[BorderLeft].extent.x - mBitmapBounds[BorderRight].extent.x) )
              {
              {
                 // We're making use of a bitmap border, so take into account the
                 // We're making use of a bitmap border, so take into account the

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

@@ -969,7 +969,7 @@ void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
    // align the horizontal
    // align the horizontal
    switch (mProfile->mAlignment)
    switch (mProfile->mAlignment)
    {
    {
-      case GuiControlProfile::RightJustify:
+      case GuiControlProfile::RightAlign:
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
 		 {
 		 {
             // We're making use of a bitmap border, so take into account the
             // We're making use of a bitmap border, so take into account the
@@ -982,7 +982,7 @@ void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
             localStart.x = mBounds.extent.x - txt_w;  
             localStart.x = mBounds.extent.x - txt_w;  
          }
          }
          break;
          break;
-      case GuiControlProfile::CenterJustify:
+      case GuiControlProfile::CenterAlign:
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
          if(mProfile->mProfileForChildren && mProfile->mBitmapArrayRects.size())
 		 {
 		 {
             // We're making use of a bitmap border, so take into account the
             // We're making use of a bitmap border, so take into account the
@@ -996,7 +996,7 @@ void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
          }
          }
          break;
          break;
       default:
       default:
-         // GuiControlProfile::LeftJustify
+         // GuiControlProfile::LeftAlign
          if(txt_w > mBounds.extent.x)
          if(txt_w > mBounds.extent.x)
 		 {
 		 {
             // DAW: The width of the text is greater than the width of the control.
             // DAW: The width of the text is greater than the width of the control.

+ 0 - 5
engine/source/gui/guiTabPageCtrl.cc

@@ -179,8 +179,3 @@ void GuiTabPageCtrl::selectWindow(void)
    //also set the first responder to be the one within this window
    //also set the first responder to be the one within this window
    setFirstResponder(mFirstResponder);
    setFirstResponder(mFirstResponder);
 }
 }
-
-void GuiTabPageCtrl::onRender(Point2I offset,const RectI &updateRect)
-{
-   GuiControl::onRender( offset, updateRect );
-}

+ 0 - 2
engine/source/gui/guiTabPageCtrl.h

@@ -57,8 +57,6 @@ class GuiTabPageCtrl : public GuiControl
       void selectWindow(void);               ///< Select this window
       void selectWindow(void);               ///< Select this window
 
 
       virtual void setText(const char *txt = NULL); ///< Override setText function to signal parent we need to update.
       virtual void setText(const char *txt = NULL); ///< Override setText function to signal parent we need to update.
-
-      void onRender(Point2I offset, const RectI &updateRect);  ///< Called when it's time to render this page to the scene
 };
 };
 
 
 #endif //_GUITABPAGECTRL_H_
 #endif //_GUITABPAGECTRL_H_

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

@@ -215,12 +215,12 @@ void GuiTextCtrl::onRender(Point2I offset, const RectI &updateRect)
         const UTF8* truncatedBufferPtr = truncatedBuffer.getPtr8();
         const UTF8* truncatedBufferPtr = truncatedBuffer.getPtr8();
         
         
         dglSetBitmapModulation(fontColor);
         dglSetBitmapModulation(fontColor);
-		renderJustifiedText(offset, mBounds.extent, (char*)truncatedBufferPtr);
+		renderText(offset, mBounds.extent, (char*)truncatedBufferPtr, mProfile);
     }
     }
     else
     else
     {
     {
 		dglSetBitmapModulation(fontColor);
 		dglSetBitmapModulation(fontColor);
-		renderJustifiedText(offset, mBounds.extent, (char*)mText);
+		renderText(offset, mBounds.extent, (char*)mText, mProfile);
 	}
 	}
 
 
     //render the child controls
     //render the child controls

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

@@ -1195,14 +1195,14 @@ void GuiTextEditCtrl::drawText( const RectI &drawRect, bool isFocused )
    {
    {
       switch( mProfile->mAlignment )
       switch( mProfile->mAlignment )
       {
       {
-      case GuiControlProfile::RightJustify:
+      case GuiControlProfile::RightAlign:
          drawPoint.x += ( drawRect.extent.x - textWidth - paddingRightBottom.x );
          drawPoint.x += ( drawRect.extent.x - textWidth - paddingRightBottom.x );
          break;
          break;
-      case GuiControlProfile::CenterJustify:
+      case GuiControlProfile::CenterAlign:
          drawPoint.x += ( ( drawRect.extent.x - textWidth ) / 2 );
          drawPoint.x += ( ( drawRect.extent.x - textWidth ) / 2 );
          break;
          break;
       default:
       default:
-      case GuiControlProfile::LeftJustify :
+      case GuiControlProfile::LeftAlign :
          drawPoint.x += paddingLeftTop.x;
          drawPoint.x += paddingLeftTop.x;
          break;
          break;
       }
       }
@@ -1226,8 +1226,8 @@ void GuiTextEditCtrl::drawText( const RectI &drawRect, bool isFocused )
    else
    else
    {
    {
       // Alignment affects large text
       // Alignment affects large text
-      if ( mProfile->mAlignment == GuiControlProfile::RightJustify
-         || mProfile->mAlignment == GuiControlProfile::CenterJustify )
+      if ( mProfile->mAlignment == GuiControlProfile::RightAlign
+         || mProfile->mAlignment == GuiControlProfile::CenterAlign )
       {
       {
          if ( mTextOffset.x + textWidth < (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x)
          if ( mTextOffset.x + textWidth < (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x)
             mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth;
             mTextOffset.x = (drawRect.point.x + drawRect.extent.x) - paddingRightBottom.x - textWidth;

+ 22 - 12
engine/source/gui/guiTypes.cc

@@ -156,12 +156,12 @@ void GuiBorderProfile::onRemove()
 
 
 S32 GuiBorderProfile::getMargin(const GuiControlState state)
 S32 GuiBorderProfile::getMargin(const GuiControlState state)
 {
 {
-	return mMargin[static_cast<S32>(state)];
+	return getMax(mMargin[static_cast<S32>(state)], 0);
 }
 }
 
 
 S32 GuiBorderProfile::getBorder(const GuiControlState state)
 S32 GuiBorderProfile::getBorder(const GuiControlState state)
 {
 {
-	return mBorder[static_cast<S32>(state)];
+	return getMax(mBorder[static_cast<S32>(state)], 0);
 }
 }
 
 
 const ColorI& GuiBorderProfile::getBorderColor(const GuiControlState state)
 const ColorI& GuiBorderProfile::getBorderColor(const GuiControlState state)
@@ -171,7 +171,7 @@ const ColorI& GuiBorderProfile::getBorderColor(const GuiControlState state)
 
 
 S32 GuiBorderProfile::getPadding(const GuiControlState state)
 S32 GuiBorderProfile::getPadding(const GuiControlState state)
 {
 {
-	return mPadding[static_cast<S32>(state)];
+	return getMax(mPadding[static_cast<S32>(state)], 0);
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
@@ -179,12 +179,20 @@ IMPLEMENT_CONOBJECT(GuiControlProfile);
 
 
 static EnumTable::Enums alignEnums[] =
 static EnumTable::Enums alignEnums[] =
 {
 {
-   { GuiControlProfile::LeftJustify,          "left"      },
-   { GuiControlProfile::CenterJustify,        "center"    },
-   { GuiControlProfile::RightJustify,         "right"     }
+   { GuiControlProfile::LeftAlign,          "left"      },
+   { GuiControlProfile::CenterAlign,        "center"    },
+   { GuiControlProfile::RightAlign,         "right"     }
 };
 };
 static EnumTable gAlignTable(3, &alignEnums[0]);
 static EnumTable gAlignTable(3, &alignEnums[0]);
 
 
+static EnumTable::Enums vAlignEnums[] =
+{
+   { GuiControlProfile::TopVAlign,          "top"      },
+   { GuiControlProfile::MiddleVAlign,        "middle"    },
+   { GuiControlProfile::BottomVAlign,         "bottom"     }
+};
+static EnumTable gVAlignTable(3, &vAlignEnums[0]);
+
 static EnumTable::Enums charsetEnums[]=
 static EnumTable::Enums charsetEnums[]=
 {
 {
     { TGE_ANSI_CHARSET,         "ANSI" },
     { TGE_ANSI_CHARSET,         "ANSI" },
@@ -227,7 +235,7 @@ GuiControlProfile::GuiControlProfile(void) :
     mTabable       = false;
     mTabable       = false;
     mCanKeyFocus   = false;
     mCanKeyFocus   = false;
     
     
-    mOpaque        = false;
+    mOpaque        = true;
 
 
 	mBorderDefault = NULL;
 	mBorderDefault = NULL;
 	mBorderLeft = NULL;
 	mBorderLeft = NULL;
@@ -246,14 +254,15 @@ GuiControlProfile::GuiControlProfile(void) :
     mTextOffset.set(0,0);
     mTextOffset.set(0,0);
     
     
     //used by GuiTextCtrl
     //used by GuiTextCtrl
-    mModal         = false;
-    mAlignment     = LeftJustify;
+    mModal         = true;
+    mAlignment     = LeftAlign;
+	mVAlignment    = MiddleVAlign;
     mAutoSizeWidth = false;
     mAutoSizeWidth = false;
     mAutoSizeHeight= false;
     mAutoSizeHeight= false;
     mReturnTab     = false;
     mReturnTab     = false;
     mNumbersOnly   = false;
     mNumbersOnly   = false;
     mProfileForChildren = NULL;
     mProfileForChildren = NULL;
-
+/*
    GuiControlProfile *def = dynamic_cast<GuiControlProfile*>(Sim::findObject("GuiDefaultProfile"));
    GuiControlProfile *def = dynamic_cast<GuiControlProfile*>(Sim::findObject("GuiDefaultProfile"));
    if (def)
    if (def)
    {
    {
@@ -286,7 +295,7 @@ GuiControlProfile::GuiControlProfile(void) :
       mNumbersOnly   = def->mNumbersOnly;
       mNumbersOnly   = def->mNumbersOnly;
       mCursorColor   = def->mCursorColor;
       mCursorColor   = def->mCursorColor;
       mProfileForChildren = def->mProfileForChildren;
       mProfileForChildren = def->mProfileForChildren;
-   }
+   }*/
 }
 }
 
 
 GuiControlProfile::~GuiControlProfile()
 GuiControlProfile::~GuiControlProfile()
@@ -326,7 +335,8 @@ void GuiControlProfile::initPersistFields()
    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));
 
 
-   addField("justify",       TypeEnum,       Offset(mAlignment, GuiControlProfile), 1, &gAlignTable);
+   addField("align", TypeEnum, Offset(mAlignment, GuiControlProfile), 1, &gAlignTable);
+   addField("vAlign", TypeEnum, Offset(mVAlignment, GuiControlProfile), 1, &gVAlignTable);
    addField("textOffset",    TypePoint2I,    Offset(mTextOffset, GuiControlProfile));
    addField("textOffset",    TypePoint2I,    Offset(mTextOffset, GuiControlProfile));
    addField("autoSizeWidth", TypeBool,       Offset(mAutoSizeWidth, GuiControlProfile));
    addField("autoSizeWidth", TypeBool,       Offset(mAutoSizeWidth, GuiControlProfile));
    addField("autoSizeHeight",TypeBool,       Offset(mAutoSizeHeight, GuiControlProfile));
    addField("autoSizeHeight",TypeBool,       Offset(mAutoSizeHeight, GuiControlProfile));

+ 12 - 4
engine/source/gui/guiTypes.h

@@ -186,12 +186,20 @@ public:
 
 
    enum AlignmentType
    enum AlignmentType
    {
    {
-      LeftJustify,
-      RightJustify,
-      CenterJustify
+      LeftAlign,
+      RightAlign,
+      CenterAlign
    };
    };
-
    AlignmentType mAlignment;                       ///< Horizontal text alignment
    AlignmentType mAlignment;                       ///< Horizontal text alignment
+
+   enum VertAlignmentType
+   {
+	   TopVAlign,
+	   BottomVAlign,
+	   MiddleVAlign
+   };
+   VertAlignmentType mVAlignment;				   ///< Vertical text alignment
+
    bool mAutoSizeWidth;                            ///< Auto-size the width-bounds of the control to fit it's contents
    bool mAutoSizeWidth;                            ///< Auto-size the width-bounds of the control to fit it's contents
    bool mAutoSizeHeight;                           ///< Auto-size the height-bounds of the control to fit it's contents
    bool mAutoSizeHeight;                           ///< Auto-size the height-bounds of the control to fit it's contents
    bool mReturnTab;                                ///< Used in GuiTextEditCtrl to specify if a tab-event should be simulated when return is pressed.
    bool mReturnTab;                                ///< Used in GuiTextEditCtrl to specify if a tab-event should be simulated when return is pressed.