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

📄 guitreeviewctrl.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
{
   if(!Parent::onWake() || !mProfile->constructBitmapArray())
      return false;

   // If destroy on sleep, then we have to give things a chance to rebuild.
   if(mDestroyOnSleep)
   {
      destroyTree();
      Con::executef(this, 1, "onWake");

      // (Re)build our icon table.
      const char * res = Con::executef(this, 1, "onDefineIcons");

      // If no icons were defined in script then use defaults.
      if(!(dAtob(res)))
      {
         buildIconTable(NULL);
      }
   }

   // Update the row height, if appropriate.
   if(mProfile->mAutoSizeHeight)
   {
      // make sure it's big enough for both bitmap AND font...
      mItemHeight = getMax((S32)mFont->getHeight(), (S32)mProfile->mBitmapArrayRects[0].extent.y);
   }

   return true;
}

void GuiTreeViewCtrl::onSleep()
{
   Parent::onSleep();

   // If appropriate, blast the tree. (We probably rebuild it on wake.)
   if( mDestroyOnSleep )
      destroyTree();
}

bool GuiTreeViewCtrl::buildIconTable(const char * icons)
{
   // Icons should be designated by the bitmap/png file names (minus the file extensions)
   // and separated by colons (:). This list should be synchronized with the Icons enum.

   // This is an abominal piece of code. -- BJG
   if (!icons)
   {
#ifdef TGE_RPG_UI ///TGE_RPG_UI 
      icons = "default:"
              "simgroup:"
              "simgroup_closed:"
              "simgroup_selected:"
              "simgroup_selected_closed:"
              "audio:"
              "camera:"
              "fxfoliage:"
              "fxlight:"
              "fxshapereplicator:"
              "fxsunlight:"
              "hidden:"
              "interior:"
              "lightning:"
              "shll_icon_passworded_hi:"
              "shll_icon_passworded:"
              "mission_area:"
              "particle:"
              "path:"
              "pathmarker:"
              "physical_area:"
              "precipitation:"
              "shape:"
              "sky:"
              "static_shape:"
              "sun:"
              "terrain:"
              "trigger:"
              "water:"
              "default";
#else
      icons = "ui/icons/default:"
              "ui/icons/simgroup:"
              "ui/icons/simgroup_closed:"
              "ui/icons/simgroup_selected:"
              "ui/icons/simgroup_selected_closed:"
              "ui/icons/audio:"
              "ui/icons/camera:"
              "ui/icons/fxfoliage:"
              "ui/icons/fxlight:"
              "ui/icons/fxshapereplicator:"
              "ui/icons/fxsunlight:"
              "ui/icons/hidden:"
              "ui/icons/interior:"
              "ui/icons/lightning:"
              "ui/icons/ui/icons/shll_icon_passworded_hi:"
              "ui/icons/shll_icon_passworded:"
              "ui/icons/mission_area:"
              "ui/icons/particle:"
              "ui/icons/path:"
              "ui/icons/pathmarker:"
              "ui/icons/physical_area:"
              "ui/icons/precipitation:"
              "ui/icons/shape:"
              "ui/icons/sky:"
              "ui/icons/static_shape:"
              "ui/icons/sun:"
              "ui/icons/terrain:"
              "ui/icons/trigger:"
              "ui/icons/water:"
              "ui/icons/default";
#endif
   }

   // Figure the size of the buffer we need...
   const char* temp = dStrchr( icons, '\t' );
   U32 textLen = temp ? ( temp - icons ) : dStrlen( icons );

   // Allocate temporary space.
   FrameAllocatorMarker txtBuff;
   char* drawText = (char*)txtBuff.alloc(sizeof(char) * (textLen + 4));
   dStrncpy( drawText, icons, textLen );
   drawText[textLen] = '\0';

   U32 numIcons = 0;

   char *buf = (char*)txtBuff.alloc(sizeof(char) * 64);
   char* token = dStrtok( drawText, ":" );

#ifdef TGE_RPG_UI ///TGE_RPG_UI 
   	StringTableEntry pIconsPath = Con::getVariable("$theme::PathIcons");
		AssertFatal(pIconsPath && pIconsPath[0],"$theme::PathIcons图标路径不能为空!");
#endif

// Count the number of icons and store them.
   while (token && numIcons < MaxIcons)
   {
#ifdef TGE_RPG_UI ///TGE_RPG_UI 
      dSprintf( buf, sizeof( buf ), "%s%s",pIconsPath ,token );
#else
      dSprintf( buf, sizeof( buf ), "%s", token );
#endif
      mIconTable[numIcons] = TextureHandle( buf, BitmapKeepTexture );
      token = dStrtok( NULL, ":" );
      numIcons++;
   }

	/*
	图标列表导出为整张图片
	GBitmap bmp(320,320,0,GBitmap::RGBA);
	ColorI clr(0,0,0,0);
	for(U32 m=0;m<320;m++)
	for(U32 k=0;k<320;k++)
		bmp.setColor(m,k,clr);

	U32 nWrite=0;

	for(U32 n=0; n< MaxIcons; n++)
	{
		int x = (n&15) * 16;
		int y = (n>>4) * 16;
		if(!bool(mIconTable[n]))
			continue;
		nWrite++;
		bmp.blt(*(mIconTable[n]).getBitmap(),x,y);
	}

	char szPath[256];
	FileStream stream;
	if(ResourceManager->openFileForWrite(stream,avar("common/icon%d.png",nWrite) ) )
		bmp.writePNG(stream);
	*/

   return true;
}

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

