Przeglądaj źródła

Merge remote-tracking branch 'refs/remotes/whilke/feature/guiGrid' into development.

MichPerry-GG 12 lat temu
rodzic
commit
ca00986e6a

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

@@ -365,6 +365,7 @@
     <ClCompile Include="..\..\source\graphics\TextureDictionary.cc" />
     <ClCompile Include="..\..\source\graphics\TextureHandle.cc" />
     <ClCompile Include="..\..\source\graphics\TextureManager.cc" />
+    <ClCompile Include="..\..\source\gui\containers\guiGridCtrl.cc" />
     <ClCompile Include="..\..\source\gui\guiArrayCtrl.cc" />
     <ClCompile Include="..\..\source\gui\guiBackgroundCtrl.cc" />
     <ClCompile Include="..\..\source\gui\guiBitmapBorderCtrl.cc" />
@@ -816,6 +817,7 @@
     <ClInclude Include="..\..\source\graphics\TextureHandle.h" />
     <ClInclude Include="..\..\source\graphics\TextureManager.h" />
     <ClInclude Include="..\..\source\graphics\TextureObject.h" />
+    <ClInclude Include="..\..\source\gui\containers\guiGridCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiArrayCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiBackgroundCtrl.h" />
     <ClInclude Include="..\..\source\gui\guiBitmapCtrl.h" />

+ 6 - 0
engine/compilers/VisualStudio 2010/Torque 2D.vcxproj.filters

@@ -1272,6 +1272,9 @@
     <ClCompile Include="..\..\source\persistence\taml\tamlCustom.cc">
       <Filter>persistence\taml</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\source\gui\containers\guiGridCtrl.cc">
+      <Filter>gui\containers</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc">
       <Filter>2d\sceneobject</Filter>
     </ClCompile>
@@ -2616,6 +2619,9 @@
     <ClInclude Include="..\..\source\persistence\taml\tamlCustom.h">
       <Filter>persistence\taml</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\gui\containers\guiGridCtrl.h">
+      <Filter>gui\containers</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\source\sim\simObjectTimerEvent.h">
       <Filter>sim</Filter>
     </ClInclude>

+ 302 - 0
engine/source/gui/containers/guiGridCtrl.cc

