2016-10-13 18:46:10 +00:00
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// particle_tree_ctrl.cpp : implementation file
//
# include "std_afx.h"
# include "object_viewer.h"
# include "particle_tree_ctrl.h"
# include "located_bindable_dialog.h"
# include "emitter_dlg.h"
# include "main_frame.h"
# include "particle_system_edit.h"
# include "particle_dlg.h"
# include "start_stop_particle_system.h"
# include "edit_ps_sound.h"
# include "edit_ps_light.h"
# include "dup_ps.h"
# include "object_viewer.h"
# include "ps_mover_dlg.h"
# include "set_value_dlg.h"
# include "create_file_dlg.h"
# include "located_properties.h"
# include "located_bindable_dialog.h"
# include "located_target_dlg.h"
# include "lb_extern_id_dlg.h"
# include "skippable_message_box.h"
//
# include "nel/3d/particle_system.h"
# include "nel/3d/particle_system_model.h"
# include "nel/3d/particle_system_shape.h"
# include "nel/3d/ps_located.h"
# include "nel/3d/ps_particle.h"
# include "nel/3d/ps_mesh.h"
# include "nel/3d/ps_force.h"
# include "nel/3d/ps_zone.h"
# include "nel/3d/ps_sound.h"
# include "nel/3d/ps_emitter.h"
# include "nel/3d/ps_edit.h"
# include "nel/3d/nelu.h"
//
# include "nel/misc/path.h"
# include "nel/misc/file.h"
using NL3D : : CParticleSystem ;
using NL3D : : CParticleSystemModel ;
using NL3D : : CPSLocated ;
using NL3D : : CPSLocatedBindable ;
using NL3D : : CNELU ;
/////////////////////////////////////////////////////////////////////////////
// CParticleTreeCtrl
enum TPSIcon
{
PSIconForce = 0 ,
PSIconParticle = 1 ,
PSIconEmitter = 2 ,
PSIconLight = 3 ,
PSIconCollisionZone = 4 ,
PSIconSound = 5 ,
PSIconParticleSystem = 6 ,
PSIconLocated = 7 ,
PSIconLocatedInstance = 8 ,
PSIconWorkspace = 9 ,
PSIconParticleSystemNotLoaded = 10
} ;
static const uint IconIDs [ ] =
{
IDB_FORCE ,
IDB_PARTICLE ,
IDB_EMITTER ,
IDB_LIGHT ,
IDB_COLLISION_ZONE ,
IDB_SOUND ,
IDB_PARTICLE_SYSTEM ,
IDB_LOCATED ,
IDB_LOCATED_INSTANCE ,
IDB_PS_WORKSPACE ,
IDB_PARTICLE_SYSTEM_NOT_LOADED
} ;
static const uint NumIconIDs = sizeof ( IconIDs ) / sizeof ( uint ) ;
// this map is used to create increasing names
static std : : map < std : : string , uint > _PSElementIdentifiers ;
//****************************************************************************************************************
CParticleTreeCtrl : : CParticleTreeCtrl ( CParticleDlg * pdlg )
{
CBitmap bm [ NumIconIDs ] ;
_ImageList . Create ( 16 , 16 , ILC_COLOR4 , 0 , NumIconIDs ) ;
for ( uint k = 0 ; k < NumIconIDs ; + + k )
{
bm [ k ] . LoadBitmap ( IconIDs [ k ] ) ;
_ImageList . Add ( & bm [ k ] , RGB ( 1 , 1 , 1 ) ) ;
}
_ParticleDlg = pdlg ;
_LastClickedPS = NULL ;
_LastActiveNode = NULL ;
_ViewFilenameFlag = true ;
}
//****************************************************************************************************************
CParticleTreeCtrl : : ~ CParticleTreeCtrl ( )
{
reset ( ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : reset ( )
{
if ( IsWindow ( * this ) )
{
DeleteAllItems ( ) ;
}
for ( std : : vector < CNodeType * > : : iterator it = _NodeTypes . begin ( ) ; it ! = _NodeTypes . end ( ) ; + + it )
{
delete * it ;
}
_NodeTypes . clear ( ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : rebuildLocatedInstance ( CParticleWorkspace : : CNode & node )
{
HTREEITEM currPS = getTreeItem ( & node ) ;
nlassert ( currPS ) ;
HTREEITEM currLocated = this - > GetChildItem ( currPS ) ;
while ( currLocated )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( currLocated ) ;
nlassert ( nt - > Type = = CNodeType : : located ) ;
CPSLocated * loc = nt - > Loc ;
for ( uint32 k = 0 ; k < loc - > getSize ( ) ; + + k )
{
CNodeType * newNt = new CNodeType ( loc , k ) ;
_NodeTypes . push_back ( newNt ) ;
// bind located instance icon
2016-11-20 13:51:11 +00:00
InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , _T ( " instance " ) , PSIconLocatedInstance , PSIconLocatedInstance , 0 , 0 , ( LPARAM ) newNt , currLocated , TVI_LAST ) ;
2016-10-13 18:46:10 +00:00
}
currLocated = GetNextItem ( currLocated , TVGN_NEXT ) ;
}
Invalidate ( ) ;
}
//=====================================================================================================
void CParticleTreeCtrl : : suppressLocatedInstanceNbItem ( CParticleWorkspace : : CNode & node , uint32 newSize )
{
HTREEITEM currPS = getTreeItem ( & node ) ;
nlassert ( currPS ) ;
HTREEITEM currLocated , currLocElement , nextCurrLocElement ;
currLocated = this - > GetChildItem ( currPS ) ;
while ( currLocated )
{
currLocElement = GetChildItem ( currLocated ) ;
while ( currLocElement )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( currLocElement ) ;
nextCurrLocElement = GetNextItem ( currLocElement , TVGN_NEXT ) ;
// remove instance item
if ( nt - > Type = = CNodeType : : locatedInstance )
{
if ( nt - > LocatedInstanceIndex > = newSize )
{
removeTreePart ( currLocElement ) ;
}
}
currLocElement = nextCurrLocElement ;
}
currLocated = GetNextItem ( currLocated , TVGN_NEXT ) ;
}
Invalidate ( ) ;
}
//=====================================================================================================
HTREEITEM CParticleTreeCtrl : : buildTreeFromPS ( CParticleWorkspace : : CNode & node , HTREEITEM rootHandle , HTREEITEM prevSibling /*= TVI_LAST*/ )
{
// for now, there's only one root ...
CNodeType * nt = new CNodeType ( & node ) ;
_NodeTypes . push_back ( nt ) ;
if ( node . isLoaded ( ) )
{
// bind particle system icon
2016-11-20 13:51:11 +00:00
HTREEITEM psRoot = InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT , utf8ToTStr ( computeCaption ( node ) ) , PSIconParticleSystem , PSIconParticleSystem , 0 , 0 , NULL , rootHandle , prevSibling ) ;
2016-10-13 18:46:10 +00:00
// set the param (doesn't seems to work during first creation)
SetItemData ( psRoot , ( LPARAM ) nt ) ;
// now, create each located
for ( uint k = 0 ; k < node . getPSPointer ( ) - > getNbProcess ( ) ; k + + )
{
CPSLocated * loc = dynamic_cast < CPSLocated * > ( node . getPSPointer ( ) - > getProcess ( k ) ) ;
if ( loc ) createNodeFromLocated ( loc , psRoot ) ;
}
rebuildLocatedInstance ( node ) ;
return psRoot ;
}
else
{
// bind a bitmap that say that the PS hasn't been loaded
2016-11-20 13:51:11 +00:00
HTREEITEM psRoot = InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT , utf8ToTStr ( computeCaption ( node ) ) , PSIconParticleSystemNotLoaded , PSIconParticleSystemNotLoaded , 0 , 0 , NULL , rootHandle , prevSibling ) ;
2016-10-13 18:46:10 +00:00
SetItemData ( psRoot , ( LPARAM ) nt ) ;
return psRoot ;
}
}
//=====================================================================================================
void CParticleTreeCtrl : : buildTreeFromWorkSpace ( CParticleWorkspace & ws )
{
reset ( ) ;
DeleteAllItems ( ) ;
CNodeType * nt = new CNodeType ( & ws ) ;
_NodeTypes . push_back ( nt ) ;
// bind particle system icon
2016-11-20 13:51:11 +00:00
HTREEITEM rootHandle = InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT , utf8ToTStr ( computeCaption ( ws ) ) , PSIconWorkspace , PSIconWorkspace , 0 , 0 , NULL , NULL , TVI_LAST ) ;
2016-10-13 18:46:10 +00:00
// set the param (doesn't seems to work during first creation)
SetItemData ( rootHandle , ( LPARAM ) nt ) ;
// now, create each particle system
for ( uint k = 0 ; k < ws . getNumNode ( ) ; + + k )
{
buildTreeFromPS ( * ws . getNode ( k ) , rootHandle ) ;
}
}
//=====================================================================================================
void CParticleTreeCtrl : : createNodeFromLocated ( NL3D : : CPSLocated * loc , HTREEITEM rootHandle )
{
// insert an item for the located
CNodeType * nt = new CNodeType ( loc ) ;
_NodeTypes . push_back ( nt ) ;
// bind located icon
2016-11-20 13:51:11 +00:00
HTREEITEM nodeHandle = InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , utf8ToTStr ( loc - > getName ( ) ) , PSIconLocated , PSIconLocated , 0 , 0 , ( LPARAM ) nt , rootHandle , TVI_LAST ) ;
2016-10-13 18:46:10 +00:00
// now, insert each object that is bound to the located
for ( uint l = 0 ; l < loc - > getNbBoundObjects ( ) ; + + l )
{
createNodeFromLocatedBindable ( loc - > getBoundObject ( l ) , nodeHandle ) ;
}
}
//=====================================================================================================
void CParticleTreeCtrl : : createNodeFromLocatedBindable ( NL3D : : CPSLocatedBindable * lb , HTREEITEM rootHandle )
{
// we ordered the image so that they match the type for a located bindable (force, particles, collision zones...)
CNodeType * nt = new CNodeType ( lb ) ;
_NodeTypes . push_back ( nt ) ;
2016-11-20 13:51:11 +00:00
InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , utf8ToTStr ( lb - > getName ( ) ) , lb - > getType ( ) , lb - > getType ( ) , PSIconForce , PSIconForce , ( LPARAM ) nt , rootHandle , TVI_LAST ) ;
2016-10-13 18:46:10 +00:00
}
BEGIN_MESSAGE_MAP ( CParticleTreeCtrl , CTreeCtrl )
//{{AFX_MSG_MAP(CParticleTreeCtrl)
ON_NOTIFY_REFLECT ( TVN_SELCHANGED , OnSelchanged )
ON_WM_RBUTTONDOWN ( )
ON_NOTIFY_REFLECT ( TVN_ENDLABELEDIT , OnEndlabeledit )
ON_NOTIFY_REFLECT ( TVN_BEGINLABELEDIT , OnBeginlabeledit )
ON_WM_LBUTTONDBLCLK ( )
ON_NOTIFY_REFLECT ( TVN_KEYDOWN , OnKeydown )
ON_WM_KEYUP ( )
//}}AFX_MSG_MAP
END_MESSAGE_MAP ( )
//=====================================================================================================
void CParticleTreeCtrl : : init ( void )
{
this - > SetImageList ( & _ImageList , TVSIL_NORMAL ) ;
}
//=====================================================================================================
void CParticleTreeCtrl : : updateRightPane ( CNodeType & nt )
{
switch ( nt . Type )
{
case CNodeType : : located :
{
nlassert ( getOwnerNode ( & nt ) ) ;
CLocatedProperties * lp = new CLocatedProperties ( getOwnerNode ( & nt ) , nt . Loc , _ParticleDlg ) ;
lp - > init ( 0 , 0 ) ;
_ParticleDlg - > setRightPane ( lp ) ;
if ( _LastClickedPS )
{
_LastClickedPS - > setCurrentEditedElement ( NULL ) ;
}
return ;
}
break ;
case CNodeType : : locatedBindable :
{
if ( dynamic_cast < NL3D : : CPSEmitter * > ( nt . Bind ) )
{
CEmitterDlg * ed = new CEmitterDlg ( getOwnerNode ( & nt ) , static_cast < NL3D : : CPSEmitter * > ( nt . Bind ) , _ParticleDlg ) ;
ed - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( ed ) ;
}
else
if ( dynamic_cast < NL3D : : CPSTargetLocatedBindable * > ( nt . Bind ) )
{
CLocatedTargetDlg * ltd = new CLocatedTargetDlg ( getOwnerNode ( & nt ) , static_cast < NL3D : : CPSTargetLocatedBindable * > ( nt . Bind ) , _ParticleDlg ) ;
ltd - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( ltd ) ;
}
else
if ( dynamic_cast < NL3D : : CPSSound * > ( nt . Bind ) )
{
nlassert ( getOwnerNode ( & nt ) ) ;
CEditPSSound * epss = new CEditPSSound ( getOwnerNode ( & nt ) , static_cast < NL3D : : CPSSound * > ( nt . Bind ) ) ;
epss - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( epss ) ;
}
else
if ( dynamic_cast < NL3D : : CPSLight * > ( nt . Bind ) )
{
nlassert ( getOwnerNode ( & nt ) ) ;
CEditPSLight * epsl = new CEditPSLight ( getOwnerNode ( & nt ) , static_cast < NL3D : : CPSLight * > ( nt . Bind ) ) ;
epsl - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( epsl ) ;
}
else
{
nlassert ( getOwnerNode ( & nt ) ) ;
CLocatedBindableDialog * lbd = new CLocatedBindableDialog ( getOwnerNode ( & nt ) , nt . Bind ) ;
lbd - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( lbd ) ;
}
if ( _LastClickedPS )
{
_LastClickedPS - > setCurrentEditedElement ( NULL ) ;
}
return ;
}
break ;
case CNodeType : : particleSystem :
{
// see if the particle system has been loaded
if ( nt . PS - > isLoaded ( ) )
{
CParticleSystemEdit * pse = new CParticleSystemEdit ( nt . PS , this ) ;
pse - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( pse ) ;
}
else
{
_ParticleDlg - > setRightPane ( NULL ) ;
}
if ( _LastClickedPS )
{
_LastClickedPS - > setCurrentEditedElement ( NULL ) ;
}
}
break ;
case CNodeType : : locatedInstance :
{
NL3D : : CParticleSystem * ps = nt . Loc - > getOwner ( ) ;
_LastClickedPS = ps ;
CPSMoverDlg * moverDlg = new CPSMoverDlg ( getOwnerNode ( & nt ) , this , & _ParticleDlg - > MainFrame - > ObjView - > getMouseListener ( ) , nt . Loc , nt . LocatedInstanceIndex ) ;
moverDlg - > init ( _ParticleDlg ) ;
_ParticleDlg - > setRightPane ( moverDlg ) ;
CObjectViewer * ov = _ParticleDlg - > MainFrame - > ObjView ;
if ( _ParticleDlg - > MainFrame - > isMoveElement ( ) )
{
ov - > getMouseListener ( ) . setModelMatrix ( _ParticleDlg - > getElementMatrix ( ) ) ;
}
ps - > setCurrentEditedElement ( nt . Loc , nt . LocatedInstanceIndex , moverDlg - > getLocatedBindable ( ) ) ;
}
break ;
case CNodeType : : workspace :
{
if ( _LastClickedPS )
{
_LastClickedPS - > setCurrentEditedElement ( NULL ) ;
}
_ParticleDlg - > setRightPane ( NULL ) ;
}
break ;
}
}
/////////////////////////////////////////////////////////////////////////////
// CParticleTreeCtrl message handlers
void CParticleTreeCtrl : : OnSelchanged ( NMHDR * pNMHDR , LRESULT * pResult )
{
NM_TREEVIEW * pNMTreeView = ( NM_TREEVIEW * ) pNMHDR ;
* pResult = 0 ;
CNodeType * nt = ( CNodeType * ) pNMTreeView - > itemNew . lParam ;
nlassert ( nt ) ;
updateRightPane ( * nt ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : OnRButtonDown ( UINT nFlags , CPoint point )
{
if ( _LastClickedPS )
{
_LastClickedPS - > setCurrentEditedElement ( NULL ) ;
}
// test whether there is an item under that point
UINT flags ;
HTREEITEM item = this - > HitTest ( point , & flags ) ;
if ( item )
{
this - > SelectItem ( item ) ;
RECT r ;
GetWindowRect ( & r ) ;
CMenu menu ;
CMenu * subMenu ;
TVITEM item ;
item . mask = TVIF_HANDLE | TVIF_PARAM ;
item . hItem = GetSelectedItem ( ) ;
GetItem ( & item ) ;
CNodeType * nt = ( CNodeType * ) item . lParam ;
UINT bIsRunning = MF_BYCOMMAND | MF_DISABLED | MF_GRAYED ;
CParticleWorkspace : : CNode * node = getOwnerNode ( nt ) ;
if ( node )
{
if ( ! node - > isStateMemorized ( ) & & _ParticleDlg - > StartStopDlg - > getState ( ) ! = CStartStopParticleSystem : : RunningMultiple )
{
bIsRunning = MF_ENABLED ;
}
}
switch ( nt - > Type )
{
case CNodeType : : located :
{
menu . LoadMenu ( IDR_LOCATED_MENU ) ;
menu . EnableMenuItem ( ID_INSTANCIATE_LOCATED , bIsRunning ) ;
menu . EnableMenuItem ( IDM_COPY_LOCATED , bIsRunning ) ;
menu . EnableMenuItem ( IDM_PASTE_BINDABLE , bIsRunning ) ;
}
break ;
case CNodeType : : locatedBindable :
menu . LoadMenu ( IDR_LOCATED_BINDABLE_MENU ) ;
menu . GetSubMenu ( 0 ) - > CheckMenuItem ( IDM_LB_LOD1N2 , MF_UNCHECKED | MF_BYCOMMAND ) ;
menu . GetSubMenu ( 0 ) - > CheckMenuItem ( IDM_LB_LOD1 , MF_UNCHECKED | MF_BYCOMMAND ) ;
menu . GetSubMenu ( 0 ) - > CheckMenuItem ( IDM_LB_LOD2 , MF_UNCHECKED | MF_BYCOMMAND ) ;
// check the menu to tell which lod is used for this located bindable
if ( nt - > Bind - > getLOD ( ) = = NL3D : : PSLod1n2 ) menu . GetSubMenu ( 0 ) - > CheckMenuItem ( IDM_LB_LOD1N2 , MF_CHECKED | MF_BYCOMMAND ) ;
if ( nt - > Bind - > getLOD ( ) = = NL3D : : PSLod1 ) menu . GetSubMenu ( 0 ) - > CheckMenuItem ( IDM_LB_LOD1 , MF_CHECKED | MF_BYCOMMAND ) ;
if ( nt - > Bind - > getLOD ( ) = = NL3D : : PSLod2 ) menu . GetSubMenu ( 0 ) - > CheckMenuItem ( IDM_LB_LOD2 , MF_CHECKED | MF_BYCOMMAND ) ;
menu . EnableMenuItem ( IDM_COPY_BINDABLE , bIsRunning ) ;
break ;
case CNodeType : : particleSystem :
if ( nt - > PS - > isLoaded ( ) )
{
menu . LoadMenu ( IDR_PARTICLE_SYSTEM_MENU ) ;
menu . EnableMenuItem ( IDM_PASTE_LOCATED , bIsRunning ) ;
}
else
{
menu . LoadMenu ( IDR_PARTICLE_SYSTEM_NOT_LOADED_MENU ) ;
}
break ;
case CNodeType : : locatedInstance :
menu . LoadMenu ( IDR_LOCATED_INSTANCE_MENU ) ;
break ;
case CNodeType : : workspace :
menu . LoadMenu ( IDR_PARTICLE_WORKSPACE_MENU ) ;
break ;
default :
return ;
break ;
}
subMenu = menu . GetSubMenu ( 0 ) ;
nlassert ( subMenu ) ;
subMenu - > TrackPopupMenu ( TPM_LEFTALIGN | TPM_RIGHTBUTTON , r . left + point . x , r . top + point . y , this ) ;
}
}
//****************************************************************************************************************
void CParticleTreeCtrl : : deleteSelection ( )
{
if ( ! GetSelectedItem ( ) ) return ;
CNodeType * nt = ( CNodeType * ) GetItemData ( GetSelectedItem ( ) ) ;
switch ( nt - > Type )
{
case CNodeType : : located :
{
_ParticleDlg - > setRightPane ( NULL ) ;
CPSLocated * loc = nt - > Loc ;
touchPSState ( nt ) ;
CParticleWorkspace : : CNode * ownerNode = getOwnerNode ( nt ) ;
nlassert ( ownerNode ) ;
ownerNode - > setModified ( true ) ;
// if the system is running, we must destroy initial infos about the located,
// as they won't need to be restored when the stop button will be pressed
ownerNode - > removeLocated ( loc ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
nt - > getOwnerPS ( ) - > remove ( loc ) ;
removeTreePart ( GetSelectedItem ( ) ) ;
}
break ;
case CNodeType : : particleSystem :
{
if ( GetSelectedItem ( ) = = _LastActiveNode )
{
setActiveNode ( NULL ) ;
_ParticleDlg - > setActiveNode ( NULL ) ;
}
nt - > PS - > getWorkspace ( ) - > removeNode ( nt - > PS ) ;
removeTreePart ( GetSelectedItem ( ) ) ;
_ParticleDlg - > setRightPane ( NULL ) ;
}
break ;
case CNodeType : : locatedBindable :
{
CPSLocatedBindable * lb = nt - > Bind ;
touchPSState ( nt ) ;
CParticleWorkspace : : CNode * ownerNode = getOwnerNode ( nt ) ;
nlassert ( ownerNode ) ;
// if the system is running, we must destroy initial infos
// that what saved about the located bindable, when the start button was pressed, as they won't need
// to be restored
ownerNode - > removeLocatedBindable ( lb ) ;
ownerNode - > setModified ( true ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
lb - > getOwner ( ) - > remove ( lb ) ;
removeTreePart ( GetSelectedItem ( ) ) ;
_ParticleDlg - > setRightPane ( NULL ) ;
}
break ;
case CNodeType : : locatedInstance :
{
nlassert ( nt - > Type = = CNodeType : : locatedInstance ) ;
nlassert ( getOwnerNode ( nt ) ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
CParticleWorkspace : : CNode * owner = getOwnerNode ( nt ) ;
nlassert ( owner ) ;
//suppressLocatedInstanceNbItem(*owner);
NL3D : : CPSEmitter : : setBypassEmitOnDeath ( true ) ;
nt - > Loc - > deleteElement ( nt - > LocatedInstanceIndex ) ;
NL3D : : CPSEmitter : : setBypassEmitOnDeath ( false ) ;
CParticleWorkspace : : CNode * ownerNode = getOwnerNode ( nt ) ;
nlassert ( ownerNode ) ;
// Move selection to parent
HTREEITEM currItem = GetSelectedItem ( ) ;
SelectItem ( GetParentItem ( GetSelectedItem ( ) ) ) ;
removeTreePart ( currItem ) ;
suppressLocatedInstanceNbItem ( * ownerNode , 0 ) ;
rebuildLocatedInstance ( * ownerNode ) ;
}
break ;
case CNodeType : : workspace :
// no-op -> close the workpsace
break ;
default :
nlassert ( 0 ) ;
break ;
}
}
//****************************************************************************************************************
BOOL CParticleTreeCtrl : : OnCmdMsg ( UINT nID , int nCode , void * pExtra , AFX_CMDHANDLERINFO * pHandlerInfo )
{
if ( nCode ! = 0 ) return CTreeCtrl : : OnCmdMsg ( nID , nCode , pExtra , pHandlerInfo ) ;
CPSLocatedBindable * toCreate = NULL ;
CNodeType * nt = ( CNodeType * ) GetItemData ( GetSelectedItem ( ) ) ;
bool createLocAndBindable = false ; // when set to true, must create a located and a simultaneously a located bindable
switch ( nID )
{
///////////////
// workspace //
///////////////
case IDM_INSERT_NEW_PS :
nlassert ( nt - > Type = = CNodeType : : workspace ) ;
insertNewPS ( * nt - > WS ) ;
break ;
case IDM_CREATE_NEW_PS :
nlassert ( nt - > Type = = CNodeType : : workspace ) ;
createNewPS ( * nt - > WS ) ;
break ;
case IDM_REMOVE_ALL_PS :
removeAllPS ( * nt - > WS ) ;
break ;
case IDM_PS_SORT_BY_FILENAME :
{
nlassert ( nt - > Type = = CNodeType : : workspace ) ;
struct CSortByFilename : public CParticleWorkspace : : ISort
{
bool less ( const CParticleWorkspace : : CNode & lhs , const CParticleWorkspace : : CNode & rhs ) const
{
return lhs . getFilename ( ) < rhs . getFilename ( ) ;
}
} ;
sortWorkspace ( * nt - > WS , CSortByFilename ( ) ) ;
}
break ;
case IDM_PS_SORT_BY_NAME :
{
nlassert ( nt - > Type = = CNodeType : : workspace ) ;
struct CSortByName : public CParticleWorkspace : : ISort
{
bool less ( const CParticleWorkspace : : CNode & lhs , const CParticleWorkspace : : CNode & rhs ) const
{
if ( ! rhs . isLoaded ( ) )
{
if ( lhs . isLoaded ( ) ) return true ;
return lhs . getFilename ( ) < rhs . getFilename ( ) ;
}
if ( ! lhs . isLoaded ( ) )
{
if ( rhs . isLoaded ( ) ) return false ;
}
return lhs . getPSPointer ( ) - > getName ( ) < rhs . getPSPointer ( ) - > getName ( ) ;
}
} ;
sortWorkspace ( * nt - > WS , CSortByName ( ) ) ;
}
break ;
case IDM_SAVE_PS_WORKSPACE :
{
_ParticleDlg - > OnSavePsWorkspace ( ) ;
}
break ;
case IDM_LOAD_PS_WORKSPACE :
{
_ParticleDlg - > OnLoadPSWorkspace ( ) ;
}
break ;
///////////////
// particles //
///////////////
case IDM_DOT_LOC : createLocAndBindable = true ;
case IDM_DOT :
toCreate = new NL3D : : CPSDot ;
break ;
case IDM_LOOKAT_LOC : createLocAndBindable = true ;
case IDM_LOOKAT :
toCreate = new NL3D : : CPSFaceLookAt ;
break ;
case IDM_FANLIGHT_LOC : createLocAndBindable = true ;
case IDM_FANLIGHT :
toCreate = new NL3D : : CPSFanLight ;
break ;
case IDM_RIBBON_LOC : createLocAndBindable = true ;
case IDM_RIBBON :
toCreate = new NL3D : : CPSRibbon ;
break ;
case IDM_TAILDOT_LOC : createLocAndBindable = true ;
case IDM_TAILDOT :
toCreate = new NL3D : : CPSTailDot ;
break ;
case IDM_MESH_LOC : createLocAndBindable = true ;
case IDM_MESH :
toCreate = new NL3D : : CPSMesh ;
break ;
case IDM_CONSTRAINT_MESH_LOC : createLocAndBindable = true ;
case IDM_CONSTRAINT_MESH :
toCreate = new NL3D : : CPSConstraintMesh ;
break ;
case IDM_FACE_LOC : createLocAndBindable = true ;
case IDM_FACE :
toCreate = new NL3D : : CPSFace ;
break ;
case IDM_SHOCKWAVE_LOC : createLocAndBindable = true ;
case IDM_SHOCKWAVE :
toCreate = new NL3D : : CPSShockWave ;
break ;
case IDM_RIBBON_LOOK_AT_LOC : createLocAndBindable = true ;
case IDM_RIBBON_LOOK_AT :
toCreate = new NL3D : : CPSRibbonLookAt ;
break ;
//////////////
// emitters //
//////////////
case IDM_DIRECTIONNAL_EMITTER_LOC : createLocAndBindable = true ;
case IDM_DIRECTIONNAL_EMITTER :
toCreate = new NL3D : : CPSEmitterDirectionnal ;
break ;
case IDM_OMNIDIRECTIONNAL_EMITTER_LOC : createLocAndBindable = true ;
case IDM_OMNIDIRECTIONNAL_EMITTER :
toCreate = new NL3D : : CPSEmitterOmni ;
break ;
case IDM_CONIC_EMITTER_LOC : createLocAndBindable = true ;
case IDM_CONIC_EMITTER :
toCreate = new NL3D : : CPSEmitterConic ;
break ;
case IDM_RECTANGLE_EMITTER_LOC : createLocAndBindable = true ;
case IDM_RECTANGLE_EMITTER :
toCreate = new NL3D : : CPSEmitterRectangle ;
break ;
case IDM_SPHERICAL_EMITTER_LOC : createLocAndBindable = true ;
case IDM_SPHERICAL_EMITTER :
toCreate = new NL3D : : CPSSphericalEmitter ;
break ;
case IDM_RADIAL_EMITTER_LOC : createLocAndBindable = true ;
case IDM_RADIAL_EMITTER :
toCreate = new NL3D : : CPSRadialEmitter ;
break ;
////////////////
// Zones //
////////////////
case IDM_ZONE_PLANE_LOC : createLocAndBindable = true ;
case IDM_ZONE_PLANE :
toCreate = new NL3D : : CPSZonePlane ;
break ;
case IDM_ZONE_SPHERE_LOC : createLocAndBindable = true ;
case IDM_ZONE_SPHERE :
toCreate = new NL3D : : CPSZoneSphere ;
break ;
case IDM_ZONE_DISC_LOC : createLocAndBindable = true ;
case IDM_ZONE_DISC :
toCreate = new NL3D : : CPSZoneDisc ;
break ;
case IDM_ZONE_RECTANGLE_LOC : createLocAndBindable = true ;
case IDM_ZONE_RECTANGLE :
toCreate = new NL3D : : CPSZoneRectangle ;
break ;
case IDM_ZONE_CYLINDER_LOC : createLocAndBindable = true ;
case IDM_ZONE_CYLINDER :
toCreate = new NL3D : : CPSZoneCylinder ;
break ;
///////////////
// forces //
///////////////
case IDM_GRAVITY_FORCE_LOC : createLocAndBindable = true ;
case IDM_GRAVITY_FORCE :
toCreate = new NL3D : : CPSGravity ;
break ;
case IDM_DIRECTIONNAL_FORCE_LOC : createLocAndBindable = true ;
case IDM_DIRECTIONNAL_FORCE :
toCreate = new NL3D : : CPSDirectionnalForce ;
break ;
case IDM_SPRING_FORCE_LOC : createLocAndBindable = true ;
case IDM_SPRING_FORCE :
toCreate = new NL3D : : CPSSpring ;
break ;
case IDM_FLUID_FRICTION_LOC : createLocAndBindable = true ;
case IDM_FLUID_FRICTION :
toCreate = new NL3D : : CPSFluidFriction ;
break ;
case IDM_CENTRAL_GRAVITY_LOC : createLocAndBindable = true ;
case IDM_CENTRAL_GRAVITY :
toCreate = new NL3D : : CPSCentralGravity ;
break ;
case IDM_CYLINDRIC_VORTEX_LOC : createLocAndBindable = true ;
case IDM_CYLINDRIC_VORTEX :
toCreate = new NL3D : : CPSCylindricVortex ;
break ;
case IDM_BROWNIAN_MOVE_LOC : createLocAndBindable = true ;
case IDM_BROWNIAN_MOVE :
toCreate = new NL3D : : CPSBrownianForce ;
break ;
case IDM_MAGNETIC_FORCE_LOC : createLocAndBindable = true ;
case IDM_MAGNETIC_FORCE :
toCreate = new NL3D : : CPSMagneticForce ;
break ;
///////////////
// sound //
///////////////
case IDM_SOUND_LOC : createLocAndBindable = true ;
case IDM_SOUND :
toCreate = new NL3D : : CPSSound ;
if ( ! _ParticleDlg - > StartStopDlg - > isRunning ( ) )
{
( static_cast < NL3D : : CPSSound * > ( toCreate ) ) - > stopSound ( ) ;
}
break ;
///////////////
// light //
///////////////
case IDM_LIGHT_LOC : createLocAndBindable = true ;
case IDM_LIGHT :
toCreate = new NL3D : : CPSLight ;
break ;
//////////////
// deletion //
//////////////
case IDM_DELETE_LOCATED :
{
deleteSelection ( ) ;
return TRUE ;
//return CTreeCtrl::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
break ;
case IDM_DELETE_LOCATED_BINDABLE :
{
deleteSelection ( ) ;
return TRUE ;
}
break ;
case IDM_DELETE_LOCATED_INSTANCE :
{
deleteSelection ( ) ;
return TRUE ;
}
break ;
// instanciate an element
case ID_INSTANCIATE_LOCATED :
{
getOwnerNode ( nt ) - > setModified ( true ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
if ( nt - > Loc - > getSize ( ) = = nt - > Loc - > getMaxSize ( ) )
{
nt - > Loc - > resize ( nt - > Loc - > getMaxSize ( ) + 1 ) ;
// force a re-update of the left pane
NM_TREEVIEW nmt ;
LRESULT pResult ;
nmt . itemNew . lParam = GetItemData ( GetSelectedItem ( ) ) ;
OnSelchanged ( ( NMHDR * ) & nmt , & pResult ) ;
}
sint32 objIndex = nt - > Loc - > newElement ( NLMISC : : CVector : : Null , NLMISC : : CVector : : Null , NULL , 0 , nt - > Loc - > getMatrixMode ( ) , 0.f ) ;
nt = new CNodeType ( nt - > Loc , objIndex ) ;
_NodeTypes . push_back ( nt ) ;
// insert the element in the tree
HTREEITEM root = InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , " instance " , PSIconLocatedInstance , PSIconLocatedInstance , 0 , 0 , ( LPARAM ) nt , GetSelectedItem ( ) , TVI_LAST ) ;
SetItemData ( root , ( DWORD ) nt ) ;
Invalidate ( ) ;
}
break ;
////////////
// LOD OP //
////////////
case IDM_LB_LOD1N2 :
nlassert ( nt - > Type = CNodeType : : locatedBindable ) ;
nt - > Bind - > setLOD ( NL3D : : PSLod1n2 ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
break ;
case IDM_LB_LOD1 :
nlassert ( nt - > Type = CNodeType : : locatedBindable ) ;
nt - > Bind - > setLOD ( NL3D : : PSLod1 ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
break ;
case IDM_LB_LOD2 :
nlassert ( nt - > Type = CNodeType : : locatedBindable ) ;
nt - > Bind - > setLOD ( NL3D : : PSLod2 ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
break ;
////////////////
// extern ID //
////////////////
case IDM_LB_EXTERN_ID :
{
nlassert ( nt - > Type = CNodeType : : locatedBindable ) ;
nlassert ( nt - > Bind ) ;
CLBExternIDDlg dlg ( nt - > Bind - > getExternID ( ) ) ;
INT_PTR res = dlg . DoModal ( ) ;
if ( res = = IDOK )
{
nt - > Bind - > setExternID ( dlg . getNewID ( ) ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
}
}
break ;
////////////////////////
// COPY / PASTE //
////////////////////////
case IDM_COPY_LOCATED :
nlassert ( nt - > Type = = CNodeType : : located ) ;
nlassert ( nt - > Loc ) ;
_LocatedCopy . reset ( NLMISC : : safe_cast < NL3D : : CPSLocated * > ( : : DupPSLocated ( nt - > Loc ) ) ) ;
break ;
case IDM_COPY_BINDABLE :
nlassert ( nt - > Type = = CNodeType : : locatedBindable ) ;
nlassert ( nt - > Bind ) ;
_LocatedBindableCopy . reset ( : : DupPSLocatedBindable ( nt - > Bind ) ) ;
break ;
case IDM_PASTE_LOCATED :
{
nlassert ( nt - > Type = = CNodeType : : particleSystem ) ;
nlassert ( nt - > PS ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
CPSLocated * copy = dynamic_cast < CPSLocated * > ( : : DupPSLocated ( _LocatedCopy . get ( ) ) ) ;
if ( ! copy ) break ;
if ( nt - > PS - > getPSPointer ( ) - > attach ( copy ) )
{
createNodeFromLocated ( copy , GetSelectedItem ( ) ) ;
Invalidate ( ) ;
}
else
{
CString mess ;
mess . LoadString ( IDS_PS_NO_FINITE_DURATION ) ;
CString errorStr ;
errorStr . LoadString ( IDS_ERROR ) ;
MessageBox ( ( LPCTSTR ) mess , ( LPCTSTR ) errorStr , MB_ICONEXCLAMATION ) ;
}
}
break ;
case IDM_PASTE_BINDABLE :
{
nlassert ( nt - > Type = = CNodeType : : located ) ;
nlassert ( nt - > Loc ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
CPSLocatedBindable * copy = : : DupPSLocatedBindable ( _LocatedBindableCopy . get ( ) ) ;
if ( ! copy ) break ;
if ( nt - > Loc - > bind ( copy ) )
{
createNodeFromLocatedBindable ( copy , GetSelectedItem ( ) ) ;
Invalidate ( ) ;
}
else
{
delete copy ;
CString mess ;
mess . LoadString ( IDS_PS_NO_FINITE_DURATION ) ;
CString errorStr ;
errorStr . LoadString ( IDS_ERROR ) ;
MessageBox ( ( LPCTSTR ) mess , ( LPCTSTR ) errorStr , MB_ICONEXCLAMATION ) ;
}
}
break ;
////////////////////////
// PARTICLE SYSTEM OP //
////////////////////////
case IDM_SET_ACTIVE_PARTICLE_SYSTEM :
nlassert ( nt - > Type = = CNodeType : : particleSystem ) ;
setActiveNode ( nt - > PS ) ;
_ParticleDlg - > setActiveNode ( nt - > PS ) ;
break ;
case ID_MENU_NEWLOCATED :
{
getOwnerNode ( nt ) - > setModified ( true ) ;
createLocated ( nt - > PS - > getPSPointer ( ) , GetSelectedItem ( ) ) ;
Invalidate ( ) ;
}
break ;
case IDM_RELOAD_PS :
{
nlassert ( ! nt - > PS - > isLoaded ( ) ) ;
_ParticleDlg - > loadPS ( * this , * nt - > PS , CParticleDlg : : ReportError ) ;
if ( nt - > PS - > isLoaded ( ) )
{
// remove old icon
HTREEITEM root = GetParentItem ( GetSelectedItem ( ) ) ;
HTREEITEM previousSibling = GetPrevSiblingItem ( GetSelectedItem ( ) ) ;
DeleteItem ( GetSelectedItem ( ) ) ;
// add newly loaded ps in the tree
buildTreeFromPS ( * nt - > PS , root , previousSibling ) ;
updateRightPane ( * nt ) ;
}
}
break ;
case IDM_REMOVE_PS_FROM_WORKSPACE :
{
deleteSelection ( ) ;
return TRUE ;
}
break ;
case IDM_MERGE_PS :
{
_ParticleDlg - > StartStopDlg - > stop ( ) ;
2016-11-20 13:51:11 +00:00
static TCHAR BASED_CODE szFilter [ ] = _T ( " ps & shapes files(*.ps;*.shape)|*.ps; *.shape|| " ) ;
CFileDialog fd ( TRUE , _T ( " .ps " ) , _T ( " *.ps ; * . shape " ), 0, szFilter);
2016-10-13 18:46:10 +00:00
if ( fd . DoModal ( ) = = IDOK )
{
CParticleWorkspace : : CNode * ownerNode = getOwnerNode ( nt ) ;
nlassert ( ownerNode ) ;
2016-11-20 13:51:11 +00:00
2016-10-13 18:46:10 +00:00
// Add search path for the texture
2016-11-20 13:51:11 +00:00
NLMISC : : CPath : : addSearchPath ( NLMISC : : CFile : : getPath ( tStrToUtf8 ( fd . GetPathName ( ) ) ) ) ;
2016-10-13 18:46:10 +00:00
std : : auto_ptr < NL3D : : CShapeBank > sb ( new NL3D : : CShapeBank ) ;
CParticleSystemModel * psm = NULL ;
try
{
NL3D : : CShapeStream ss ;
NLMISC : : CIFile inputFile ;
2016-11-20 13:51:11 +00:00
inputFile . open ( tStrToUtf8 ( fd . GetPathName ( ) ) ) ;
2016-10-13 18:46:10 +00:00
ss . serial ( inputFile ) ;
2016-11-20 13:51:11 +00:00
std : : string shapeName = NLMISC : : CFile : : getFilename ( tStrToUtf8 ( fd . GetPathName ( ) ) ) ;
2016-10-13 18:46:10 +00:00
sb - > add ( shapeName , ss . getShapePointer ( ) ) ;
NL3D : : CShapeBank * oldSB = CNELU : : Scene - > getShapeBank ( ) ;
CNELU : : Scene - > setShapeBank ( sb . get ( ) ) ;
NL3D : : CTransformShape * trs = CNELU : : Scene - > createInstance ( shapeName ) ;
NL3D : : CNELU : : Scene - > setShapeBank ( oldSB ) ;
if ( ! trs )
{
localizedMessageBox ( * this , IDS_COULDNT_INSTANCIATE_PS , IDS_ERROR , MB_OK | MB_ICONEXCLAMATION ) ;
return false ;
}
psm = dynamic_cast < CParticleSystemModel * > ( trs ) ;
if ( ! psm )
{
localizedMessageBox ( * this , IDS_COULDNT_INSTANCIATE_PS , IDS_ERROR , MB_OK | MB_ICONEXCLAMATION ) ;
// Not a particle system
NL3D : : CShapeBank * oldSB = CNELU : : Scene - > getShapeBank ( ) ;
NL3D : : CNELU : : Scene - > setShapeBank ( sb . get ( ) ) ;
NL3D : : CNELU : : Scene - > deleteInstance ( trs ) ;
NL3D : : CNELU : : Scene - > setShapeBank ( oldSB ) ;
return false ;
}
}
2016-11-20 13:51:11 +00:00
catch ( const NLMISC : : EStream & e )
2016-10-13 18:46:10 +00:00
{
2016-11-20 13:51:11 +00:00
MessageBox ( utf8ToTStr ( e . what ( ) ) , getStrRsc ( IDS_ERROR ) , MB_OK | MB_ICONEXCLAMATION ) ;
2016-10-13 18:46:10 +00:00
return TRUE ;
}
ownerNode - > setResetAutoCountFlag ( false ) ;
bool wasActiveNode = _LastActiveNode = = GetSelectedItem ( ) ;
if ( wasActiveNode )
{
_ParticleDlg - > StartStopDlg - > stop ( ) ;
}
// link to the root for manipulation
_ParticleDlg - > _ObjView - > getSceneRoot ( ) - > hrcLinkSon ( psm ) ;
bool mergeOK = nt - > PS - > getPSPointer ( ) - > merge ( NLMISC : : safe_cast < NL3D : : CParticleSystemShape * > ( ( NL3D : : IShape * ) psm - > Shape ) ) ;
NL3D : : CShapeBank * oldSB = CNELU : : Scene - > getShapeBank ( ) ;
CNELU : : Scene - > setShapeBank ( sb . get ( ) ) ;
CNELU : : Scene - > deleteInstance ( psm ) ;
CNELU : : Scene - > setShapeBank ( oldSB ) ;
if ( ! mergeOK )
{
localizedMessageBox ( * this , IDS_PS_NO_FINITE_DURATION , IDS_ERROR , MB_ICONEXCLAMATION ) ;
return TRUE ;
}
if ( wasActiveNode )
{
setActiveNode ( NULL ) ;
_ParticleDlg - > setActiveNode ( NULL ) ;
}
HTREEITEM prevSibling = GetPrevSiblingItem ( GetSelectedItem ( ) ) ;
HTREEITEM prevParent = GetParentItem ( GetSelectedItem ( ) ) ;
removeTreePart ( GetSelectedItem ( ) ) ;
ownerNode - > setModified ( true ) ;
HTREEITEM newRoot = buildTreeFromPS ( * ownerNode , prevParent , prevSibling ) ;
Select ( newRoot , TVGN_CARET ) ;
if ( wasActiveNode )
{
setActiveNode ( ownerNode ) ;
_ParticleDlg - > setActiveNode ( ownerNode ) ;
}
updateRightPane ( * nt ) ;
_LastClickedPS = NULL ;
}
}
break ;
case ID_MENU_SAVE_PS :
nlassert ( getOwnerNode ( nt ) ) ;
_ParticleDlg - > savePS ( * this , * getOwnerNode ( nt ) , false ) ;
break ;
case IDM_SAVE_PS_AS :
{
if ( nt - > PS - > getResetAutoCountFlag ( ) & & nt - > PS - > getPSPointer ( ) - > getAutoCountFlag ( ) )
{
MessageBox ( nt - > PS - > getFilename ( ) . c_str ( ) + getStrRsc ( IDS_AUTO_COUNT_ERROR ) , getStrRsc ( IDS_WARNING ) , MB_ICONEXCLAMATION ) ;
}
else
{
_ParticleDlg - > StartStopDlg - > stop ( ) ;
std : : string fileName = nt - > PS - > getFilename ( ) ;
2016-11-20 13:51:11 +00:00
static TCHAR BASED_CODE szFilter [ ] = _T ( " ps & shapes files(*.ps;*.shape)|*.ps; *.shape|| " ) ;
CFileDialog fd ( FALSE , _T ( " .ps " ) , utf8ToTStr ( fileName ) , OFN_OVERWRITEPROMPT , szFilter , this ) ;
2016-10-13 18:46:10 +00:00
if ( fd . DoModal ( ) = = IDOK )
{
2016-11-20 13:51:11 +00:00
_ParticleDlg - > savePSAs ( * this , * nt - > PS , tStrToUtf8 ( fd . GetPathName ( ) ) , false ) ;
2016-10-13 18:46:10 +00:00
}
}
}
break ;
case IDM_CLEAR_PS_CONTENT :
{
if ( localizedMessageBox ( * this , IDS_CLEAR_CONTENT , IDS_PARTICLE_EDITOR , MB_YESNO ) = = IDYES )
{
CParticleWorkspace : : CNode * ownerNode = getOwnerNode ( nt ) ;
nlassert ( ownerNode ) ;
ownerNode - > setResetAutoCountFlag ( false ) ;
bool wasActiveNode = _LastActiveNode = = GetSelectedItem ( ) ;
if ( wasActiveNode )
{
setActiveNode ( NULL ) ;
_ParticleDlg - > setActiveNode ( NULL ) ;
}
HTREEITEM prevSibling = GetPrevSiblingItem ( GetSelectedItem ( ) ) ;
HTREEITEM prevParent = GetParentItem ( GetSelectedItem ( ) ) ;
removeTreePart ( GetSelectedItem ( ) ) ;
ownerNode - > createEmptyPS ( ) ;
ownerNode - > setModified ( true ) ;
buildTreeFromPS ( * ownerNode , prevParent , prevSibling ) ;
if ( wasActiveNode )
{
setActiveNode ( ownerNode ) ;
_ParticleDlg - > setActiveNode ( ownerNode ) ;
}
updateRightPane ( * nt ) ;
_LastClickedPS = NULL ;
}
}
break ;
//////////
// MISC //
//////////
case IDM_FORCE_ZBIAS :
// querry zbias
CSetValueDlg valueDlg ;
// Set default value
valueDlg . Value = " 0.00 " ;
valueDlg . Title . LoadString ( IDS_FORCE_ZBIAS ) ;
// Open dialog
if ( valueDlg . DoModal ( ) = = IDOK )
{
float value ;
int dummy ; // to avoid non numeric characters at the end
if ( sscanf ( ( LPCTSTR ) ( valueDlg . Value + " \n 0 " ) , " %f \n %d " , & value , & dummy ) = = 2 )
{
nlassert ( getOwnerNode ( nt ) - > getPSPointer ( ) ) ;
getOwnerNode ( nt ) - > getPSPointer ( ) - > setZBias ( - value ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
}
else
{
CString caption ;
CString mess ;
caption . LoadString ( IDS_CAPTION_ERROR ) ;
mess . LoadString ( IDS_BAD_ZBIAS ) ;
MessageBox ( ( LPCTSTR ) mess , ( LPCTSTR ) caption , MB_ICONERROR ) ;
}
}
break ;
}
if ( toCreate )
{
HTREEITEM son , lastSon , father ;
if ( createLocAndBindable )
{
std : : pair < CParticleTreeCtrl : : CNodeType * , HTREEITEM > p = createLocated ( nt - > PS - > getPSPointer ( ) , GetSelectedItem ( ) ) ;
nt = p . first ;
son = 0 ;
father = p . second ;
lastSon = p . second ;
nlassert ( getOwnerNode ( nt ) & & getOwnerNode ( nt ) - > getPSPointer ( ) ) ;
if ( getOwnerNode ( nt ) - > getPSPointer ( ) - > getBypassMaxNumIntegrationSteps ( ) )
{
if ( toCreate - > getType ( ) = = NL3D : : PSParticle | | toCreate - > getType ( ) = = NL3D : : PSEmitter )
{
nt - > Loc - > setInitialLife ( 1.f ) ;
}
// object must have finite duration with that flag
}
}
else
{
son = GetChildItem ( GetSelectedItem ( ) ) ;
father = GetSelectedItem ( ) ;
}
if ( ! nt - > Loc - > bind ( toCreate ) )
{
2016-11-20 13:51:11 +00:00
MessageBox ( _T ( " The system is flagged with 'No max Nb steps', or uses the preset 'Spell FX'. System must have finite duration. Can't add object. To solve this, set a limited life time for the father. " ) , _T ( " Error " ) , MB_ICONEXCLAMATION ) ;
2016-10-13 18:46:10 +00:00
delete toCreate ;
if ( createLocAndBindable )
{
nlassert ( 0 ) ;
/* ps->remove(nt->Loc);
DeleteItem ( father ) ;
_NodeTypes . erase ( std : : find ( _NodeTypes . begin ( ) , _NodeTypes . end ( ) , nt ) ) ;
delete nt ; */
}
return CTreeCtrl : : OnCmdMsg ( nID , nCode , pExtra , pHandlerInfo ) ;
}
// complete the name
std : : string name = toCreate - > getName ( ) ;
char num [ 128 ] ;
if ( _PSElementIdentifiers . count ( name ) )
{
sprintf ( num , " %d " , + + _PSElementIdentifiers [ name ] ) ;
toCreate - > setName ( name + num ) ;
}
else
{
_PSElementIdentifiers [ toCreate - > getName ( ) ] = 0 ;
toCreate - > setName ( name + " 0 " ) ;
}
CNodeType * newNt = new CNodeType ( toCreate ) ;
_NodeTypes . push_back ( newNt ) ;
// insert the element in the tree
// we want that the instance always appears in the last position
if ( ! createLocAndBindable )
{
if ( ! son )
{
lastSon = GetSelectedItem ( ) ;
}
else
{
lastSon = TVI_FIRST ;
while ( son ! = NULL )
{
if ( ( ( CNodeType * ) GetItemData ( son ) ) - > Type = = CNodeType : : locatedInstance )
{
break ;
}
lastSon = son ;
son = GetChildItem ( son ) ;
}
}
}
getOwnerNode ( nt ) - > setModified ( true ) ;
// TODO : an enum for CPSLocatedBindable::getType would be better...
2016-11-20 13:51:11 +00:00
InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , utf8ToTStr ( toCreate - > getName ( ) ) , toCreate - > getType ( ) , toCreate - > getType ( ) , 0 , 0 , ( LPARAM ) newNt , father , lastSon ) ;
2016-10-13 18:46:10 +00:00
touchPSState ( nt ) ;
Invalidate ( ) ;
_ParticleDlg - > StartStopDlg - > resetAutoCount ( getOwnerNode ( nt ) ) ;
}
return CTreeCtrl : : OnCmdMsg ( nID , nCode , pExtra , pHandlerInfo ) ;
}
//****************************************************************************************************************
std : : pair < CParticleTreeCtrl : : CNodeType * , HTREEITEM > CParticleTreeCtrl : : createLocated ( NL3D : : CParticleSystem * ps , HTREEITEM headItem )
{
std : : string name ;
char num [ 128 ] ;
if ( _PSElementIdentifiers . count ( std : : string ( " located " ) ) )
{
sprintf ( num , " located %d " , + + _PSElementIdentifiers [ std : : string ( " located " ) ] ) ;
name = num ;
}
else
{
name = std : : string ( " located 0 " ) ;
_PSElementIdentifiers [ " located " ] = 0 ;
}
CPSLocated * loc = new CPSLocated ;
loc - > setName ( name ) ;
loc - > setMatrixMode ( NL3D : : PSFXWorldMatrix ) ;
ps - > attach ( loc ) ;
CNodeType * newNt = new CNodeType ( loc ) ;
_NodeTypes . push_back ( newNt ) ;
// insert item in tree
2016-11-20 13:51:11 +00:00
HTREEITEM insertedItem = InsertItem ( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT , utf8ToTStr ( name ) , PSIconLocated , PSIconLocated , 0 , 0 , ( LPARAM ) newNt , headItem , TVI_LAST ) ;
2016-10-13 18:46:10 +00:00
touchPSState ( newNt ) ;
return std : : make_pair ( newNt , insertedItem ) ;
}
//****************************************************************************************************************
/// The user finished to edit a label in the tree
void CParticleTreeCtrl : : OnEndlabeledit ( NMHDR * pNMHDR , LRESULT * pResult )
{
NMTVDISPINFO * info = ( NMTVDISPINFO * ) pNMHDR ;
* pResult = 0 ;
if ( info - > item . pszText )
{
CNodeType * nt = ( CNodeType * ) info - > item . lParam ;
switch ( nt - > Type )
{
case CNodeType : : workspace :
{
2016-11-20 13:51:11 +00:00
nt - > WS - > setName ( tStrToUtf8 ( info - > item . pszText ) ) ;
2016-10-13 18:46:10 +00:00
workspaceModifiedFlagChanged ( * nt - > WS ) ; // change name (this may be called twice because of the modification callback, but this doesn't matter)
}
break ;
case CNodeType : : particleSystem :
{
if ( ! nt - > PS - > isLoaded ( ) )
{
localizedMessageBox ( * this , IDS_CANT_CHANGE_PS_NAME , IDS_ERROR , MB_OK | MB_ICONEXCLAMATION ) ;
}
else
{
2016-11-20 13:51:11 +00:00
nt - > PS - > getPSPointer ( ) - > setName ( tStrToUtf8 ( info - > item . pszText ) ) ;
2016-10-13 18:46:10 +00:00
nt - > PS - > setModified ( true ) ;
}
2016-11-20 13:51:11 +00:00
this - > SetItemText ( info - > item . hItem , utf8ToTStr ( computeCaption ( * nt - > PS ) ) ) ;
2016-10-13 18:46:10 +00:00
}
break ;
case CNodeType : : located :
{
nlassert ( getOwnerNode ( nt ) ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
this - > SetItemText ( info - > item . hItem , info - > item . pszText ) ;
2016-11-20 13:51:11 +00:00
nt - > Loc - > setName ( tStrToUtf8 ( info - > item . pszText ) ) ;
2016-10-13 18:46:10 +00:00
}
break ;
case CNodeType : : locatedBindable :
{
nlassert ( getOwnerNode ( nt ) ) ;
getOwnerNode ( nt ) - > setModified ( true ) ;
this - > SetItemText ( info - > item . hItem , info - > item . pszText ) ;
2016-11-20 13:51:11 +00:00
nt - > Bind - > setName ( tStrToUtf8 ( info - > item . pszText ) ) ;
2016-10-13 18:46:10 +00:00
}
break ;
}
}
}
//****************************************************************************************************************
void CParticleTreeCtrl : : moveElement ( const NLMISC : : CMatrix & m )
{
NLMISC : : CMatrix mat ;
// no == operator yet... did the matrix change ?
if ( m . getPos ( ) = = mat . getPos ( )
& & m . getI ( ) = = mat . getI ( )
& & m . getJ ( ) = = mat . getJ ( )
& & m . getK ( ) = = mat . getK ( )
) return ;
nlassert ( _ParticleDlg ) ;
// the current element must be an instance
if ( : : IsWindow ( m_hWnd ) )
{
HTREEITEM currItem = GetSelectedItem ( ) ;
if ( currItem )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( currItem ) ;
if ( nt - > Type = = CNodeType : : locatedInstance )
{
if ( nt - > Loc - > getMatrixMode ( ) = = NL3D : : PSFXWorldMatrix )
{
mat = _ParticleDlg - > getPSWorldMatrix ( ) . inverted ( ) * m ;
}
else if ( nt - > Loc - > getMatrixMode ( ) = = NL3D : : PSIdentityMatrix )
{
mat = m ;
}
else
{
return ;
}
CWnd * rightPane = _ParticleDlg - > getRightPane ( ) ;
NL3D : : IPSMover * psm = NULL ;
if ( dynamic_cast < CPSMoverDlg * > ( rightPane ) )
{
CPSMoverDlg * rp = ( CPSMoverDlg * ) rightPane ;
psm = ( ( CPSMoverDlg * ) rightPane ) - > getMoverInterface ( ) ;
if ( psm & & ! psm - > onlyStoreNormal ( ) )
{
psm - > setMatrix ( rp - > getLocatedIndex ( ) , mat ) ;
}
else
{
rp - > getLocated ( ) - > getPos ( ) [ rp - > getLocatedIndex ( ) ] = mat . getPos ( ) ;
}
// update the dialog
rp - > updatePosition ( ) ;
}
}
}
}
}
//****************************************************************************************************************
NLMISC : : CMatrix CParticleTreeCtrl : : getElementMatrix ( void ) const
{
HTREEITEM currItem = GetSelectedItem ( ) ;
if ( currItem )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( currItem ) ;
if ( nt - > Type = = CNodeType : : locatedInstance )
{
NLMISC : : CVector pos = nt - > Loc - > getPos ( ) [ nt - > LocatedInstanceIndex ] ;
NLMISC : : CMatrix m ;
m . identity ( ) ;
m . setPos ( pos ) ;
if ( nt - > Loc - > getMatrixMode ( ) = = NL3D : : PSFXWorldMatrix )
{
m = _ParticleDlg - > getPSWorldMatrix ( ) * m ;
}
return m ;
}
}
return NLMISC : : CMatrix : : Identity ;
}
//****************************************************************************************************************
CParticleSystem * CParticleTreeCtrl : : CNodeType : : getOwnerPS ( ) const
{
switch ( Type )
{
case located : return Loc - > getOwner ( ) ;
case particleSystem : return PS - > getPSPointer ( ) ;
case locatedBindable : return Bind - > getOwner ( ) - > getOwner ( ) ;
case locatedInstance : return Loc - > getOwner ( ) ;
case workspace : return NULL ;
default :
nlassert ( 0 ) ;
break ;
}
return NULL ;
}
//****************************************************************************************************************
CParticleWorkspace : : CNode * CParticleTreeCtrl : : getOwnerNode ( CNodeType * nt ) const
{
if ( ! nt ) return NULL ;
HTREEITEM node = getTreeItem ( nt ) ;
while ( node )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( node ) ;
if ( ! nt ) return NULL ;
if ( nt - > Type = = CNodeType : : particleSystem )
{
return nt - > PS ;
}
node = GetParentItem ( node ) ;
}
return NULL ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : updateCaption ( CParticleWorkspace : : CNode & node )
{
HTREEITEM item = getTreeItem ( & node ) ;
if ( ! item ) return ;
// update name of ps to dipslay a star in front of it (this tells that the ps has been modified)
2016-11-20 13:51:11 +00:00
SetItemText ( item , utf8ToTStr ( computeCaption ( node ) ) ) ;
2016-10-13 18:46:10 +00:00
}
//****************************************************************************************************************
std : : string CParticleTreeCtrl : : computeCaption ( const std : : string & path , const std : : string & userName , bool modified )
{
std : : string name ;
if ( modified )
{
name = " * " ;
}
if ( ! userName . empty ( ) )
{
name + = userName ;
if ( _ViewFilenameFlag )
{
name + = " - " ;
}
}
if ( _ViewFilenameFlag )
{
name + = NLMISC : : CFile : : getFilename ( path ) ;
}
return name ;
}
//****************************************************************************************************************
std : : string CParticleTreeCtrl : : computeCaption ( CParticleWorkspace : : CNode & node )
{
std : : string baseCaption ;
if ( node . isLoaded ( ) )
{
baseCaption = computeCaption ( node . getRelativePath ( ) , node . getPSPointer ( ) - > getName ( ) , node . isModified ( ) ) ;
}
else
{
baseCaption = computeCaption ( node . getRelativePath ( ) , " " , false ) ;
}
if ( ! node . getTriggerAnim ( ) . empty ( ) )
{
baseCaption = " ( " + node . getTriggerAnim ( ) + " ) " + baseCaption ;
}
if ( node . getParentSkel ( ) )
{
baseCaption = " (L) " + baseCaption ;
}
return baseCaption ;
}
//****************************************************************************************************************
std : : string CParticleTreeCtrl : : computeCaption ( CParticleWorkspace & workspace )
{
return computeCaption ( workspace . getFilename ( ) , workspace . getName ( ) , workspace . isModified ( ) ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : insertNewPS ( CParticleWorkspace & pws )
{
2016-11-20 13:51:11 +00:00
static const TCHAR BASED_CODE szFilter [ ] = _T ( " NeL Particle systems (*.ps)|*.ps|| " ) ;
CFileDialog fd ( TRUE , _T ( " .ps " ) , _T ( " *.ps " ) , OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST , szFilter , this ) ;
2016-10-13 18:46:10 +00:00
const uint MAX_NUM_CHAR = 65536 ;
2016-11-20 13:51:11 +00:00
TCHAR filenamesBuf [ MAX_NUM_CHAR ] ;
_tcscpy ( filenamesBuf , _T ( " *.ps " ) ) ;
2016-10-13 18:46:10 +00:00
fd . m_ofn . lpstrFile = filenamesBuf ;
fd . m_ofn . nMaxFile = MAX_NUM_CHAR - 1 ;
if ( fd . DoModal ( ) = = IDOK )
{
CParticleWorkspace : : IModificationCallback * oldCallback = pws . getModificationCallback ( ) ;
pws . setModificationCallback ( NULL ) ;
POSITION pos = fd . GetStartPosition ( ) ;
bool diplayLoadingError = true ;
bool diplayNodeAlreadyInserted = true ;
bool hasSelectedNode = _ParticleDlg - > getActiveNode ( ) ! = NULL ;
CParticleWorkspace : : CNode * firstLoadedNode = NULL ;
while ( pos )
{
CString path = fd . GetNextPathName ( pos ) ;
2016-11-20 13:51:11 +00:00
CParticleWorkspace : : CNode * node = pws . addNode ( tStrToUtf8 ( path ) ) ;
2016-10-13 18:46:10 +00:00
if ( ! node )
{
if ( diplayNodeAlreadyInserted )
{
if ( pos )
{
CSkippableMessageBox smb ( path + getStrRsc ( IDS_PS_ALREADY_INSERTED ) , getStrRsc ( IDS_ERROR ) , this ) ;
smb . DoModal ( ) ;
diplayNodeAlreadyInserted = ! smb . getBypassFlag ( ) ;
}
else
{
2016-11-20 13:51:11 +00:00
MessageBox ( CString ( utf8ToTStr ( NLMISC : : CFile : : getFilename ( tStrToUtf8 ( path ) ) ) ) + getStrRsc ( IDS_PS_ALREADY_INSERTED ) , getStrRsc ( IDS_ERROR ) , MB_OK | MB_ICONEXCLAMATION ) ;
2016-10-13 18:46:10 +00:00
}
}
continue ;
}
if ( diplayLoadingError )
{
diplayLoadingError = _ParticleDlg - > loadPS ( * this , * node , pos ? CParticleDlg : : ReportErrorSkippable : CParticleDlg : : ReportError ) ;
}
else
{
_ParticleDlg - > loadPS ( * this , * node , CParticleDlg : : Silent ) ;
}
if ( ! node - > isLoaded ( ) )
{
pws . removeNode ( pws . getNumNode ( ) - 1 ) ;
}
else
{
if ( ! firstLoadedNode ) firstLoadedNode = node ;
buildTreeFromPS ( * node , GetRootItem ( ) ) ;
}
}
pws . setModificationCallback ( oldCallback ) ;
if ( firstLoadedNode )
{
expandRoot ( ) ;
pws . touch ( ) ;
if ( ! hasSelectedNode )
{
_ParticleDlg - > setActiveNode ( firstLoadedNode ) ;
setActiveNode ( firstLoadedNode ) ;
}
}
// update modified state
2016-11-20 13:51:11 +00:00
SetItemText ( GetRootItem ( ) , utf8ToTStr ( computeCaption ( pws ) ) ) ;
2016-10-13 18:46:10 +00:00
}
}
//****************************************************************************************************************
void CParticleTreeCtrl : : createNewPS ( CParticleWorkspace & pws )
{
CCreateFileDlg cfd ( getStrRsc ( IDS_CREATE_NEW_PS ) , NLMISC : : CPath : : standardizeDosPath ( pws . getPath ( ) ) , " ps " , this ) ;
if ( cfd . DoModal ( ) = = IDOK )
{
if ( pws . containsFile ( cfd . getFileName ( ) ) )
{
MessageBox ( ( LPCTSTR ) ( CString ( NLMISC : : CFile : : getFilename ( cfd . getFileName ( ) ) . c_str ( ) ) + getStrRsc ( IDS_PS_ALREADY_INSERTED ) ) , getStrRsc ( IDS_ERROR ) , MB_ICONEXCLAMATION ) ;
}
if ( cfd . touchFile ( ) )
{
CParticleWorkspace : : CNode * node = pws . addNode ( cfd . getFullPath ( ) ) ;
nlassert ( node ) ; // should always succeed because we tested if file already exists
node - > createEmptyPS ( ) ;
_ParticleDlg - > savePS ( * this , * node , false ) ; // write empty ps to disk
// create an icon at the end of workspace
buildTreeFromPS ( * node , GetRootItem ( ) ) ;
}
}
}
//****************************************************************************************************************
void CParticleTreeCtrl : : removeTreePart ( HTREEITEM root )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( root ) ;
_NodeTypes . erase ( std : : find ( _NodeTypes . begin ( ) , _NodeTypes . end ( ) , nt ) ) ;
delete nt ;
HTREEITEM child = GetChildItem ( root ) ;
while ( child )
{
HTREEITEM tmpChild = child ;
child = GetNextSiblingItem ( child ) ;
removeTreePart ( tmpChild ) ;
}
DeleteItem ( root ) ;
}
//****************************************************************************************************************
HTREEITEM CParticleTreeCtrl : : getTreeItem ( CNodeType * nt ) const
{
if ( ! GetRootItem ( ) ) return NULL ;
std : : stack < HTREEITEM > leftToTraverse ;
leftToTraverse . push ( GetRootItem ( ) ) ;
while ( ! leftToTraverse . empty ( ) )
{
HTREEITEM curr = leftToTraverse . top ( ) ;
leftToTraverse . pop ( ) ;
if ( ( CNodeType * ) GetItemData ( curr ) = = nt )
{
return curr ;
}
if ( GetChildItem ( curr ) ) leftToTraverse . push ( GetChildItem ( curr ) ) ;
if ( GetNextSiblingItem ( curr ) ) leftToTraverse . push ( GetNextSiblingItem ( curr ) ) ;
}
return NULL ;
}
//****************************************************************************************************************
HTREEITEM CParticleTreeCtrl : : getTreeItem ( CParticleWorkspace : : CNode * node ) const
{
if ( ! GetRootItem ( ) ) return NULL ;
std : : stack < HTREEITEM > leftToTraverse ;
leftToTraverse . push ( GetRootItem ( ) ) ;
while ( ! leftToTraverse . empty ( ) )
{
HTREEITEM curr = leftToTraverse . top ( ) ;
leftToTraverse . pop ( ) ;
const CNodeType * nt = ( CNodeType * ) GetItemData ( curr ) ;
if ( nt & & nt - > Type = = CNodeType : : particleSystem & & nt - > PS = = node )
{
return curr ;
}
if ( GetChildItem ( curr ) ) leftToTraverse . push ( GetChildItem ( curr ) ) ;
if ( GetNextSiblingItem ( curr ) ) leftToTraverse . push ( GetNextSiblingItem ( curr ) ) ;
}
return NULL ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : nodeModifiedFlagChanged ( CParticleWorkspace : : CNode & node )
{
updateCaption ( node ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : workspaceModifiedFlagChanged ( CParticleWorkspace & ws )
{
// for now assume that workspace is the root
HTREEITEM root = GetRootItem ( ) ;
if ( ! root ) return ;
SetItemText ( root , ( LPCTSTR ) computeCaption ( ws ) . c_str ( ) ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : nodeSkelParentChanged ( CParticleWorkspace : : CNode & node )
{
updateCaption ( node ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : setActiveNode ( CParticleWorkspace : : CNode * node )
{
HTREEITEM newItem = getTreeItem ( node ) ;
if ( _LastActiveNode ) SetItemState ( _LastActiveNode , 0 , TVIS_BOLD ) ;
if ( newItem )
{
SetItemState ( newItem , TVIS_BOLD , TVIS_BOLD ) ;
}
_LastActiveNode = newItem ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : touchPSState ( CNodeType * nt )
{
if ( ! nt ) return ;
CParticleWorkspace : : CNode * ownerNode = getOwnerNode ( nt ) ;
if ( ownerNode & & ownerNode - > getPSModel ( ) )
{
ownerNode - > getPSModel ( ) - > touchLightableState ( ) ;
ownerNode - > getPSModel ( ) - > touchTransparencyState ( ) ;
}
}
//****************************************************************************************************************
void CParticleTreeCtrl : : OnBeginlabeledit ( NMHDR * pNMHDR , LRESULT * pResult )
{
TV_DISPINFO * pTVDispInfo = ( TV_DISPINFO * ) pNMHDR ;
NMTVDISPINFO * info = ( NMTVDISPINFO * ) pNMHDR ;
* pResult = 0 ;
CEdit * pEdit = GetEditControl ( ) ;
if ( ! pEdit ) return ;
if ( info - > item . pszText )
{
CNodeType * nt = ( CNodeType * ) info - > item . lParam ;
switch ( nt - > Type )
{
case CNodeType : : workspace :
2016-11-20 13:51:11 +00:00
pEdit - > SetWindowText ( utf8ToTStr ( nt - > WS - > getName ( ) ) ) ;
2016-10-13 18:46:10 +00:00
break ;
case CNodeType : : particleSystem :
{
if ( ! nt - > PS - > isLoaded ( ) )
{
2016-11-20 13:51:11 +00:00
pEdit - > SetWindowText ( _T ( " " ) ) ;
2016-10-13 18:46:10 +00:00
//localizedMessageBox(*this, IDS_CANT_CHANGE_PS_NAME, IDS_ERROR, MB_OK|MB_ICONEXCLAMATION);
}
else
{
2016-11-20 13:51:11 +00:00
pEdit - > SetWindowText ( utf8ToTStr ( nt - > PS - > getPSPointer ( ) - > getName ( ) ) ) ;
2016-10-13 18:46:10 +00:00
}
}
break ;
case CNodeType : : located :
{
2016-11-20 13:51:11 +00:00
pEdit - > SetWindowText ( utf8ToTStr ( nt - > Loc - > getName ( ) ) ) ;
2016-10-13 18:46:10 +00:00
}
break ;
case CNodeType : : locatedBindable :
{
2016-11-20 13:51:11 +00:00
pEdit - > SetWindowText ( utf8ToTStr ( nt - > Bind - > getName ( ) ) ) ;
2016-10-13 18:46:10 +00:00
}
break ;
}
}
* pResult = 0 ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : OnLButtonDblClk ( UINT nFlags , CPoint point )
{
UINT flags ;
HTREEITEM item = this - > HitTest ( point , & flags ) ;
if ( item )
{
CNodeType * nt = ( CNodeType * ) GetItemData ( item ) ;
nlassert ( nt ) ;
if ( nt - > Type = = CNodeType : : particleSystem & & nt - > PS - > isLoaded ( ) )
{
_ParticleDlg - > setActiveNode ( nt - > PS ) ;
setActiveNode ( nt - > PS ) ;
return ;
}
}
CTreeCtrl : : OnLButtonDblClk ( nFlags , point ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : sortWorkspace ( CParticleWorkspace & ws , CParticleWorkspace : : ISort & sorter )
{
// stop all fx
nlassert ( _ParticleDlg ) ;
_ParticleDlg - > StartStopDlg - > stop ( ) ;
CParticleWorkspace : : CNode * activeNode = _ParticleDlg - > getActiveNode ( ) ;
setActiveNode ( NULL ) ;
reset ( ) ;
ws . sort ( sorter ) ;
buildTreeFromWorkSpace ( ws ) ;
Select ( GetRootItem ( ) , TVGN_FIRSTVISIBLE ) ;
setActiveNode ( activeNode ) ;
expandRoot ( ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : OnKeydown ( NMHDR * pNMHDR , LRESULT * pResult )
{
/*
TV_KEYDOWN * pTVKeyDown = ( TV_KEYDOWN * ) pNMHDR ;
if ( pTVKeyDown - > wVKey = = VK_DELETE )
{
deleteSelection ( ) ;
}
* pResult = 0 ;
*/
}
//****************************************************************************************************************
void CParticleTreeCtrl : : OnKeyUp ( UINT nChar , UINT nRepCnt , UINT nFlags )
{
/*
if ( nChar = = VK_DELETE )
{
deleteSelection ( ) ;
}
*/
CTreeCtrl : : OnKeyUp ( nChar , nRepCnt , nFlags ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : expandRoot ( )
{
if ( GetRootItem ( ) ) Expand ( GetRootItem ( ) , TVE_EXPAND ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : setViewFilenameFlag ( bool enabled )
{
if ( enabled = = _ViewFilenameFlag ) return ;
_ViewFilenameFlag = enabled ;
updateAllCaptions ( ) ;
}
//****************************************************************************************************************
void CParticleTreeCtrl : : updateAllCaptions ( )
{
if ( ! GetRootItem ( ) ) return ;
std : : stack < HTREEITEM > leftToTraverse ;
leftToTraverse . push ( GetRootItem ( ) ) ;
// TODO: factorize code to traverse all nodes
while ( ! leftToTraverse . empty ( ) )
{
HTREEITEM curr = leftToTraverse . top ( ) ;
leftToTraverse . pop ( ) ;
CNodeType * nt = ( CNodeType * ) GetItemData ( curr ) ;
switch ( nt - > Type )
{
case CNodeType : : particleSystem :
2016-11-20 13:51:11 +00:00
SetItemText ( curr , utf8ToTStr ( computeCaption ( * nt - > PS ) ) ) ;
2016-10-13 18:46:10 +00:00
break ;
case CNodeType : : workspace :
2016-11-20 13:51:11 +00:00
SetItemText ( curr , utf8ToTStr ( computeCaption ( * nt - > WS ) ) ) ;
2016-10-13 18:46:10 +00:00
break ;
case CNodeType : : located :
case CNodeType : : locatedBindable :
case CNodeType : : locatedInstance :
// no-op
break ;
default :
nlassert ( 0 ) ;
break ;
}
if ( GetChildItem ( curr ) ) leftToTraverse . push ( GetChildItem ( curr ) ) ;
if ( GetNextSiblingItem ( curr ) ) leftToTraverse . push ( GetNextSiblingItem ( curr ) ) ;
}
}
//****************************************************************************************************************
void CParticleTreeCtrl : : removeAllPS ( CParticleWorkspace & ws )
{
if ( localizedMessageBox ( * this , IDS_REMOVE_ALL_PS , IDS_PARTICLE_SYSTEM_EDITOR , MB_OKCANCEL | MB_ICONQUESTION ) ! = IDOK ) return ;
setActiveNode ( NULL ) ;
_ParticleDlg - > setActiveNode ( NULL ) ;
uint numNodes = ws . getNumNode ( ) ;
for ( uint k = 0 ; k < numNodes ; + + k )
{
ws . removeNode ( ( uint ) 0 ) ;
}
reset ( ) ;
buildTreeFromWorkSpace ( ws ) ;
}