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

📄 guitreeviewctrl.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
#include "core/frameAllocator.h"
#include "gui/controls/guiTreeViewCtrl.h"
#include "gui/containers/guiScrollCtrl.h"
#include "console/consoleTypes.h"
#include "console/console.h"
#include "dgl/dgl.h"
#include "gui/core/guiTypes.h"
#include "platform/event.h"
#include "editor/worldEditor.h"
#include "sim/sceneObject.h"
#include "gui/core/guiDefaultControlRender.h"

IMPLEMENT_CONOBJECT(GuiTreeViewCtrl);

GuiTreeViewCtrl::Item::Item()
{
   // Just null our memory, it's safest!
   mState = 0;
   mScriptInfo.mText = 0;
   mScriptInfo.mValue = 0;
}

GuiTreeViewCtrl::Item::~Item()
{
   if(mState.test(InspectorData))
   {
      // DO NO THING
   }
   else
   {
      if ( getText() )
      {
         delete [] getText();
         setText(NULL);
      }

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

void GuiTreeViewCtrl::Item::setNormalImage(S8 id)
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to set normal image %d for item %d, which is InspectorData!", id, mId);
      return;
   }

   mScriptInfo.mNormalImage = id;
}

void GuiTreeViewCtrl::Item::setExpandedImage(S8 id)
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to set expanded image %d for item %d, which is InspectorData!", id, mId);
      return;
   }

   mScriptInfo.mExpandedImage = id;
}

void GuiTreeViewCtrl::Item::setText(char *txt)
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to set text for item %d, which is InspectorData!", mId);
      return;
   }

   mScriptInfo.mText = txt;
}

void GuiTreeViewCtrl::Item::setValue(const char *val)
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to set value for item %d, which is InspectorData!", mId);
      return;
   }

   mScriptInfo.mValue = const_cast<char*>(val); // mValue really ought to be a StringTableEntry
}

const S8 GuiTreeViewCtrl::Item::getNormalImage() const
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to get the normal image for item %d, which is InspectorData!", mId);
      return 0; // fail safe for width determinations
   }

   return mScriptInfo.mNormalImage;
}

const S8 GuiTreeViewCtrl::Item::getExpandedImage() const
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to get the expanded image for item %d, which is InspectorData!", mId);
      return 0; // fail safe for width determinations
   }

   return mScriptInfo.mExpandedImage;
}

char *GuiTreeViewCtrl::Item::getText()
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to get the text for item %d, which is InspectorData!", mId);
      return NULL;
   }

   return mScriptInfo.mText;
}

char *GuiTreeViewCtrl::Item::getValue()
{
   if(mState.test(InspectorData))
   {
      Con::errorf("Tried to get the value for item %d, which is InspectorData!", mId);
      return NULL;
   }

   return mScriptInfo.mValue;
}

void GuiTreeViewCtrl::Item::setObject(SimObject *obj)
{
   if(!mState.test(InspectorData))
   {
      Con::errorf("Tried to set the object for item %d, which is not InspectorData!", mId);
      return;
   }

   mInspectorInfo.mObject = obj;
}

SimObject *GuiTreeViewCtrl::Item::getObject()
{
   if(!mState.test(InspectorData))
   {
      Con::errorf("Tried to get the object for item %d, which is not InspectorData!", mId);
      return NULL;
   }

   return mInspectorInfo.mObject;
}


const U32 GuiTreeViewCtrl::Item::getDisplayTextLength()
{
   if(mState.test(Item::InspectorData))
   {
      SimObject *obj = getObject();

      if(!obj)
         return 0;

      // For the results buffer, it's prefix along with a bunch of other stuff.
      // So we'll be mostly accurate and add a bit of fudge.
      return (16
         + (obj->getName() ? dStrlen(obj->getName()) : 0) + dStrlen(obj->getClassName())
         + dStrlen(obj->getIdString()) + 20
         );
   }
   else
   {
      return dStrlen(getText());
   }

   // Should never be here. (This useful comment provided by BJG)
}