@@ -0,0 +1,302 @@
+#include "gui/containers/guiGridCtrl.h"
+
+IMPLEMENT_CONOBJECT(GuiGridControl);
+
+GuiGridControl::GuiGridControl()
+{
+	mIsContainer = true;
+}
+
+void GuiGridControl::initPersistFields()
+{
+	Parent::initPersistFields();
+
+	addField("Rows",		TypeStringTableEntryVector, Offset(mGridRows, GuiGridControl));
+	addField("Columns",     TypeStringTableEntryVector, Offset(mGridCols, GuiGridControl));
+
+}
+
+bool GuiGridControl::onWake()
+{
+	if ( !Parent::onWake() )
+		return false;
+
+	return true;
+}
+
+void GuiGridControl::onSleep()
+{
+	Parent::onSleep();
+}
+
+
+void GuiGridControl::inspectPostApply()
+{
+	resize(getPosition(), getExtent());
+}
+
+bool GuiGridControl::IsPointInGridControl(GuiControl* ctrl, const Point2I& pt)
+{
+	if (mRowSizes.size() > 0 && mColSizes.size() > 0)
+	{
+		RectI gridRect = GetGridRect(ctrl);
+		RectI ctrlRect = ctrl->getBounds();
+
+		Point2I chkPt = gridRect.point + ctrlRect.point;
+		Point2I chkBound = chkPt + ctrlRect.extent;
+
+		if (pt.x >= chkPt.x && pt.x <= chkBound.x &&
+			pt.y >= chkPt.y && pt.y <= chkBound.y)
+			return true;
+		else
+			return false;
+	}
+	else
+		return false;
+
+}
+
+void GuiGridControl::addObject(SimObject *obj)
+{
+	if (mRowSizes.size() <= 0 && mRowSizes.size() <= 0)
+		AdjustGrid(mBounds.extent);
+
+	GuiControl *ctrl = static_cast<GuiControl *>(obj);
+	if (ctrl)
+	{
+		RectI ctrlRect = GetGridRect(ctrl);
+		if (ctrl->getExtent().isZero())
+		{
+			ctrl->setExtent(ctrlRect.extent);
+		}
+		else
+		{
+			if (ctrl->mBounds.extent.x > ctrlRect.extent.x)
+				ctrl->mBounds.extent.x = ctrlRect.extent.x;
+			if (ctrl->mBounds.extent.y > ctrlRect.extent.y)
+				ctrl->mBounds.extent.y = ctrlRect.extent.y;
+		}
+
+		Point2I pt = ctrl->getPosition();
+		mOrginalControlPos.push_back(pt);
+		pt += ctrlRect.point;
+		ctrl->setPosition(pt);
+	}
+
+	Parent::addObject(obj);
+}
+
+void GuiGridControl::removeObject(SimObject *obj)
+{
+	for(int idx =0; idx < objectList.size();idx++)
+	{
+		if ( objectList[idx] == obj )
+		{
+			mOrginalControlPos.erase(idx);
+			break;
+		}
+	}
+
+	Parent::removeObject(obj);
+}
+
+
+void GuiGridControl::resize(const Point2I &newPosition, const Point2I &newExtent)
+{
+	setUpdate();
+
+	Point2I actualNewExtent = Point2I(  getMax(mMinExtent.x, newExtent.x),
+		getMax(mMinExtent.y, newExtent.y));
+	mBounds.set(newPosition, actualNewExtent);
+
+	bool bFirstResize = false;
+	iterator i;
+	Vector<Point2I> oldCtrlExtent;
+	
+	if (mRowSizes.size() == 0 && mColSizes.size() == 0)
+	{
+		bFirstResize = true;
+	}
+	else
+	{
+		for(i = begin(); i != end(); i++)
+		{
+			GuiControl *ctrl = static_cast<GuiControl *>(*i);
+			if (ctrl)
+			{
+				RectI newRect = GetGridRect(ctrl);		
+				oldCtrlExtent.push_back(newRect.extent);
+			}
+		}
+
+	}
+
+	AdjustGrid(mBounds.extent);
+
+	//resize and position all child controls.
+	int idx=0;
+	for(i = begin(); i != end(); i++)
+	{
+		GuiControl *ctrl = static_cast<GuiControl *>(*i);
+		if (ctrl)
+		{
+			RectI newRect = GetGridRect(ctrl);		
+			
+			if (ctrl->getExtent().x == 0 && ctrl->getExtent().y == 0)
+				ctrl->setExtent(newRect.extent);
+
+			ctrl->setPosition(mOrginalControlPos[idx] + newRect.point);
+
+			if (bFirstResize)
+			{
+				ctrl->parentResized(newRect.extent, newRect.extent);
+			}
+			else
+			{
+				ctrl->parentResized(oldCtrlExtent[idx++], newRect.extent);
+			}
+		}
+	}
+
+	GuiControl *parent = getParent();
+	if (parent)
+		parent->childResized(this);
+
+	setUpdate();
+
+}
+
+RectI GuiGridControl::GetGridRect(GuiControl* ctrl)
+{
+	S32 col = dAtoi(ctrl->getDataField( StringTable->insert("Col"), NULL));
+	S32 row = dAtoi(ctrl->getDataField( StringTable->insert("Row"), NULL));
+	S32 colSpan = dAtoi(ctrl->getDataField( StringTable->insert("ColSpan"), NULL));
+	S32 rowSpan = dAtoi(ctrl->getDataField( StringTable->insert("RowSpan"), NULL));
+
+	AssertFatal (col < mColSizes.size(), "Col is out of bounds");
+	AssertFatal (row < mRowSizes.size(), "Row is out of bounds");
+
+	if (colSpan < 1) colSpan = 1;
+	if (rowSpan < 1) rowSpan = 1;
+
+	RectI newRect(0,0,0,0);
+
+	for(int i = 0; i < col; i++)
+	{
+		newRect.point.x += mColSizes[i];
+	}
+	for(int i =col; i < col+colSpan; i++)
+	{
+		newRect.extent.x += mColSizes[i];
+	}
+	
+	for(int i = 0; i < row; i++)
+	{
+		newRect.point.y += mRowSizes[i];
+	}
+	for(int i =row; i < row+rowSpan; i++)
+	{
+		newRect.extent.y += mRowSizes[i];
+	}
+
+	return newRect;
+}
+
+void GuiGridControl::AdjustGrid(const Point2I& newExtent)
+{
+	mColSizes.clear();
+	mRowSizes.clear();
+	AdjustGridItems(newExtent.x, mGridCols, mColSizes);
+	AdjustGridItems(newExtent.y, mGridRows, mRowSizes);
+}
+
+void GuiGridControl::AdjustGridItems(S32 size, Vector<StringTableEntry>& strItems, Vector<S32>& items)
+{
+	Vector<GridItem> GridItems;
+	S32 bFoundStar = false;
+	S32 IndexRemaining = -1;
+	S32 totalSize = 0;
+	S32 idx =0;
+
+
+	//First step : Convert the string based column data into a GridItem vector.
+	for(auto col = strItems.begin(); col != strItems.end(); ++col, idx++)
+	{
+		StringTableEntry str = *col;
+
+		int len = dStrlen(str);
+		AssertFatal(len >= 1, "Item can not be blank.");
+		
+		//we support three types of values (absolute size in pixels, percentage based, and remaining size in pixels).
+		if (str[0] == '*') // use the remaining space left in the columns.
+		{
+			AssertFatal(!bFoundStar, "Can only use one * item field");
+			GridItem gi;
+			gi.IsAbsolute = false;
+			gi.IsPercentage = false;
+			gi.IsRemaining = true;
+			gi.Size = 0;
+			GridItems.push_back(gi);
+		}
+		else if ( len > 1 && str[len-1] == '%' ) //percentage based
+		{
+			char* tmp = new char[len-1];
+			dStrncpy(tmp, str, len-1);
+			int perc = dAtoi(tmp);
+			delete tmp;
+
+			GridItem gi;
+			gi.IsAbsolute = false;
+			gi.IsPercentage = true;
+			gi.IsRemaining = false;
+			gi.Size = perc;
+			GridItems.push_back(gi);
+
+		}
+		else //standard absolute pixel based
+		{
+			int px = dAtoi(str);
+
+			GridItem gi;
+			gi.IsAbsolute = true;
+			gi.IsPercentage = false;
+			gi.IsRemaining = false;
+			gi.Size = px;
+			GridItems.push_back(gi);
+
+			totalSize += px;
+		}
+	}
+
+	//step two: iterate the grid columns again, and fill in any percentage based sizing, and setup the correct grid array.
+	int remainingSize = size - totalSize;
+	int sizeForPerc = remainingSize;
+	for(int i = 0; i < GridItems.size(); ++i)
+	{
+		GridItem gi = GridItems[i];
+
+		if (gi.IsAbsolute)
+		{
+			items.push_back(gi.Size);
+		}
+		else if (gi.IsPercentage)
+		{
+			F32 perc = gi.Size / 100.0f;
+			S32 realSize = sizeForPerc * perc;
+			remainingSize -= realSize;
+			items.push_back(realSize);
+		}
+		else if(gi.IsRemaining)
+		{
+			//place holder for the moment.
+			items.push_back(0);
+			IndexRemaining = i;
+		}			
+	}
+
+	if (IndexRemaining >= 0)
+	{
+		items[IndexRemaining] = remainingSize;
+		remainingSize = 0;
+	}
+}

