123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- //-----------------------------------------------------------------------------
- // 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.
- //-----------------------------------------------------------------------------
- #include "gui/containers/guiGridCtrl.h"
- //------------------------------------------------------------------------------
- IMPLEMENT_CONOBJECT(GuiGridControl);
- //------------------------------------------------------------------------------
- GuiGridControl::GuiGridControl()
- {
- mIsContainer = true;
- }
- //------------------------------------------------------------------------------
- void GuiGridControl::initPersistFields()
- {
- Parent::initPersistFields();
- addField("Rows", TypeStringTableEntryVector, Offset(mGridRows, GuiGridControl), "Number of rows in the grid");
- addField("Columns", TypeStringTableEntryVector, Offset(mGridCols, GuiGridControl), "Number of columns in the grid");
- }
- //------------------------------------------------------------------------------
- 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;
- bFoundStar = false;
- S32 IndexRemaining = -1;
- S32 totalSize = 0;
- S32 idx =0;
- //First step : Convert the string based column data into a GridItem vector.
- for(Vector<char const*>::iterator 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 * (S32)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;
- }
- }
|