void GuiTreeViewCtrl::Item::getDisplayText(U32 bufLen, char *buf)
{
   FrameAllocatorMarker txtAlloc;

   char *displayText = NULL;

   if(mState.test(Item::InspectorData))
   {
      // Inspector data!
      SimObject *obj = getObject();
      if(obj)
      {
         // For the prefix, max size is 3 + 1 + 3 + 1 = 8, so 16 for safety
         char *prefix = (char*)txtAlloc.alloc(16);

         // Alright, let's get some info...
         bool isH = obj->isHidden();
         bool isL = obj->isLocked();

         // z - not really used.
         // Calculate prefix string. (BJG TODO - simpler to have lookup table?)
         dSprintf(prefix, sizeof(prefix), "%s%s%s%s",
            (isH ? "" : ""),
            (isH && isL ? "" : ""),
            (isL ? "" : ""),
            (isL || isH ? "" : "")
            );

#ifdef TGE_RPG_UI ///
			dSprintf(buf, bufLen, "%s%d%s%s(%s)",  prefix,
            obj->getId(),
				obj->getName() ? "," : "",
            obj->getName() ? obj->getName() : "",
            obj->getClassName()
            );
#else
         dSprintf(buf, bufLen, "%s%d: %s - %s",  prefix,
            obj->getId(),
            obj->getName() ? obj->getName() : "",
            obj->getClassName()
            );
#endif
      }
   }
   else
   {
      // Script data! (copy it in)
      dStrncpy(buf, getText(), bufLen);
   }
}

const S32 GuiTreeViewCtrl::Item::getDisplayTextWidth(GFont *font)
{
   FrameAllocatorMarker txtAlloc;
   U32 bufLen = getDisplayTextLength();
   char *buf = (char*)txtAlloc.alloc(bufLen);
   getDisplayText(bufLen, buf);

   return font->getStrWidth(buf);
}

const bool GuiTreeViewCtrl::Item::isParent() const
{
   if(mState.test(VirtualParent))
   {
      if( !isInspectorData() )
         return true;

      // Does our object have any children?
      if(mInspectorInfo.mObject)
      {
         SimSet *s = dynamic_cast<SimSet*>( (SimObject*)mInspectorInfo.mObject);
         if (s->size() > 0)
            return s->size();
      }
   }

   // Otherwise, just return whether the child list is populated.
   return mChild;
}

const bool GuiTreeViewCtrl::Item::isExpanded() const
{
   if(mState.test(InspectorData))
      return mInspectorInfo.mObject ? mInspectorInfo.mObject->isExpanded() : false;
   else
      return mState.test(Expanded);
}

void GuiTreeViewCtrl::Item::setExpanded(bool f)
{
   if(mState.test(InspectorData))
      mInspectorInfo.mObject->setExpanded(f);
   else
      mState.set(Expanded, f);
}

void GuiTreeViewCtrl::Item::setVirtualParent( bool value )
{
   mState.set(VirtualParent, value);
}

GuiTreeViewCtrl::Item *GuiTreeViewCtrl::Item::findChildByValue(const SimObject *obj)
{
   // Iterate over our children and try to find the given
   // SimObject

   Item *res = mChild;

   while(res)
   {
      // Skip non-inspector data stuff.
      if(res->mState.test(InspectorData))
      {
         if(res->getObject() == obj)
            break; // Whoa.
      }
      res = res->mNext;
   }
   // If the loop terminated we are NULL, otherwise we have the result in res.
   return res;
}

GuiTreeViewCtrl::Item *GuiTreeViewCtrl::Item::findChildByValue( StringTableEntry Value )
{
   // Iterate over our children and try to find the given Value
   // Note : This is a case-insensitive search
   Item *res = mChild;

   while(res)
   {
      // check the script value of the item against the specified value
      if( dStricmp( res->mScriptInfo.mValue, Value ) == 0 )
         return res;
      res = res->mNext;
   }
   // If the loop terminated we didn't find an item with the specified script value
   return NULL;
}


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

