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

📄 guiinspector.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "gui/editor/guiInspector.h"
#include "core/frameAllocator.h"

//////////////////////////////////////////////////////////////////////////
// GuiInspector
//////////////////////////////////////////////////////////////////////////
// The GuiInspector Control houses the body of the inspector.
// It is not exposed as a conobject because it merely does the grunt work
// and is only meant to be used when housed by a scroll control.  Therefore
// the GuiInspector control is a scroll control that creates it's own 
// content.  That content being of course, the GuiInspector control.
IMPLEMENT_CONOBJECT(GuiInspector);

GuiInspector::GuiInspector()
{
   mGroups.clear();
   mTarget = NULL;
}

GuiInspector::~GuiInspector()
{
   clearGroups();
}

bool GuiInspector::onAdd()
{
   if( !Parent::onAdd() )
      return false;

   return true;
}

//////////////////////////////////////////////////////////////////////////
// Handle Parent Sizing (We constrain ourself to our parents width)
//////////////////////////////////////////////////////////////////////////
void GuiInspector::parentResized(const Point2I &oldParentExtent, const Point2I &newParentExtent)
{
   GuiControl *parent = getParent();
   if( parent && dynamic_cast<GuiScrollCtrl*>(parent) != NULL )
   {
      GuiScrollCtrl *scroll = dynamic_cast<GuiScrollCtrl*>(parent);
      setWidth( ( newParentExtent.x - ( scroll->scrollBarThickness() + 4  ) ) );
   }
   else
      Parent::parentResized(oldParentExtent,newParentExtent);
}

bool GuiInspector::findExistentGroup( StringTableEntry groupName )
{
   // If we have no groups, it couldn't possibly exist
   if( mGroups.empty() )
      return false;

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

   for( ; i != mGroups.end(); i++ )
   {
      if( dStricmp( (*i)->getGroupName(), groupName ) == 0 )
         return true;
   }

   return false;
}

void GuiInspector::clearGroups()
{
   // If we have no groups, there's nothing to clear!
   if( mGroups.empty() )
      return;

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

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

   mGroups.clear();
}

void GuiInspector::inspectObject( SimObject *object )
{
   // If our target is the same as our current target, just update the groups.
   if( mTarget == object )
   {
      Vector<GuiInspectorGroup*>::iterator i = mGroups.begin();
      for ( ; i != mGroups.end(); i++ )
         (*i)->inspectGroup();
      return;
   }

   // Clear our current groups
   clearGroups();

   // Set Target
   mTarget = object;

   // Always create the 'general' group (for un-grouped fields)
   GuiInspectorGroup* general = new GuiInspectorGroup( mTarget, "General", this );
   if( general != NULL )
   {
      general->registerObject();
      mGroups.push_back( general );
      addObject( general );
   }

   // Grab this objects field list
   AbstractClassRep::FieldList &fieldList = mTarget->getModifiableFieldList();
   AbstractClassRep::FieldList::iterator itr;

   // Iterate through, identifying the groups and create necessary GuiInspectorGroups
   for(itr = fieldList.begin(); itr != fieldList.end(); itr++)
   {
      if(itr->type == AbstractClassRep::StartGroupFieldType && !findExistentGroup( itr->pGroupname ) )
      {
         GuiInspectorGroup *group = new GuiInspectorGroup( mTarget, itr->pGroupname, this );
         if( group != NULL )
         {
            group->registerObject();
            mGroups.push_back( group );
            addObject( group );
         }            
      }
   }

   // Deal with dynamic fields
   GuiInspectorGroup *dynGroup = new GuiInspectorDynamicGroup( mTarget, "Dynamic Fields", this);
   if( dynGroup != NULL )
   {
      dynGroup->registerObject();
      mGroups.push_back( dynGroup );
      addObject( dynGroup );
   }

   // If the general group is still empty at this point, kill it.
   for(S32 i=0; i<mGroups.size(); i++)
   {
      if(mGroups[i] == general && general->mStack->size() == 0)
      {
         mGroups.erase(i);
         general->deleteObject();
         updatePanes();
      }
   }
}

ConsoleMethod( GuiInspector, inspect, void, 3, 3, "Inspect(Object)")
{
   SimObject * target = Sim::findObject(argv[2]);
   if(!target)
   {
      if(dAtoi(argv[2]) > 0)
         Con::warnf("%s::inspect(): invalid object: %s", argv[0], argv[2]);
      
      object->clearGroups();
      return;
   }

   object->inspectObject(target);
}

