Browse Source

Alignment Override

This code allows a user to directly override a profile by setting the alignment and vertical alignment on a control. This prevents the proliferation of profiles for minor adjustments to a single control. I expect to make more override settings soon.
Peter Robinson 3 years ago
parent
commit
44ac168f9e

+ 6 - 4
engine/source/2d/gui/guiSpriteCtrl.cc

@@ -324,22 +324,24 @@ F32 GuiSpriteCtrl::getAspectRatio()
 Point2I GuiSpriteCtrl::applyAlignment(RectI &bounds, Point2I &size)
 {
 	Point2I offset = Point2I(0, 0);
+	AlignmentType align = getAlignmentType();
+	VertAlignmentType vAlign = getVertAlignmentType();
 
-	if (mProfile->mAlignment == GuiControlProfile::AlignmentType::RightAlign)
+	if (align == AlignmentType::RightAlign)
 	{
 		offset.x = bounds.extent.x - size.x;
 	}
-	else if (mProfile->mAlignment == GuiControlProfile::AlignmentType::CenterAlign)
+	else if (align == AlignmentType::CenterAlign)
 	{
 		S32 halfW = mRound(size.x / 2);
 		offset.x = mRound(bounds.extent.x / 2) - halfW;
 	}
 
-	if (mProfile->mVAlignment == GuiControlProfile::VertAlignmentType::BottomVAlign)
+	if (vAlign == VertAlignmentType::BottomVAlign)
 	{
 		offset.y = bounds.extent.y - size.y;
 	}
-	else if (mProfile->mVAlignment == GuiControlProfile::VertAlignmentType::MiddleVAlign)
+	else if (vAlign == VertAlignmentType::MiddleVAlign)
 	{
 		S32 halfH = mRound(size.y / 2);
 		offset.y = mRound(bounds.extent.y / 2) - halfH;

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

@@ -740,7 +740,7 @@ RectI GuiWindowCtrl::renderButtons(const Point2I &offset, const RectI &contentRe
 		distanceFromEdge += rightSize;
 	}
 
-	if (mProfile->mAlignment != GuiControlProfile::AlignmentType::RightAlign)
+	if (getAlignmentType() != AlignmentType::RightAlign)
 	{
 		return RectI(contentRect.point.x, contentRect.point.y, contentRect.extent.x - distanceFromEdge, contentRect.extent.y);
 	}
@@ -757,7 +757,7 @@ RectI GuiWindowCtrl::renderButton(const RectI &contentRect, S32 distanceFromEdge
 	RectI buttonContent = applyMargins(offset, extent, buttonState, profile);
 	S32 horizMarginSize = contentRect.extent.x - buttonContent.extent.x;
 	RectI finalButtonRect = RectI(contentRect.point, Point2I(buttonContent.extent.y + horizMarginSize, contentRect.extent.y));
-	if (mProfile->mAlignment != GuiControlProfile::AlignmentType::RightAlign)
+	if (getAlignmentType() != AlignmentType::RightAlign)
 	{
 		//get the right margin and add it to the distance from the edge
 		GuiBorderProfile *rightProfile = profile->getRightBorder();

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

@@ -1322,11 +1322,11 @@ bool GuiMenuListCtrl::onRenderItem(RectI &itemRect, GuiMenuItemCtrl *item)
 		RectI textRect = RectI(itemRect.point.x + itemRect.extent.y, itemRect.point.y, itemRect.extent.x - (2 * itemRect.extent.y), itemRect.extent.y);
 
 		//Command Description
-		profile->mAlignment = GuiControlProfile::AlignmentType::LeftAlign;
+		profile->mAlignment = AlignmentType::LeftAlign;
 		renderText(textRect.point, textRect.extent, item->getText(), profile);
 
 		//Hot Keys!!
-		profile->mAlignment = GuiControlProfile::AlignmentType::RightAlign;
+		profile->mAlignment = AlignmentType::RightAlign;
 		renderText(textRect.point, textRect.extent, item->getHotKeyText(), profile);
 	}
 

+ 53 - 10
engine/source/gui/guiControl.cc

@@ -51,6 +51,24 @@
 
 IMPLEMENT_CONOBJECT_CHILDREN(GuiControl);
 
+static EnumTable::Enums alignCtrlEnums[] =
+{
+   { AlignmentType::LeftAlign,          "left"      },
+   { AlignmentType::CenterAlign,        "center"    },
+   { AlignmentType::RightAlign,         "right"     },
+   { AlignmentType::DefaultAlign,       "default"   }
+};
+static EnumTable gAlignCtrlTable(3, &alignCtrlEnums[0]);
+
+static EnumTable::Enums vAlignCtrlEnums[] =
+{
+   { VertAlignmentType::TopVAlign,          "top"      },
+   { VertAlignmentType::MiddleVAlign,        "middle"    },
+   { VertAlignmentType::BottomVAlign,         "bottom"     },
+   { VertAlignmentType::DefaultVAlign,       "default"   }
+};
+static EnumTable gVAlignCtrlTable(3, &vAlignCtrlEnums[0]);
+
 //used to locate the next/prev responder when tab is pressed
 S32 GuiControl::smCursorChanged           = -1;
 GuiControl *GuiControl::smPrevResponder = NULL;
@@ -79,6 +97,9 @@ GuiControl::GuiControl()
    mText                = StringTable->EmptyString;
    mTextID              = StringTable->EmptyString;
 
+   mAlignment = AlignmentType::DefaultAlign;
+   mVAlignment = VertAlignmentType::DefaultVAlign;
+
    mLangTable           = NULL;
    mFirstResponder      = NULL;
    mCanSaveFieldDictionary = false;
@@ -206,6 +227,8 @@ void GuiControl::initPersistFields()
    addField("textID", TypeString, Offset(mTextID, GuiControl));
    addField("textWrap", TypeBool, Offset(mTextWrap, GuiControl), &writeTextWrapFn, "If true, text will wrap to additional lines.");
    addField("textExtend", TypeBool, Offset(mTextExtend, GuiControl), &writeTextExtendFn, "If true, extent will change based on the size of the control's text when possible.");
+   addField("align", TypeEnum, Offset(mAlignment, GuiControl), 1, &gAlignCtrlTable);
+   addField("vAlign", TypeEnum, Offset(mVAlignment, GuiControl), 1, &gVAlignCtrlTable);
    endGroup("Text");
 }
 
@@ -1793,15 +1816,15 @@ void GuiControl::renderText(const Point2I& offset, const Point2I& extent, const
 
         if (blockHeight < totalHeight)
         {
-            startOffsetY = getTextVerticalOffset(blockHeight, totalHeight, profile->mVAlignment);
+            startOffsetY = getTextVerticalOffset(blockHeight, totalHeight, getVertAlignmentType(profile));
         }
         else if (!mTextWrap)
         {
-            startOffsetY = getTextVerticalOffset(blockHeight, totalHeight, GuiControlProfile::VertAlignmentType::MiddleVAlign);
+            startOffsetY = getTextVerticalOffset(blockHeight, totalHeight, VertAlignmentType::MiddleVAlign);
         }
         else
         {
-            startOffsetY = getTextVerticalOffset(blockHeight, totalHeight, GuiControlProfile::VertAlignmentType::TopVAlign);
+            startOffsetY = getTextVerticalOffset(blockHeight, totalHeight, VertAlignmentType::TopVAlign);
         }
 
         renderLineList(offset, extent, startOffsetY, lineList, profile, rot);
@@ -1826,7 +1849,7 @@ void GuiControl::renderLineList(const Point2I& offset, const Point2I& extent, co
 		U32 textWidth = profile->mFont->getStrWidth(trimmedLine.c_str());
 		if(textWidth < totalWidth)
 		{
-            offsetX = getTextHorizontalOffset(textWidth, totalWidth, profile->mAlignment);
+            offsetX = getTextHorizontalOffset(textWidth, totalWidth, getAlignmentType(profile));
 		}
 
 		Point2I start = Point2I(0, 0);
@@ -1928,26 +1951,26 @@ void GuiControl::renderTextLine(const Point2I& startPoint, const string line, Gu
     dglDrawText(profile->mFont, startPoint, line.c_str(), profile->mFontColors, 9, rotationInDegrees);
 }
 
-S32 GuiControl::getTextHorizontalOffset(S32 textWidth, S32 totalWidth, GuiControlProfile::AlignmentType align)
+S32 GuiControl::getTextHorizontalOffset(S32 textWidth, S32 totalWidth, AlignmentType align)
 {
-	if (align == GuiControlProfile::RightAlign)
+	if (align == RightAlign)
 	{
 		return totalWidth - textWidth;
 	}
-	else if (align == GuiControlProfile::CenterAlign)
+	else if (align == CenterAlign)
 	{
 		return (totalWidth - textWidth) / 2;
 	}
 	return 0;//left aligned
 }
 
-S32 GuiControl::getTextVerticalOffset(S32 textHeight, S32 totalHeight, GuiControlProfile::VertAlignmentType align)
+S32 GuiControl::getTextVerticalOffset(S32 textHeight, S32 totalHeight, VertAlignmentType align)
 {
-	if (align == GuiControlProfile::MiddleVAlign)
+	if (align == MiddleVAlign)
 	{
 		return (totalHeight - textHeight) / 2;
 	}
-	else if (align == GuiControlProfile::BottomVAlign)
+	else if (align == BottomVAlign)
 	{
 		return totalHeight - textHeight;
 	}
@@ -2012,4 +2035,24 @@ void GuiControl::setTextID(S32 id)
 const char *GuiControl::getText()
 {
 	return mText;
+}
+
+AlignmentType GuiControl::getAlignmentType()
+{
+    return getAlignmentType(mProfile);
+}
+
+AlignmentType GuiControl::getAlignmentType(GuiControlProfile* profile)
+{
+    return mAlignment == AlignmentType::DefaultAlign ? profile->mAlignment : mAlignment;
+}
+
+VertAlignmentType GuiControl::getVertAlignmentType()
+{
+    return getVertAlignmentType(mProfile);
+}
+
+VertAlignmentType GuiControl::getVertAlignmentType(GuiControlProfile* profile)
+{
+    return mVAlignment == VertAlignmentType::DefaultVAlign ? profile->mVAlignment : mVAlignment;
 }

+ 9 - 2
engine/source/gui/guiControl.h

@@ -210,6 +210,9 @@ protected:
 	bool				mTextWrap;
     bool                mTextExtend;
 
+    AlignmentType       mAlignment;
+    VertAlignmentType   mVAlignment;
+
     /// @}
 
     /// @name Console
@@ -766,8 +769,12 @@ protected:
 	virtual void processTick() {};
 	virtual void advanceTime(F32 timeDelta) {};
 
-	S32 getTextHorizontalOffset(S32 textWidth, S32 totalWidth, GuiControlProfile::AlignmentType align);
-	S32 getTextVerticalOffset(S32 textHeight, S32 totalHeight, GuiControlProfile::VertAlignmentType align);
+	S32 getTextHorizontalOffset(S32 textWidth, S32 totalWidth, AlignmentType align);
+	S32 getTextVerticalOffset(S32 textHeight, S32 totalHeight, VertAlignmentType align);
+    AlignmentType getAlignmentType();
+    VertAlignmentType getVertAlignmentType();
+    AlignmentType getAlignmentType(GuiControlProfile* profile);
+    VertAlignmentType getVertAlignmentType(GuiControlProfile* profile);
 };
 /// @}
 

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

@@ -46,7 +46,7 @@ GuiTextEditTextBlock::GuiTextEditTextBlock()
     mLineStartIbeamValue = 0;
 }
 
-void GuiTextEditTextBlock::render(const RectI& bounds, string line, U32 ibeamStartValue, GuiControlProfile* profile, GuiControlState currentState, GuiTextEditSelection& selector)
+void GuiTextEditTextBlock::render(const RectI& bounds, string line, U32 ibeamStartValue, GuiControlProfile* profile, GuiControlState currentState, GuiTextEditSelection& selector, AlignmentType align)
 {
     mGlobalBounds.set(bounds.point, bounds.extent);
     mText.assign(line);
@@ -62,7 +62,7 @@ void GuiTextEditTextBlock::render(const RectI& bounds, string line, U32 ibeamSta
         U32 lengthOfPostBlockText = mClamp(line.length() - (selEnd - mLineStartIbeamValue), 0, line.length());
         U32 lengthOfHighlightBlockText = mClamp(line.length() - (lengthOfPreBlockText + lengthOfPostBlockText), 0, line.length());
 
-        processTextAlignment(line, profile);
+        processTextAlignment(line, profile, align);
         Point2I movingStartPoint = getGlobalTextStart();
         movingStartPoint.x += renderTextSection(movingStartPoint, 0, lengthOfPreBlockText, profile, currentState);
         movingStartPoint.x += renderTextSection(movingStartPoint, lengthOfPreBlockText, lengthOfHighlightBlockText, profile, currentState, true);
@@ -152,18 +152,18 @@ void GuiTextEditTextBlock::processScrollVelocity(const S32 delta, const S32 exte
     mTextScrollX = mClamp(mTextScrollX + delta, 0, max);
 }
 
-void GuiTextEditTextBlock::processTextAlignment(const string line, GuiControlProfile* profile)
+void GuiTextEditTextBlock::processTextAlignment(const string line, GuiControlProfile* profile, AlignmentType align)
 {
-    if (profile->mAlignment == GuiControlProfile::AlignmentType::LeftAlign || 
+    if (align == AlignmentType::LeftAlign ||
         mGlobalBounds.extent.x < profile->mFont->getStrWidth(line.c_str()))
     {
         mTextOffsetX = 0;
     }
-    else if (profile->mAlignment == GuiControlProfile::AlignmentType::RightAlign)
+    else if (align == AlignmentType::RightAlign)
     {
         mTextOffsetX = mGlobalBounds.extent.x - profile->mFont->getStrWidth(line.c_str());
     }
-    else if (profile->mAlignment == GuiControlProfile::AlignmentType::CenterAlign)
+    else if (align == AlignmentType::CenterAlign)
     {
         mTextOffsetX = (S32)mRound((mGlobalBounds.extent.x - profile->mFont->getStrWidth(line.c_str())) / 2);
     }
@@ -1061,7 +1061,7 @@ void GuiTextEditCtrl::renderLineList(const Point2I& offset, const Point2I& exten
         Point2I start = Point2I(0, offsetY);
         Point2I blockExtent = Point2I(extent.x, textHeight);
         RectI blockBounds = RectI(start + offset + profile->mTextOffset, blockExtent);
-        mTextBlockList[i].render(blockBounds, lineList[i], ibeamPos, mProfile, getCurrentState(), mSelector);
+        mTextBlockList[i].render(blockBounds, lineList[i], ibeamPos, mProfile, getCurrentState(), mSelector, getAlignmentType());
 
         offsetY += textHeight;
         ibeamPos += lineList[i].length();

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

@@ -85,14 +85,14 @@ public:
 	inline const U32 getStartValue() const { return mLineStartIbeamValue; }
 	inline RectI getGlobalBounds() const { return mGlobalBounds; }
 	inline Point2I getGlobalTextStart() { return Point2I(mGlobalBounds.point.x + mTextOffsetX - mTextScrollX, mGlobalBounds.point.y); }
-	void render(const RectI& bounds, string line, U32 ibeamStartValue, GuiControlProfile* profile, GuiControlState currentState, GuiTextEditSelection& selector);
+	void render(const RectI& bounds, string line, U32 ibeamStartValue, GuiControlProfile* profile, GuiControlState currentState, GuiTextEditSelection& selector, AlignmentType align);
 	U32 renderTextSection(const Point2I& startPoint, const U32 subStrStart, const U32 subStrLen, GuiControlProfile* profile, const GuiControlState currentState, bool isSelectedText = false);
 	void performScrollJumpX(const S32 targetX, const S32 areaStart, const S32 areaEnd);
 	U32 calculateIbeamPositionInLine(const S32 targetX, GuiControlProfile* profile);
 	inline bool calculateCursorAtEOL(const U32 cursorPos) { return cursorPos == mText.length(); }
 	inline void resetScroll() { mTextScrollX = 0; }
 	void processScrollVelocity(const S32 delta, const S32 extentX, GuiControlProfile* profile);
-	void processTextAlignment(const string line, GuiControlProfile* profile);
+	void processTextAlignment(const string line, GuiControlProfile* profile, AlignmentType align);
 };
 
 class GuiTextEditCtrl : public GuiControl

+ 11 - 11
engine/source/gui/guiTypes.cc

@@ -252,17 +252,17 @@ IMPLEMENT_CONOBJECT(GuiControlProfile);
 
 static EnumTable::Enums alignEnums[] =
 {
-   { GuiControlProfile::LeftAlign,          "left"      },
-   { GuiControlProfile::CenterAlign,        "center"    },
-   { GuiControlProfile::RightAlign,         "right"     }
+   { AlignmentType::LeftAlign,          "left"      },
+   { AlignmentType::CenterAlign,        "center"    },
+   { AlignmentType::RightAlign,         "right"     }
 };
 static EnumTable gAlignTable(3, &alignEnums[0]);
 
 static EnumTable::Enums vAlignEnums[] =
 {
-   { GuiControlProfile::TopVAlign,          "top"      },
-   { GuiControlProfile::MiddleVAlign,        "middle"    },
-   { GuiControlProfile::BottomVAlign,         "bottom"     }
+   { VertAlignmentType::TopVAlign,          "top"      },
+   { VertAlignmentType::MiddleVAlign,        "middle"    },
+   { VertAlignmentType::BottomVAlign,         "bottom"     }
 };
 static EnumTable gVAlignTable(3, &vAlignEnums[0]);
 
@@ -335,8 +335,8 @@ GuiControlProfile::GuiControlProfile(void) :
 	// default image asset
 	mImageAsset = NULL;
 	
-	mAlignment     = LeftAlign;
-	mVAlignment    = MiddleVAlign;
+	mAlignment     = AlignmentType::LeftAlign;
+	mVAlignment    = VertAlignmentType::MiddleVAlign;
    mProfileForChildrenName = NULL;
 	mProfileForChildren = NULL;
 
@@ -379,8 +379,8 @@ GuiControlProfile::GuiControlProfile(void) :
       mBitmapName = def->mBitmapName;
       mTextOffset = def->mTextOffset;
 
-      //used by GuiTextCtrl
       mAlignment = def->mAlignment;
+	  mVAlignment = def->mVAlignment;
       mCursorColor = def->mCursorColor;
 
       // Child profile
@@ -422,6 +422,8 @@ void GuiControlProfile::initPersistFields()
    addGroup("Font");
 	   addField("fontType",      TypeString,     Offset(mFontType, GuiControlProfile));
 	   addField("fontSize",      TypeS32,        Offset(mFontSize, GuiControlProfile));
+	   addField("align", TypeEnum, Offset(mAlignment, GuiControlProfile), 1, &gAlignTable);
+	   addField("vAlign", TypeEnum, Offset(mVAlignment, GuiControlProfile), 1, &gVAlignTable);
 	   addField("fontDirectory", TypeString,	 Offset(mFontDirectory, GuiControlProfile));
 	   addField("fontCharset",   TypeEnum,       Offset(mFontCharset, GuiControlProfile), 1, &gCharsetTable);
 	   addField("fontColors",    TypeColorI,     Offset(mFontColors, GuiControlProfile), 10);
@@ -434,8 +436,6 @@ void GuiControlProfile::initPersistFields()
 	   addField("fontColorTextSL", TypeColorI, Offset(mFontColors[ColorTextSL], GuiControlProfile));
    endGroup("Font");
 
-   addField("align", TypeEnum, Offset(mAlignment, GuiControlProfile), 1, &gAlignTable);
-   addField("vAlign", TypeEnum, Offset(mVAlignment, GuiControlProfile), 1, &gVAlignTable);
    addField("textOffset",    TypePoint2I,    Offset(mTextOffset, GuiControlProfile));
    addField("cursorColor",   TypeColorI,     Offset(mCursorColor, GuiControlProfile));
 

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

@@ -97,6 +97,22 @@ enum class GuiDirection
 	Right			
 };
 
+enum AlignmentType
+{
+	LeftAlign,
+	RightAlign,
+	CenterAlign,
+	DefaultAlign
+};
+
+enum VertAlignmentType
+{
+	TopVAlign,
+	BottomVAlign,
+	MiddleVAlign,
+	DefaultVAlign
+};
+
 class GuiCursor : public SimObject
 {
 private:
@@ -216,20 +232,8 @@ public:
 
    Resource<GFont>   mFont;                        ///< Font resource
 
-   enum AlignmentType
-   {
-      LeftAlign,
-      RightAlign,
-      CenterAlign
-   };
+   
    AlignmentType mAlignment;                       ///< Horizontal text alignment
-
-   enum VertAlignmentType
-   {
-	   TopVAlign,
-	   BottomVAlign,
-	   MiddleVAlign
-   };
    VertAlignmentType mVAlignment;				   ///< Vertical text alignment
                              
    bool mMouseOverSelected;                        ///< True if this object should be "selected" while the mouse is over it