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

📄 guiinspector.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:

   mIsExpanded          = true;
   mIsAnimating         = false;
   mCollapsing          = true;
   mAnimateDestHeight   = mBarWidth.y;
   mAnimateStep         = 1;
   mChildHeight         = 32;
   mCaption             = StringTable->insert(groupName);
   mTarget              = target;
   mParent              = parent;
}

GuiInspectorGroup::~GuiInspectorGroup()
{
   if( !mChildren.empty() )
   {
      Vector<GuiInspectorField*>::iterator i = mChildren.begin();
      for( ; i != mChildren.end(); i++ );
         
   } 
}

//////////////////////////////////////////////////////////////////////////
// Persistence 
//////////////////////////////////////////////////////////////////////////
void GuiInspectorGroup::initPersistFields()
{
   Parent::initPersistFields();

   addField("Caption", TypeString, Offset(mCaption, GuiInspectorGroup));
}

//////////////////////////////////////////////////////////////////////////
// Scene Events
//////////////////////////////////////////////////////////////////////////
bool GuiInspectorGroup::onAdd()
{
   if( !Parent::onAdd() )
      return false;

   // Create our field stack control
   mStack = new GuiStackControl();
   if( !mStack )
      return false;

   addObject( mStack );
   mStack->setField( "padding", "1.0" );
   mStack->resize( mBarWidth + Point2I(1,1), mBounds.extent - ( mBarWidth + Point2I(1,1) ) );

   inspectGroup();

   return true;
}


//////////////////////////////////////////////////////////////////////////
// Mouse Events
//////////////////////////////////////////////////////////////////////////
void GuiInspectorGroup::onMouseDown( const GuiEvent &event )
{
   // Calculate Group Caption Rect ( Clip rect within 4 units of the outer bounds so we don't render into border )
   RectI captionRect( Point2I(mBarWidth.x, 0), Point2I( mBounds.extent.x - 4, mBarWidth.y  ) );
   // Calculate Y Offset to center vertically the caption
   U32 captionYOffset = mFloor( (F32)( captionRect.extent.y - mProfile->mFont->getHeight() ) / 2 );
   // Calculate Expand/Collapse Button Rect
   RectI toggleRect( Point2I( captionYOffset, captionYOffset ), mBarWidth - Point2I(captionYOffset * 2, captionYOffset * 2) );
   toggleRect.inset( 1,1 );

   if( toggleRect.pointInRect( globalToLocalCoord( event.mousePoint ) ) && !mIsAnimating )
   {
      if( !mIsExpanded )
         animateTo( getExpandedHeight() );
      else
         animateTo( mBarWidth.y );
   }
}

//////////////////////////////////////////////////////////////////////////
// Control Sizing Helpers
//////////////////////////////////////////////////////////////////////////
S32 GuiInspectorGroup::getExpandedHeight()
{
   if( mStack != NULL && mStack->getCount() != 0 )
      return mStack->getHeight() + mBarWidth.y + 1;
   return mBarWidth.y;
}

void GuiInspectorGroup::resize( const Point2I &newPosition, const Point2I &newExtent )
{
   Parent::resize( newPosition, newExtent );
   
   if( mStack != NULL && !mIsAnimating && mIsExpanded )
      mStack->setExtent( mBounds.extent - ( mBarWidth + Point2I(1,1) ) );
}

//////////////////////////////////////////////////////////////////////////
// Control Sizing Animation Functions
//////////////////////////////////////////////////////////////////////////
void GuiInspectorGroup::animateTo( S32 height )
{
   // We do nothing if we're already animating
   if( mIsAnimating )
      return;

   bool collapsing = (bool)( mBounds.extent.y > height );

   // If we're already at the destination height, bail
   if( mBounds.extent.y >= height && !collapsing )
      return;

   // If we're already at the destination height, bail
   if( mBounds.extent.y <= height && collapsing )
      return;

   // Set destination height
   mAnimateDestHeight = height;

   // Set Animation Mode
   mCollapsing = collapsing;

   // Set Animation Step (Increment)
   if( collapsing )
      mAnimateStep = mFloor( (F32)( mBounds.extent.y - height ) / 2 );
   else
      mAnimateStep = mFloor( (F32)( height - mBounds.extent.y ) / 2 );

   // Start our animation
   mIsAnimating = true;

}