+ 55 - 0
engine/source/gui/containers/guiGridCtrl.h

@@ -0,0 +1,55 @@
+#ifndef _GUIGRIDCTRL_H_
+#define _GUIGRIDCTRL_H_
+
+#ifndef _GUICONTROL_H_
+#include "gui/guiControl.h"
+#endif
+
+#include "graphics/dgl.h"
+#include "console/console.h"
+#include "console/consoleTypes.h"
+
+class GuiGridControl : public GuiControl
+{
+private:
+
+	struct GridItem
+	{
+		int Size;
+		bool IsPercentage;
+		bool IsRemaining;
+		bool IsAbsolute;
+	};
+
+private:
+	typedef GuiControl Parent;
+
+	Vector<StringTableEntry> mGridRows;
+	Vector<StringTableEntry> mGridCols;
+
+	Vector<S32> mRowSizes;
+	Vector<S32> mColSizes;
+	Vector<Point2I> mOrginalControlPos;
+
+	void AdjustGrid(const Point2I& newExtent);
+	void AdjustGridItems(S32 size, Vector<StringTableEntry>& strItems, Vector<S32>& items);
+	RectI GetGridRect(GuiControl* ctrl);
+	bool IsPointInGridControl(GuiControl* ctrl, const Point2I& pt);
+
+
+public:
+	GuiGridControl();
+
+	void resize(const Point2I &newPosition, const Point2I &newExtent);
+	void inspectPostApply();
+
+	void addObject(SimObject *obj);
+	void removeObject(SimObject *obj);
+	bool onWake();
+	void onSleep();
+
+	static void initPersistFields();
+	DECLARE_CONOBJECT(GuiGridControl);
+};
+
+#endif // _GUIGRIDCTRL_H_