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

📄 entitiesdialog.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************************/
/*  EntitiesDialog.cpp                                                                  */
/*                                                                                      */
/*  Author:       Jim Mischel, Ken Baird, Jeff Lomax                                    */
/*  Description:  Dialog code for templates                                             */
/*                                                                                      */
/*  The contents of this file are subject to the Genesis3D Public License               */
/*  Version 1.01 (the "License"); you may not use this file except in                   */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.genesis3d.com                                                            */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Genesis3D, released March 25, 1999.                            */
/*Genesis3D Version 1.1 released November 15, 1999                            */
/*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
/*                                                                                      */
/*  Modified by Tom Morris for GenEdit-Classic ver. 0.58, April 23, 2001				*/
/****************************************************************************************/
#include "stdafx.h"
#include "Globals.h"
#include "EntitiesDialog.h"
#include "KeyEditDlg.h"
#include "EntityTable.h"
#include <assert.h>
#include "ram.h"
#include "util.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CEntitiesDialog dialog

CEntitiesDialog::CEntitiesDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CEntitiesDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CEntitiesDialog)
	//}}AFX_DATA_INIT
	mCurrentEntity = 0;
	mCurrentKey = LB_ERR;


	CDialog::Create(IDD,pParent);

	pDoc = CGlobals::GetActiveDocument();
}


void CEntitiesDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CEntitiesDialog)
	DDX_Control(pDX, IDC_ENTITIES_STATIC, m_entitiesStaticString);
	DDX_Control(pDX, IDC_PROPERTIESLIST, m_PropertiesList);
	DDX_Control(pDX, IDC_ENTITYCOMBO, m_EntityCombo);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CEntitiesDialog, CDialog)
	//{{AFX_MSG_MAP(CEntitiesDialog)
	ON_CBN_SELCHANGE(IDC_ENTITYCOMBO, OnSelchangeEntitylist)
	ON_LBN_DBLCLK(IDC_PROPERTIESLIST, OnDblclkPropertieslist)
	ON_WM_VKEYTOITEM()
	ON_WM_DRAWITEM()
	ON_NOTIFY_EX( TTN_NEEDTEXT, 0, NeedTextNotify )
	
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEntitiesDialog message handlers



BOOL CEntitiesDialog::OnInitDialog() 
{
	pDoc = CGlobals::GetActiveDocument();


	CDialog::OnInitDialog();

	pDoc->mpMainFrame->HideAllPropDialogsBut(this);


//	CEntityArray *Entities = Level_GetEntities (pDoc->pLevel); //	moved to UpdateEntities
//	EditEntity(*Entities, pDoc->mCurrentEntity, pDoc);	//	moved to UpdateEntities


	return true;

}


/*
UpdateMainControls --->(conditional)EditEntity ---> ShowDialog() ---> FillInDialog --->Reset combo box

UpdateMainControls ---> UpdateEntities ---> EditEntity--->ShowDialog ---> FillInDialog--->reset combo box
*/



bool CEntitiesDialog::UpdateEntities(CGenEditDoc *pDoc)
{
	if (pDoc != NULL)
	{
		CEntityArray *Entities = Level_GetEntities (pDoc->pLevel);	
		EditEntity(*Entities, pDoc->mCurrentEntity, pDoc);
		
		pDoc->UpdateEntityOrigins();
	
		if (((CDialogBar*)this->GetParent())->IsWindowVisible())	//	post 0.57
		{

				FillInDialog();
				//	Be very careful when speccing flags for UpdateAllViews()
				//	The wrong flags at the wrong time will totally screw things up
				pDoc->UpdateAllViews(UAV_ALL3DVIEWS, NULL);
				//	pDoc->SetModifiedFlag();

			if (!((CDialogBar*)this->GetParent())->IsFloating())	//	post 0.57
			{
			//	Restore focus to active view ONLY when the Prop Panel is Docked
				CMDIChildWnd *pMDIChild	=(CMDIChildWnd *)pDoc->mpMainFrame->MDIGetActive();
				if(pMDIChild)
				{
					CView	*cv	=(CView *)pMDIChild->GetActiveView();
					if( cv)
						cv->SetFocus() ;
				}
			}
		}
	}
	return true;
}