void GuiInspectorGroup::processTick()
{
   // We do nothing here if we're NOT animating
   if( !mIsAnimating )
      return;

   // We're collapsing ourself down (Hiding our contents)
   if( mCollapsing )
   {
      if( mBounds.extent.y < mAnimateDestHeight )
         mBounds.extent.y = mAnimateDestHeight;
      else if( ( mBounds.extent.y - mAnimateStep ) < mAnimateDestHeight )
         mBounds.extent.y = mAnimateDestHeight;

      if( mBounds.extent.y == mAnimateDestHeight )
         mIsAnimating = false;
      else
         mBounds.extent.y -= mAnimateStep;

      if( !mIsAnimating )
         mIsExpanded = false;
   }
   else // We're expanding ourself (Showing our contents)
   {
      if( mBounds.extent.y > mAnimateDestHeight )
         mBounds.extent.y = mAnimateDestHeight;
      else if( ( mBounds.extent.y + mAnimateStep ) > mAnimateDestHeight )
         mBounds.extent.y = mAnimateDestHeight;

      if( mBounds.extent.y == mAnimateDestHeight )
         mIsAnimating = false;
      else
         mBounds.extent.y += mAnimateStep;

      if( !mIsAnimating )
         mIsExpanded = true;
   }

   GuiControl* parent = getParent();
   if( parent )
      parent->childResized( this );
}

//////////////////////////////////////////////////////////////////////////
// Control Rendering
//////////////////////////////////////////////////////////////////////////
void GuiInspectorGroup::onRender(Point2I offset, const RectI &updateRect)
{
   //////////////////////////////////////////////////////////////////////////
   // Calculate Necessary Rendering Rectangles
   //////////////////////////////////////////////////////////////////////////
  
   // Calculate actual world bounds for rendering
   RectI worldBounds( offset, mBounds.extent );
   // Calculate rendering rectangle for the groups content
   RectI contentRect( offset + mBarWidth, mBounds.extent - ( mBarWidth + Point2I(1,1) ));
   // Calculate Group Caption Rect ( Clip rect within 4 units of the outer bounds so we don't render into border )
   RectI captionRect( offset + Point2I(mBarWidth.x, 0), Point2I( mBounds.extent.x - ( mBarWidth.x + 4 ), mBarWidth.y ) );
   // Calculate Y Offset to center vertically the caption
   U32 captionYOffset = mFloor( (F32)( captionRect.extent.y - mProfile->mFont->getHeight() ) / 2 );
   // Calculate Expand/Collapse Button Rect
   RectI toggleRect( offset + Point2I( captionYOffset, captionYOffset ), mBarWidth - Point2I(captionYOffset * 2, captionYOffset * 2) );
         toggleRect.inset( 1,1 );
 
    // Draw Border
   renderFilledBorder( worldBounds, mProfile );
   
   // Draw Content Background
   if( mIsExpanded || ( mIsAnimating && !mCollapsing ) )
      dglDrawRectFill( contentRect, ColorI(255,255,255) );

   // Backup Bitmap Modulation
   ColorI currColor;
   dglGetBitmapModulation( &currColor );

   dglSetBitmapModulation( mProfile->mFontColor );
   // Draw Caption ( Vertically Centered )
   dglDrawText( mProfile->mFont, Point2I( captionRect.point.x, captionRect.point.y + captionYOffset ), mCaption, &mProfile->mFontColor );

   dglSetBitmapModulation( currColor );


   // Draw Expand/Collapse Button
   if( mIsExpanded )
      renderFilledBorder( toggleRect, mProfile->mFillColorNA, mProfile->mBorderColorNA );
   else
      renderFilledBorder( toggleRect, mProfile->mBorderColorNA, mProfile->mFillColorNA );

   Parent::onRender( offset, updateRect );
}

GuiInspectorField* GuiInspectorGroup::constructField( S32 fieldType )
{
   ConsoleBaseType *cbt = ConsoleBaseType::getType(fieldType);
   AssertFatal(cbt, "GuiInspectorGroup::constructField - could not resolve field type!");

   // Alright, is it a datablock?
   if(cbt->isDatablock())
   {
      // This is fairly straightforward to deal with.
      GuiInspectorDatablockField *dbFieldClass = new GuiInspectorDatablockField( cbt->getTypeClassName() );
      if( dbFieldClass != NULL )
      {
         // return our new datablock field with correct datablock type enumeration info
         return dbFieldClass;
      }
   }

   // Nope, not a datablock. So maybe it has a valid inspector field override we can use?
   if(!cbt->getInspectorFieldType())
      // Nothing, so bail.
      return NULL;

   // Otherwise try to make it!
   ConsoleObject *co = create(cbt->getInspectorFieldType());
   GuiInspectorField *gif = dynamic_cast<GuiInspectorField*>(co);

   if(!gif)
   {
      // Wasn't appropriate type, bail.
      delete co;
      return NULL;
   }

   return gif;
}

GuiInspectorField *GuiInspectorGroup::findField( StringTableEntry fieldName )
{
   // If we don't have any field children we can't very well find one then can we?
   if( mChildren.empty() )
      return NULL;

   Vector<GuiInspectorField*>::iterator i = mChildren.begin();

   for( ; i != mChildren.end(); i++ )
   {
      if( (*i)->getFieldName() != NULL && dStricmp( (*i)->getFieldName(), fieldName ) == 0 )
         return (*i);
   }

   return NULL;
}