void GuiInspector::setName( StringTableEntry newName )
{
   if( mTarget == NULL )
   {
      Con::warnf("GuiInspector::setName - No Target!" );
      return;
   }

   StringTableEntry name = StringTable->insert(newName);

   // Only assign a new name if we provide one
   mTarget->assignName(name);

}

ConsoleMethod( GuiInspector, setName, void, 3, 3, "setName(NewObjectName)")
{
   object->setName(argv[2]);
}


//////////////////////////////////////////////////////////////////////////
// GuiInspectorField
//////////////////////////////////////////////////////////////////////////
// The GuiInspectorField control is a representation of a single abstract
// field for a given ConsoleObject derived object.  It handles creation
// getting and setting of it's fields data and editing control.  
//
// Creation of custom edit controls is done through this class and is
// dependent upon the dynamic console type, which may be defined to be
// custom for different types.
//
// Note : GuiInspectorField controls must have a GuiInspectorGroup as their
//        parent.  
IMPLEMENT_CONOBJECT(GuiInspectorField);

// Caption width is in percentage of total width
S32 GuiInspectorField::smCaptionWidth = 35;

GuiInspectorField::GuiInspectorField( GuiInspectorGroup* parent, SimObjectPtr<SimObject> target, AbstractClassRep::Field* field )
{
   if( field != NULL )
      mCaption    = StringTable->insert( field->pFieldname );
   else
      mCaption    = StringTable->insert( "" );

   mParent     = parent;
   mTarget     = target;
   mField      = field;
   mBounds.set(0,0,100,20);

}

GuiInspectorField::GuiInspectorField()
{
   mCaption       = StringTable->insert( "" );
   mParent        = NULL;
   mTarget        = NULL;
   mField         = NULL;
   mBounds.set(0,0,100,20);
}

GuiInspectorField::~GuiInspectorField()
{
}

//////////////////////////////////////////////////////////////////////////
// Get/Set Data Functions
//////////////////////////////////////////////////////////////////////////
void GuiInspectorField::setData( StringTableEntry data )
{
   if( mField == NULL || mTarget == NULL )
      return;

   mTarget->inspectPreApply();

   mTarget->setDataField( getFieldName(), NULL, data );

   // Force our edit to update
   updateValue( data );

   mTarget->inspectPostApply();
}

StringTableEntry GuiInspectorField::getData()
{
   if( mField == NULL || mTarget == NULL )
      return "";

   return mTarget->getDataField( getFieldName(), NULL );
}

//////////////////////////////////////////////////////////////////////////
// Overrideables for custom edit fields
//////////////////////////////////////////////////////////////////////////
GuiControl* GuiInspectorField::constructEditControl()
{
   GuiControl* retCtrl = new GuiTextEditCtrl();
   
   // If we couldn't construct the control, bail!
   if( retCtrl == NULL )
      return retCtrl;

   // Let's make it look pretty.
   retCtrl->setField( "profile", "GuiInspectorTextEditProfile" );

   // Don't forget to register ourselves
   registerEditControl( retCtrl );

   char szBuffer[512];
   dSprintf( szBuffer, 512, "%d.apply(%d.getText());",getId(), retCtrl->getId() );
   retCtrl->setField("AltCommand", szBuffer );
   retCtrl->setField("Validate", szBuffer );


   return retCtrl;
}

void GuiInspectorField::registerEditControl( GuiControl *ctrl )
{
   char szName[512];
   dSprintf( szName, 512, "IE_%s_%d_Field", ctrl->getClassName(), mTarget->getId());

   // Register the object
   ctrl->registerObject( szName );
}

