⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guitreeviewctrl.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
      //Con::executef(this,2, "onDeleteObject",Con::getIntArg(item->mInspectorInfo.mObject->getIdString()));
      SimObject *obj = item->getObject();
      if( obj )
         obj->deleteObject();
      item->setObject(NULL);
   }
   else
   {
      // Clean up the memory...
      if ( item->getText() )
      {
         delete [] item->getText();
         item->setText(NULL);
      }

      if ( item->getValue() )
      {
         delete [] item->getValue();
         item->setValue(NULL);
      }
   }

   // unlink
   if(item->mPrevious)
      item->mPrevious->mNext = item->mNext;
   if(item->mNext)
      item->mNext->mPrevious = item->mPrevious;
   if(item->mParent && (item->mParent->mChild == item))
      item->mParent->mChild = item->mNext;

   // remove from vector
   mItems[item->mId-1] = 0;

   // set as root free item
   item->mNext = mItemFreeList;
   mItemFreeList = item;
   mItemCount--;
}

//------------------------------------------------------------------------------
void GuiTreeViewCtrl::deleteItem(Item *item)
{
   removeItem(item->mId);
}

//------------------------------------------------------------------------------

void GuiTreeViewCtrl::destroyTree()
{
   // clear the item list
   for(U32 i = 0; i < mItems.size(); i++)
      delete mItems[i];
   mItems.clear();

   // clear the free list
   while(mItemFreeList)
   {
      Item * next = mItemFreeList->mNext;
      delete mItemFreeList;
      mItemFreeList = next;
   }

   mVisibleItems.clear();
   mSelectedItems.clear();

   //
   mItemFreeList = 0;
   mRoot = 0;
   mItemCount = 0;
   mSelectedItem = 0;
   mDraggedToItem = 0;
}

//------------------------------------------------------------------------------

void GuiTreeViewCtrl::buildItem( Item* item, U32 tabLevel )
{
   if (!item )
      return;

   // If it's inspector data, make sure we still have it, if not, kill it.
   if(item->isInspectorData())
   {
      // Blast an item if it doesn't have a corresponding SimObject...
      if(!item->getObject())
      {
         removeItem(item->mId);
         return;
      }
   }

   // If it's a virtual parent, give a chance to update itself...
   if(item->mState.test( Item::VirtualParent) )
   {
      // If it returns true the item has been removed.
      if(!onVirtualParentBuild(item))
         return;
   }

   item->mTabLevel = tabLevel;
   mVisibleItems.push_back( item );

   if ( bool( mProfile->mFont )  )
   {
      S32 width = ( tabLevel + 1 ) * mTabSize + item->getDisplayTextWidth(mProfile->mFont);
      if ( mProfile->mBitmapArrayRects.size() > 0 )
         width += mProfile->mBitmapArrayRects[0].extent.x;
      
      width += (item->mTabLevel+1) * mItemHeight; // using mItemHeight for icon width, close enough
                                                  // this will only fail if somebody starts using super wide icons.

      if ( width > mMaxWidth )
         mMaxWidth = width;
   }

   // if expanded, then add all the children items as well
   if ( item->isExpanded() )
   {
      Item * child = item->mChild;
      while ( child )
      {
         // Bit of a hack so we can safely remove items as we
         // traverse.
         Item *tmp = child;
         child = child->mNext;

         buildItem( tmp, tabLevel + 1 );
      }
   }
}

//------------------------------------------------------------------------------

void GuiTreeViewCtrl::buildVisibleTree()
{
   mMaxWidth = 0;
   mVisibleItems.clear();

   // Update the flags.
   mFlags.clear(RebuildVisible);

   // build the root items
   Item * traverse = mRoot;
   while(traverse)
   {
      buildItem(traverse, 0);
      traverse = traverse->mNext;
   }

   // adjust the GuiArrayCtrl
   mCellSize.set(mMaxWidth+1, mItemHeight);
   setSize(Point2I(1, mVisibleItems.size()));
   syncSelection();
}

