1486 lines
35 KiB
C++
1486 lines
35 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2002.
|
|
// -------------------------------------------------------------------------
|
|
// File name: propertyitem.cpp
|
|
// Version: v1.00
|
|
// Created: 5/6/2002 by Timur.
|
|
// Compilers: Visual Studio.NET
|
|
// Description:
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
#include "propertyitem.h"
|
|
#include "PropertyCtrl.h"
|
|
#include "InPlaceEdit.h"
|
|
#include "InPlaceComboBox.h"
|
|
#include "InPlaceButton.h"
|
|
|
|
#include "EquipPackDialog.h"
|
|
#include "SelectSoundPresetDlg.h"
|
|
#include "SelectEAXPresetDlg.h"
|
|
|
|
#include "ShaderEnum.h"
|
|
#include "ShadersDialog.h"
|
|
|
|
// AI
|
|
#include "AIDialog.h"
|
|
#include "AICharactersDialog.h"
|
|
#include "AIAnchorsDialog.h"
|
|
#include "AI\AIBehaviorLibrary.h"
|
|
#include "AI\AIGoalLibrary.h"
|
|
|
|
#include <ITimer.h>
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define CMD_ADD_CHILD_ITEM 100
|
|
#define CMD_ADD_ITEM 101
|
|
#define CMD_DELETE_ITEM 102
|
|
|
|
#define BUTTON_WIDTH 16
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! Undo object for Variable in property control..
|
|
class CUndoVariableChange : public IUndoObject
|
|
{
|
|
public:
|
|
CUndoVariableChange( IVariable *var,const char *undoDescription )
|
|
{
|
|
// Stores the current state of this object.
|
|
assert( var != 0 );
|
|
m_undoDescription = undoDescription;
|
|
m_var = var;
|
|
m_undo = m_var->Clone(false);
|
|
}
|
|
protected:
|
|
virtual int GetSize() {
|
|
int size = sizeof(*this);
|
|
//if (m_var)
|
|
//size += m_var->GetSize();
|
|
if (m_undo)
|
|
size += m_undo->GetSize();
|
|
if (m_redo)
|
|
size += m_redo->GetSize();
|
|
return size;
|
|
}
|
|
virtual const char* GetDescription() { return m_undoDescription; };
|
|
virtual void Undo( bool bUndo )
|
|
{
|
|
if (bUndo)
|
|
{
|
|
m_redo = m_var->Clone(false);
|
|
}
|
|
m_var->CopyValue( m_undo );
|
|
}
|
|
virtual void Redo()
|
|
{
|
|
if (m_redo)
|
|
m_var->CopyValue(m_redo);
|
|
}
|
|
|
|
private:
|
|
CString m_undoDescription;
|
|
TSmartPtr<IVariable> m_undo;
|
|
TSmartPtr<IVariable> m_redo;
|
|
TSmartPtr<IVariable> m_var;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
namespace {
|
|
struct {
|
|
int dataType;
|
|
const char *name;
|
|
PropertyType type;
|
|
int image;
|
|
} s_propertyTypeNames[] =
|
|
{
|
|
{ IVariable::DT_SIMPLE,"Bool",ePropertyBool,2 },
|
|
{ IVariable::DT_SIMPLE,"Int",ePropertyInt,0 },
|
|
{ IVariable::DT_SIMPLE,"Float",ePropertyFloat,0 },
|
|
{ IVariable::DT_SIMPLE,"Vector",ePropertyVector,10 },
|
|
{ IVariable::DT_SIMPLE,"String",ePropertyString,3 },
|
|
{ IVariable::DT_PERCENT,"Float",ePropertyInt,13 },
|
|
{ IVariable::DT_COLOR,"Color",ePropertyColor,1 },
|
|
{ IVariable::DT_ANGLE,"Angle",ePropertyAngle,0 },
|
|
{ IVariable::DT_FILE,"File",ePropertyFile,7 },
|
|
{ IVariable::DT_TEXTURE,"Texture",ePropertyTexture,4 },
|
|
{ IVariable::DT_SOUND,"Sound",ePropertySound,6 },
|
|
{ IVariable::DT_OBJECT,"Model",ePropertyModel,5 },
|
|
{ IVariable::DT_SIMPLE,"Selection",ePropertySelection,-1 },
|
|
{ IVariable::DT_SIMPLE,"List",ePropertyList,-1 },
|
|
{ IVariable::DT_SHADER,"Shader",ePropertyShader,9 },
|
|
{ IVariable::DT_MATERIAL,"Material",ePropertyMaterial,9 },
|
|
{ IVariable::DT_AI_BEHAVIOR,"AIBehavior",ePropertyAiBehavior,8 },
|
|
{ IVariable::DT_AI_ANCHOR,"AIAnchor",ePropertyAiAnchor,8 },
|
|
{ IVariable::DT_AI_CHARACTER,"AICharacter",ePropertyAiCharacter,8 },
|
|
{ IVariable::DT_EQUIP,"Equip",ePropertyEquip,11 },
|
|
{ IVariable::DT_SOUNDPRESET,"SoundPreset",ePropertySoundPreset,11 },
|
|
{ IVariable::DT_EAXPRESET,"EAXPreset",ePropertyEAXPreset,11 },
|
|
{ IVariable::DT_LOCAL_STRING,"LocalString",ePropertyLocalString,3 },
|
|
};
|
|
static int NumPropertyTypes = sizeof(s_propertyTypeNames)/sizeof(s_propertyTypeNames[0]);
|
|
|
|
const char* DISPLAY_NAME_ATTR = "DisplayName";
|
|
const char* VALUE_ATTR = "Value";
|
|
const char* TYPE_ATTR = "Type";
|
|
const char* TIP_ATTR = "Tip";
|
|
const char* FILEFILTER_ATTR = "FileFilters";
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CPropertyItem implementation.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CPropertyItem::CPropertyItem( CPropertyCtrl* pCtrl )
|
|
{
|
|
m_propertyCtrl = pCtrl;
|
|
m_parent = 0;
|
|
m_bExpandable = false;
|
|
m_bExpanded = false;
|
|
m_bSelected = false;
|
|
m_bNoCategory = false;
|
|
|
|
m_cNumber = 0;
|
|
m_cEdit = 0;
|
|
m_cCombo = 0;
|
|
m_cButton = 0;
|
|
m_image = -1;
|
|
m_bIgnoreChildsUpdate = false;
|
|
m_value = "";
|
|
m_type = ePropertyInvalid;
|
|
|
|
m_modified = false;
|
|
m_lastModified = 0;
|
|
m_valueMultiplier = 1;
|
|
}
|
|
|
|
CPropertyItem::~CPropertyItem()
|
|
{
|
|
if (m_pVariable)
|
|
ReleaseVariable();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SetXmlNode( XmlNodeRef &node )
|
|
{
|
|
m_node = node;
|
|
// No Undo while just creating properties.
|
|
//GetIEditor()->SuspendUndo();
|
|
ParseXmlNode();
|
|
//GetIEditor()->ResumeUndo();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::ParseXmlNode( bool bRecursive/* =true */)
|
|
{
|
|
if (!m_node->getAttr( DISPLAY_NAME_ATTR,m_name ))
|
|
{
|
|
m_name = m_node->getTag();
|
|
}
|
|
|
|
CString value;
|
|
bool bHasValue=m_node->getAttr( VALUE_ATTR,value );
|
|
|
|
CString type;
|
|
m_node->getAttr( TYPE_ATTR,type);
|
|
|
|
m_tip = "";
|
|
m_node->getAttr( TIP_ATTR,m_tip );
|
|
|
|
m_image = -1;
|
|
m_type = ePropertyInvalid;
|
|
for (int i = 0; i < NumPropertyTypes; i++)
|
|
{
|
|
if (stricmp(type,s_propertyTypeNames[i].name) == 0)
|
|
{
|
|
m_type = s_propertyTypeNames[i].type;
|
|
m_image = s_propertyTypeNames[i].image;
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_rangeMin = -10000;
|
|
m_rangeMax = 10000;
|
|
m_iInternalPrecision=2; // m.m.
|
|
if (m_type == ePropertyFloat || m_type == ePropertyInt)
|
|
{
|
|
m_node->getAttr( "Min",m_rangeMin );
|
|
m_node->getAttr( "Max",m_rangeMax );
|
|
m_node->getAttr( "Precision",m_iInternalPrecision ); // m.m.
|
|
}
|
|
|
|
if (bHasValue)
|
|
SetValue( value );
|
|
|
|
m_bNoCategory = false;
|
|
|
|
if (m_type == ePropertyVector)
|
|
{
|
|
bRecursive = false;
|
|
|
|
m_childs.clear();
|
|
Vec3 vec;
|
|
m_node->getAttr( VALUE_ATTR,vec );
|
|
// Create 3 sub elements.
|
|
XmlNodeRef x = m_node->createNode( "X" );
|
|
XmlNodeRef y = m_node->createNode( "Y" );
|
|
XmlNodeRef z = m_node->createNode( "Z" );
|
|
x->setAttr( TYPE_ATTR,"Float" );
|
|
y->setAttr( TYPE_ATTR,"Float" );
|
|
z->setAttr( TYPE_ATTR,"Float" );
|
|
|
|
x->setAttr( VALUE_ATTR,vec.x );
|
|
y->setAttr( VALUE_ATTR,vec.y );
|
|
z->setAttr( VALUE_ATTR,vec.z );
|
|
|
|
// Start ignoring all updates comming from childs. (Initializing childs).
|
|
m_bIgnoreChildsUpdate = true;
|
|
|
|
CPropertyItem *itemX = new CPropertyItem( m_propertyCtrl );
|
|
itemX->SetXmlNode( x );
|
|
AddChild( itemX );
|
|
|
|
CPropertyItem *itemY = new CPropertyItem( m_propertyCtrl );
|
|
itemY->SetXmlNode( y );
|
|
AddChild( itemY );
|
|
|
|
CPropertyItem *itemZ = new CPropertyItem( m_propertyCtrl );
|
|
itemZ->SetXmlNode( z );
|
|
AddChild( itemZ );
|
|
|
|
m_bNoCategory = true;
|
|
m_bExpandable = true;
|
|
|
|
m_bIgnoreChildsUpdate = false;
|
|
}
|
|
else if (bRecursive)
|
|
{
|
|
// If recursive and not vector.
|
|
|
|
m_bExpandable = false;
|
|
// Create sub-nodes.
|
|
for (i=0; i < m_node->getChildCount(); i++)
|
|
{
|
|
m_bIgnoreChildsUpdate = true;
|
|
|
|
XmlNodeRef child = m_node->getChild(i);
|
|
CPropertyItem *item = new CPropertyItem( m_propertyCtrl );
|
|
item->SetXmlNode( m_node->getChild(i) );
|
|
AddChild( item );
|
|
m_bExpandable = true;
|
|
|
|
m_bIgnoreChildsUpdate = false;
|
|
}
|
|
}
|
|
m_modified = false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SetVariable( IVariable *var )
|
|
{
|
|
// Release previous variable.
|
|
if (m_pVariable)
|
|
ReleaseVariable();
|
|
|
|
m_pVariable = var;
|
|
assert( m_pVariable != NULL );
|
|
|
|
m_pVariable->AddOnSetCallback( functor(*this,&CPropertyItem::OnVariableChange) );
|
|
|
|
m_tip = "";
|
|
m_name = m_pVariable->GetHumanName();
|
|
|
|
int dataType = m_pVariable->GetDataType();
|
|
|
|
m_image = -1;
|
|
m_type = ePropertyInvalid;
|
|
int i;
|
|
|
|
if (dataType != IVariable::DT_SIMPLE)
|
|
{
|
|
for (i = 0; i < NumPropertyTypes; i++)
|
|
{
|
|
if (dataType == s_propertyTypeNames[i].dataType)
|
|
{
|
|
m_type = s_propertyTypeNames[i].type;
|
|
m_image = s_propertyTypeNames[i].image;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_enumList = m_pVariable->GetEnumList();
|
|
if (m_enumList)
|
|
{
|
|
m_type = ePropertySelection;
|
|
}
|
|
|
|
if (m_type == ePropertyInvalid)
|
|
{
|
|
switch(m_pVariable->GetType())
|
|
{
|
|
case IVariable::INT:
|
|
m_type = ePropertyInt;
|
|
break;
|
|
case IVariable::BOOL:
|
|
m_type = ePropertyBool;
|
|
break;
|
|
case IVariable::FLOAT:
|
|
m_type = ePropertyFloat;
|
|
break;
|
|
case IVariable::VECTOR:
|
|
m_type = ePropertyVector;
|
|
break;
|
|
case IVariable::STRING:
|
|
m_type = ePropertyString;
|
|
break;
|
|
}
|
|
for (i = 0; i < NumPropertyTypes; i++)
|
|
{
|
|
if (m_type == s_propertyTypeNames[i].type)
|
|
{
|
|
m_image = s_propertyTypeNames[i].image;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_valueMultiplier = 1;
|
|
m_rangeMin = -10000;
|
|
m_rangeMax = 10000;
|
|
m_iInternalPrecision=2; // m.m.
|
|
|
|
// Get variable limits.
|
|
m_pVariable->GetLimits( m_rangeMin,m_rangeMax );
|
|
|
|
// Check if value is percsents.
|
|
if (dataType == IVariable::DT_PERCENT)
|
|
{
|
|
// Scale all values by 100.
|
|
m_valueMultiplier = 100;
|
|
m_rangeMin = 0;
|
|
m_rangeMax = 100;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CString value = VarToValue(var);
|
|
|
|
m_value = value;
|
|
SetValue( value );
|
|
|
|
m_bNoCategory = false;
|
|
|
|
if (m_type == ePropertyVector)
|
|
{
|
|
m_childs.clear();
|
|
|
|
Vec3 vec;
|
|
m_pVariable->Get( vec );
|
|
IVariable *pVX = new CVariable<float>;
|
|
pVX->SetName( "x" );
|
|
pVX->Set( vec.x );
|
|
IVariable *pVY = new CVariable<float>;
|
|
pVY->SetName( "y" );
|
|
pVY->Set( vec.y );
|
|
IVariable *pVZ = new CVariable<float>;
|
|
pVZ->SetName( "z" );
|
|
pVZ->Set( vec.z );
|
|
|
|
// Start ignoring all updates comming from childs. (Initializing childs).
|
|
m_bIgnoreChildsUpdate = true;
|
|
|
|
CPropertyItem *itemX = new CPropertyItem( m_propertyCtrl );
|
|
itemX->SetVariable( pVX );
|
|
AddChild( itemX );
|
|
|
|
CPropertyItem *itemY = new CPropertyItem( m_propertyCtrl );
|
|
itemY->SetVariable( pVY );
|
|
AddChild( itemY );
|
|
|
|
CPropertyItem *itemZ = new CPropertyItem( m_propertyCtrl );
|
|
itemZ->SetVariable( pVZ );
|
|
AddChild( itemZ );
|
|
|
|
m_bNoCategory = true;
|
|
m_bExpandable = true;
|
|
|
|
m_bIgnoreChildsUpdate = false;
|
|
}
|
|
/*
|
|
else if (bRecursive)
|
|
{
|
|
// If recursive and not vector.
|
|
|
|
m_bExpandable = false;
|
|
// Create sub-nodes.
|
|
for (i=0; i < m_node->getChildCount(); i++)
|
|
{
|
|
m_bIgnoreChildsUpdate = true;
|
|
|
|
XmlNodeRef child = m_node->getChild(i);
|
|
CPropertyItem *item = new CPropertyItem( this,m_propertyCtrl );
|
|
item->SetXmlNode( m_node->getChild(i) );
|
|
m_childs.push_back( item );
|
|
m_bExpandable = true;
|
|
|
|
m_bIgnoreChildsUpdate = false;
|
|
}
|
|
}
|
|
*/
|
|
|
|
if (m_pVariable->NumChildVars() > 0)
|
|
{
|
|
if (m_type == ePropertyInvalid)
|
|
m_type = ePropertyTable;
|
|
m_bIgnoreChildsUpdate = true;
|
|
for (i = 0; i < m_pVariable->NumChildVars(); i++)
|
|
{
|
|
CPropertyItem *item = new CPropertyItem( m_propertyCtrl );
|
|
item->SetVariable(m_pVariable->GetChildVar(i));
|
|
AddChild( item );
|
|
m_bExpandable = true;
|
|
}
|
|
m_bIgnoreChildsUpdate = false;
|
|
}
|
|
m_modified = false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::ReleaseVariable()
|
|
{
|
|
if (m_pVariable)
|
|
{
|
|
// Unwire all from variable.
|
|
m_pVariable->Unwire(0);
|
|
m_pVariable->RemoveOnSetCallback(functor(*this, &CPropertyItem::OnVariableChange));
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! Find item that reference specified property.
|
|
CPropertyItem* CPropertyItem::FindItemByVar( IVariable *pVar )
|
|
{
|
|
if (m_pVariable == pVar)
|
|
return this;
|
|
for (int i = 0; i < m_childs.size(); i++)
|
|
{
|
|
CPropertyItem* pFound = m_childs[i]->FindItemByVar(pVar);
|
|
if (pFound)
|
|
return pFound;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CString CPropertyItem::GetFullName() const
|
|
{
|
|
if (m_parent)
|
|
{
|
|
return m_parent->GetFullName() + "::" + m_name;
|
|
}
|
|
else
|
|
return m_name;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CPropertyItem* CPropertyItem::FindItemByFullName( const CString &name )
|
|
{
|
|
if (GetFullName() == name)
|
|
return this;
|
|
for (int i = 0; i < m_childs.size(); i++)
|
|
{
|
|
CPropertyItem* pFound = m_childs[i]->FindItemByFullName(name);
|
|
if (pFound)
|
|
return pFound;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::AddChild( CPropertyItem *item )
|
|
{
|
|
assert(item);
|
|
m_bExpandable = true;
|
|
item->m_parent = this;
|
|
m_childs.push_back(item);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::RemoveChild( CPropertyItem *item )
|
|
{
|
|
// Find item and erase it from childs array.
|
|
for (int i = 0; i < m_childs.size(); i++)
|
|
{
|
|
if (item == m_childs[i])
|
|
{
|
|
m_childs.erase( m_childs.begin() + i );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnChildChanged( CPropertyItem *child )
|
|
{
|
|
if (m_bIgnoreChildsUpdate)
|
|
return;
|
|
|
|
if (m_type == ePropertyVector)
|
|
{
|
|
assert( m_childs.size() == 3 );
|
|
// Get values from childs.
|
|
CString x = m_childs[0]->GetValue();
|
|
CString y = m_childs[1]->GetValue();
|
|
CString z = m_childs[2]->GetValue();
|
|
bool prevIgnore = m_bIgnoreChildsUpdate;
|
|
m_bIgnoreChildsUpdate = true;
|
|
SetValue( x+","+y+","+z,false );
|
|
m_bIgnoreChildsUpdate = prevIgnore;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SetSelected( bool selected )
|
|
{
|
|
m_bSelected = selected;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SetExpanded( bool expanded )
|
|
{
|
|
if (IsDisabled())
|
|
{
|
|
m_bExpanded = false;
|
|
}
|
|
else
|
|
m_bExpanded = expanded;
|
|
}
|
|
|
|
bool CPropertyItem::IsDisabled() const
|
|
{
|
|
if (m_pVariable)
|
|
{
|
|
return m_pVariable->GetFlags() & IVariable::UI_DISABLED;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CPropertyItem::IsBold() const
|
|
{
|
|
if (m_pVariable)
|
|
{
|
|
return m_pVariable->GetFlags() & IVariable::UI_BOLD;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::CreateInPlaceControl( CWnd* pWndParent,CRect& ctrlRect )
|
|
{
|
|
CRect nullRc(0,0,0,0);
|
|
switch (m_type)
|
|
{
|
|
case ePropertyFloat:
|
|
case ePropertyInt:
|
|
case ePropertyAngle:
|
|
{
|
|
m_cNumber = new CNumberCtrl;
|
|
m_cNumber->SetUpdateCallback( functor(*this, &CPropertyItem::OnNumberCtrlUpdate) );
|
|
//m_cNumber->SetBeginUpdateCallback( functor(*this, &CPropertyItem::OnNumberCtrlBeginUpdate) );
|
|
//m_cNumber->SetEndUpdateCallback( functor(*this, &CPropertyItem::OnNumberCtrlEndUpdate) );
|
|
|
|
// (digits behind the comma, only used for floats)
|
|
if(m_type == ePropertyFloat)
|
|
m_cNumber->SetInternalPrecision( m_iInternalPrecision );
|
|
|
|
// Only for integers.
|
|
if (m_type == ePropertyInt)
|
|
m_cNumber->SetInteger(true);
|
|
m_cNumber->SetMultiplier( m_valueMultiplier );
|
|
m_cNumber->SetRange( m_rangeMin,m_rangeMax );
|
|
|
|
//m_cNumber->Create( pWndParent,rect,1,CNumberCtrl::LEFTARROW|CNumberCtrl::NOBORDER );
|
|
m_cNumber->Create( pWndParent,nullRc,1,CNumberCtrl::NOBORDER|CNumberCtrl::LEFTALIGN );
|
|
m_cNumber->SetLeftAlign( true );
|
|
}
|
|
break;
|
|
|
|
case ePropertyString:
|
|
case ePropertyVector:
|
|
case ePropertyLocalString:
|
|
m_cEdit = new CInPlaceEdit( m_value,functor(*this, &CPropertyItem::OnEditChanged) );
|
|
m_cEdit->Create( WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_LEFT, nullRc, pWndParent,2 );
|
|
break;
|
|
|
|
case ePropertyShader:
|
|
case ePropertyMaterial:
|
|
case ePropertyAiBehavior:
|
|
case ePropertyAiAnchor:
|
|
case ePropertyAiCharacter:
|
|
case ePropertyEquip:
|
|
case ePropertySoundPreset:
|
|
case ePropertyEAXPreset:
|
|
m_cEdit = new CInPlaceEdit( m_value,functor(*this, &CPropertyItem::OnEditChanged) );
|
|
m_cEdit->Create( WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_LEFT, nullRc, pWndParent,2 );
|
|
if (m_type == ePropertyShader)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnShaderBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_type == ePropertyAiBehavior)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnAIBehaviorBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_type == ePropertyAiAnchor)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnAIAnchorBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_type == ePropertyAiCharacter)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnAICharacterBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_type == ePropertyEquip)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnEquipBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_type == ePropertySoundPreset)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnSoundPresetBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_type == ePropertyEAXPreset)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnEAXPresetBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
else if (m_type == ePropertyMaterial)
|
|
{
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnMaterialBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
}
|
|
if (m_cButton)
|
|
{
|
|
m_cButton->SetXButtonStyle( BS_XT_SEMIFLAT,FALSE );
|
|
}
|
|
break;
|
|
|
|
//case ePropertyBool:
|
|
case ePropertySelection:
|
|
{
|
|
// Combo box.
|
|
m_cCombo = new CInPlaceComboBox();
|
|
m_cCombo->SetReadOnly( true );
|
|
m_cCombo->Create( NULL,"",WS_CHILD|WS_VISIBLE, nullRc, pWndParent,2 );
|
|
m_cCombo->SetUpdateCallback( functor(*this, &CPropertyItem::OnComboSelection) );
|
|
|
|
if (m_type == ePropertySelection)
|
|
{
|
|
if (m_enumList)
|
|
{
|
|
for (int i = 0; i < m_enumList->GetItemsCount(); i++)
|
|
{
|
|
m_cCombo->AddString( m_enumList->GetItemName(i) );
|
|
}
|
|
}
|
|
|
|
/*
|
|
CString sel;
|
|
m_node->getAttr( "Selection",sel );
|
|
if (!sel.IsEmpty())
|
|
{
|
|
char *token;
|
|
char str[1024];
|
|
strcpy( str,sel );
|
|
token = strtok( str,"," );
|
|
while (token != NULL)
|
|
{
|
|
m_cCombo->AddString( token );
|
|
token = strtok( NULL,"," );
|
|
}
|
|
}
|
|
*/
|
|
} else if (m_type == ePropertyBool)
|
|
{
|
|
m_cCombo->AddString( "True" );
|
|
m_cCombo->AddString( "False" );
|
|
if (GetBoolValue())
|
|
m_cCombo->SetCurSel(0,false);
|
|
else
|
|
m_cCombo->SetCurSel(1,false);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ePropertyColor:
|
|
{
|
|
m_cEdit = new CInPlaceEdit( m_value,functor(*this, &CPropertyItem::OnEditChanged) );
|
|
m_cEdit->Create( WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_LEFT, nullRc, pWndParent,2 );
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnColorBrowseButton) );
|
|
|
|
m_cButton->Create( "",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
m_cButton->SetXButtonStyle( BS_XT_SEMIFLAT,FALSE );
|
|
}
|
|
break;
|
|
|
|
case ePropertyFile:
|
|
case ePropertyTexture:
|
|
case ePropertyModel:
|
|
case ePropertySound:
|
|
m_cEdit = new CInPlaceEdit( m_value,functor(*this, &CPropertyItem::OnEditChanged) );
|
|
m_cEdit->Create( WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|ES_LEFT, nullRc, pWndParent,2 );
|
|
|
|
m_cButton = new CInPlaceButton( functor(*this, &CPropertyItem::OnFileBrowseButton) );
|
|
m_cButton->Create( "...",WS_CHILD|WS_VISIBLE,nullRc,pWndParent,4 );
|
|
|
|
// Use file browse icon.
|
|
m_cButton->SetXButtonStyle( BS_XT_SEMIFLAT,FALSE );
|
|
m_cButton->SetIcon( CSize(16,15),IDI_FILE_BROWSE );
|
|
m_cButton->SetBorderGap(0);
|
|
break;
|
|
/*
|
|
case ePropertyList:
|
|
{
|
|
AddButton( "Add", CWDelegate(this,(TDelegate)OnAddItemButton) );
|
|
}
|
|
break;
|
|
*/
|
|
}
|
|
|
|
MoveInPlaceControl( ctrlRect );
|
|
SendToControl();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::DestroyInPlaceControl()
|
|
{
|
|
ReceiveFromControl();
|
|
|
|
if (m_cNumber)
|
|
{
|
|
delete m_cNumber;
|
|
m_cNumber = 0;
|
|
}
|
|
if (m_cEdit)
|
|
{
|
|
delete m_cEdit;
|
|
m_cEdit = 0;
|
|
}
|
|
if (m_cCombo)
|
|
{
|
|
delete m_cCombo;
|
|
m_cCombo = 0;
|
|
}
|
|
if (m_cButton)
|
|
{
|
|
delete m_cButton;
|
|
m_cButton = 0;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::MoveInPlaceControl( const CRect& rect )
|
|
{
|
|
CRect rc = rect;
|
|
if (m_cButton)
|
|
{
|
|
if (m_type == ePropertyColor)
|
|
{
|
|
rc.right = rc.left + BUTTON_WIDTH + 2;
|
|
m_cButton->MoveWindow( rc,FALSE );
|
|
rc = rect;
|
|
rc.left += BUTTON_WIDTH + 2 + 4;
|
|
}
|
|
else
|
|
{
|
|
rc.left = rc.right - BUTTON_WIDTH;
|
|
m_cButton->MoveWindow( rc,FALSE );
|
|
rc = rect;
|
|
rc.right -= BUTTON_WIDTH;
|
|
}
|
|
m_cButton->SetFont(m_propertyCtrl->GetFont());
|
|
}
|
|
|
|
if (m_cNumber)
|
|
{
|
|
CRect rcn = rc;
|
|
//rcn.right = rc.left + 60;
|
|
if (rcn.Width() > 60)
|
|
rcn.right = rc.left + 60;
|
|
m_cNumber->MoveWindow( rcn,FALSE );
|
|
m_cNumber->SetFont(m_propertyCtrl->GetFont());
|
|
}
|
|
if (m_cEdit)
|
|
{
|
|
m_cEdit->MoveWindow( rc,FALSE );
|
|
m_cEdit->SetFont(m_propertyCtrl->GetFont());
|
|
}
|
|
if (m_cCombo)
|
|
{
|
|
m_cCombo->MoveWindow( rc,FALSE );
|
|
m_cCombo->SetFont(m_propertyCtrl->GetFont());
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SetFocus()
|
|
{
|
|
if (m_cNumber)
|
|
{
|
|
m_cNumber->SetFocus();
|
|
}
|
|
if (m_cEdit)
|
|
{
|
|
m_cEdit->SetFocus();
|
|
}
|
|
if (m_cCombo)
|
|
{
|
|
m_cCombo->SetFocus();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::ReceiveFromControl()
|
|
{
|
|
if (m_cEdit)
|
|
{
|
|
CString str;
|
|
m_cEdit->GetWindowText( str );
|
|
SetValue( str );
|
|
}
|
|
if (m_cCombo)
|
|
{
|
|
SetValue( m_cCombo->GetSelectedString() );
|
|
}
|
|
if (m_cNumber)
|
|
{
|
|
SetValue( m_cNumber->GetValueAsString() );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SendToControl()
|
|
{
|
|
bool bInPlaceCtrl = false;
|
|
if (m_cButton)
|
|
{
|
|
if (m_type == ePropertyColor)
|
|
{
|
|
COLORREF clr = StringToColor(m_value);
|
|
m_cButton->SetColorFace( clr );
|
|
bInPlaceCtrl = true;
|
|
}
|
|
}
|
|
if (m_cEdit)
|
|
{
|
|
m_cEdit->SetText(m_value);
|
|
bInPlaceCtrl = true;
|
|
}
|
|
if (m_cCombo)
|
|
{
|
|
if (m_type == ePropertyBool)
|
|
m_cCombo->SetCurSel( GetBoolValue()?0:1,false );
|
|
else
|
|
m_cCombo->SelectString(m_value);
|
|
bInPlaceCtrl = true;
|
|
}
|
|
if (m_cNumber)
|
|
{
|
|
m_cNumber->SetValue( atof(m_value) );
|
|
bInPlaceCtrl = true;
|
|
}
|
|
if (!bInPlaceCtrl)
|
|
m_propertyCtrl->Invalidate();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnComboSelection()
|
|
{
|
|
ReceiveFromControl();
|
|
SendToControl();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::DrawValue( CDC *dc,CRect rect )
|
|
{
|
|
// Setup text.
|
|
dc->SetBkMode( TRANSPARENT );
|
|
|
|
static char str[4096];
|
|
strcpy( str,m_value );
|
|
if (m_valueMultiplier != 1)
|
|
{
|
|
sprintf( str,"%g",atof(m_value)*m_valueMultiplier );
|
|
}
|
|
if (m_type == ePropertyList)
|
|
{
|
|
//sprintf( str,"%d items",(int)Children.Num() );
|
|
return;
|
|
}
|
|
else if (m_type == ePropertyBool)
|
|
{
|
|
CPoint p1( rect.left,rect.top+1 );
|
|
int sz = rect.bottom - rect.top - 1;
|
|
CRect rc(p1.x,p1.y,p1.x+sz,p1.y+sz );
|
|
dc->DrawFrameControl( rc,DFC_BUTTON,DFCS_BUTTON3STATE );
|
|
if (GetBoolValue())
|
|
{
|
|
strcpy( str,"True" );
|
|
m_propertyCtrl->m_icons.Draw( dc,12,p1,ILD_TRANSPARENT );
|
|
}
|
|
else
|
|
{
|
|
strcpy( str,"False" );
|
|
}
|
|
CRect textRc;
|
|
textRc = rect;
|
|
textRc.left += 15;
|
|
::DrawTextEx( dc->GetSafeHdc(),str, strlen(str), textRc, DT_END_ELLIPSIS|DT_LEFT|DT_SINGLELINE|DT_VCENTER, NULL );
|
|
strcpy( str,"" );
|
|
}
|
|
else if (m_type == ePropertyFile || m_type == ePropertyTexture ||
|
|
m_type == ePropertySound || m_type == ePropertyModel)
|
|
{
|
|
// Any file.
|
|
// Check if file name fits into the designated rectangle.
|
|
CSize textSize = dc->GetTextExtent( str,strlen(str) );
|
|
if (textSize.cx > rect.Width())
|
|
{
|
|
// Cut file name...
|
|
CString file = Path::GetFile(str);
|
|
strcpy( str,"...\\" );
|
|
strcat( str,file );
|
|
}
|
|
}
|
|
|
|
if (m_type == ePropertyColor)
|
|
{
|
|
//CRect rc( CPoint(rect.right-BUTTON_WIDTH,rect.top),CSize(BUTTON_WIDTH,rect.bottom-rect.top) );
|
|
CRect rc( CPoint(rect.left,rect.top+1),CSize(BUTTON_WIDTH+2,rect.bottom-rect.top-2) );
|
|
//CPen pen( PS_SOLID,1,RGB(128,128,128));
|
|
CPen pen( PS_SOLID,1,RGB(0,0,0));
|
|
CBrush brush( StringToColor(m_value) );
|
|
CPen *pOldPen = dc->SelectObject( &pen );
|
|
CBrush *pOldBrush = dc->SelectObject( &brush );
|
|
dc->Rectangle( rc );
|
|
//COLORREF col = StringToColor(m_value);
|
|
//rc.DeflateRect( 1,1 );
|
|
//dc->FillSolidRect( rc,col );
|
|
dc->SelectObject( pOldPen );
|
|
dc->SelectObject( pOldBrush );
|
|
rect.left = rect.left + BUTTON_WIDTH + 2 + 4;
|
|
}
|
|
|
|
CRect textRc;
|
|
textRc = rect;
|
|
::DrawTextEx( dc->GetSafeHdc(),str, strlen(str), textRc, DT_END_ELLIPSIS|DT_LEFT|DT_SINGLELINE|DT_VCENTER, NULL );
|
|
}
|
|
|
|
COLORREF CPropertyItem::StringToColor( const CString &value )
|
|
{
|
|
float r,g,b;
|
|
int res = 0;
|
|
if (res != 3)
|
|
res = sscanf( value,"%f,%f,%f",&r,&g,&b );
|
|
if (res != 3)
|
|
res = sscanf( value,"R:%f,G:%f,B:%f",&r,&g,&b );
|
|
if (res != 3)
|
|
res = sscanf( value,"R:%f G:%f B:%f",&r,&g,&b );
|
|
if (res != 3)
|
|
res = sscanf( value,"%f %f %f",&r,&g,&b );
|
|
if (res != 3)
|
|
{
|
|
sscanf( value,"%f",&r );
|
|
return r;
|
|
}
|
|
int ir = r;
|
|
int ig = g;
|
|
int ib = b;
|
|
|
|
return RGB(ir,ig,ib);
|
|
}
|
|
|
|
bool CPropertyItem::GetBoolValue()
|
|
{
|
|
if (stricmp(m_value,"true")==0 || atoi(m_value) != 0)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const char* CPropertyItem::GetValue() const
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::SetValue( const char* sValue,bool bRecordUndo )
|
|
{
|
|
CString value = sValue;
|
|
if (m_type == ePropertyBool)
|
|
{
|
|
if (stricmp(value,"true")==0 || atof(value) != 0)
|
|
value = "1";
|
|
else
|
|
value = "0";
|
|
}
|
|
|
|
bool bModified = false;
|
|
if (m_value.Compare(value) != 0)
|
|
{
|
|
bModified = true;
|
|
}
|
|
m_value = value;
|
|
|
|
if (m_pVariable)
|
|
{
|
|
if (bModified)
|
|
{
|
|
float currTime = GetIEditor()->GetSystem()->GetITimer()->GetCurrTime();
|
|
if (currTime > m_lastModified+1) // At least one second between undo stores.
|
|
{
|
|
if (bRecordUndo && !CUndo::IsRecording())
|
|
{
|
|
CUndo undo( CString(m_pVariable->GetName()) + " Changed" );
|
|
undo.Record( new CUndoVariableChange(m_pVariable,"PropertyChange") );
|
|
}
|
|
else if (bRecordUndo)
|
|
{
|
|
GetIEditor()->RecordUndo( new CUndoVariableChange(m_pVariable,"PropertyChange") );
|
|
}
|
|
}
|
|
|
|
ValueToVar( m_value,m_pVariable );
|
|
m_lastModified = currTime;
|
|
}
|
|
// Return now, (OnVariableChange was called).
|
|
return;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// DEPRICATED (For XmlNode).
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (m_node)
|
|
m_node->setAttr( VALUE_ATTR,m_value );
|
|
//CString xml = m_node->getXML();
|
|
|
|
if (bModified)
|
|
{
|
|
m_modified = true;
|
|
if (m_type == ePropertyVector && m_childs.size() == 3)
|
|
{
|
|
Vec3 vec;
|
|
if (m_node)
|
|
m_node->getAttr( VALUE_ATTR,vec );
|
|
if (m_pVariable)
|
|
m_pVariable->Get(vec);
|
|
// Get values from childs.
|
|
char str[1024];
|
|
sprintf( str,"%g",vec.x );
|
|
m_childs[0]->SetValue(str,false);
|
|
sprintf( str,"%g",vec.y );
|
|
m_childs[1]->SetValue(str,false);
|
|
sprintf( str,"%g",vec.z );
|
|
m_childs[2]->SetValue(str,false);
|
|
}
|
|
|
|
if (m_parent)
|
|
m_parent->OnChildChanged( this );
|
|
// If Value changed mark document modified.
|
|
// Notify parent that this Item have been modified.
|
|
m_propertyCtrl->OnItemChange( this );
|
|
}
|
|
|
|
SendToControl();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CString CPropertyItem::VarToValue( IVariable *var )
|
|
{
|
|
assert( var );
|
|
|
|
if (m_enumList)
|
|
{
|
|
return m_enumList->GetNameFromVariableValue(var);
|
|
}
|
|
|
|
CString value;
|
|
if (m_type == ePropertyColor)
|
|
{
|
|
Vec3 v;
|
|
m_pVariable->Get(v);
|
|
int r = v.x*255;
|
|
int g = v.y*255;
|
|
int b = v.z*255;
|
|
r = max(0,min(r,255));
|
|
g = max(0,min(g,255));
|
|
b = max(0,min(b,255));
|
|
value.Format( "%d,%d,%d",r,g,b );
|
|
return value;
|
|
}
|
|
|
|
m_pVariable->Get(value);
|
|
|
|
if (m_type == ePropertyAngle)
|
|
{
|
|
// Convert from radians to degrees.
|
|
float f;
|
|
m_pVariable->Get(f);
|
|
f = RAD2DEG(f);
|
|
char str[32];
|
|
sprintf( str,"%g",f );
|
|
value = str;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::ValueToVar( const CString &value,IVariable *var )
|
|
{
|
|
assert( m_pVariable != NULL );
|
|
|
|
if (m_enumList)
|
|
{
|
|
m_enumList->SetVariableValue( var,value );
|
|
return;
|
|
}
|
|
|
|
if (m_type == ePropertyAngle)
|
|
{
|
|
// Convert from degrees to radians.
|
|
float f = (float)atof(m_value);
|
|
m_pVariable->Set(DEG2RAD(f));
|
|
}
|
|
else if (m_type == ePropertyColor)
|
|
{
|
|
COLORREF col = StringToColor(value);
|
|
Vec3 v;
|
|
v.x = GetRValue(col)/255.0f;
|
|
v.y = GetGValue(col)/255.0f;
|
|
v.z = GetBValue(col)/255.0f;
|
|
m_pVariable->Set(v);
|
|
}
|
|
else
|
|
{
|
|
// Any other variable type.
|
|
if (m_type != ePropertyInvalid && m_type != ePropertyTable)
|
|
m_pVariable->Set(m_value);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnVariableChange( IVariable *var )
|
|
{
|
|
// When variable change, invalidate UI.
|
|
m_modified = true;
|
|
|
|
m_value = VarToValue(var);
|
|
|
|
if (m_type == ePropertyVector && m_childs.size() == 3)
|
|
{
|
|
Vec3 vec;
|
|
m_pVariable->Get(vec);
|
|
// Get values from childs.
|
|
char str[1024];
|
|
sprintf( str,"%g",vec.x );
|
|
m_childs[0]->SetValue(str,false);
|
|
sprintf( str,"%g",vec.y );
|
|
m_childs[1]->SetValue(str,false);
|
|
sprintf( str,"%g",vec.z );
|
|
m_childs[2]->SetValue(str,false);
|
|
}
|
|
|
|
SendToControl();
|
|
if (m_parent)
|
|
m_parent->OnChildChanged( this );
|
|
|
|
// If Value changed mark document modified.
|
|
// Notify parent that this Item have been modified.
|
|
// This may delete this control...
|
|
m_propertyCtrl->OnItemChange( this );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnMouseWheel( UINT nFlags,short zDelta,CPoint point )
|
|
{
|
|
if (m_cCombo)
|
|
{
|
|
int sel = m_cCombo->GetCurSel();
|
|
if (zDelta > 0)
|
|
{
|
|
sel++;
|
|
if (m_cCombo->SetCurSel( sel ) == CB_ERR)
|
|
m_cCombo->SetCurSel( 0 );
|
|
}
|
|
else
|
|
{
|
|
sel--;
|
|
if (m_cCombo->SetCurSel( sel ) == CB_ERR)
|
|
m_cCombo->SetCurSel( m_cCombo->GetCount()-1 );
|
|
}
|
|
}
|
|
else if (m_cNumber)
|
|
{
|
|
if (zDelta > 0)
|
|
{
|
|
m_cNumber->SetValue( m_cNumber->GetValue() + m_cNumber->GetStep() );
|
|
}
|
|
else
|
|
{
|
|
m_cNumber->SetValue( m_cNumber->GetValue() - m_cNumber->GetStep() );
|
|
}
|
|
ReceiveFromControl();
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnLButtonDblClk( UINT nFlags,CPoint point )
|
|
{
|
|
if (m_type == ePropertyBool)
|
|
{
|
|
// Swap boolean value.
|
|
if (GetBoolValue())
|
|
SetValue( "0" );
|
|
else
|
|
SetValue( "1" );
|
|
}
|
|
else
|
|
{
|
|
// Simulate button click.
|
|
if (m_cButton)
|
|
m_cButton->Click();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnLButtonDown( UINT nFlags,CPoint point )
|
|
{
|
|
if (m_type == ePropertyBool)
|
|
{
|
|
CRect rect;
|
|
m_propertyCtrl->GetItemRect( this,rect );
|
|
rect = m_propertyCtrl->GetItemValueRect( rect );
|
|
|
|
CPoint p( rect.left-2,rect.top+1 );
|
|
int sz = rect.bottom - rect.top;
|
|
rect = CRect(p.x,p.y,p.x+sz,p.y+sz );
|
|
|
|
if (rect.PtInRect(point))
|
|
{
|
|
// Swap boolean value.
|
|
if (GetBoolValue())
|
|
SetValue( "0" );
|
|
else
|
|
SetValue( "1" );
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnColorBrowseButton()
|
|
{
|
|
COLORREF clr = StringToColor(m_value);
|
|
if (GetIEditor()->SelectColor(clr,m_propertyCtrl))
|
|
{
|
|
int r,g,b;
|
|
r = GetRValue(clr);
|
|
g = GetGValue(clr);
|
|
b = GetBValue(clr);
|
|
//val.Format( "R:%d G:%d B:%d",r,g,b );
|
|
CString val;
|
|
val.Format( "%d,%d,%d",r,g,b );
|
|
SetValue( val );
|
|
m_propertyCtrl->Invalidate();
|
|
//RedrawWindow( OwnerProperties->hWnd,NULL,NULL,RDW_INVALIDATE|RDW_UPDATENOW|RDW_ALLCHILDREN );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnFileBrowseButton()
|
|
{
|
|
ECustomFileType ftype = EFILE_TYPE_ANY;
|
|
|
|
if (m_type == ePropertyTexture)
|
|
{
|
|
// Filters for texture.
|
|
ftype = EFILE_TYPE_TEXTURE;
|
|
}
|
|
else if (m_type == ePropertySound)
|
|
{
|
|
// Filters for sounds.
|
|
ftype = EFILE_TYPE_SOUND;
|
|
}
|
|
else if (m_type == ePropertyModel)
|
|
{
|
|
// Filters for models.
|
|
ftype = EFILE_TYPE_GEOMETRY;
|
|
}
|
|
CString startPath = Path::GetPath(m_value);
|
|
|
|
/*
|
|
if (ftype == EFILE_TYPE_ANY)
|
|
{
|
|
CString relativeFilename;
|
|
if (CFileUtil::SelectFile( "All Files (*.*)|*.*",startPath,relativeFilename ))
|
|
{
|
|
SetValue( relativeFilename );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*/
|
|
CString relativeFilename = m_value;
|
|
if (CFileUtil::SelectSingleFile( ftype,relativeFilename,"",startPath ))
|
|
{
|
|
SetValue( relativeFilename );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnShaderBrowseButton()
|
|
{
|
|
CShadersDialog cShaders( m_value );
|
|
if (cShaders.DoModal() == IDOK)
|
|
{
|
|
SetValue( cShaders.GetSelection() );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::ReloadValues()
|
|
{
|
|
if (m_node)
|
|
ParseXmlNode(false);
|
|
if (m_pVariable)
|
|
SetVariable(m_pVariable);
|
|
for (int i = 0; i < GetChildCount(); i++)
|
|
{
|
|
GetChild(i)->ReloadValues();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CString CPropertyItem::GetTip() const
|
|
{
|
|
if (!m_tip.IsEmpty())
|
|
return m_tip;
|
|
|
|
CString type;
|
|
for (int i = 0; i < NumPropertyTypes; i++)
|
|
{
|
|
if (m_type == s_propertyTypeNames[i].type)
|
|
{
|
|
type = s_propertyTypeNames[i].name;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CString tip;
|
|
tip = CString("[")+type+"] ";
|
|
tip += m_name + ": " + m_value;
|
|
|
|
if (m_pVariable)
|
|
{
|
|
CString description = m_pVariable->GetDescription();
|
|
if (!description.IsEmpty())
|
|
{
|
|
tip += CString("\r\n") + description;
|
|
}
|
|
}
|
|
return tip;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnEditChanged()
|
|
{
|
|
ReceiveFromControl();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnNumberCtrlUpdate( CNumberCtrl *ctrl )
|
|
{
|
|
ReceiveFromControl();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnAIBehaviorBrowseButton()
|
|
{
|
|
CAIDialog aiDlg(m_propertyCtrl);
|
|
aiDlg.SetAIBehavior( m_value );
|
|
if (aiDlg.DoModal() == IDOK)
|
|
{
|
|
SetValue( aiDlg.GetAIBehavior() );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnAIAnchorBrowseButton()
|
|
{
|
|
CAIAnchorsDialog aiDlg(m_propertyCtrl);
|
|
aiDlg.SetAIAnchor(m_value);
|
|
if (aiDlg.DoModal()==IDOK)
|
|
{
|
|
SetValue(aiDlg.GetAIAnchor());
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnAICharacterBrowseButton()
|
|
{
|
|
CAICharactersDialog aiDlg(m_propertyCtrl);
|
|
aiDlg.SetAICharacter( m_value );
|
|
if (aiDlg.DoModal() == IDOK)
|
|
{
|
|
SetValue( aiDlg.GetAICharacter() );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnEquipBrowseButton()
|
|
{
|
|
CEquipPackDialog EquipDlg(m_propertyCtrl);
|
|
EquipDlg.SetCurrEquipPack(m_value);
|
|
if (EquipDlg.DoModal()==IDOK)
|
|
{
|
|
SetValue(EquipDlg.GetCurrEquipPack());
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnSoundPresetBrowseButton()
|
|
{
|
|
CSelectSoundPresetDlg PresetDlg;
|
|
PresetDlg.SetCurrPreset(m_value);
|
|
if (PresetDlg.DoModal()==IDOK)
|
|
{
|
|
SetValue(PresetDlg.GetCurrPreset());
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnEAXPresetBrowseButton()
|
|
{
|
|
CSelectEAXPresetDlg PresetDlg;
|
|
PresetDlg.SetCurrPreset(m_value);
|
|
if (PresetDlg.DoModal()==IDOK)
|
|
{
|
|
SetValue(PresetDlg.GetCurrPreset());
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CPropertyItem::OnMaterialBrowseButton()
|
|
{
|
|
// Open material browser dialog.
|
|
}
|