int CEntitiesDialog::EditEntity( CEntityArray& Entities, int CurrentEntity, CGenEditDoc* Doc)
{
	// If more than one entity selected, make sure they're all the same type.
	int nSel = 0;
	CString EntityClassname;
	int i;

	pDoc = Doc;
	mEntityArray = &Entities;

	for (i = 0; i < mEntityArray->GetSize(); ++i)
	{
		CEntity *pEnt;

		pEnt = &Entities[i];
		if (pEnt->IsSelected ())
		{
			if (nSel == 0)	// if it's the first one selected
			{
				EntityClassname = pEnt->GetClassname ();
				mCurrentEntity = i;
			}
			else	//	otherwise it's not the first selected entity
			{		//	compare this one with the first selected entity
					//	if selected entities are of different types
					//	TEST TO SEE IF SELECTED ENTITIES ARE OF DIFFERENT TYPES
				if (pEnt->GetClassname () != EntityClassname)
				{						
								//	new g3dc
								//	show the dialog box, keeping in mind that
						ShowDialog(false);	//	multiple types of entities are selected	
//						AfxMessageBox ("To edit multiple entities, they must all be of the same type.");
						
						return CurrentEntity; // we're outta here
				}
			}
			++nSel;
		}
	}

	//	Now, we may have only one entity selected, OR we may have multiple
	//	entities selected. But since we already tested (above) to see if multiple
	//	entities are of different types, we are confident that multiple selected
	//	entities are of the same type.

									//	MultiEntityFlag gets set to TRUE if more than
									//	one entity OF THE SAME TYPE is selected.
	MultiEntityFlag = (nSel > 1);	// 
	if (MultiEntityFlag)	// if more than one entity is selected
	{						//	don't do nuthin'
	}
	else					//	only a single entity be selected
	{
		if (CurrentEntity != -1)	//	if it's not the NULL spot on the list
		{
			mCurrentEntity = CurrentEntity;
		}
		else
		{
			//	Let's set entity 0 as selected if it exists...
			mCurrentEntity = 0;
			if (mEntityArray->GetSize()  > 0)
			{
				pDoc->ResetAllSelectedEntities();
				pDoc->SelectEntity (&(*mEntityArray)[mCurrentEntity]);
				pDoc->mCurrentEntity = mCurrentEntity;
			}
		}
	}

	ShowDialog(true);

	m_iCurrentEntity = mCurrentEntity;
	return mCurrentEntity;
}





bool CEntitiesDialog::ShowDialog(bool bShow)
{
	if (this->GetParent()->IsWindowVisible()) // post 0.57 if Properties Panel Visible
	{
		SetWindowPos(NULL,5,10,0,0,SWP_NOZORDER|SWP_NOSIZE);
		this->ShowWindow(SW_SHOW);		
		
		if (bShow)	//	single entity or multiple entities of the same type are selected
		{
			//		if (pDoc->GetSelState() & ONEENTITY)	//	NEW G3DC
			//			MultiEntityFlag = 0;
			
			m_entitiesStaticString.SetWindowText("Ready...");
			
			// we have to go through and setup all of our stuff
			FillInDialog();
			
			m_PropertiesList.EnableWindow(TRUE);

			if (!((CDialogBar*)this->GetParent())->IsFloating()) //	post 0.57
			{
				m_PropertiesList.SetFocus(); // set focus ONLY when panel is NOT floating.
				//	While undocked, this will send a SetFocus message to the MainFrame
				//	which calls UpdateMainControls, which ultimately calls this function
				//	again, resulting in an endless loop.
			}
			
			if (MultiEntityFlag)
				m_EntityCombo.EnableWindow (FALSE);
			else
				m_EntityCombo.EnableWindow(TRUE);
			
			if (!EnableToolTips (TRUE))
			{
				return FALSE;
			}
			
		}
		
		else if (!bShow)	//	different entity types are selected
		{
			m_EntityCombo.EnableWindow (FALSE);
			//		MessageBeep(MB_ICONEXCLAMATION);
			m_entitiesStaticString.SetWindowText("Not Same Type...");
			m_PropertiesList.EnableWindow(FALSE);
		}
		return true;
	}
	return true;
}