void GuiTreeViewCtrl::onPreRender()
{
   Parent::onPreRender();

   // Update every render in case new objects are added
   buildVisibleTree();
}

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

bool GuiTreeViewCtrl::hitTest(const Point2I & pnt, Item* & item, BitSet32 & flags)
{

   // Initialize some things.
   const Point2I pos = globalToLocalCoord(pnt);
   flags.clear();
   item = 0;

   // get the hit cell
   Point2I cell((pos.x < 0 ? -1 : pos.x / mCellSize.x),
                (pos.y < 0 ? -1 : pos.y / mCellSize.y));

   // valid?
   if((cell.x < 0 || cell.x >= mSize.x) ||
      (cell.y < 0 || cell.y >= mSize.y))
      return false;

   flags.set(OnRow);

   // Grab the cell.
   if (cell.y >= mVisibleItems.size())
      return false; //Invalid cell, so don't do anything

   item = mVisibleItems[cell.y];

   S32 min = mTabSize * item->mTabLevel;

   // left of icon/text?
   if(pos.x < min)
   {
      flags.set(OnIndent);
      return true;
   }

   // check image
   S32 image = BmpChild;

   if(item->isInspectorData())
      image = item->isExpanded() ? BmpExp : BmpCon;
   else
      image = item->isExpanded() ? item->getExpandedImage() : item->getNormalImage();

   if((image >= 0) && (image < mProfile->mBitmapArrayRects.size()))
      min += mProfile->mBitmapArrayRects[image].extent.x;

   // Is it on the image?
   if(pos.x < min)
   {
      flags.set(OnImage);
      return(true);
   }

   // Bump over to the start of the text.
   min += mTextOffset;

   // Check against the text.
   FrameAllocatorMarker txtAlloc;
   U32 bufLen = item->getDisplayTextLength();
   char *buf = (char*)txtAlloc.alloc(bufLen);
   item->getDisplayText(bufLen, buf);

   min += mProfile->mFont->getStrWidth(buf);
   if(pos.x < min)
      flags.set(OnText);

   return true;
}

void GuiTreeViewCtrl::setInstantGroup(SimObject * obj)
{
   // make sure we're talking about a group.
   SimGroup * grp = dynamic_cast<SimGroup*>(obj);

   // Set the instant group variable.
   if(grp)
   {
      Con::setVariable("instantGroup", grp->getIdString());
   }
}