GuiTreeViewCtrl::GuiTreeViewCtrl()
{
   VECTOR_SET_ASSOCIATION(mItems);
   VECTOR_SET_ASSOCIATION(mVisibleItems);
   VECTOR_SET_ASSOCIATION(mSelectedItems);
   VECTOR_SET_ASSOCIATION(mSelected);

   mItemFreeList = 0;
   mRoot = 0;
   mInstantGroup = 0;
   mItemCount = 0;
   mSelectedItem = 0;
   mStart = 0;

   mDraggedToItem = 0;
   mOldDragY = 0;
   mCurrentDragCell = 0;
   mPreviousDragCell = 0;
   mDragMidPoint = NomDragMidPoint;
   mMouseDragged = false;
   mDebug = false;

   // persist info..
   mTabSize = 16;
   mTextOffset = 2;
   mFullRowSelect = false;
   mItemHeight = 20;

   //
   setSize(Point2I(1, 0));

   // Set up default state
   mFlags.set(ShowTreeLines);
   mFlags.set(IsEditable, false);
   mFlags.set(IsDeletable);

   mDestroyOnSleep = true;
   mSupportMouseDragging = true;
   mMultipleSelections = true;
}

GuiTreeViewCtrl::~GuiTreeViewCtrl()
{
   destroyTree();
}


//------------------------------------------------------------------------------
void GuiTreeViewCtrl::initPersistFields()
{
   Parent::initPersistFields();

   addGroup("TreeView");
   addField("tabSize",              TypeS32,    Offset(mTabSize,              GuiTreeViewCtrl));
   addField("textOffset",           TypeS32,    Offset(mTextOffset,           GuiTreeViewCtrl));
   addField("fullRowSelect",        TypeBool,   Offset(mFullRowSelect,        GuiTreeViewCtrl));
   addField("itemHeight",           TypeS32,    Offset(mItemHeight,           GuiTreeViewCtrl));
   addField("destroyTreeOnSleep",   TypeBool,   Offset(mDestroyOnSleep,       GuiTreeViewCtrl));
   addField("MouseDragging",        TypeBool,   Offset(mSupportMouseDragging, GuiTreeViewCtrl));
   addField("MultipleSelections",   TypeBool,   Offset(mMultipleSelections,   GuiTreeViewCtrl));
   endGroup("TreeView");
}

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

GuiTreeViewCtrl::Item * GuiTreeViewCtrl::getItem(S32 itemId)
{
   if((itemId > 0) && (itemId <= mItems.size()))
      return(mItems[itemId-1]);
   return(0);
}

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

GuiTreeViewCtrl::Item * GuiTreeViewCtrl::createItem(S32 icon)
{
   Item * item;

   // grab from the free list?
   if(mItemFreeList)
   {
      item = mItemFreeList;
      mItemFreeList = item->mNext;

      // re-add to vector
      mItems[item->mId-1] = item;
   }
   else
   {
      item = new Item;
      mItems.push_back(item);

      // set the id
      item->mId = mItems.size();
   }

   // reset
   if (icon)
      item->mIcon = icon;
   else
      item->mIcon = Default; //default icon to stick next to an item

   item->mNext = item->mPrevious = item->mParent = item->mChild = 0;
   item->mState.clear();
   item->setText(0);
   item->setValue(0);
   item->mState = 0;
   item->mTabLevel = 0;

   mItemCount++;
   return(item);
}

//------------------------------------------------------------------------------
void GuiTreeViewCtrl::destroyChildren(Item * item, Item * parent)
{
   if (!item || item == parent)
      return;

   if (item->isParent())
      destroyChildren(item->mChild, parent);
   else if(item->mNext)
      destroyChildren(item->mNext, parent);
   else
   {
      // destroy the item and back up
      Item * prevItem = item->mPrevious;
      destroyItem(item);
      destroyChildren(prevItem, parent);
   }
}
void GuiTreeViewCtrl::destroyItem(Item * item)
{
   if(!item)
      return;

   if(item->isInspectorData())
   {
      // make sure the SimObjectPtr is clean!

⌨️ 快捷键说明

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