Initial commit
This commit is contained in:
442
Torque/SDK/engine/editor/creator.cc
Normal file
442
Torque/SDK/engine/editor/creator.cc
Normal file
@@ -0,0 +1,442 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "editor/creator.h"
|
||||
#include "dgl/dgl.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(CreatorTree);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Class CreatorTree::Node
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
CreatorTree::Node::Node() :
|
||||
mFlags(0),
|
||||
mParent(0),
|
||||
mName(0),
|
||||
mValue(0),
|
||||
mId(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),
|
||||
mTxtOffset(5),
|
||||
mRoot(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
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleMethod( CreatorTree, addGroup, S32, 4, 4, "(string group, string name, string value)")
|
||||
{
|
||||
CreatorTree::Node * grp = object->findNode(dAtoi(argv[2]));
|
||||
|
||||
if(!grp || !grp->isGroup())
|
||||
return(-1);
|
||||
|
||||
// return same named group if found...
|
||||
for(U32 i = 0; i < grp->mChildren.size(); i++)
|
||||
if(!dStricmp(argv[3], grp->mChildren[i]->mName))
|
||||
return(grp->mChildren[i]->mId);
|
||||
|
||||
CreatorTree::Node * node = object->createNode(argv[3], 0, true, grp);
|
||||
object->build();
|
||||
return(node ? node->getId() : -1);
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, addItem, S32, 5, 5, "(Node group, string name, string value)")
|
||||
{
|
||||
CreatorTree::Node * grp = object->findNode(dAtoi(argv[2]));
|
||||
|
||||
if(!grp || !grp->isGroup())
|
||||
return -1;
|
||||
|
||||
CreatorTree::Node * node = object->createNode(argv[3], argv[4], false, grp);
|
||||
object->build();
|
||||
return(node ? node->getId() : -1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleMethod( CreatorTree, fileNameMatch, bool, 5, 5, "(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(argv[3]);
|
||||
if(dStrlen(argv[4]) < (typeLen + 1))
|
||||
return(false);
|
||||
|
||||
// world
|
||||
if(dToupper(argv[4][0]) != dToupper(argv[2][0]))
|
||||
return(false);
|
||||
|
||||
return(!dStrnicmp(argv[4]+1, argv[3], typeLen));
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, getSelected, S32, 2, 2, "Return a handle to the currently selected item.")
|
||||
{
|
||||
return(object->getSelected());
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, isGroup, bool, 3, 3, "(Group g)")
|
||||
{
|
||||
CreatorTree::Node * node = object->findNode(dAtoi(argv[2]));
|
||||
if(node && node->isGroup())
|
||||
return(true);
|
||||
return(false);
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, getName, const char*, 3, 3, "(Node item)")
|
||||
{
|
||||
CreatorTree::Node * node = object->findNode(dAtoi(argv[2]));
|
||||
return(node ? node->mName : 0);
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, getValue, const char*, 3, 3, "(Node n)")
|
||||
{
|
||||
CreatorTree::Node * node = object->findNode(dAtoi(argv[2]));
|
||||
return(node ? node->mValue : 0);
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, clear, void, 2, 2, "Clear the tree.")
|
||||
{
|
||||
object->clear();
|
||||
}
|
||||
|
||||
ConsoleMethod( CreatorTree, getParent, S32, 3, 3, "(Node n)")
|
||||
{
|
||||
CreatorTree::Node * node = object->findNode(dAtoi(argv[2]));
|
||||
if(node && node->mParent)
|
||||
return(node->mParent->getId());
|
||||
else
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
// Start drawing stuff
|
||||
if( node->isGroup() ) { // If we need a box...
|
||||
dglDrawRectFill( boxStart, boxEnd, mProfile->mFillColor ); // Box background
|
||||
dglDrawRect( boxStart, boxEnd, mProfile->mFontColor ); // Border
|
||||
|
||||
// Cross line
|
||||
dglDrawLine( boxStart.x + 2, boxStart.y + 4, boxStart.x + 7, boxStart.y + 4, mProfile->mFontColor );
|
||||
|
||||
if( !node->isExpanded() ) // If it's a [+] draw down line
|
||||
dglDrawLine( boxStart.x + 4, boxStart.y + 2, boxStart.x + 4, boxStart.y + 7, mProfile->mFontColor );
|
||||
}
|
||||
else {
|
||||
// Draw horizontal line
|
||||
dglDrawLine( 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
|
||||
dglDrawLine( boxStart.x + 4, boxStart.y - 6, boxStart.x + 4, boxStart.y + 10, mProfile->mFontColor );
|
||||
else // Otherwise, just a small one
|
||||
dglDrawLine( 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() ) {
|
||||
dglDrawLine( 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 );
|
||||
|
||||
dglSetBitmapModulation(fontColor); //node->isSelected() ? mProfile->mFontColorHL : mProfile->mFontColor);
|
||||
dglDrawText( mProfile->mFont,
|
||||
Point2I( offset.x + mTxtOffset + mTabSize * ( node->mTab + 1 ), offset.y ),
|
||||
node->mName);
|
||||
}
|
||||
Reference in New Issue
Block a user