void GuiTreeViewCtrl::syncSelection()
{
   // for each visible item check to see if it is on the mSelected list.
   // if it is then make sure that it is on the mSelectedItems list as well.
   for (S32 i = 0; i < mVisibleItems.size(); i++) 
   {
      for (S32 j = 0; j < mSelected.size(); j++) 
      {
         if (mVisibleItems[i]->mId == mSelected[j]) 
         {
            // check to see if it is on the visible items list.
            bool addToSelectedItems = true;
            for (S32 k = 0; k < mSelectedItems.size(); k++) 
            {
               if (mSelected[j] == mSelectedItems[k]->mId) 
               {
                  // don't add it
                  addToSelectedItems = false;
               }
            }
            if (addToSelectedItems) 
            {
               mVisibleItems[i]->mState.set(Item::Selected, true);
               mSelectedItems.push_front(mVisibleItems[i]);
               break;
            }
         } 
         else if (mVisibleItems[i]->isInspectorData()) 
         {
            if (mVisibleItems[i]->getObject()->getId() == mSelected[j]) 
            {
               // check to see if it is on the visible items list.
               bool addToSelectedItems = true;
               for (S32 k = 0; k < mSelectedItems.size(); k++) 
               {
                  if (mSelectedItems[k]->isInspectorData()) 
                  {
                     if (mSelected[j] == mSelectedItems[k]->getObject()->getId()) 
                     {
                        // don't add it
                        addToSelectedItems = false;
                     }
                  } 
                  else 
                  {
                     if (mSelected[j] == mSelectedItems[k]->mId) 
                     {
                        // don't add it
                        addToSelectedItems = false;
                     }
                  }
               }
               if (addToSelectedItems) 
               {
                  mVisibleItems[i]->mState.set(Item::Selected, true);
                  mSelectedItems.push_front(mVisibleItems[i]);
                  break;
               }
            }
         }

      }

   }
}

void GuiTreeViewCtrl::removeSelection(S32 itemId)
{
   if (mDebug)
      Con::printf("removeSelection called");
   Item * item = getItem(itemId);

   // the item may have been selected at one point but was never created/visible in the tree
   // so remove it.
   for (S32 j = 0; j <mSelected.size(); j++) 
   {
      if (item) 
      {
         if (item->isInspectorData()) 
         {
            if (item->getObject()->getId() == mSelected[j]) 
            {
               mSelected.erase(j);
               break;
            }
         }
      }

      if (mSelected[j] == itemId) 
      {
         mSelected.erase(j);
         break;
      }
   }

   if(!item)
   {
      // maybe what we were passed wasn't an item id but an object id.
      for (S32 i = 0; i <mItems.size(); i++) 
      {
         if (mItems[i] != 0) 
         {
            if (mItems[i]->isInspectorData()) 
            {
               if (mItems[i]->getObject()->getId() == itemId) 
               {
                  item = mItems[i];
                  break;
               }
            }
         }
      }

      if (!item) 
      {
         //Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::removeSelection: invalid item id! Perhaps it isn't visible yet");
         return;
      }
   }

   item->mState.set(Item::Selected, false);
   
   for (S32 i = 0; i < mSelectedItems.size(); i++) 
   {
      if (mSelectedItems[i] == item) 
      {
         mSelectedItems.erase(i);
         break;
      }
   }
}

void GuiTreeViewCtrl::addSelection(S32 itemId)
{
   if (mDebug)
      Con::printf("addSelection called");

   Item * item = getItem(itemId);

   if(!item)
   {
      // maybe what we were passed wasn't an item id but an object id.
      for (S32 i = 0; i <mItems.size(); i++)
      {
         if (mItems[i] != 0)
         {
            if (mItems[i]->isInspectorData())
            {
               if (mItems[i]->getObject()->getId() == itemId)
               {
                  item = mItems[i];
                  //looks like it is. check to see if it is on the list
                  bool alreadySelected = false;
                  Vector<Item *>::iterator i;
                  for(i = mSelectedItems.begin(); i != mSelectedItems.end(); i++)
                  {
                     if (*(i) == item)
                     {
                        //already a selected item which means this call should be ignored
                        alreadySelected = true;
                        return;
                     }
                  }
                  break;
               }
            }
         }
      }

      if (!item)
      {
         // Do we want to allow more than one selected item?
         if( !mMultipleSelections )
            clearSelection();

         //Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::addSelection: invalid item id! Perhaps it isn't visible yet.");
         mSelected.push_front(itemId);
         return;
      }
   }
   else
   {
      // Do we want to allow more than one selected item?
      if( !mMultipleSelections )
         clearSelection();

      // regardless of whether we found an item, we keep track of the Id that was passed
      // as the item may simply not have been created/visible yet.
      mSelected.push_front(itemId);
   }

   item->mState.set(Item::Selected, true);

   // Also make it so we can see it if we didn't already.
   scrollVisible(item);

⌨️ 快捷键说明

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