//------------------------------------------------------------------------------

bool GuiTreeViewCtrl::scrollVisible( Item *item )
{
   // Now, make sure it's visible (ie, all parents expanded)
   Item *parent = item->mParent;

   if( !item->isInspectorData() && item->mState.test(Item::VirtualParent) )
      onVirtualParentExpand(item);

   while(parent)
   {
      parent->setExpanded(true);

      if( !parent->isInspectorData() && parent->mState.test(Item::VirtualParent) )
         onVirtualParentExpand(parent);

      parent = parent->mParent;
   }

   // Get our scroll-pappy, if any.
   GuiScrollCtrl *pappy = dynamic_cast<GuiScrollCtrl*>( getParent() );

   if ( !pappy )
   {
      Con::warnf("GuiTreeViewCtrl::scrollVisible - parent control is not a GuiScrollCtrl!");
      return false;
   }

   // And now, build the visible tree so we know where we have to scroll.
   buildVisibleTree();

   // All done, let's figure out where we have to scroll...
   for(S32 i=0; i<mVisibleItems.size(); i++)
   {
      if(mVisibleItems[i] == item)
      {
         pappy->scrollRectVisible(RectI(0, i * mItemHeight, mMaxWidth, mItemHeight));
         return true;
      }
   }

   // If we got here, it's probably bad...
   Con::errorf("GuiTreeViewCtrl::scrollVisible - was unable to find specified item in visible list!");
   return false;
}

//------------------------------------------------------------------------------

S32 GuiTreeViewCtrl::insertItem(S32 parentId, const char * text, const char * value, const char * iconString, S16 normalImage, S16 expandedImage)
{
   if((parentId < 0) || (parentId > mItems.size()))
   {
      Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::insertItem: invalid parent id!");
      return 0;
   }

   if((parentId != 0) && (mItems[parentId-1] == 0))
   {
      Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::insertItem: parent item invalid!");
      return 0;
   }
   S32 icon = getIcon(iconString);

   // create an item (assigns id)
   Item * item = createItem(icon);

   // fill the data
   item->setText( new char[dStrlen( text ) + 1] );
   dStrcpy( item->getText(), text );
   item->setValue( new char[dStrlen( value ) + 1] );
   dStrcpy( item->getValue(), value );
   item->setNormalImage( normalImage );
   item->setExpandedImage( expandedImage );

   // root level?
   if(parentId == 0)
   {
      // insert back
      if(mRoot)
      {
         Item * traverse = mRoot;
         while(traverse->mNext)
            traverse = traverse->mNext;

         traverse->mNext = item;
         item->mPrevious = traverse;
      }
      else
         mRoot = item;

      mFlags.set(RebuildVisible);
   }
   else
   {
      Item * parent = mItems[parentId-1];

      // insert back
      if(parent->mChild)
      {
         Item * traverse = parent->mChild;
         while(traverse->mNext)
            traverse = traverse->mNext;

         traverse->mNext = item;
         item->mPrevious = traverse;
      }
      else
         parent->mChild = item;

      item->mParent = parent;

      if(parent->isExpanded())
         mFlags.set(RebuildVisible);
   }

   //
   if(mFlags.test(RebuildVisible))
      buildVisibleTree();

   return(item->mId);
}

//------------------------------------------------------------------------------

bool GuiTreeViewCtrl::removeItem(S32 itemId)
{
   // tree?
   if(itemId == 0)
   {
      destroyTree();
      return(true);
   }

   Item * item = getItem(itemId);
   if(!item)
   {
      //Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::removeItem: invalid item id!");
      return false;
   }

   // root?
   if(item == mRoot)
      mRoot = item->mNext;

   // Dispose of any children...
   if (item->mChild)
      destroyChildren(item->mChild, item);

   // Kill the item...
   destroyItem(item);

   // Update the rendered tree...
   buildVisibleTree();

   return true;
}


