creator.cpp
Engine/source/gui/worldEditor/creator.cpp
Public Functions
ConsoleDocClass(CreatorTree , "@brief Creator tree from old editor. Not used in current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">editor.\n\n</a>" "@internal" )
DefineEngineMethod(CreatorTree , addGroup , S32 , (S32 group, const char *name, const char *value) , "(string group, string name, string <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>)" )
DefineEngineMethod(CreatorTree , addItem , S32 , (S32 group, const char *name, const char *value) , "(Node group, string name, string <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>)" )
DefineEngineMethod(CreatorTree , clear , void , () , "Clear the tree." )
DefineEngineMethod(CreatorTree , fileNameMatch , bool , (const char *world, const char *type, const char *filename) , "(string world, string type, string filename)" )
DefineEngineMethod(CreatorTree , getName , const char * , (const char *item) , "(Node item)" )
DefineEngineMethod(CreatorTree , getParent , S32 , (S32 nodeValue) , "(Node <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>)" )
DefineEngineMethod(CreatorTree , getSelected , S32 , () , "Return <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> handle <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the currently selected item." )
DefineEngineMethod(CreatorTree , getValue , const char * , (S32 nodeValue) , "(Node <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>)" )
DefineEngineMethod(CreatorTree , isGroup , bool , (const char *group) , "(Group g)" )
Detailed Description
Public Functions
ConsoleDocClass(CreatorTree , "@brief Creator tree from old editor. Not used in current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">editor.\n\n</a>" "@internal" )
DefineEngineMethod(CreatorTree , addGroup , S32 , (S32 group, const char *name, const char *value) , "(string group, string name, string <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>)" )
DefineEngineMethod(CreatorTree , addItem , S32 , (S32 group, const char *name, const char *value) , "(Node group, string name, string <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>)" )
DefineEngineMethod(CreatorTree , clear , void , () , "Clear the tree." )
DefineEngineMethod(CreatorTree , fileNameMatch , bool , (const char *world, const char *type, const char *filename) , "(string world, string type, string filename)" )
DefineEngineMethod(CreatorTree , getName , const char * , (const char *item) , "(Node item)" )
DefineEngineMethod(CreatorTree , getParent , S32 , (S32 nodeValue) , "(Node <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>)" )
DefineEngineMethod(CreatorTree , getSelected , S32 , () , "Return <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> handle <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the currently selected item." )
DefineEngineMethod(CreatorTree , getValue , const char * , (S32 nodeValue) , "(Node <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>)" )
DefineEngineMethod(CreatorTree , isGroup , bool , (const char *group) , "(Group g)" )
IMPLEMENT_CONOBJECT(CreatorTree )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "console/engineAPI.h" 26#include "gui/worldEditor/creator.h" 27 28#include "gfx/gfxDrawUtil.h" 29 30 31IMPLEMENT_CONOBJECT(CreatorTree); 32 33ConsoleDocClass( CreatorTree, 34 "@brief Creator tree from old editor. Not used in current editor.\n\n" 35 "@internal" 36); 37 38//------------------------------------------------------------------------------ 39// Class CreatorTree::Node 40//------------------------------------------------------------------------------ 41 42CreatorTree::Node::Node() : 43 mFlags(0), 44 mParent(0), 45 mName(0), 46 mId(0), 47 mValue(0), 48 mTab(0) 49{ 50 VECTOR_SET_ASSOCIATION(mChildren); 51} 52 53CreatorTree::Node::~Node() 54{ 55 for(U32 i = 0; i < mChildren.size(); i++) 56 delete mChildren[i]; 57} 58 59//------------------------------------------------------------------------------ 60 61void CreatorTree::Node::expand(bool exp) 62{ 63 if(exp) 64 { 65 if(mParent) 66 mParent->expand(exp); 67 mFlags.set(Node::Expanded); 68 } 69 else if(!isRoot()) 70 { 71 if(isGroup()) 72 for(U32 i = 0; i < mChildren.size(); i++) 73 mChildren[i]->expand(exp); 74 75 mFlags.clear(Selected); 76 mFlags.clear(Expanded); 77 } 78} 79 80//------------------------------------------------------------------------------ 81 82CreatorTree::Node * CreatorTree::Node::find(S32 id) 83{ 84 if(mId == id) 85 return(this); 86 87 if(!isGroup()) 88 return(0); 89 90 for(U32 i = 0; i < mChildren.size(); i++) 91 { 92 Node * node = mChildren[i]->find(id); 93 if(node) 94 return(node); 95 } 96 97 return(0); 98} 99 100//------------------------------------------------------------------------------ 101 102bool CreatorTree::Node::isFirst() 103{ 104 AssertFatal(!isRoot(), "CreatorTree::Node::isFirst - cannot call on root node"); 105 return(this == mParent->mChildren[0]); 106} 107 108bool CreatorTree::Node::isLast() 109{ 110 AssertFatal(!isRoot(), "CreatorTree::Node::isLast - cannot call on root node"); 111 return(this == mParent->mChildren[mParent->mChildren.size()-1]); 112} 113 114bool CreatorTree::Node::hasChildItem() 115{ 116 for(U32 i = 0; i < mChildren.size(); i++) 117 { 118 if(mChildren[i]->isGroup() && mChildren[i]->hasChildItem()) 119 return(true); 120 121 if(!mChildren[i]->isGroup()) 122 return(true); 123 } 124 125 return(false); 126} 127 128S32 CreatorTree::Node::getSelected() 129{ 130 for(U32 i = 0; i < mChildren.size(); i++) 131 { 132 if(mChildren[i]->isSelected()) 133 return(mChildren[i]->mId); 134 else if(mChildren[i]->isGroup()) 135 { 136 S32 ret = mChildren[i]->getSelected(); 137 if(ret != -1) 138 return(ret); 139 } 140 } 141 return(-1); 142} 143 144//------------------------------------------------------------------------------ 145// Class CreatorTree 146//------------------------------------------------------------------------------ 147CreatorTree::CreatorTree() : 148 mCurId(0), 149 mRoot(0), 150 mTxtOffset(5), 151 mTabSize(11), 152 mMaxWidth(0) 153{ 154 VECTOR_SET_ASSOCIATION(mNodeList); 155 clear(); 156} 157 158CreatorTree::~CreatorTree() 159{ 160 delete mRoot; 161} 162 163//------------------------------------------------------------------------------ 164 165CreatorTree::Node * CreatorTree::createNode(const char * name, const char * value, bool group, Node * parent) 166{ 167 Node * node = new Node(); 168 node->mId = mCurId++; 169 node->mName = name ? StringTable->insert(name) : 0; 170 node->mValue = value ? StringTable->insert(value) : 0; 171 node->mFlags.set(Node::Group, group); 172 173 // add to the parent group 174 if(parent) 175 { 176 node->mParent = parent; 177 if(!addNode(parent, node)) 178 { 179 delete node; 180 return(0); 181 } 182 } 183 184 return(node); 185} 186 187//------------------------------------------------------------------------------ 188 189void CreatorTree::clear() 190{ 191 delete mRoot; 192 mCurId = 0; 193 mRoot = createNode(0, 0, true); 194 mRoot->mFlags.set(Node::Root | Node::Expanded); 195 mSize = Point2I(1,0); 196} 197 198//------------------------------------------------------------------------------ 199 200bool CreatorTree::addNode(Node * parent, Node * node) 201{ 202 if(!parent->isGroup()) 203 return(false); 204 205 // 206 parent->mChildren.push_back(node); 207 return(true); 208} 209 210//------------------------------------------------------------------------------ 211 212CreatorTree::Node * CreatorTree::findNode(S32 id) 213{ 214 return(mRoot->find(id)); 215} 216 217//------------------------------------------------------------------------------ 218 219void CreatorTree::sort() 220{ 221 // groups then items by alpha 222} 223 224//------------------------------------------------------------------------------ 225DefineEngineMethod( CreatorTree, addGroup, S32, (S32 group, const char * name, const char * value), , "(string group, string name, string value)") 226{ 227 CreatorTree::Node * grp = object->findNode(group); 228 229 if(!grp || !grp->isGroup()) 230 return(-1); 231 232 // return same named group if found... 233 for(U32 i = 0; i < grp->mChildren.size(); i++) 234 if(!dStricmp(name, grp->mChildren[i]->mName)) 235 return(grp->mChildren[i]->mId); 236 237 CreatorTree::Node * node = object->createNode(name, 0, true, grp); 238 object->build(); 239 return(node ? node->getId() : -1); 240} 241 242DefineEngineMethod( CreatorTree, addItem, S32, (S32 group, const char * name, const char * value), , "(Node group, string name, string value)") 243{ 244 CreatorTree::Node * grp = object->findNode(group); 245 246 if(!grp || !grp->isGroup()) 247 return -1; 248 249 CreatorTree::Node * node = object->createNode(name, value, false, grp); 250 object->build(); 251 return(node ? node->getId() : -1); 252} 253 254//------------------------------------------------------------------------------ 255DefineEngineMethod( CreatorTree, fileNameMatch, bool, (const char * world, const char * type, const char * filename), , "(string world, string type, string filename)") 256{ 257 // argv[2] - world short 258 // argv[3] - type short 259 // argv[4] - filename 260 261 // interior filenames 262 // 0 - world short ('b', 'x', ...) 263 // 1-> - type short ('towr', 'bunk', ...) 264 U32 typeLen = dStrlen(type); 265 if(dStrlen(filename) < (typeLen + 1)) 266 return(false); 267 268 // world 269 if(dToupper(filename[0]) != dToupper(world[0])) 270 return(false); 271 272 return(!dStrnicmp(filename+1, type, typeLen)); 273} 274 275DefineEngineMethod( CreatorTree, getSelected, S32, (), , "Return a handle to the currently selected item.") 276{ 277 return(object->getSelected()); 278} 279 280DefineEngineMethod( CreatorTree, isGroup, bool, (const char * group), , "(Group g)") 281{ 282 CreatorTree::Node * node = object->findNode(dAtoi(group)); 283 if(node && node->isGroup()) 284 return(true); 285 return(false); 286} 287 288DefineEngineMethod( CreatorTree, getName, const char*, (const char * item), , "(Node item)") 289{ 290 CreatorTree::Node * node = object->findNode(dAtoi(item)); 291 return(node ? node->mName : 0); 292} 293 294DefineEngineMethod( CreatorTree, getValue, const char*, (S32 nodeValue), , "(Node n)") 295{ 296 CreatorTree::Node * node = object->findNode(nodeValue); 297 return(node ? node->mValue : 0); 298} 299 300DefineEngineMethod( CreatorTree, clear, void, (), , "Clear the tree.") 301{ 302 object->clear(); 303} 304 305DefineEngineMethod( CreatorTree, getParent, S32, (S32 nodeValue), , "(Node n)") 306{ 307 CreatorTree::Node * node = object->findNode(nodeValue); 308 if(node && node->mParent) 309 return(node->mParent->getId()); 310 311 return(-1); 312} 313//------------------------------------------------------------------------------ 314 315void CreatorTree::buildNode(Node * node, U32 tab) 316{ 317 if(node->isExpanded()) 318 for(U32 i = 0; i < node->mChildren.size(); i++) 319 { 320 Node * child = node->mChildren[i]; 321 child->mTab = tab; 322 child->select(false); 323 mNodeList.push_back(child); 324 325 // grab width 326 if(bool(mProfile->mFont) && child->mName) 327 { 328 S32 width = (tab + 1) * mTabSize + mProfile->mFont->getStrWidth(child->mName) + mTxtOffset; 329 if(width > mMaxWidth) 330 mMaxWidth = width; 331 } 332 333 if(node->mChildren[i]->isGroup()) 334 buildNode(node->mChildren[i], tab+1); 335 } 336} 337 338//------------------------------------------------------------------------------ 339 340void CreatorTree::build() 341{ 342 mMaxWidth = 0; 343 mNodeList.clear(); 344 buildNode(mRoot, 0); 345 mCellSize.set( mMaxWidth + 1, 11 ); 346 setSize(Point2I(1, mNodeList.size())); 347} 348 349//------------------------------------------------------------------------------ 350bool CreatorTree::onWake() 351{ 352 if(!Parent::onWake()) 353 return(false); 354 355 mTabSize = 11; 356 357 358 // 359 build(); 360 mCellSize.set( mMaxWidth + 1, 11 ); 361 setSize(Point2I(1, mNodeList.size())); 362 return true; 363} 364 365//------------------------------------------------------------------------------ 366 367void CreatorTree::onMouseUp(const GuiEvent & event) 368{ 369 onAction(); 370} 371 372void CreatorTree::onMouseDown(const GuiEvent & event) 373{ 374 Point2I pos = globalToLocalCoord(event.mousePoint); 375 376 bool dblClick = event.mouseClickCount > 1; 377 378 // determine cell 379 Point2I cell(pos.x < 0 ? -1 : pos.x / mCellSize.x, pos.y < 0 ? -1 : pos.y / mCellSize.y); 380 if(cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y) 381 { 382 Node * node = mNodeList[cell.y]; 383 S32 offset = mTabSize * node->mTab; 384 if(node->isGroup() && node->mChildren.size() && pos.x >= offset && pos.x <= (offset + mTabSize)) 385 { 386 node->expand(!node->isExpanded()); 387 build(); 388 dblClick = false; 389 } 390 391 if(pos.x >= offset) 392 { 393 if(dblClick) 394 node->expand(!node->isExpanded()); 395 build(); 396 node->select(true); 397 } 398 } 399} 400 401//------------------------------------------------------------------------------ 402 403void CreatorTree::onMouseDragged(const GuiEvent & event) 404{ 405 TORQUE_UNUSED(event); 406} 407 408//------------------------------------------------------------------------------ 409void CreatorTree::onRenderCell(Point2I offset, Point2I cell, bool, bool) 410{ 411 Point2I cellOffset = offset; 412 413 Node *node = mNodeList[cell.y]; 414 415 // Get our points 416 Point2I boxStart( cellOffset.x + mTabSize * node->mTab, cellOffset.y ); 417 418 boxStart.x += 2; 419 boxStart.y += 1; 420 421 Point2I boxEnd = Point2I( boxStart ); 422 423 boxEnd.x += 8; 424 boxEnd.y += 8; 425 426 GFXDrawUtil *drawer = GFX->getDrawUtil(); 427 428 // Start drawing stuff 429 if( node->isGroup() ) 430 { 431 // If we need a box... 432 drawer->drawRectFill( boxStart, boxEnd, mProfile->mFillColor ); // Box background 433 drawer->drawRect( boxStart, boxEnd, mProfile->mFontColor ); // Border 434 435 // Cross line 436 drawer->drawLine( boxStart.x + 2, boxStart.y + 4, boxStart.x + 7, boxStart.y + 4, mProfile->mFontColor ); 437 438 if( !node->isExpanded() ) // If it's a [+] draw down line 439 drawer->drawLine( boxStart.x + 4, boxStart.y + 2, boxStart.x + 4, boxStart.y + 7, mProfile->mFontColor ); 440 } 441 else 442 { 443 // Draw horizontal line 444 drawer->drawLine( boxStart.x + 4, boxStart.y + 4, boxStart.x + 9, boxStart.y + 4, mProfile->mFontColor ); 445 446 if( !node->isLast() ) // If it's a continuing one, draw a long down line 447 drawer->drawLine( boxStart.x + 4, boxStart.y - 6, boxStart.x + 4, boxStart.y + 10, mProfile->mFontColor ); 448 else // Otherwise, just a small one 449 drawer->drawLine( boxStart.x + 4, boxStart.y - 2, boxStart.x + 4, boxStart.y + 4, mProfile->mFontColor ); 450 } 451 452 //draw in all the required continuation lines 453 Node *parent = node->mParent; 454 455 while( !parent->isRoot() ) 456 { 457 if( !parent->isLast() ) 458 { 459 drawer->drawLine( cellOffset.x + ( parent->mTab * mTabSize ) + 6, 460 cellOffset.y - 2, 461 cellOffset.x + ( parent->mTab * mTabSize ) + 6, 462 cellOffset.y + 11, 463 mProfile->mFontColor ); 464 } 465 parent = parent->mParent; 466 } 467 468 ColorI fontColor = mProfile->mFontColor; 469 if( node->isSelected() ) 470 fontColor = mProfile->mFontColorHL; 471 else if( node->isGroup() && node->hasChildItem() ) 472 fontColor.set( 128, 0, 0 ); 473 else if( !node->isGroup() ) 474 fontColor.set( 0, 0, 128 ); 475 476 drawer->setBitmapModulation(fontColor); //node->isSelected() ? mProfile->mFontColorHL : mProfile->mFontColor); 477 drawer->drawText( mProfile->mFont, 478 Point2I( offset.x + mTxtOffset + mTabSize * ( node->mTab + 1 ), offset.y ), 479 node->mName); 480} 481