int CEntitiesDialog::DoDialog( CEntityArray& Entities, CGenEditDoc* Doc)
{
	// the list of entities
	mEntityArray = &Entities;
	pDoc = Doc;
//	DoModal();

	return mCurrentEntity;
}


int CEntitiesDialog::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const
{
	CPoint pt;
	UINT Index;
	BOOL bOutside;

	// Make point relative to properties list box
	pt = point;
	ClientToScreen (&pt);
	m_PropertiesList.ScreenToClient (&pt);

	// If the passed point is within the boundaries of the properties list box,
	// and is over one of the properties, instruct the caller to display
	// the tooltip obtained from EntityTable_GetToolTip.
	Index = m_PropertiesList.ItemFromPoint (pt, bOutside);
	if (bOutside)
	{
		return -1;
	}

	pTI->lpszText = LPSTR_TEXTCALLBACK;
	pTI->hwnd = m_hWnd;
	pTI->uId = (UINT)m_PropertiesList.m_hWnd;
	pTI->uFlags |= (TTF_IDISHWND | TTF_NOTBUTTON);
	// Ok, this is a seriously ugly hack.
	// But I can't seem to get it to work any other way.
	// I need to pass the item index to the NeedTextNotify callback, but there
	// is no field for it (apparently the above uId and uFlags must be set
	// exactly like they are, or things don't work).
	// Anyway, what I do here is set an object-global index and then retrieve it 
	// in the NeedTextNotify function.
	UglyGlobalItemId = Index;

	return 1;
}

#pragma warning (disable:4100)
BOOL CEntitiesDialog::NeedTextNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
	TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
	const char *pDocField;
	CString EntityClassname;
	CString FieldName;
	int Index;
	CEntity *pEnt;

	// default return value is nothing...
	pTTT->szText[0] = '\0';

	// Fill the szText field with the documentation string for the current field.
	
	// Get current entity selection and retrieve its name
	Index = m_EntityCombo.GetCurSel ();
	if (Index == CB_ERR)
	{
		return FALSE;
	}
	Index = m_EntityCombo.GetItemData (Index);
	pEnt = &((*mEntityArray)[Index]);
	EntityClassname = pEnt->GetClassname ();

	m_PropertiesList.GetText (UglyGlobalItemId, FieldName);

	pDocField = EntityTable_GetEntityFieldDoc (Level_GetEntityDefs (pDoc->pLevel), EntityClassname, FieldName);
	if (pDocField != NULL)
	{
		strncpy (pTTT->szText, pDocField, sizeof (pTTT->szText));
		pTTT->szText[sizeof (pTTT->szText)-1] = '\0';
	}
	return FALSE;
}
#pragma warning (default:4100)

static void stripQuotes
	(
	  CString &str
	)
{
	char *temp = Util_Strdup (str);
	
	if (*temp == '"')
	{
	    strcpy (temp, temp+1);
	}
	if (temp[strlen (temp) - 1] == '"')
	{
		temp[strlen (temp) - 1] = '\0';
	}
	str = temp;

	geRam_Free (temp);
}

//============================================================
// This funtion will go through the list of key value
// pairs and add all of the entities properly into the
// correct arrays
//============================================================
typedef struct tagSortStruct
{
	CEntity *pEnt ;
	int		nItem ;
} SSortStruct, *PSortStruct;

static int compare( const void * arg1, const void * arg2 )
{
	PSortStruct pLeft ;
	PSortStruct pRight ;
	CString		Left ;
	CString		Right ;
	int32		LeftVal, LeftLen ;
	int32		RightVal, RightLen ;

	pLeft = (PSortStruct)arg1 ;
	pRight = (PSortStruct)arg2 ;

	Left = pLeft->pEnt->GetName ();
	if (Left == "")
	{
		Left = "Unnamed";
	}

	// strip quotes from the entity name
	stripQuotes ( Left );
	
	Right = pRight->pEnt->GetName ();
	if (Right == "")
	{
		Right = "Unnamed";
	}

	// strip quotes from the entity name
	stripQuotes ( Right );

	LeftLen = Left.GetLength() ;
	Util_GetEndStringValue( Left, &LeftVal, &LeftLen ) ;
	RightLen = Right.GetLength() ;
	Util_GetEndStringValue( Right, &RightVal, &RightLen ) ;

⌨️ 快捷键说明

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