bool GuiInspectorGroup::inspectGroup()
{
   // We can't inspect a group without a target!
   if( !mTarget )
      return false;

   bool bNoGroup = false;

   // Un-grouped fields are all sorted into the 'general' group
   if ( dStricmp( mCaption, "General" ) == 0 )
      bNoGroup = true;

   AbstractClassRep::FieldList &fieldList = mTarget->getModifiableFieldList();
   AbstractClassRep::FieldList::iterator itr;

   bool bGrabItems = false;
   bool bNewItems = false;

   for(itr = fieldList.begin(); itr != fieldList.end(); itr++)
   {
      if( itr->type == AbstractClassRep::StartGroupFieldType )
      {
         // If we're dealing with general fields, always set grabItems to true (to skip them)
         if( bNoGroup == true )
            bGrabItems = true;
         else if( itr->pGroupname != NULL && dStricmp( itr->pGroupname, mCaption ) == 0 )
            bGrabItems = true;
         continue;
      }
      else if ( itr->type == AbstractClassRep::EndGroupFieldType )
      {
         // If we're dealing with general fields, always set grabItems to false (to grab them)
         if( bNoGroup == true )
            bGrabItems = false;
         else if( itr->pGroupname != NULL && dStricmp( itr->pGroupname, mCaption ) == 0 )
            bGrabItems = false;
         continue;
      }

      if( ( bGrabItems == true || ( bNoGroup == true && bGrabItems == false ) ) && itr->type != AbstractClassRep::DepricatedFieldType )
      {
         if( bNoGroup == true && bGrabItems == true )
            continue; 

         // If the field already exists, just update it
         GuiInspectorField *field = findField( itr->pFieldname );
         if( field != NULL )
         {
            field->updateValue( field->getData() );
            continue;
         }

         bNewItems = true;
         
         field = constructField( itr->type );
         if( field == NULL )
            field = new GuiInspectorField( this, mTarget, itr );
         else
         {
            field->setTarget( mTarget );
            field->setParent( this );
            field->setField( itr );
         }
         
         field->registerObject();
         mChildren.push_back( field );
         mStack->addObject( field );
      }
   }

   // If we've no new items, there's no need to resize anything!
   if( bNewItems == false && !mChildren.empty() )
      return true;

   if( mIsExpanded && getHeight() != getExpandedHeight() )
      setHeight( getExpandedHeight() );

   if( mChildren.empty() && getHeight() != mBarWidth.y )
      setHeight( mBarWidth.y );

   setUpdate();

   return true;
}

//////////////////////////////////////////////////////////////////////////
// GuiInspectorDynamicGroup - inspectGroup override
//////////////////////////////////////////////////////////////////////////
bool GuiInspectorDynamicGroup::inspectGroup()
{
   // We can't inspect a group without a target!
   if( !mTarget )
      return false;

   // Clearing the fields and recreating them will more than likely be more
   // efficient than looking up existent fields, updating them, and then iterating
   // over existent fields and making sure they still exist, if not, deleting them.
   clearFields();

   // Then populate with fields
   SimFieldDictionary * fieldDictionary = mTarget->getFieldDictionary();
   for(SimFieldDictionaryIterator ditr(fieldDictionary); *ditr; ++ditr)
   {
      SimFieldDictionary::Entry * entry = (*ditr);

      GuiInspectorField *field = new GuiInspectorDynamicField( this, mTarget, entry );
      if( field != NULL )
      {
         field->registerObject();
         mChildren.push_back( field );
         mStack->addObject( field );

      }
   }

   if( mIsExpanded && getHeight() != getExpandedHeight() )
      setHeight( getExpandedHeight() );

   setUpdate();

   return true;
}

void GuiInspectorDynamicGroup::clearFields()
{
   // If we have no groups, it couldn't possibly exist
   if( mChildren.empty() )
      return;

   // Attempt to find it in the group list
   Vector<GuiInspectorField*>::iterator i = mChildren.begin();

   for( ; i != mChildren.end(); i++ )
      if( (*i)->isProperlyAdded() )
         (*i)->deleteObject();

   mChildren.clear();
}

SimFieldDictionary::Entry* GuiInspectorDynamicGroup::findDynamicFieldInDictionary( StringTableEntry fieldName )
{
   if( !mTarget )
      return false;

   SimFieldDictionary * fieldDictionary = mTarget->getFieldDictionary();

   for(SimFieldDictionaryIterator ditr(fieldDictionary); *ditr; ++ditr)
   {
      SimFieldDictionary::Entry * entry = (*ditr);
      
      if( dStricmp( entry->slotName, fieldName ) == 0 )
         return entry;

⌨️ 快捷键说明

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