Serious-Engine/Sources/WorldEditor/BrowseWindow.cpp
2016-03-11 15:57:17 +02:00

1520 lines
43 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
// BrowseWindow.cpp : implementation file
//
#include "stdafx.h"
#include "BrowseWindow.h"
#include <shlobj.h>
#include <Engine/Templates/Stock_CTextureData.h>
#include <Engine/Templates/Stock_CEntityClass.h>
#ifdef _DEBUG
#undef new
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
INDEX _iLastHittedItem = -1;
static CTFileName _fnRightClickedItemFileName;
static BOOL _bRightClickedIsSelected;
/////////////////////////////////////////////////////////////////////////////
// CBrowseWindow
CBrowseWindow::CBrowseWindow()
{
m_pDrawPort = NULL;
m_pViewPort = NULL;
m_iLastHittedItem = 0;
m_bDirectoryOpen = FALSE;
}
CBrowseWindow::~CBrowseWindow()
{
if( m_pViewPort != NULL)
{
_pGfx->DestroyWindowCanvas( m_pViewPort);
m_pViewPort = NULL;
}
}
BEGIN_MESSAGE_MAP(CBrowseWindow, CWnd)
//{{AFX_MSG_MAP(CBrowseWindow)
ON_WM_VSCROLL()
ON_WM_PAINT()
ON_WM_DROPFILES()
ON_WM_SIZE()
ON_COMMAND(ID_INSERT_ITEMS, OnInsertItems)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_DELETE_ITEMS, OnDeleteItems)
ON_COMMAND(ID_BIG_ICONS, OnBigIcons)
ON_COMMAND(ID_MEDIUM_ICONS, OnMediumIcons)
ON_COMMAND(ID_SMALL_ICONS, OnSmallIcons)
ON_COMMAND(ID_SHOW_DESCRIPTION, OnShowDescription)
ON_COMMAND(ID_SHOW_FILENAME, OnShowFilename)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(ID_RECREATE_TEXTURE, OnRecreateTexture)
ON_COMMAND(ID_CREATE_AND_ADD_TEXTURE, OnCreateAndAddTexture)
ON_COMMAND(ID_SELECT_BY_TEXTURE_IN_SELECTED_SECTORS, OnSelectByTextureInSelectedSectors)
ON_COMMAND(ID_SELECT_BY_TEXTURE_IN_WORLD, OnSelectByTextureInWorld)
ON_COMMAND(ID_SELECT_FOR_DROP_MARKER, OnSelectForDropMarker)
ON_COMMAND(ID_SET_AS_CURRENT_TEXTURE, OnSetAsCurrentTexture)
ON_COMMAND(ID_CONVERT_CLASS, OnConvertClass)
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_MICRO_ICONS, OnMicroIcons)
ON_COMMAND(ID_SELECT_EXCEPT_TEXTURES, OnSelectExceptTextures)
ON_COMMAND(ID_ADD_TEXTURES_FROM_WORLD, OnAddTexturesFromWorld)
ON_COMMAND(ID_SHOW_TREE_SHORTCUTS, OnShowTreeShortcuts)
ON_COMMAND(ID_EXPORT_TEXTURE, OnExportTexture)
ON_COMMAND(ID_BROWSER_CONTEXT_HELP, OnBrowserContextHelp)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBrowseWindow message handlers
BOOL CBrowseWindow::AttachToControl( CWnd *pwndParent)
{
BOOL bResult = TRUE;
bResult = Create( NULL, NULL, WS_BORDER|WS_VISIBLE|WS_VSCROLL, CRect(0,0,10,10),
pwndParent, IDW_BROWSER);
if( bResult)
{
DragAcceptFiles();
}
SetFocus();
EnableToolTips( TRUE);
return bResult;
}
void CBrowseWindow::SetBrowserPtr( CBrowser *pBrowser)
{
m_pBrowser = pBrowser;
}
void CBrowseWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int iPosition = GetScrollPos(SB_VERT);
int intMin, intMax;
GetScrollRange( SB_VERT, &intMin, &intMax);
INDEX iMin = intMin;
INDEX iMax = intMax;
switch( nSBCode )
{
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
{
SetScrollPos(SB_VERT, nPos);
break;
}
case SB_LINEDOWN:
{
iPosition = Clamp( iPosition+m_IconHeight, iMin, iMax);
SetScrollPos(SB_VERT, iPosition);
break;
}
case SB_PAGEDOWN:
{
iPosition = Clamp( iPosition+m_IconsInColumn*m_IconHeight, iMin, iMax);
SetScrollPos(SB_VERT, iPosition);
break;
}
case SB_LINEUP:
{
iPosition = Clamp( iPosition-m_IconHeight, iMin, iMax);
SetScrollPos(SB_VERT, iPosition);
break;
}
case SB_PAGEUP:
{
iPosition = Clamp( iPosition-m_IconsInColumn*m_IconHeight, iMin, iMax);
SetScrollPos(SB_VERT, iPosition);
break;
}
}
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
Invalidate(FALSE);
}
#define BOX( dp, xs, ys, w, h, color, type) \
dp->DrawLine( xs, ys, xs, ys+h, color, type); \
dp->DrawLine( xs, ys+h, xs+w, ys+h, color, type); \
dp->DrawLine( xs+w, ys+h, xs+w, ys, color, type); \
dp->DrawLine( xs+w, ys, xs, ys, color, type);
#define ICONS_TRAY_WIDTH 16
#define ICONS_TRAY_HEIGHT 16
void CBrowseWindow::OnPaint()
{
{
CPaintDC dc(this); // device context for painting (does BeginPaint()/EndPaint()!)
}
CWorldEditorApp *pApp = (CWorldEditorApp *)AfxGetApp();
PIXaabbox2D rectPict;
INDEX i;
if (m_pDrawPort==NULL || !m_pDrawPort->Lock()) {
return;
}
// To write description
m_pDrawPort->SetFont( theApp.m_pfntSystem);
m_pDrawPort->SetTextAspect( 1.0f);
// clear browsing window
m_pDrawPort->FillZBuffer( ZBUF_BACK);
m_pDrawPort->Fill( C_BLACK | CT_OPAQUE);
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if (pVTNDir==NULL) {
m_pDrawPort->Unlock();
return;
}
if(m_bDirectoryOpen)
{
INDEX iYOffset = GetScrollPos( SB_VERT);
INDEX iLineVisible = iYOffset/m_IconHeight;
PIX pixStart = iYOffset%m_IconHeight;
for( i=0; i<m_IconsVisible+m_IconsInLine; i++)
{
CVirtualTreeNode *pVTN = GetItem( i + iLineVisible*m_IconsInLine);
if( pVTN == NULL)
{
break;
}
PIX x = (i%m_IconsInLine) * m_IconWidth;
PIX y = (i/m_IconsInLine) * m_IconHeight - pixStart + ICONS_TRAY_HEIGHT + 1;
switch( pVTNDir->vtn_bmBrowsingMode)
{
case BM_ICONS_MICRO:
case BM_ICONS_SMALL:
case BM_ICONS_MEDIUM:
case BM_ICONS_LARGE:
{
PIX pixIconWidth = m_IconWidth;
PIX pixIconHeight = m_IconHeight;
// if we are browsing large icons, leave some space for icon text
if( pVTNDir->vtn_bmBrowsingMode == BM_ICONS_LARGE)
{
pixIconHeight -= STRING_HEIGHT;
}
// set error texture
CTextureData *ptdIcon = pApp->m_ptdError;
if( pVTN->vtn_pTextureData != NULL)
{
ptdIcon = pVTN->vtn_pTextureData;
}
// get texture width and height
PIX pixTextureWidth = ptdIcon->GetWidth();
PIX pixTextureHeight= ptdIcon->GetHeight();
// apply texture aspect ratio to icon
if( pixTextureWidth>pixTextureHeight)
{
pixIconHeight /= pixTextureWidth/pixTextureHeight;
}
else
{
pixIconWidth /= pixTextureHeight/pixTextureWidth;
}
// if we have large icons
if( pVTNDir->vtn_bmBrowsingMode == BM_ICONS_LARGE)
{
// rectangle for texture polygon is smaller because of subtitling info text
rectPict = PIXaabbox2D(
PIX2D(x+m_IconWidth/2-pixIconWidth/2+1, y+m_IconHeight/2-pixIconHeight/2+1),
PIX2D(x+m_IconWidth/2+pixIconWidth/2-2, y+m_IconHeight/2+pixIconHeight/2-2-STRING_HEIGHT));
}
else
{
// texture box covers maximum space
rectPict = PIXaabbox2D(
PIX2D(x+m_IconWidth/2-pixIconWidth/2+1, y+m_IconHeight/2-pixIconHeight/2+1),
PIX2D(x+m_IconWidth/2+pixIconWidth/2-2, y+m_IconHeight/2+pixIconHeight/2-2));
}
// draw icon
CTextureObject toIcon;
toIcon.SetData( ptdIcon);
m_pDrawPort->PutTexture( &toIcon, rectPict);
// if we have large icons
if( pVTNDir->vtn_bmBrowsingMode == BM_ICONS_LARGE)
{
// type info text
if( pVTN->vtn_fnItem.FileExt() == ".tex")
{
m_pDrawPort->PutText( pVTN->vtn_fnItem.FileName(), x, y + m_IconHeight-2-STRING_HEIGHT);
}
else
{
m_pDrawPort->PutText( pVTN->vtn_strName, x, y + m_IconHeight-2-STRING_HEIGHT);
}
}
if( pVTN->vtn_bSelected)
{
BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_WHITE|CT_OPAQUE, _FULL_);
BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_lRED|CT_OPAQUE, _POINT_);
}
break;
}
case BM_DESCRIPTION:
case BM_FILENAME:
{
// First paint little icon
rectPict = PIXaabbox2D( PIX2D(x, y), PIX2D(x+STRING_HEIGHT, y+STRING_HEIGHT));
if( pVTN->vtn_pTextureData != NULL)
{
CTextureObject toIcon;
toIcon.SetData( pVTN->vtn_pTextureData);
m_pDrawPort->PutTexture( &toIcon, rectPict);
}
else
{
m_pDrawPort->PutTexture( pApp->m_ptoError, rectPict);
}
// if we are using descriptive name
if( pVTNDir->vtn_bmBrowsingMode == BM_DESCRIPTION)
{
if( pVTN->vtn_fnItem.FileExt() == ".tex")
{
m_pDrawPort->PutText( pVTN->vtn_fnItem.FileName(), x + STRING_HEIGHT, y);
}
else
{
m_pDrawPort->PutText( pVTN->vtn_strName, x + STRING_HEIGHT, y);
}
}
// if we are using file name
else
{
m_pDrawPort->PutText( pVTN->vtn_fnItem, x + STRING_HEIGHT, y);
}
if( pVTN->vtn_bSelected)
{
BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_WHITE|CT_OPAQUE, _FULL_);
BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_lRED|CT_OPAQUE, _POINT_);
}
break;
}
default:
{
ASSERTALWAYS( "Unrecognizible browsing type found !");
}
}
}
}
// draw icons tray
CTextureObject to;
to.SetData(theApp.m_ptdIconsTray);
INDEX iSelected=0;
switch( pVTNDir->vtn_bmBrowsingMode)
{
case BM_ICONS_MICRO: iSelected = 0; break;
case BM_ICONS_SMALL: iSelected = 1; break;
case BM_ICONS_MEDIUM: iSelected = 2; break;
case BM_ICONS_LARGE: iSelected = 3; break;
case BM_DESCRIPTION: iSelected = 4; break;
case BM_FILENAME: iSelected = 5; break;
}
FLOAT fRatio = theApp.m_ptdIconsTray->GetWidth()/theApp.m_ptdIconsTray->GetPixWidth();
MEX2D mex2dStart = MEX2D(0, MEX(iSelected*16*fRatio));
MEX2D mex2dEnd = MEX2D(MEX(16*8*fRatio), MEX((iSelected*16+16)*fRatio));
MEXaabbox2D boxTexture = MEXaabbox2D( mex2dStart, mex2dEnd);
PIXaabbox2D boxScreen = PIXaabbox2D( PIX2D(0, 0), PIX2D(8*16, 16));
m_pDrawPort->Fill( 0, 0, m_pDrawPort->GetWidth(), 17, C_BLACK|CT_OPAQUE);
m_pDrawPort->PutTexture( &to, boxScreen, boxTexture);
m_pDrawPort->Unlock();
m_pViewPort->SwapBuffers();
}
void CBrowseWindow::OnContextMenu( CPoint point)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL)
{
AfxMessageBox( L"Virtual tree doesn't yet exists. Create at least one virtual directory "
L"to be able to insert items into it.");
return;
}
CWorldEditorDoc *pDoc = theApp.GetDocument();
// convert coordinates from screen to client
CPoint ptClientCoordinates = point;
ScreenToClient( &ptClientCoordinates);
// Add hit icon to selection
FLOAT fDummyX, fDummyY;
INDEX iHittedItem = HitItem( ptClientCoordinates, fDummyX, fDummyY);
_fnRightClickedItemFileName = CTString("");
if( iHittedItem != -1)
{
CVirtualTreeNode *pVTN = GetItem( iHittedItem);
ASSERT( pVTN != NULL);
_fnRightClickedItemFileName = pVTN->vtn_fnItem;
_bRightClickedIsSelected = pVTN->vtn_bSelected;
}
CMenu menu;
if( menu.LoadMenu(IDR_BROWSERPOPUP))
{
CMenu* pPopup = menu.GetSubMenu(0);
UINT iRecreateTextureCommandState = MF_DISABLED|MF_GRAYED;
if( _fnRightClickedItemFileName.FileExt()==CTString(".tex") ||
_fnRightClickedItemFileName.FileExt()==CTString(".tbn") )
{
iRecreateTextureCommandState = MF_ENABLED;
}
// enable recreate texture and set as current texture commands if texture right-clicked
pPopup->EnableMenuItem(ID_RECREATE_TEXTURE, iRecreateTextureCommandState);
pPopup->EnableMenuItem(ID_SET_AS_CURRENT_TEXTURE, iRecreateTextureCommandState);
pPopup->EnableMenuItem(ID_EXPORT_TEXTURE, iRecreateTextureCommandState);
UINT iSelectForDropMarkerCommandState = MF_DISABLED|MF_GRAYED;
if( _fnRightClickedItemFileName.FileExt()==CTString(".ecl"))
{
iSelectForDropMarkerCommandState = MF_ENABLED;
}
// enable recreate texture command if texture right-clicked
pPopup->EnableMenuItem(ID_SELECT_FOR_DROP_MARKER, iSelectForDropMarkerCommandState);
if( pDoc == NULL)
{
pPopup->EnableMenuItem(ID_ADD_TEXTURES_FROM_WORLD, MF_DISABLED|MF_GRAYED);
pPopup->EnableMenuItem(ID_SELECT_EXCEPT_TEXTURES, MF_DISABLED|MF_GRAYED);
}
// enable select by texture commands only if texture is right-clicked and document exists
UINT iSelectByTextureCommandState = MF_DISABLED|MF_GRAYED;
if( (_fnRightClickedItemFileName.FileExt()==CTString(".tex")) && (pDoc!=NULL))
{
iSelectByTextureCommandState = MF_ENABLED;
}
UINT iConvertClassCommandState = MF_DISABLED|MF_GRAYED;
if( (_fnRightClickedItemFileName.FileExt()==CTString(".ecl")) &&
(pDoc!=NULL) &&
(pDoc->m_selEntitySelection.Count() != 0) &&
(pDoc->m_iMode == ENTITY_MODE) )
{
iConvertClassCommandState = MF_ENABLED;
}
pPopup->EnableMenuItem(ID_SELECT_BY_TEXTURE_IN_SELECTED_SECTORS, iSelectByTextureCommandState);
pPopup->EnableMenuItem(ID_SELECT_BY_TEXTURE_IN_WORLD, iSelectByTextureCommandState);
pPopup->EnableMenuItem(ID_CONVERT_CLASS, iConvertClassCommandState);
UINT iClassHelp = MF_DISABLED|MF_GRAYED;
if( _fnRightClickedItemFileName.FileExt()==CTString(".ecl"))
{
iClassHelp = MF_ENABLED;
}
pPopup->EnableMenuItem(ID_BROWSER_CONTEXT_HELP, iClassHelp);
pPopup->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,
point.x, point.y, this);
}
}
INDEX CBrowseWindow::HitItem( CPoint point, FLOAT &fHitXOffset, FLOAT &fHitYOffset) const
{
PIXaabbox2D rectItem;
PIXaabbox2D boxPoint;
INDEX i;
INDEX iYOffset = GetScrollPos( SB_VERT);
INDEX iLineVisible = iYOffset/m_IconHeight;
PIX pixStart = iYOffset%m_IconHeight;
for( i=0; i<m_IconsVisible; i++)
{
CVirtualTreeNode *pVTN = GetItem( i + iLineVisible*m_IconsInLine);
if( pVTN == NULL)
{
break;
}
PIX x = i%m_IconsInLine * m_IconWidth;
PIX y = i/m_IconsInLine * m_IconHeight - pixStart + ICONS_TRAY_HEIGHT + 1;
rectItem = PIXaabbox2D( PIX2D(x, y), PIX2D(x+m_IconWidth, y+m_IconHeight));
boxPoint = PIXaabbox2D( PIX2D(point.x, point.y) );
if( (rectItem & boxPoint) == boxPoint)
{
fHitXOffset = FLOAT((point.x-x))/m_IconWidth;
fHitYOffset = FLOAT((point.y-y))/m_IconHeight;
return (i + iLineVisible*m_IconsInLine);
}
}
return -1;
}
HGLOBAL CreateHDrop( const CTFileName &fnToDrag, BOOL bAddAppPath/*=TRUE*/)
{
CTFileName fnFullToDrag;
if( bAddAppPath)
{
fnFullToDrag = _fnmApplicationPath + fnToDrag;
}
else
{
fnFullToDrag = fnToDrag;
}
HGLOBAL hGlobal;
// allocate space for DROPFILE structure plus the number of file and one extra byte for final NULL terminator
hGlobal = GlobalAlloc(GHND|GMEM_SHARE,(DWORD) (sizeof(DROPFILES)+strlen(fnFullToDrag)+2));
if(hGlobal == NULL)
return hGlobal;
LPDROPFILES pDropFiles;
char *pchDropFileName;
pDropFiles = (LPDROPFILES)GlobalLock(hGlobal);
pchDropFileName = ((char *)pDropFiles)+sizeof(DROPFILES);
// set the offset where the starting point of the file start
pDropFiles->pFiles = sizeof(DROPFILES);
// filename does not contain wide characters
pDropFiles->fWide = FALSE;
// we want drop point's coordinates in client area
pDropFiles->fNC = FALSE;
strcpy(pchDropFileName, (const char *)fnFullToDrag);
// final null terminator as per CF_HDROP Format specs.
pchDropFileName[strlen(pchDropFileName)+1]=0;
GlobalUnlock(hGlobal);
return hGlobal;
}
void CBrowseWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL) return;
// if we hitted icons tray
if( (point.x < ICONS_TRAY_WIDTH*6) && (point.y < (ICONS_TRAY_HEIGHT + 1)) )
{
INDEX iSelected = point.x/ICONS_TRAY_WIDTH;
switch( iSelected)
{
case 0: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MICRO; break;
case 1: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_SMALL; break;
case 2: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MEDIUM; break;
case 3: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_LARGE; break;
case 4: pVTNDir->vtn_bmBrowsingMode = BM_DESCRIPTION; break;
case 5: pVTNDir->vtn_bmBrowsingMode = BM_FILENAME; break;
}
Refresh();
return;
}
// toggle hitted icon selection status
FLOAT fDummyX, fDummyY;
INDEX iHittedItem = HitItem( point, fDummyX, fDummyY);
if( iHittedItem == -1) return;
BOOL bShift = (nFlags & MK_SHIFT);
BOOL bCtrl = (nFlags & MK_CONTROL);
if( !bCtrl)
{
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
it->vtn_bSelected = FALSE;
}
}
INDEX ctItems = 0;
{FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
if( !it->vtn_bIsDirectory) ctItems++;
}}
INDEX iMin = iHittedItem;
INDEX iMax = iHittedItem;
if( bShift)
{
iMin = ClampDn( Min( m_iLastHittedItem, iHittedItem), (INDEX)0);
iMax = ClampUp( Max( m_iLastHittedItem, iHittedItem), ctItems);
}
INDEX iCurrent = 0;
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
CVirtualTreeNode &vtn = *it;
if( !vtn.vtn_bIsDirectory)
{
if( (iCurrent >= iMin) && (iCurrent <= iMax) )
{
if( bCtrl&&!bShift)
{
vtn.vtn_bSelected = !vtn.vtn_bSelected;
}
else
{
vtn.vtn_bSelected = TRUE;
}
}
iCurrent++;
}
}
if( !bShift) m_iLastHittedItem = iHittedItem;
CVirtualTreeNode *pVTNHit = GetItem( iHittedItem);
HGLOBAL hglobal = CreateHDrop( pVTNHit->vtn_fnItem);
m_DataSource.CacheGlobalData( CF_HDROP, hglobal);
m_DataSource.DoDragDrop( DROPEFFECT_COPY);
Invalidate( FALSE);
}
void CBrowseWindow::OnDropFiles(HDROP hDropInfo)
{
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
INDEX iNoOfFiles = DragQueryFile( hDropInfo, 0xFFFFFFFF, NULL, 0);
char chrFile[ 256];
// get dropped coordinates
CPoint point;
DragQueryPoint( hDropInfo, &point);
CVirtualTreeNode *pVTN = m_pBrowser->GetSelectedDirectory();
if( pVTN != NULL)
{
CloseDirectory( pVTN);
for( INDEX i=0; i<iNoOfFiles; i++)
{
DragQueryFileA( hDropInfo, i, chrFile, 256);
CTFileName fnDroped = CTString(chrFile);
if( fnDroped != CTString("") )
{
try
{
fnDroped.RemoveApplicationPath_t();
InsertItem( fnDroped, point);
}
catch( char *err_str)
{
AfxMessageBox( CString(err_str));
}
}
}
OpenDirectory( pVTN);
}
else
{
AfxMessageBox( L"ERROR: Virtual tree doesn't exist.");
}
CWnd::OnDropFiles(hDropInfo);
}
CVirtualTreeNode *CBrowseWindow::GetItem( INDEX iItem) const
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL)
{
return NULL;
}
INDEX ct=0;
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
//
if( !it->vtn_bIsDirectory)
{
if( ct == iItem)
{
return( &it.Current());
}
ct++;
}
}
return NULL;
}
INDEX CBrowseWindow::GetItemNo( CVirtualTreeNode *pVTN)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL)
{
return -1;
}
if( pVTNDir->vtn_lhChildren.IsEmpty())
{
return -1;
}
INDEX ct=0;
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
if( !it->vtn_bIsDirectory)
{
if( &it.Current() == pVTN)
{
return( ct);
}
ct++;
}
}
return -1;
}
void CBrowseWindow::InsertItem( CTFileName fnItem, CPoint pt)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL)
{
return;
}
FLOAT fHitXRatio;
FLOAT fHitYRatio;
INDEX iHittedItem = HitItem( pt, fHitXRatio, fHitYRatio);
CVirtualTreeNode *pVTNHit = NULL;
if( iHittedItem != -1)
{
pVTNHit = GetItem( iHittedItem);
}
CVirtualTreeNode *pvtnToRemove = NULL;
// check for all items in current virtual tree directory
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
// if it isn't directory means that it is item
if( !it->vtn_bIsDirectory)
{
// don't allow inserting same item twice
if( it->vtn_fnItem == fnItem)
{
if( pt.x == -1) return;
pvtnToRemove = &it.Current();
}
}
}
if( (pVTNHit == pvtnToRemove) && (pVTNHit != NULL) ) return;
if( pvtnToRemove != NULL)
{
pvtnToRemove->vtn_lnInDirectory.Remove();
if( pvtnToRemove->vtn_pTextureData != NULL)
{
_pTextureStock->Release( pvtnToRemove->vtn_pTextureData);
}
delete pvtnToRemove;
}
// if item is texture
if( fnItem.FileExt() == ".tex")
{
CTextureData *ptdTexture;
// try to
try
{
// obtain texture
ptdTexture = _pTextureStock->Obtain_t( fnItem);
}
// catch and
catch( char *err_str)
{
// report errors
AfxMessageBox( CString(err_str));
return;
}
// now it must be valid
ASSERT( ptdTexture != NULL);
// get texture dimensions
MEX mexWidth = ptdTexture->GetWidth();
MEX mexHeight = ptdTexture->GetHeight();
// release texture, we don't need it any more
_pTextureStock->Release( ptdTexture);
// mark both dimensions as incorrect
BOOL bWidthOk = FALSE;
BOOL bHeightOk = FALSE;
// see if both width and height are potentions of 2
for( INDEX i=0; i<32; i++)
{
// check width, mark if correct
if( (1L << i) == mexWidth) bWidthOk = TRUE;
if( (1L << i) == mexHeight) bHeightOk = TRUE;
}
// if width or height are not potentios of 2
if( !bWidthOk || !bHeightOk)
{
char err_str[ 256];
sprintf( err_str, "Dropped texture \"%s\" has incorrect dimensions %.2f x %.2f."
"All textures must have dimensions that are potentions of 2.",
(CTString&)fnItem, METERS_MEX( mexWidth), METERS_MEX( mexHeight));
AfxMessageBox( CString(err_str));
return;
}
}
else if( fnItem.FileExt() == ".ecl")
{
// obtain class
CEntityClass *pec = _pEntityClassStock->Obtain_t( fnItem);
// get thumbnail file name from the class
CTFileName fnThumbnail = CTString(pec->ec_pdecDLLClass->dec_strIconFileName);
// release class
_pEntityClassStock->Release( pec);
// if thumbnail's name is "", don't add this item
if( fnThumbnail == CTString("") )
{
return;
}
}
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
CVirtualTreeNode *pVTN = new CVirtualTreeNode;
pVTN->vtn_fnItem = fnItem;
pVTN->vtn_bIsDirectory = FALSE;
pVTN->vtn_strName = fnItem.FileName();
if( pVTNDir->vtn_lhChildren.Count() == 0)
{
pVTN->vtn_bSelected = TRUE;
}
if( pt.x == -1)
{
pVTNDir->vtn_lhChildren.AddTail( pVTN->vtn_lnInDirectory);
}
else
{
if( iHittedItem == -1)
{
pVTNDir->vtn_lhChildren.AddTail( pVTN->vtn_lnInDirectory);
}
else if( ((m_IconsInLine != 1) && (fHitXRatio < 0.5f)) ||
((m_IconsInLine == 1) && (fHitYRatio < 0.5f)) )
{
ASSERT( pVTNHit != NULL);
pVTNHit->vtn_lnInDirectory.AddBefore( pVTN->vtn_lnInDirectory);
}
else
{
ASSERT( pVTNHit != NULL);
pVTNHit->vtn_lnInDirectory.AddAfter( pVTN->vtn_lnInDirectory);
}
}
m_pBrowser->m_bVirtualTreeChanged = TRUE;
Invalidate(FALSE);
}
void CBrowseWindow::DeleteSelectedItems()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL)
{
return;
}
FORDELETELIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
if( !it->vtn_bIsDirectory)
{
if( it->vtn_bSelected)
{
it->vtn_lnInDirectory.Remove();
if( it->vtn_pTextureData != NULL)
{
_pTextureStock->Release( it->vtn_pTextureData);
}
delete &it.Current();
}
}
}
m_pBrowser->m_bVirtualTreeChanged = TRUE;
Invalidate(FALSE);
}
void CBrowseWindow::Refresh(void)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( (pVTNDir == NULL) || (!m_bDirectoryOpen) )
{
return;
}
switch( pVTNDir->vtn_bmBrowsingMode)
{
case BM_ICONS_MICRO:
{
m_IconWidth = 16;
m_IconHeight = 16;
break;
}
case BM_ICONS_SMALL:
{
m_IconWidth = 32;
m_IconHeight = 32;
break;
}
case BM_ICONS_MEDIUM:
{
m_IconWidth = 64;
m_IconHeight = 64;
break;
}
case BM_ICONS_LARGE:
{
m_IconWidth = 128;
// allow some space for text
m_IconHeight = 128 + STRING_HEIGHT;
break;
}
case BM_DESCRIPTION:
case BM_FILENAME:
{
m_IconWidth = m_BrowseWndWidth - 8;
m_IconHeight = STRING_HEIGHT;
break;
}
default:
{
ASSERTALWAYS( "Unrecognizible browsing type found !");
}
}
m_IconsInLine = m_BrowseWndWidth/m_IconWidth;
if( m_IconsInLine == 0)
{
m_IconsInLine = 1;
}
m_IconsInColumn = m_BrowseWndHeight/m_IconHeight + 1;
m_IconsVisible = m_IconsInLine * m_IconsInColumn;
INDEX iItemsCt = -1;
if( !pVTNDir->vtn_lhChildren.IsEmpty())
{
iItemsCt = GetItemNo( LIST_TAIL( pVTNDir->vtn_lhChildren,
CVirtualTreeNode, vtn_lnInDirectory) );
}
INDEX ctLines = iItemsCt/m_IconsInLine;
SetScrollRange( SB_VERT, 0, ctLines*m_IconHeight);
Invalidate(FALSE);
}
void CBrowseWindow::OpenDirectory( CVirtualTreeNode *pVTNDir)
{
CWorldEditorApp *pApp = (CWorldEditorApp *)AfxGetApp();
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
if(m_bDirectoryOpen || pVTNDir==NULL)
{
return;
}
ASSERT( pVTNDir != NULL);
// remember name of last opened virtual tree
theApp.m_strOpenedVTDirectory = theApp.GetNameForVirtualTreeNode( pVTNDir);
wchar_t achrOpenedDirectoryMessage[ 256];
swprintf( achrOpenedDirectoryMessage, L"Opened directory: \"%s\"",
CString(theApp.m_strOpenedVTDirectory));
// put selected directory name into status line
pMainFrame->m_wndStatusBar.SetPaneText( STATUS_LINE_PANE, achrOpenedDirectoryMessage, TRUE);
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
try
{
// if not directory
if( !it->vtn_bIsDirectory)
{
CTFileName fnThumbnail; // thumbnail's file name
// if texture
if( it->vtn_fnItem.FileExt() == ".tex")
{
// use same texture for thumbnail
fnThumbnail = it->vtn_fnItem;
}
// if world
else if ( it->vtn_fnItem.FileExt() == ".wld")
{
// use file name with extension .tbn for thumbnail
fnThumbnail = it->vtn_fnItem.FileDir() + it->vtn_fnItem.FileName() + ".tbn";
// use base name for description
it->vtn_strName = it->vtn_fnItem.FileName();
}
// if class
else if ( it->vtn_fnItem.FileExt() == ".ecl")
{
// obtain class
CEntityClass *pec = _pEntityClassStock->Obtain_t( it->vtn_fnItem);
// get thumbnail file name from the class
fnThumbnail = CTString(pec->ec_pdecDLLClass->dec_strIconFileName);
// get description name from the class
it->vtn_strName = pec->ec_pdecDLLClass->dec_strName;
// release class
_pEntityClassStock->Release( pec);
}
// if unknown extension
else
{
// use no thumbnail
fnThumbnail = CTString("");
}
// if no thumbnail
if( fnThumbnail == "")
{
it->vtn_pTextureData = NULL;
}
// if there is valid thumbnail file name
else
{
// obtain thumbnail
it->vtn_pTextureData = _pTextureStock->Obtain_t( fnThumbnail);
// must be valid
ASSERT( it->vtn_pTextureData != NULL);
// if it is really texture, type full info
if( it->vtn_fnItem.FileExt() == ".tex")
{
// use base name and dimension for desription
it->vtn_strName = (CTString&)it->vtn_fnItem+" "+it->vtn_pTextureData->GetDescription();
}
// else description is just item's file name
else
{
it->vtn_strName = it->vtn_fnItem.FileName();
}
}
}
}
catch( char *error)
{
// ingnore errors
(void) error;
it->vtn_pTextureData = NULL;
}
}
SetScrollPos(SB_VERT, 0);
m_bDirectoryOpen = TRUE;
Refresh();
Invalidate(FALSE);
}
void CBrowseWindow::CloseDirectory( CVirtualTreeNode *pVTN)
{
if( !m_bDirectoryOpen)
{
return;
}
ASSERT( pVTN != NULL);
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTN->vtn_lhChildren, it)
{
if( !it->vtn_bIsDirectory)
{
if( it->vtn_pTextureData != NULL)
{
_pTextureStock->Release( it->vtn_pTextureData);
it->vtn_pTextureData = NULL;
}
}
}
m_bDirectoryOpen = FALSE;
}
void CBrowseWindow::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// if window canvas is valid
if( m_pViewPort!=NULL)
{
// resize it
m_pViewPort->Resize();
Refresh();
}
}
void CBrowseWindow::OnInsertItems()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir == NULL)
{
AfxMessageBox( L"ERROR: Virtual tree doesn't exist.");
return;
}
char *pFilters = "Items (*.tex, *.wld, *.ecl)\0*.tex;*.wld;*.ecl\0"
"World Files (*.wld)\0*.wld\0"
"Texture files (*.tex)\0*.tex\0"
"Class files (*.ecl)\0*.ecl\0"
"All files (*.*)\0*.*\0\0";
// call file requester for opening textures
CDynamicArray<CTFileName> afnItems;
_EngineGUI.FileRequester( "Insert items", pFilters, KEY_NAME_CREATE_TEXTURE_DIR,
"Textures\\", "", &afnItems);
if( afnItems.Count() == 0) return;
// insert items
FOREACHINDYNAMICARRAY( afnItems, CTFileName, itItem)
{
try
{
InsertItem( *itItem, CPoint(-1, -1));
}
catch( char *err_str)
{
AfxMessageBox( CString(err_str));
}
}
CloseDirectory( pVTNDir);
OpenDirectory( pVTNDir);
}
void CBrowseWindow::OnDeleteItems()
{
DeleteSelectedItems();
}
void CBrowseWindow::OnBigIcons()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
pVTNDir->vtn_bmBrowsingMode = BM_ICONS_LARGE;
Refresh();
}
void CBrowseWindow::OnMediumIcons()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MEDIUM;
Refresh();
}
void CBrowseWindow::OnMicroIcons()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MICRO;
Refresh();
}
void CBrowseWindow::OnSmallIcons()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
pVTNDir->vtn_bmBrowsingMode = BM_ICONS_SMALL;
Refresh();
}
void CBrowseWindow::OnShowDescription()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
pVTNDir->vtn_bmBrowsingMode = BM_DESCRIPTION;
Refresh();
}
void CBrowseWindow::OnShowFilename()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
pVTNDir->vtn_bmBrowsingMode = BM_FILENAME;
Refresh();
}
void CBrowseWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
// get hitted item's index
FLOAT fDummyX, fDummyY;
INDEX iHittedItem = HitItem( point, fDummyX, fDummyY);
// if hit none reported, return
if( iHittedItem == -1)
{
return;
}
// get item object from hitted index
CVirtualTreeNode *pVTN = GetItem( iHittedItem);
// must not be null
ASSERT( pVTN != NULL);
// get item's file name
CTFileName fnItem = pVTN->vtn_fnItem;
// if it is texture
if( fnItem.FileExt() == ".tex")
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if(pDoc!=NULL && pDoc->GetEditingMode()==TERRAIN_MODE)
{
CTerrainLayer *ptlLayer=GetLayer();
CTerrain *ptTerrain=GetTerrain();
if(ptlLayer!=NULL && ptTerrain!=NULL)
{
try
{
ptlLayer->SetLayerTexture_t(fnItem);
theApp.m_ctTerrainPageCanvas.MarkChanged();
ptTerrain->RefreshTerrain();
}
catch(char *strError)
{
(void) strError;
}
}
}
else
{
// set it as new primitive's material default texture
theApp.SetNewActiveTexture( _fnmApplicationPath + fnItem);
// paste new active texture over polygon selection
theApp.TexturizeSelection();
}
}
// if it is world (template)
else if( fnItem.FileExt() == ".wld")
{
// open document with item's file name
theApp.m_pDocTemplate->OpenDocumentFile( CString(_fnmApplicationPath + fnItem));
}
}
void CBrowseWindow::OnRecreateTexture()
{
if( _bRightClickedIsSelected)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
if( it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tex") )
{
_EngineGUI.CreateTexture( it->vtn_fnItem);
}
}
}
else if( _fnRightClickedItemFileName.FileExt()==CTString(".tex"))
{
_EngineGUI.CreateTexture( _fnRightClickedItemFileName);
}
Refresh();
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc != NULL) pDoc->UpdateAllViews( NULL);
}
void CBrowseWindow::OnSelectByTextureInSelectedSectors()
{
SelectByTextures( TRUE, FALSE);
}
void CBrowseWindow::OnCreateAndAddTexture()
{
CDynamicArray<CTFileName> afnCreatedTextures;
CTFileName fnCreatedTexture = _EngineGUI.CreateTexture( CTString(""), &afnCreatedTextures);
if( afnCreatedTextures.Count() != 0)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
if( pVTNDir != NULL)
{
CloseDirectory( pVTNDir);
}
// insert created textures
FOREACHINDYNAMICARRAY( afnCreatedTextures, CTFileName, itTexture)
{
CTFileName &fn=*itTexture;
InsertItem( fn, CPoint(-1, -1));
}
if( pVTNDir != NULL)
{
OpenDirectory( pVTNDir);
}
}
}
void CBrowseWindow::OnSelectForDropMarker()
{
theApp.m_fnClassForDropMarker = _fnRightClickedItemFileName;
}
void CBrowseWindow::OnSetAsCurrentTexture()
{
// set it as new primitive's material default texture
theApp.SetNewActiveTexture( _fnmApplicationPath + _fnRightClickedItemFileName);
}
void CBrowseWindow::OnConvertClass()
{
if( _fnRightClickedItemFileName.FileExt()!=CTString(".ecl"))
{
WarningMessage( "Only classes can be used for converting classe");
return;
}
try
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// create the entity of requested class
CEntity *penNewClass;
penNewClass = pDoc->m_woWorld.CreateEntity_t(
iten->GetPlacement(), _fnRightClickedItemFileName);
// try to copy entity properties
CDLLEntityClass *pdecDLLClassNew = penNewClass->GetClass()->ec_pdecDLLClass;
for(;pdecDLLClassNew!=NULL; pdecDLLClassNew = pdecDLLClassNew->dec_pdecBase)
{
for(INDEX iPropertyNew=0; iPropertyNew<pdecDLLClassNew->dec_ctProperties; iPropertyNew++)
{
CEntityProperty &epPropertyNew = pdecDLLClassNew->dec_aepProperties[iPropertyNew];
CDLLEntityClass *pdecDLLClassOld = iten->GetClass()->ec_pdecDLLClass;
for(;pdecDLLClassOld!=NULL; pdecDLLClassOld = pdecDLLClassOld->dec_pdecBase)
{
for(INDEX iPropertyOld=0; iPropertyOld<pdecDLLClassOld->dec_ctProperties; iPropertyOld++)
{
CEntityProperty &epPropertyOld = pdecDLLClassOld->dec_aepProperties[iPropertyOld];
if( (CTString(epPropertyNew.ep_strName) == epPropertyOld.ep_strName) &&
(epPropertyNew.ep_eptType == epPropertyOld.ep_eptType) )
{
penNewClass->CopyOneProperty( epPropertyOld, epPropertyNew, *iten, FALSE);
}
}
}
}
}
// prepare the entity
penNewClass->Initialize();
}
CWorldEditorView *pWorldEditorView = theApp.GetActiveView();
if( pWorldEditorView != NULL)
{
pWorldEditorView->OnDeleteEntities();
}
}
catch( char *err_str)
{
AfxMessageBox( CString(err_str));
}
}
static void GetToolTipText(void *pBrowser, char *pToolTipText)
{
CBrowseWindow *pBrowseWindow = (CBrowseWindow *) pBrowser;
pBrowseWindow->GetToolTipText( pToolTipText);
}
void CBrowseWindow::GetToolTipText( char *pToolTipText)
{
CPoint point;
::GetCursorPos(&point);
ScreenToClient(&point);
// get hitted item's index
FLOAT fDummyX, fDummyY;
INDEX iHittedItem = HitItem( point, fDummyX, fDummyY);
// if hit none reported, return
if( iHittedItem == -1)
{
strcpy( pToolTipText, "");
return;
}
// get item object from hitted index
CVirtualTreeNode *pVTN = GetItem( iHittedItem);
strcpy(pToolTipText, pVTN->vtn_strName);
}
void CBrowseWindow::OnMouseMove(UINT nFlags, CPoint point)
{
theApp.m_cttToolTips.MouseMoveNotify( m_hWnd, 500, &::GetToolTipText, this);
CWnd::OnMouseMove(nFlags, point);
}
void CBrowseWindow::OnSelectByTextureInWorld()
{
SelectByTextures( FALSE, FALSE);
}
void CBrowseWindow::OnSelectExceptTextures( void)
{
SelectByTextures( FALSE, TRUE);
}
void CBrowseWindow::SelectByTextures( BOOL bInSelectedSectors, BOOL bExceptSelected)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
// for each entity in the world
FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
// if it is brush entity
if (iten->en_RenderType == CEntity::RT_BRUSH) {
// for each mip in its brush
FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm) {
// for all sectors in this mip
FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
// if sector is selected
if( !bInSelectedSectors || itbsc->IsSelected(BSCF_SELECTED))
{
// for all polygons in sector
FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
{
// if it is not non translucent portal and is not selected and has same texture
if ( /*(!(itbpo->bpo_ulFlags&BPOF_PORTAL) || (itbpo->bpo_ulFlags&BPOF_TRANSLUCENT) ||
(itbpo->bpo_bppProperties.bpp_uwPretenderDistance!=0) ) &&*/
!itbpo->IsSelected(BPOF_SELECTED) &&
(itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData() != NULL) )
{
CTFileName fnTexture = itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData()->GetName();
BOOL bSelect = bExceptSelected;
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
if( _bRightClickedIsSelected)
{
if(it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tex") &&
fnTexture == it->vtn_fnItem)
{
bSelect = !bExceptSelected;
break;
}
}
else if( fnTexture == _fnRightClickedItemFileName)
{
bSelect = !bExceptSelected;
break;
}
}
if( bSelect) pDoc->m_selPolygonSelection.Select(*itbpo);
}
}
}
}
}
}
}
pDoc->SetEditingMode( POLYGON_MODE);
pDoc->m_chSelections.MarkChanged();
pDoc->UpdateAllViews( NULL);
}
void CBrowseWindow::OnAddTexturesFromWorld()
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
CWorldEditorDoc *pDoc = theApp.GetDocument();
if (pDoc == NULL) return;
CloseDirectory( pVTNDir);
// for each entity in the world
FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
// if it is brush entity
if (iten->en_RenderType == CEntity::RT_BRUSH) {
// for each mip in its brush
FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm) {
// for all sectors in this mip
FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
// for all polygons in sector
FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
{
try
{
CTextureObject &to1 = itbpo->bpo_abptTextures[0].bpt_toTexture;
if(to1.GetData() != NULL)
InsertItem( to1.GetData()->GetName(), CPoint(-1, -1));
CTextureObject &to2 = itbpo->bpo_abptTextures[1].bpt_toTexture;
if(to2.GetData() != NULL)
InsertItem( to2.GetData()->GetName(), CPoint(-1, -1));
CTextureObject &to3 = itbpo->bpo_abptTextures[2].bpt_toTexture;
if(to3.GetData() != NULL)
InsertItem( to3.GetData()->GetName(), CPoint(-1, -1));
}
catch( char *err_str)
{
AfxMessageBox( CString(err_str));
}
}
}
}
}
}
OpenDirectory( pVTNDir);
}
void CBrowseWindow::OnShowTreeShortcuts()
{
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
pMainFrame->OnShowTreeShortcuts();
}
void ExportTexture( CTFileName fnTexture)
{
CTextureData *ptd;
CImageInfo ii;
try
{
ptd = _pTextureStock->Obtain_t( fnTexture);
for( INDEX iFrame=0; iFrame<ptd->td_ctFrames; iFrame++)
{
ptd->Export_t( ii, iFrame);
// obtain name for export file
CTFileName fnFrame;
if( ptd->td_ctFrames == 1)
{
fnFrame = fnTexture.NoExt()+".tga";
}
else
{
fnFrame.PrintF("%s%03d.tga", (const char *)fnTexture.NoExt(), iFrame);
}
// if file exists, ask for substitution name
if( FileExists( fnFrame) && iFrame==0 )
{
CTString strDefaultDir = fnFrame.FileDir();
CTString strDefaultFile = fnFrame.FileName()+fnFrame.FileExt();
// invoke "Save as" dialog
fnFrame = _EngineGUI.FileRequester( "Save As", FILTER_TGA FILTER_END,
"Export texture directory", strDefaultDir, strDefaultFile, NULL, FALSE);
}
if( fnFrame != "")
{
ii.SaveTGA_t(fnFrame);
ii.Clear();
}
}
}
catch( char *strError)
{
AfxMessageBox( CString(strError));
ii.Clear();
}
}
void CBrowseWindow::OnExportTexture()
{
if( _bRightClickedIsSelected)
{
CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
ASSERT( pVTNDir != NULL);
FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
{
if( it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tex") ||
it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tbn") )
{
ExportTexture( it->vtn_fnItem);
}
}
}
else if( _fnRightClickedItemFileName.FileExt()==CTString(".tex") ||
_fnRightClickedItemFileName.FileExt()==CTString(".tbn") )
{
ExportTexture( _fnRightClickedItemFileName);
}
}
void CBrowseWindow::OnBrowserContextHelp()
{
if( _fnRightClickedItemFileName.FileExt()==CTString(".ecl"))
{
theApp.DisplayHelp(_fnRightClickedItemFileName, HH_DISPLAY_TOPIC, NULL);
}
}