//------------------------------------------------------------------------------

const S32 GuiTreeViewCtrl::getFirstRootItem() const
{
   return (mRoot ? mRoot->mId : 0);
}

//------------------------------------------------------------------------------

S32 GuiTreeViewCtrl::getChildItem(S32 itemId)
{
   Item * item = getItem(itemId);
   if(!item)
   {
      Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getChild: invalid item id!");
      return(0);
   }

   return(item->mChild ? item->mChild->mId : 0);
}

S32 GuiTreeViewCtrl::getParentItem(S32 itemId)
{
   Item * item = getItem(itemId);
   if(!item)
   {
      Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getParent: invalid item id!");
      return(0);
   }

   return(item->mParent ? item->mParent->mId : 0);
}

S32 GuiTreeViewCtrl::getNextSiblingItem(S32 itemId)
{
   Item * item = getItem(itemId);
   if(!item)
   {
      Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getNextSibling: invalid item id!");
      return(0);
   }

   return(item->mNext ? item->mNext->mId : 0);
}

S32 GuiTreeViewCtrl::getPrevSiblingItem(S32 itemId)
{
   Item * item = getItem(itemId);
   if(!item)
   {
      Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getPrevSibling: invalid item id!");
      return(0);
   }

   return(item->mPrevious ? item->mPrevious->mId : 0);
}

//------------------------------------------------------------------------------

S32 GuiTreeViewCtrl::getItemCount()
{
   return(mItemCount);
}

S32 GuiTreeViewCtrl::getSelectedItem()
{
   return mSelectedItem;
}

//------------------------------------------------------------------------------

void GuiTreeViewCtrl::moveItemUp( S32 itemId )
{
   GuiTreeViewCtrl::Item* item = getItem( itemId );
   if ( !item )
   {
      Con::errorf( ConsoleLogEntry::General, "GuiTreeViewCtrl::moveItemUp: invalid item id!");
      return;
   }

   Item* prevItem = item->mPrevious;
   if ( !prevItem )
   {
      Con::errorf( ConsoleLogEntry::General, "GuiTreeViewCtrl::moveItemUp: no previous sibling - how'd this get called?");
      return;
   }

   //  Diddle the linked list!
   if ( prevItem->mPrevious )
      prevItem->mPrevious->mNext = item;
   else if ( item->mParent )
      item->mParent->mChild = item;

   if ( item->mNext )
      item->mNext->mPrevious = prevItem;

   item->mPrevious = prevItem->mPrevious;
   prevItem->mNext = item->mNext;
   item->mNext = prevItem;
   prevItem->mPrevious = item;

   // And update the simobjects if apppropriate...
   SimObject * simobj = NULL;
   if (item->isInspectorData())
      simobj = item->getObject();

   SimSet *parentSet = NULL;

   // grab the current parentSet if there is any...
   if(item->mParent->isInspectorData())
      parentSet = dynamic_cast<SimSet*>(item->mParent->getObject());
   else
   {
      // parent is probably script data so we search up the tree for a
      // set to put our object in
      Item * temp = item->mParent;
      while (!temp->isInspectorData())
         temp = temp->mParent;

      // found an ancestor who is an inspectorData?
      parentSet = temp->isInspectorData() ? dynamic_cast<SimSet*>(temp->getObject()) : NULL;
   }

   // Reorder the item and make sure that the children of the item get updated
   // correctly prev item may be script... so find a prevItem if there is.
   // We only need to reorder if there you move it above an inspector item.
   if (simobj && parentSet)
   {
      Item * temp = item->mNext;

      while(temp)
      {
         if (temp->isInspectorData())
            break;
         temp = temp->mNext;
      }

      if (temp)
         parentSet->reOrder(item->getObject(), temp->getObject());
   }

   buildVisibleTree();
}

//------------------------------------------------------------------------------

bool GuiTreeViewCtrl::onWake()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -