123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 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 "platform/platform.h"
- #include "console/engineAPI.h"
- #include "gui/worldEditor/creator.h"
- #include "gfx/gfxDrawUtil.h"
- IMPLEMENT_CONOBJECT(CreatorTree);
- ConsoleDocClass( CreatorTree,
- "@brief Creator tree from old editor. Not used in current editor.\n\n"
- "@internal"
- );
- //------------------------------------------------------------------------------
- // Class CreatorTree::Node
- //------------------------------------------------------------------------------
- CreatorTree::Node::Node() :
- mFlags(0),
- mParent(0),
- mName(0),
- mId(0),
- mValue(0),
- mTab(0)
- {
- VECTOR_SET_ASSOCIATION(mChildren);
- }
- CreatorTree::Node::~Node()
- {
- for(U32 i = 0; i < mChildren.size(); i++)
- delete mChildren[i];
- }
- //------------------------------------------------------------------------------
- void CreatorTree::Node::expand(bool exp)
- {
- if(exp)
- {
- if(mParent)
- mParent->expand(exp);
- mFlags.set(Node::Expanded);
- }
- else if(!isRoot())
- {
- if(isGroup())
- for(U32 i = 0; i < mChildren.size(); i++)
- mChildren[i]->expand(exp);
- mFlags.clear(Selected);
- mFlags.clear(Expanded);
- }
- }
- //------------------------------------------------------------------------------
- CreatorTree::Node * CreatorTree::Node::find(S32 id)
- {
- if(mId == id)
- return(this);
- if(!isGroup())
- return(0);
- for(U32 i = 0; i < mChildren.size(); i++)
- {
- Node * node = mChildren[i]->find(id);
- if(node)
- return(node);
- }
- return(0);
- }
- //------------------------------------------------------------------------------
- bool CreatorTree::Node::isFirst()
- {
- AssertFatal(!isRoot(), "CreatorTree::Node::isFirst - cannot call on root node");
- return(this == mParent->mChildren[0]);
- }
- bool CreatorTree::Node::isLast()
- {
- AssertFatal(!isRoot(), "CreatorTree::Node::isLast - cannot call on root node");
- return(this == mParent->mChildren[mParent->mChildren.size()-1]);
- }
- bool CreatorTree::Node::hasChildItem()
- {
- for(U32 i = 0; i < mChildren.size(); i++)
- {
- if(mChildren[i]->isGroup() && mChildren[i]->hasChildItem())
- return(true);
- if(!mChildren[i]->isGroup())
- return(true);
- }
- return(false);
- }
- S32 CreatorTree::Node::getSelected()
- {
- for(U32 i = 0; i < mChildren.size(); i++)
- {
- if(mChildren[i]->isSelected())
- return(mChildren[i]->mId);
- else if(mChildren[i]->isGroup())
- {
- S32 ret = mChildren[i]->getSelected();
- if(ret != -1)
- return(ret);
- }
- }
- return(-1);
- }
- //------------------------------------------------------------------------------
- // Class CreatorTree
- //------------------------------------------------------------------------------
- CreatorTree::CreatorTree() :
- mCurId(0),
- mRoot(0),
- mTxtOffset(5),
- mTabSize(11),
- mMaxWidth(0)
- {
- VECTOR_SET_ASSOCIATION(mNodeList);
- clear();
- }
- CreatorTree::~CreatorTree()
- {
- delete mRoot;
- }
- //------------------------------------------------------------------------------
- CreatorTree::Node * CreatorTree::createNode(const char * name, const char * value, bool group, Node * parent)
- {
- Node * node = new Node();
- node->mId = mCurId++;
- node->mName = name ? StringTable->insert(name) : 0;
- node->mValue = value ? StringTable->insert(value) : 0;
- node->mFlags.set(Node::Group, group);
- // add to the parent group
- if(parent)
- {
- node->mParent = parent;
- if(!addNode(parent, node))
- {
- delete node;
- return(0);
- }
- }
- return(node);
- }
- //------------------------------------------------------------------------------
- void CreatorTree::clear()
- {
- delete mRoot;
- mCurId = 0;
- mRoot = createNode(0, 0, true);
- mRoot->mFlags.set(Node::Root | Node::Expanded);
- mSize = Point2I(1,0);
- }
- //------------------------------------------------------------------------------
- bool CreatorTree::addNode(Node * parent, Node * node)
- {
- if(!parent->isGroup())
- return(false);
- //
- parent->mChildren.push_back(node);
- return(true);
- }
- //------------------------------------------------------------------------------
- CreatorTree::Node * CreatorTree::findNode(S32 id)
- {
- return(mRoot->find(id));
- }
- //------------------------------------------------------------------------------
- void CreatorTree::sort()
- {
- // groups then items by alpha
- }
- //------------------------------------------------------------------------------
- DefineEngineMethod( CreatorTree, addGroup, S32, (S32 group, const char * name, const char * value), , "(string group, string name, string value)")
- {
- CreatorTree::Node * grp = object->findNode(group);
- if(!grp || !grp->isGroup())
- return(-1);
- // return same named group if found...
- for(U32 i = 0; i < grp->mChildren.size(); i++)
- if(!dStricmp(name, grp->mChildren[i]->mName))
- return(grp->mChildren[i]->mId);
- CreatorTree::Node * node = object->createNode(name, 0, true, grp);
- object->build();
- return(node ? node->getId() : -1);
- }
- DefineEngineMethod( CreatorTree, addItem, S32, (S32 group, const char * name, const char * value), , "(Node group, string name, string value)")
- {
- CreatorTree::Node * grp = object->findNode(group);
- if(!grp || !grp->isGroup())
- return -1;
- CreatorTree::Node * node = object->createNode(name, value, false, grp);
- object->build();
- return(node ? node->getId() : -1);
- }
- //------------------------------------------------------------------------------
- DefineEngineMethod( CreatorTree, fileNameMatch, bool, (const char * world, const char * type, const char * filename), , "(string world, string type, string filename)")
- {
- // argv[2] - world short
- // argv[3] - type short
- // argv[4] - filename
- // interior filenames
- // 0 - world short ('b', 'x', ...)
- // 1-> - type short ('towr', 'bunk', ...)
- U32 typeLen = dStrlen(type);
- if(dStrlen(filename) < (typeLen + 1))
- return(false);
- // world
- if(dToupper(filename[0]) != dToupper(world[0]))
- return(false);
- return(!dStrnicmp(filename+1, type, typeLen));
- }
- DefineEngineMethod( CreatorTree, getSelected, S32, (), , "Return a handle to the currently selected item.")
- {
- return(object->getSelected());
- }
- DefineEngineMethod( CreatorTree, isGroup, bool, (const char * group), , "(Group g)")
- {
- CreatorTree::Node * node = object->findNode(dAtoi(group));
- if(node && node->isGroup())
- return(true);
- return(false);
- }
- DefineEngineMethod( CreatorTree, getName, const char*, (const char * item), , "(Node item)")
- {
- CreatorTree::Node * node = object->findNode(dAtoi(item));
- return(node ? node->mName : 0);
- }
- DefineEngineMethod( CreatorTree, getValue, const char*, (S32 nodeValue), , "(Node n)")
- {
- CreatorTree::Node * node = object->findNode(nodeValue);
- return(node ? node->mValue : 0);
- }
- DefineEngineMethod( CreatorTree, clear, void, (), , "Clear the tree.")
- {
- object->clear();
- }
- DefineEngineMethod( CreatorTree, getParent, S32, (S32 nodeValue), , "(Node n)")
- {
- CreatorTree::Node * node = object->findNode(nodeValue);
- if(node && node->mParent)
- return(node->mParent->getId());
- return(-1);
- }
- //------------------------------------------------------------------------------
- void CreatorTree::buildNode(Node * node, U32 tab)
- {
- if(node->isExpanded())
- for(U32 i = 0; i < node->mChildren.size(); i++)
- {
- Node * child = node->mChildren[i];
- child->mTab = tab;
- child->select(false);
- mNodeList.push_back(child);
- // grab width
- if(bool(mProfile->mFont) && child->mName)
- {
- S32 width = (tab + 1) * mTabSize + mProfile->mFont->getStrWidth(child->mName) + mTxtOffset;
- if(width > mMaxWidth)
- mMaxWidth = width;
- }
- if(node->mChildren[i]->isGroup())
- buildNode(node->mChildren[i], tab+1);
- }
- }
- //------------------------------------------------------------------------------
- void CreatorTree::build()
- {
- mMaxWidth = 0;
- mNodeList.clear();
- buildNode(mRoot, 0);
- mCellSize.set( mMaxWidth + 1, 11 );
- setSize(Point2I(1, mNodeList.size()));
- }
- //------------------------------------------------------------------------------
- bool CreatorTree::onWake()
- {
- if(!Parent::onWake())
- return(false);
- mTabSize = 11;
- //
- build();
- mCellSize.set( mMaxWidth + 1, 11 );
- setSize(Point2I(1, mNodeList.size()));
- return true;
- }
- //------------------------------------------------------------------------------
- void CreatorTree::onMouseUp(const GuiEvent & event)
- {
- onAction();
- }
- void CreatorTree::onMouseDown(const GuiEvent & event)
- {
- Point2I pos = globalToLocalCoord(event.mousePoint);
- bool dblClick = event.mouseClickCount > 1;
- // determine cell
- Point2I cell(pos.x < 0 ? -1 : pos.x / mCellSize.x, pos.y < 0 ? -1 : pos.y / mCellSize.y);
- if(cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
- {
- Node * node = mNodeList[cell.y];
- S32 offset = mTabSize * node->mTab;
- if(node->isGroup() && node->mChildren.size() && pos.x >= offset && pos.x <= (offset + mTabSize))
- {
- node->expand(!node->isExpanded());
- build();
- dblClick = false;
- }
- if(pos.x >= offset)
- {
- if(dblClick)
- node->expand(!node->isExpanded());
- build();
- node->select(true);
- }
- }
- }
- //------------------------------------------------------------------------------
- void CreatorTree::onMouseDragged(const GuiEvent & event)
- {
- TORQUE_UNUSED(event);
- }
- //------------------------------------------------------------------------------
- void CreatorTree::onRenderCell(Point2I offset, Point2I cell, bool, bool)
- {
- Point2I cellOffset = offset;
- Node *node = mNodeList[cell.y];
- // Get our points
- Point2I boxStart( cellOffset.x + mTabSize * node->mTab, cellOffset.y );
- boxStart.x += 2;
- boxStart.y += 1;
- Point2I boxEnd = Point2I( boxStart );
- boxEnd.x += 8;
- boxEnd.y += 8;
- GFXDrawUtil *drawer = GFX->getDrawUtil();
- // Start drawing stuff
- if( node->isGroup() )
- {
- // If we need a box...
- drawer->drawRectFill( boxStart, boxEnd, mProfile->mFillColor ); // Box background
- drawer->drawRect( boxStart, boxEnd, mProfile->mFontColor ); // Border
- // Cross line
- drawer->drawLine( boxStart.x + 2, boxStart.y + 4, boxStart.x + 7, boxStart.y + 4, mProfile->mFontColor );
- if( !node->isExpanded() ) // If it's a [+] draw down line
- drawer->drawLine( boxStart.x + 4, boxStart.y + 2, boxStart.x + 4, boxStart.y + 7, mProfile->mFontColor );
- }
- else
- {
- // Draw horizontal line
- drawer->drawLine( boxStart.x + 4, boxStart.y + 4, boxStart.x + 9, boxStart.y + 4, mProfile->mFontColor );
- if( !node->isLast() ) // If it's a continuing one, draw a long down line
- drawer->drawLine( boxStart.x + 4, boxStart.y - 6, boxStart.x + 4, boxStart.y + 10, mProfile->mFontColor );
- else // Otherwise, just a small one
- drawer->drawLine( boxStart.x + 4, boxStart.y - 2, boxStart.x + 4, boxStart.y + 4, mProfile->mFontColor );
- }
- //draw in all the required continuation lines
- Node *parent = node->mParent;
- while( !parent->isRoot() )
- {
- if( !parent->isLast() )
- {
- drawer->drawLine( cellOffset.x + ( parent->mTab * mTabSize ) + 6,
- cellOffset.y - 2,
- cellOffset.x + ( parent->mTab * mTabSize ) + 6,
- cellOffset.y + 11,
- mProfile->mFontColor );
- }
- parent = parent->mParent;
- }
- ColorI fontColor = mProfile->mFontColor;
- if( node->isSelected() )
- fontColor = mProfile->mFontColorHL;
- else if( node->isGroup() && node->hasChildItem() )
- fontColor.set( 128, 0, 0 );
- else if( !node->isGroup() )
- fontColor.set( 0, 0, 128 );
- drawer->setBitmapModulation(fontColor); //node->isSelected() ? mProfile->mFontColorHL : mProfile->mFontColor);
- drawer->drawText( mProfile->mFont,
- Point2I( offset.x + mTxtOffset + mTabSize * ( node->mTab + 1 ), offset.y ),
- node->mName);
- }
|