123
This commit is contained in:
952
Editor/PanelTreeBrowser.cpp
Normal file
952
Editor/PanelTreeBrowser.cpp
Normal file
@@ -0,0 +1,952 @@
|
||||
// PanelTreeBrowser.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "PanelTreeBrowser.h"
|
||||
#include "PanelPreview.h"
|
||||
|
||||
#include "ViewManager.h"
|
||||
#include "Viewport.h"
|
||||
|
||||
#include "Objects\EntityScript.h"
|
||||
|
||||
#include "EntityPrototype.h"
|
||||
#include "EntityPrototypeLibrary.h"
|
||||
#include "EntityPrototypeManager.h"
|
||||
#include "Prefabs\PrefabManager.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
// Sort the item in reverse alphabetical order.
|
||||
static int CALLBACK TreeCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
|
||||
{
|
||||
// lParamSort contains a pointer to the tree control.
|
||||
// The lParam of an item is just its handle, as specified with SetItemData
|
||||
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)lParamSort;
|
||||
|
||||
int nChilds1 = (pTreeCtrl->ItemHasChildren((HTREEITEM)lParam1) == TRUE) ? 1 : 0;
|
||||
int nChilds2 = (pTreeCtrl->ItemHasChildren((HTREEITEM)lParam2) == TRUE) ? 1 : 0;
|
||||
if (nChilds1 != nChilds2)
|
||||
return nChilds2 - nChilds1;
|
||||
|
||||
CString strItem1 = pTreeCtrl->GetItemText((HTREEITEM) lParam1);
|
||||
CString strItem2 = pTreeCtrl->GetItemText((HTREEITEM) lParam2);
|
||||
|
||||
return stricmp(strItem1, strItem2);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Simple sub string searching case insensitive.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
inline const char* strstri( const char *s1, const char *s2)
|
||||
{
|
||||
int i,j,k;
|
||||
for(i=0;s1[i];i++)
|
||||
for(j=i,k=0;tolower(s1[j])==tolower(s2[k]);j++,k++)
|
||||
if(!s2[k+1])
|
||||
return (s1+i);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CPanelTreeBrowser dialog
|
||||
StdMap<CString,int> CPanelTreeBrowser::m_selectionHistory;
|
||||
CPanelTreeBrowser::FileHistory CPanelTreeBrowser::m_fileHistory;
|
||||
|
||||
CPanelTreeBrowser::CPanelTreeBrowser(CWnd* pParent /*=NULL*/)
|
||||
: CXTResizeDialog(CPanelTreeBrowser::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CPanelTreeBrowser)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_panelPreview = NULL;
|
||||
m_panelPreviewId = 0;
|
||||
}
|
||||
|
||||
CPanelTreeBrowser::~CPanelTreeBrowser()
|
||||
{
|
||||
if (m_panelPreviewId)
|
||||
GetIEditor()->RemoveRollUpPage( ROLLUP_OBJECTS,m_panelPreviewId );
|
||||
m_panelPreviewId = 0;
|
||||
m_panelPreview = 0;
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CXTResizeDialog::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_BROWSER_TREE, m_tree);
|
||||
DDX_Control(pDX, IDC_RELOAD,m_reloadBtn );
|
||||
DDX_Control(pDX, IDC_FILTER,m_filter );
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CPanelTreeBrowser, CXTResizeDialog)
|
||||
ON_NOTIFY(NM_DBLCLK, IDC_BROWSER_TREE, OnDblclkBrowserTree)
|
||||
ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSER_TREE, OnSelchangedBrowserTree)
|
||||
ON_NOTIFY(TVN_BEGINDRAG, IDC_BROWSER_TREE, OnBeginDrag)
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_LBUTTONUP()
|
||||
ON_NOTIFY(NM_CLICK, IDC_BROWSER_TREE, OnClickBrowserTree)
|
||||
ON_BN_CLICKED(IDC_RELOAD, OnReload)
|
||||
ON_WM_DESTROY()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CPanelTreeBrowser message handlers
|
||||
|
||||
BOOL CPanelTreeBrowser::OnInitDialog()
|
||||
{
|
||||
CXTResizeDialog::OnInitDialog();
|
||||
|
||||
m_dragImage = 0;
|
||||
m_bFiles = false;
|
||||
|
||||
CMFCUtils::LoadTrueColorImageList( m_cImageList,IDB_TREE_VIEW,16,RGB(255,0,255) );
|
||||
|
||||
// Create the list
|
||||
//m_cImageList.Create(IDB_TREE_VIEW, 16, 1, RGB (255, 0, 255));
|
||||
|
||||
// Attach it to the control
|
||||
m_tree.SetImageList(&m_cImageList, TVSIL_NORMAL);
|
||||
//m_tree.SetImageList(&m_cImageList, TVSIL_STATE);
|
||||
|
||||
m_tree.SetIndent( 0 );
|
||||
//m_tree.SetBkColor( RGB(0xE0,0xE0,0xE0) );
|
||||
|
||||
SetResize( IDC_BROWSER_TREE,SZ_RESIZE(1) );
|
||||
SetResize( IDC_FILTER,SZ_RESIZE(1) );
|
||||
|
||||
// Add the Master CD folder to the list
|
||||
//HTREEITEM hRoot = m_tree.InsertItem( "Root", 2, 2, TVI_ROOT);
|
||||
|
||||
/*
|
||||
RecurseDirectory( "c:\\mastercd\\Objects", TVI_ROOT, "*.cgf" );
|
||||
|
||||
//m_tree.Expand( m_tree.GetRootItem(), TVE_COLLAPSE);
|
||||
//CRect rc;
|
||||
//GetClientRect( rc );
|
||||
//int h = m_tree.GetVisibleCount()*m_tree.GetItemHeight();
|
||||
//SetWindowPos( NULL,0,0,rc.right,h+80,SWP_NOMOVE );
|
||||
|
||||
m_tree.Expand( m_tree.GetFirstVisibleItem(), TVE_COLLAPSE);
|
||||
*/
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::OnDestroy()
|
||||
{
|
||||
CXTResizeDialog::OnDestroy();
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::Create( SelectCallback &cb,const CString &searchSpec,CWnd *parent,int flags )
|
||||
{
|
||||
CXTResizeDialog::Create( IDD,parent );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SetResize( IDC_RELOAD,SZ_HORREPOS(1) );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
m_flags = flags;
|
||||
m_bSelectOnClick = flags & SELECT_ONCLICK;
|
||||
m_bDragDropEnabled = !(flags & NO_DRAGDROP);
|
||||
|
||||
m_searchspec = searchSpec;
|
||||
Refresh(false);
|
||||
|
||||
m_selectCallback = cb;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::Refresh( bool bReloadFiles )
|
||||
{
|
||||
CWaitCursor wait;
|
||||
CString searchSpec = m_searchspec;
|
||||
|
||||
char dir[_MAX_PATH];
|
||||
char drive[_MAX_DRIVE];
|
||||
char fname[_MAX_FNAME];
|
||||
char fext[_MAX_EXT];
|
||||
|
||||
_splitpath( searchSpec,drive,dir,fname,fext );
|
||||
|
||||
CString searchPath = Path::GetPath( searchSpec );
|
||||
CString fileSpec = searchSpec.Mid( searchPath.GetLength() );
|
||||
|
||||
m_path = dir;
|
||||
m_fileSpec = fileSpec;
|
||||
|
||||
//@HACK
|
||||
// hardcoded names.
|
||||
if (searchSpec == "*EntityClass")
|
||||
{
|
||||
// Entity classes.
|
||||
FillEntityScripts();
|
||||
}
|
||||
else if (searchSpec == "*EntityPrototype")
|
||||
{
|
||||
// Entity prototypes.
|
||||
FillEntityPrototypes();
|
||||
}
|
||||
else if (searchSpec == "*Prefabs")
|
||||
{
|
||||
// Entity prototypes.
|
||||
FillPrefabs();
|
||||
}
|
||||
else
|
||||
{
|
||||
FileHistory::iterator it = m_fileHistory.find(fileSpec);
|
||||
if (it == m_fileHistory.end() || bReloadFiles)
|
||||
{
|
||||
// Load files from disk.
|
||||
FilesInfo finfo;
|
||||
LoadFiles( finfo );
|
||||
FillFiles( finfo );
|
||||
}
|
||||
else {
|
||||
FillFiles( it->second );
|
||||
}
|
||||
m_bFiles = true;
|
||||
|
||||
/*
|
||||
// Just files.
|
||||
RecurseDirectory( GetIEditor()->GetMasterCDFolder(),dir,TVI_ROOT,fileSpec );
|
||||
*/
|
||||
CString numFiles;
|
||||
numFiles.Format( "%d Files",m_itemsMap.GetCount() );
|
||||
SetDlgItemText( IDC_NUM_FILES,numFiles );
|
||||
}
|
||||
|
||||
SelectLastKnownItem();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::AddPreviewPanel()
|
||||
{
|
||||
if (m_panelPreview)
|
||||
return;
|
||||
if (!(m_flags & NO_PREVIEW) && gSettings.bPreviewGeometryWindow)
|
||||
{
|
||||
// Searching geometries.
|
||||
if (strstr(m_fileSpec,"*.ccgf") != 0 || strstr(m_fileSpec,"*.cgf") != 0 || strstr(m_fileSpec,"*.cga") != 0)
|
||||
{
|
||||
// Create Preview.
|
||||
m_panelPreview = new CPanelPreview( AfxGetMainWnd() );
|
||||
m_panelPreviewId = GetIEditor()->AddRollUpPage( ROLLUP_OBJECTS,"Object Preview",m_panelPreview );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::SelectLastKnownItem()
|
||||
{
|
||||
//Select item from history.
|
||||
int index;
|
||||
if (m_selectionHistory.Find(m_path+m_fileSpec,index))
|
||||
{
|
||||
int cnt = 0;
|
||||
HTREEITEM hItem = GetTreeItemByIndex( m_tree.GetRootItem(),index,cnt );
|
||||
if (hItem) {
|
||||
m_tree.Select( hItem,TVGN_CARET );
|
||||
m_tree.EnsureVisible( hItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::SelectFile( const CString &filename )
|
||||
{
|
||||
SelectCallback cb = m_selectCallback;
|
||||
m_selectCallback = 0;
|
||||
HTREEITEM hItem = stl::find_in_map( m_fileToItem,filename,(HTREEITEM)0 );
|
||||
if (hItem)
|
||||
{
|
||||
m_tree.Select( hItem,TVGN_CARET );
|
||||
m_tree.EnsureVisible( hItem );
|
||||
//m_tree.SetItemBold( hItem,TRUE );
|
||||
//m_tree.SetItemColor( hItem,RGB(255,0,0) );
|
||||
}
|
||||
m_selectCallback = cb;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::FillEntityScripts()
|
||||
{
|
||||
m_tree.SetRedraw(FALSE);
|
||||
m_fileToItem.clear();
|
||||
m_itemsMap.Clear();
|
||||
m_tree.DeleteAllItems();
|
||||
|
||||
CString filter;
|
||||
m_filter.GetWindowText( filter );
|
||||
bool bFilter = !filter.IsEmpty();
|
||||
|
||||
StdMap<CString,HTREEITEM> items;
|
||||
// Entity scripts.
|
||||
std::vector<CEntityScript*> scripts;
|
||||
CEntityScriptRegistry::Instance()->GetScripts( scripts );
|
||||
for (int i = 0; i < scripts.size(); i++)
|
||||
{
|
||||
// If class is not usable simply skip it.
|
||||
if (!scripts[i]->IsUsable())
|
||||
continue;
|
||||
|
||||
CString name = scripts[i]->GetName();
|
||||
|
||||
if (bFilter)
|
||||
{
|
||||
if (strstri(name,filter) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
HTREEITEM hRoot = TVI_ROOT;
|
||||
char *token;
|
||||
|
||||
CString clsFile = scripts[i]->GetRelativeFile();
|
||||
clsFile.Replace( "Scripts\\Default\\Entities\\","" );
|
||||
char classFile[1024];
|
||||
strcpy( classFile,clsFile );
|
||||
|
||||
token = strtok( classFile,"\\/" );
|
||||
|
||||
CString itemName;
|
||||
while (token)
|
||||
{
|
||||
CString strToken = token;
|
||||
|
||||
token = strtok( NULL,"\\/" );
|
||||
if (!token)
|
||||
break;
|
||||
|
||||
itemName += strToken+"\\";
|
||||
if (!items.Find( itemName,hRoot ))
|
||||
{
|
||||
hRoot = m_tree.InsertItem(strToken, 0, 0, hRoot );
|
||||
m_tree.SetItemData( hRoot,(DWORD_PTR)hRoot );// Fort sorting.
|
||||
items.Insert( itemName,hRoot );
|
||||
}
|
||||
}
|
||||
|
||||
HTREEITEM hNewItem = m_tree.InsertItem(name, 3, 3, hRoot );
|
||||
m_tree.SetItemData( hNewItem,(DWORD_PTR)hNewItem );// Fort sorting.
|
||||
m_tree.SetItemState(hNewItem, TVIS_BOLD, TVIS_BOLD);
|
||||
m_itemsMap[hNewItem] = name;
|
||||
}
|
||||
CString numFiles;
|
||||
numFiles.Format( "%d Entities",m_itemsMap.GetCount() );
|
||||
SetDlgItemText( IDC_NUM_FILES,numFiles );
|
||||
|
||||
SortTree();
|
||||
|
||||
m_tree.SetRedraw(TRUE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::FillEntityPrototypes()
|
||||
{
|
||||
m_tree.SetRedraw(FALSE);
|
||||
m_fileToItem.clear();
|
||||
m_itemsMap.Clear();
|
||||
m_tree.DeleteAllItems();
|
||||
|
||||
CString filter;
|
||||
m_filter.GetWindowText( filter );
|
||||
bool bFilter = !filter.IsEmpty();
|
||||
|
||||
CEntityPrototypeManager *protMan = GetIEditor()->GetEntityProtManager();
|
||||
|
||||
for (int j = 0; j < protMan->GetLibraryCount(); j++)
|
||||
{
|
||||
IDataBaseLibrary *lib = protMan->GetLibrary(j);
|
||||
|
||||
if (bFilter)
|
||||
{
|
||||
if (strstri(lib->GetName(),filter) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
std::map<CString,HTREEITEM> groupMap;
|
||||
|
||||
HTREEITEM hLibItem = m_tree.InsertItem( lib->GetName(), 0, 0 );
|
||||
m_tree.SetItemData( hLibItem,(DWORD_PTR)hLibItem );// Fort sorting.
|
||||
for (int i = 0; i < lib->GetItemCount(); i++)
|
||||
{
|
||||
CEntityPrototype* prototype = (CEntityPrototype*)lib->GetItem(i);
|
||||
|
||||
CString groupName = prototype->GetGroupName();
|
||||
|
||||
HTREEITEM hGroupItem = hLibItem;
|
||||
if (!groupName.IsEmpty())
|
||||
{
|
||||
HTREEITEM hItem = stl::find_in_map( groupMap,groupName,(HTREEITEM)0 );
|
||||
if (hItem)
|
||||
{
|
||||
hGroupItem = hItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
hGroupItem = m_tree.InsertItem( groupName, 0, 0, hLibItem );
|
||||
m_tree.SetItemData( hGroupItem,(DWORD_PTR)hGroupItem );// Fort sorting.
|
||||
groupMap[groupName] = hGroupItem;
|
||||
}
|
||||
}
|
||||
CString itemName = prototype->GetShortName();
|
||||
HTREEITEM hNewItem = m_tree.InsertItem(itemName, 3, 3, hGroupItem );
|
||||
m_tree.SetItemData( hNewItem,(DWORD_PTR)hNewItem );// Fort sorting.
|
||||
m_tree.SetItemState(hNewItem, TVIS_BOLD, TVIS_BOLD);
|
||||
|
||||
CString fullItemName = GuidUtil::ToString(prototype->GetGUID());
|
||||
m_itemsMap[hNewItem] = fullItemName;
|
||||
}
|
||||
}
|
||||
|
||||
CString numFiles;
|
||||
numFiles.Format( "%d Entities",m_itemsMap.GetCount() );
|
||||
SetDlgItemText( IDC_NUM_FILES,numFiles );
|
||||
|
||||
SortTree();
|
||||
|
||||
m_tree.SetRedraw(TRUE);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::FillPrefabs()
|
||||
{
|
||||
m_tree.SetRedraw(FALSE);
|
||||
m_fileToItem.clear();
|
||||
m_itemsMap.Clear();
|
||||
m_tree.DeleteAllItems();
|
||||
|
||||
CString filter;
|
||||
m_filter.GetWindowText( filter );
|
||||
bool bFilter = !filter.IsEmpty();
|
||||
|
||||
CPrefabManager *pManager = GetIEditor()->GetPrefabManager();
|
||||
|
||||
for (int j = 0; j < pManager->GetLibraryCount(); j++)
|
||||
{
|
||||
IDataBaseLibrary *lib = pManager->GetLibrary(j);
|
||||
|
||||
if (bFilter)
|
||||
{
|
||||
if (strstri(lib->GetName(),filter) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
std::map<CString,HTREEITEM> groupMap;
|
||||
|
||||
HTREEITEM hLibItem = m_tree.InsertItem( lib->GetName(), 0, 0 );
|
||||
m_tree.SetItemData( hLibItem,(DWORD_PTR)hLibItem );// Fort sorting.
|
||||
for (int i = 0; i < lib->GetItemCount(); i++)
|
||||
{
|
||||
CEntityPrototype* prototype = (CEntityPrototype*)lib->GetItem(i);
|
||||
|
||||
CString groupName = prototype->GetGroupName();
|
||||
|
||||
HTREEITEM hGroupItem = hLibItem;
|
||||
if (!groupName.IsEmpty())
|
||||
{
|
||||
HTREEITEM hItem = stl::find_in_map( groupMap,groupName,(HTREEITEM)0 );
|
||||
if (hItem)
|
||||
{
|
||||
hGroupItem = hItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
hGroupItem = m_tree.InsertItem( groupName, 0, 0, hLibItem );
|
||||
m_tree.SetItemData( hGroupItem,(DWORD_PTR)hGroupItem );// Fort sorting.
|
||||
groupMap[groupName] = hGroupItem;
|
||||
}
|
||||
}
|
||||
CString itemName = prototype->GetShortName();
|
||||
HTREEITEM hNewItem = m_tree.InsertItem(itemName, 1, 1, hGroupItem );
|
||||
m_tree.SetItemData( hNewItem,(DWORD_PTR)hNewItem );// Fort sorting.
|
||||
m_tree.SetItemState(hNewItem, TVIS_BOLD, TVIS_BOLD);
|
||||
|
||||
CString fullItemName = GuidUtil::ToString(prototype->GetGUID());
|
||||
m_itemsMap[hNewItem] = fullItemName;
|
||||
}
|
||||
}
|
||||
|
||||
CString numFiles;
|
||||
numFiles.Format( "%d Prefabs",m_itemsMap.GetCount() );
|
||||
SetDlgItemText( IDC_NUM_FILES,numFiles );
|
||||
|
||||
SortTree();
|
||||
|
||||
m_tree.SetRedraw(TRUE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CPanelTreeBrowser::RecurseDirectory( const CString &basePath,const CString &searchPath, HTREEITEM hRoot, LPCSTR pszFileSpec )
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Enumerate all files in the passed directory which match to the the
|
||||
// passed pattern. Also continue with adding all subdirectories
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CString szFolder = searchPath;
|
||||
|
||||
//char szFolder[_MAX_PATH];
|
||||
//strcpy( szFolder,searchPath );
|
||||
|
||||
CFileEnum cTempFiles;
|
||||
__finddata64_t sFile;
|
||||
char szFilePath[_MAX_PATH];
|
||||
HTREEITEM hNewRoot, hNewItem;
|
||||
|
||||
ASSERT(pszFileSpec);
|
||||
|
||||
CString fileSpec = pszFileSpec;
|
||||
std::vector<CString> fileSpecs;
|
||||
|
||||
// Split file spec with ';'
|
||||
while (!fileSpec.IsEmpty())
|
||||
{
|
||||
int splitpos = fileSpec.Find(';');
|
||||
if (splitpos < 0)
|
||||
{
|
||||
fileSpecs.push_back(fileSpec);
|
||||
break;
|
||||
}
|
||||
fileSpecs.push_back(fileSpec.Mid(0,splitpos));
|
||||
fileSpec = fileSpec.Mid(splitpos+1);
|
||||
}
|
||||
|
||||
// Make the path ready for appening a folder or filename
|
||||
szFolder = Path::AddBackslash(szFolder);
|
||||
int numFiles = 0;
|
||||
|
||||
// Start the enumeration of the files
|
||||
if (cTempFiles.StartEnumeration(szFolder, "*.*", &sFile))
|
||||
{
|
||||
do
|
||||
{
|
||||
// Construct the full filepath of the current file
|
||||
strcpy(szFilePath, szFolder);
|
||||
strcat(szFilePath, sFile.name);
|
||||
|
||||
// Have we found a directory ?
|
||||
if (sFile.attrib & _A_SUBDIR)
|
||||
{
|
||||
// Skip the parent directory entries
|
||||
if (_stricmp(sFile.name, ".") == 0 ||
|
||||
_stricmp(sFile.name, "..") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add it to the list and start recursion
|
||||
hNewRoot = m_tree.InsertItem(sFile.name, 0, 0, hRoot);
|
||||
m_tree.SetItemData( hNewRoot,(DWORD_PTR)hNewRoot );// Fort sorting.
|
||||
int num = RecurseDirectory( basePath,szFilePath, hNewRoot, pszFileSpec);
|
||||
m_tree.Expand( hNewRoot,TVE_COLLAPSE);
|
||||
m_tree.SortChildren(hNewRoot);
|
||||
if (num == 0)
|
||||
{
|
||||
// Delete empty directory item.
|
||||
m_tree.DeleteItem( hNewRoot );
|
||||
}
|
||||
numFiles += num;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int nImage = 1;
|
||||
|
||||
// Check if the file name maches the pattern
|
||||
bool bFileMatch = false;
|
||||
for (int i = 0; i < fileSpecs.size(); i++)
|
||||
{
|
||||
if (PathMatchSpec(sFile.name,fileSpecs[i]))
|
||||
{
|
||||
bFileMatch = true;
|
||||
break;
|
||||
}
|
||||
nImage = 2;
|
||||
}
|
||||
if (!bFileMatch)
|
||||
continue;
|
||||
|
||||
// Remove the extension from the name
|
||||
PathRenameExtension(sFile.name, "");
|
||||
|
||||
// Add the file to the list
|
||||
hNewItem = m_tree.InsertItem(sFile.name, nImage, nImage, hRoot);
|
||||
m_tree.SetItemData( hNewItem,(DWORD_PTR)hNewItem );// Fort sorting.
|
||||
m_tree.SetItemState(hNewItem, TVIS_BOLD, TVIS_BOLD);
|
||||
|
||||
m_itemsMap[hNewItem] = szFilePath;
|
||||
|
||||
|
||||
numFiles++;
|
||||
|
||||
} while (cTempFiles.GetNextFile(&sFile));
|
||||
}
|
||||
return numFiles;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::LoadFiles( FilesInfo &info )
|
||||
{
|
||||
CString fileSpec = m_fileSpec;
|
||||
CString currFileSpec;
|
||||
static CFileUtil::FileArray files;
|
||||
|
||||
info.files.clear();
|
||||
|
||||
// Reserve many files.
|
||||
files.resize(0);
|
||||
files.reserve( 10000 );
|
||||
|
||||
// Split file spec with ';'
|
||||
while (!fileSpec.IsEmpty())
|
||||
{
|
||||
int splitpos = fileSpec.Find(';');
|
||||
if (splitpos < 0)
|
||||
{
|
||||
currFileSpec = fileSpec;
|
||||
CFileUtil::ScanDirectory( m_path,currFileSpec,files,true );
|
||||
break;
|
||||
}
|
||||
CString currFileSpec = fileSpec.Mid(0,splitpos);
|
||||
CFileUtil::ScanDirectory( m_path,currFileSpec,files,true );
|
||||
fileSpec = fileSpec.Mid(splitpos+1);
|
||||
}
|
||||
|
||||
info.files.reserve( files.size() );
|
||||
for (int i = 0; i < files.size(); i++)
|
||||
{
|
||||
info.files.push_back( files[i].filename );
|
||||
}
|
||||
//std::sort( info.files.begin(),info.files.end() );
|
||||
|
||||
m_fileHistory[m_fileSpec] = info;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::FillFiles( FilesInfo &finfo )
|
||||
{
|
||||
m_tree.SetRedraw( FALSE );
|
||||
m_fileToItem.clear();
|
||||
m_itemsMap.Clear();
|
||||
|
||||
m_tree.DeleteAllItems();
|
||||
|
||||
int offsetPath = Path::AddBackslash(m_path).GetLength();
|
||||
|
||||
CString filter;
|
||||
m_filter.GetWindowText( filter );
|
||||
bool bFilter = !filter.IsEmpty();
|
||||
|
||||
CString filename,ext,path;
|
||||
std::map<CString,HTREEITEM> pathmap;
|
||||
for (int i = 0; i < finfo.files.size(); i++)
|
||||
{
|
||||
Path::Split( finfo.files[i],path,filename,ext );
|
||||
|
||||
if (bFilter)
|
||||
{
|
||||
if (strstri(filename,filter) == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
HTREEITEM hGroup = TVI_ROOT;
|
||||
|
||||
if (!path.IsEmpty())
|
||||
{
|
||||
hGroup = stl::find_in_map( pathmap,path,(HTREEITEM)0 );
|
||||
if (!hGroup)
|
||||
{
|
||||
hGroup = TVI_ROOT;
|
||||
int startPos = 0;
|
||||
int prevPos = 0;
|
||||
CString subpath;
|
||||
while (startPos < path.GetLength())
|
||||
{
|
||||
prevPos = startPos;
|
||||
int pos = path.Find( '\\',startPos );
|
||||
if (pos >= 0)
|
||||
{
|
||||
startPos = pos+1;
|
||||
}
|
||||
else
|
||||
startPos = path.GetLength();
|
||||
subpath = path.Mid(0,pos);
|
||||
HTREEITEM hItem = stl::find_in_map( pathmap,subpath,(HTREEITEM)0 );
|
||||
if (!hItem)
|
||||
{
|
||||
CString subGroupName = path.Mid(prevPos,startPos-prevPos-1);
|
||||
hGroup = m_tree.InsertItem( subGroupName,0,0,hGroup );
|
||||
m_tree.SetItemData( hGroup,(DWORD_PTR)hGroup );// Fort sorting.
|
||||
pathmap[subpath] = hGroup;
|
||||
}
|
||||
else
|
||||
hGroup = hItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nImage = 1;
|
||||
if (stricmp(ext,".cga")==0)
|
||||
{
|
||||
nImage = 2;
|
||||
}
|
||||
HTREEITEM hNewItem = m_tree.InsertItem( filename, nImage, nImage, hGroup );
|
||||
m_tree.SetItemData( hNewItem,(DWORD_PTR)hNewItem );// Fort sorting.
|
||||
//m_tree.SetItemState(hNewItem, TVIS_BOLD, TVIS_BOLD);
|
||||
CString filename = Path::AddBackslash(m_path) + finfo.files[i];
|
||||
m_itemsMap[hNewItem] = filename;
|
||||
m_fileToItem[filename] = hNewItem;
|
||||
}
|
||||
|
||||
SortTree();
|
||||
|
||||
m_tree.SetRedraw( TRUE );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::OnDblclkBrowserTree(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
*pResult = 0;
|
||||
|
||||
if (m_tree.GetSelectedItem() == NULL)
|
||||
return;
|
||||
|
||||
CString file = GetSelectedFile();
|
||||
if (file.IsEmpty())
|
||||
return;
|
||||
|
||||
AcceptFile( file );
|
||||
}
|
||||
|
||||
CString CPanelTreeBrowser::GetSelectedFile()
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Return the path of the currently selected file. If there is no
|
||||
// currently selected file, just a NULL terminated string will be
|
||||
// returned
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CString strFileName;
|
||||
m_itemsMap.Find( m_tree.GetSelectedItem(),strFileName );
|
||||
return strFileName;
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::AcceptFile( const CString &file )
|
||||
{
|
||||
if (!file.IsEmpty())
|
||||
{
|
||||
// Select this file.
|
||||
if (m_selectCallback)
|
||||
m_selectCallback( file );
|
||||
//GetIEditor()->StartObjectCreation( m_objectType,file );
|
||||
}
|
||||
}
|
||||
|
||||
bool CPanelTreeBrowser::GetTreeItemIndex( HTREEITEM hRoot,HTREEITEM hItem,int &index )
|
||||
{
|
||||
HTREEITEM hIt = hRoot;
|
||||
while (hIt != NULL)
|
||||
{
|
||||
if (hIt == hItem)
|
||||
return true;
|
||||
|
||||
index++;
|
||||
|
||||
if (m_tree.ItemHasChildren(hIt))
|
||||
{
|
||||
if (GetTreeItemIndex( m_tree.GetNextItem(hIt,TVGN_CHILD),hItem,index ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
hIt = m_tree.GetNextSiblingItem( hIt );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HTREEITEM CPanelTreeBrowser::GetTreeItemByIndex( HTREEITEM hRoot,int itemIndex,int &index )
|
||||
{
|
||||
HTREEITEM hIt = hRoot;
|
||||
while (hIt != NULL)
|
||||
{
|
||||
if (index == itemIndex)
|
||||
return hIt;
|
||||
|
||||
index++;
|
||||
if (m_tree.ItemHasChildren(hIt))
|
||||
{
|
||||
HTREEITEM h = GetTreeItemByIndex( m_tree.GetNextItem(hIt,TVGN_CHILD),itemIndex,index );
|
||||
if (h != NULL)
|
||||
{
|
||||
return h;
|
||||
}
|
||||
}
|
||||
hIt = m_tree.GetNextSiblingItem( hIt );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::OnSelchangedBrowserTree(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
||||
|
||||
int index = 0;
|
||||
GetTreeItemIndex( m_tree.GetRootItem(),m_tree.GetSelectedItem(),index );
|
||||
|
||||
// Store selected item in history for this browser.
|
||||
m_selectionHistory[m_path+m_fileSpec] = index;
|
||||
|
||||
// If geometry update preview.
|
||||
if (m_panelPreview)
|
||||
{
|
||||
CString file = "";
|
||||
m_itemsMap.Find( pNMTreeView->itemNew.hItem,file );
|
||||
if (!file.IsEmpty())
|
||||
{
|
||||
// Check if preview panel is expended.
|
||||
m_panelPreview->LoadFile( file );
|
||||
}
|
||||
}
|
||||
if (m_bSelectOnClick)
|
||||
{
|
||||
CString file = "";
|
||||
m_itemsMap.Find( pNMTreeView->itemNew.hItem,file );
|
||||
if (!file.IsEmpty())
|
||||
{
|
||||
if (m_selectCallback)
|
||||
m_selectCallback( file );
|
||||
}
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
||||
|
||||
if (!m_bDragDropEnabled)
|
||||
return;
|
||||
|
||||
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
|
||||
|
||||
m_draggedFile = "";
|
||||
m_itemsMap.Find( hItem,m_draggedFile );
|
||||
if (m_draggedFile.IsEmpty())
|
||||
return;
|
||||
|
||||
m_tree.Select( hItem,TVGN_CARET );
|
||||
|
||||
m_dragImage = m_tree.CreateDragImage( hItem );
|
||||
if (m_dragImage)
|
||||
{
|
||||
m_dragImage->BeginDrag(0, CPoint(-10, -10));
|
||||
|
||||
CRect rc;
|
||||
AfxGetMainWnd()->GetWindowRect( rc );
|
||||
|
||||
CPoint p = pNMTreeView->ptDrag;
|
||||
ClientToScreen( &p );
|
||||
p.x -= rc.left;
|
||||
p.y -= rc.top;
|
||||
|
||||
m_dragImage->DragEnter( AfxGetMainWnd(),p );
|
||||
SetCapture();
|
||||
GetIEditor()->EnableUpdate( false );
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::OnMouseMove(UINT nFlags, CPoint point)
|
||||
{
|
||||
CRect rc;
|
||||
AfxGetMainWnd()->GetWindowRect( rc );
|
||||
|
||||
ClientToScreen( &point );
|
||||
point.x -= rc.left;
|
||||
point.y -= rc.top;
|
||||
|
||||
if (m_dragImage)
|
||||
{
|
||||
m_dragImage->DragMove( point );
|
||||
}
|
||||
|
||||
//CXTResizeDialog::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::OnLButtonUp(UINT nFlags, CPoint point)
|
||||
{
|
||||
//CXTResizeDialog::OnLButtonUp(nFlags, point);
|
||||
|
||||
if (m_dragImage)
|
||||
{
|
||||
CPoint p;
|
||||
GetCursorPos( &p );
|
||||
|
||||
GetIEditor()->EnableUpdate( true );
|
||||
|
||||
m_dragImage->DragLeave( AfxGetMainWnd() );
|
||||
m_dragImage->EndDrag();
|
||||
delete m_dragImage;
|
||||
m_dragImage = 0;
|
||||
ReleaseCapture();
|
||||
|
||||
CViewport *pView = GetIEditor()->GetViewManager()->GetViewportAtPoint(p);
|
||||
if (pView)
|
||||
{
|
||||
// Drag and drop into one of views.
|
||||
// Start object creation.
|
||||
AcceptFile( m_draggedFile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPanelTreeBrowser::OnClickBrowserTree(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::OnReload()
|
||||
{
|
||||
Refresh(true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::SortItem( HTREEITEM hParent )
|
||||
{
|
||||
TVSORTCB tvs;
|
||||
tvs.hParent = hParent;
|
||||
tvs.lpfnCompare = TreeCompareProc;
|
||||
tvs.lParam = (LPARAM)&m_tree;
|
||||
m_tree.SortChildrenCB(&tvs);
|
||||
|
||||
// Look at all of the root-level items
|
||||
HTREEITEM hCurrent = m_tree.GetNextItem( hParent,TVGN_CHILD );
|
||||
while (hCurrent != NULL)
|
||||
{
|
||||
SortItem( hCurrent );
|
||||
// Try to get the next item
|
||||
hCurrent = m_tree.GetNextItem(hCurrent, TVGN_NEXT);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CPanelTreeBrowser::SortTree()
|
||||
{
|
||||
SortItem( TVI_ROOT );
|
||||
}
|
||||
Reference in New Issue
Block a user