void GuiInspectorField::onRender(Point2I offset, const RectI &updateRect)
{
   RectI worldRect( offset, mBounds.extent );
   // Calculate Caption Rect
   RectI captionRect( offset , Point2I( mFloor( mBounds.extent.x * (F32)( (F32)GuiInspectorField::smCaptionWidth / 100.0 ) ), mBounds.extent.y ) );
   // Calculate Edit Field Rect
   RectI editFieldRect( offset + Point2I( captionRect.extent.x + 1, 0 ) , Point2I( mBounds.extent.x - ( captionRect.extent.x + 5 ) , mBounds.extent.y ) );

   // Calculate Y Offset to center vertically the caption
   U32 captionYOffset = mFloor( (F32)( captionRect.extent.y - mProfile->mFont->getHeight() ) / 2 );

   renderFilledBorder( captionRect, mProfile->mBorderColor, mProfile->mFillColor );
   renderFilledBorder( editFieldRect, mProfile->mBorderColor, mProfile->mFillColor );


   RectI clipRect = dglGetClipRect();

   if( clipRect.intersect( captionRect ) )
   {
      // Backup Bitmap Modulation
      ColorI currColor;
      dglGetBitmapModulation( &currColor );

      dglSetBitmapModulation( mProfile->mFontColor );

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

      dglSetBitmapModulation( currColor );

      dglSetClipRect( clipRect );
   }

   Parent::onRender( offset, updateRect );
}

bool GuiInspectorField::onAdd()
{
   if( !Parent::onAdd() )
      return false;

   mEdit = constructEditControl();

   if( mEdit == NULL )
      return false;

   // Add our edit as a child
   addObject( mEdit );

   // Calculate Caption Rect
   RectI captionRect( mBounds.point , Point2I( mFloor( mBounds.extent.x * (F32)( (F32)GuiInspectorField::smCaptionWidth / 100.0 ) ), mBounds.extent.y ) );

   // Calculate Edit Field Rect
   RectI editFieldRect( Point2I( captionRect.extent.x + 1, 0 ) , Point2I( mBounds.extent.x - ( captionRect.extent.x + 5 ) , mBounds.extent.y ) );

   // Resize to fit properly in allotted space
   mEdit->resize( editFieldRect.point, editFieldRect.extent );

   // Prefer GuiInspectorFieldProfile 
   SimObject *profilePtr = Sim::findObject("GuiInspectorFieldProfile");
   if( profilePtr != NULL )
      setControlProfile( dynamic_cast<GuiControlProfile*>(profilePtr) );

   // Force our editField to set it's value
   updateValue( getData() );

   return true;
}

void GuiInspectorField::updateValue( StringTableEntry newValue )
{
   GuiTextEditCtrl *ctrl = dynamic_cast<GuiTextEditCtrl*>( mEdit );
   if( ctrl != NULL )
      ctrl->setText( newValue );
}

ConsoleMethod( GuiInspectorField, apply, void, 3,3, "apply(newValue);" )
{
   object->setData( argv[2] );
}

void GuiInspectorField::resize( const Point2I &newPosition, const Point2I &newExtent )
{
   Parent::resize( newPosition, newExtent );

   if( mEdit != NULL )
   {
      // Calculate Caption Rect
      RectI captionRect( mBounds.point , Point2I( mFloor( mBounds.extent.x * (F32)( (F32)GuiInspectorField::smCaptionWidth / 100.0 ) ), mBounds.extent.y ) );

      // Calculate Edit Field Rect
      RectI editFieldRect( Point2I( captionRect.extent.x + 1, 0 ) , Point2I( mBounds.extent.x - ( captionRect.extent.x + 5 ) , mBounds.extent.y ) );

      mEdit->resize( editFieldRect.point, editFieldRect.extent );
   }
}

//////////////////////////////////////////////////////////////////////////
// GuiInspectorGroup
//////////////////////////////////////////////////////////////////////////
//
// The GuiInspectorGroup control is a helper control that the inspector
// makes use of which houses a collapsible pane type control for separating
// inspected objects fields into groups.  The content of the inspector is 
// made up of zero or more GuiInspectorGroup controls inside of a GuiStackControl
//
//
//
IMPLEMENT_CONOBJECT(GuiInspectorGroup);

GuiInspectorGroup::GuiInspectorGroup()
{
   mBounds.set(0,0,200,20);
   mBarWidth.set(18,18);

   mChildren.clear();

   mCaption             = StringTable->insert("");
   mTarget              = NULL;
   mParent              = NULL;
   mIsExpanded          = true;
   mIsAnimating         = false;
   mCollapsing          = true;
   mAnimateDestHeight   = mBarWidth.y;
   mAnimateStep         = 1;
}

GuiInspectorGroup::GuiInspectorGroup( SimObjectPtr<SimObject> target, StringTableEntry groupName, SimObjectPtr<GuiInspector> parent )
{
   mBounds.set(0,0,200,20);
   mBarWidth.set(18,18);

   mChildren.clear();

⌨️ 快捷键说明

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