Serious-Engine/Sources/SeriousSkaStudio/DlgBarTreeView.cpp

1753 lines
58 KiB
C++
Raw Permalink Normal View History

2016-03-12 01:20:51 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2016-03-11 14:57:17 +01:00
// DlgBarTreeView.cpp: implementation of the CDlgBarTreeView class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SeriousSkaStudio.h"
#include "DlgBarTreeView.h"
#include "resource.h"
#include "MainFrm.h"
#include "ChildFrm.h"
#include "DlgTemplate.h"
#include <Engine\Base\Stream.h>
#include <Engine\Ska\Skeleton.h>
#ifdef _DEBUG
#undef new
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// array of depth in recursion to selected item
CStaticStackArray<INDEX> _aSelectItem;
// array of selected mesh surfaces
CStaticStackArray<INDEX> _aiSelectedMeshSurfaces;
CStaticArray<class CTextureControl> _atxcTexControls;
CStaticArray<class CTexCoordControl> _atxccTexCoordControls;
CStaticArray<class CFloatControl> _afcFloatControls;
CStaticArray<class CFlagControl> _afcFlagControls;
CStaticArray<class CColorControl> _accColors;
extern INDEX iCustomControlID;
BEGIN_MESSAGE_MAP(CDlgBarTreeView, CDlgTemplate)
//{{AFX_MSG_MAP(CDlgBarTreeView)
ON_NOTIFY(TCN_SELCHANGE, IDC_MODE_SELECT_TAB, OnSelchangeModeSelectTab)
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CDlgBarTreeView::CDlgBarTreeView()
{
pdlgCurrent = NULL;
}
CDlgBarTreeView::~CDlgBarTreeView()
{
}
// returns info of item in tree view
NodeInfo &CDlgBarTreeView::GetNodeInfo(HTREEITEM hItem)
{
ASSERT(hItem!=NULL);
INDEX iNodeIndex = m_TreeCtrl.GetItemData(hItem);
return theApp.aNodeInfo[iNodeIndex];
}
// returns infog of selected item in tree view
NodeInfo &CDlgBarTreeView::GetSelectedNodeInfo()
{
HTREEITEM hSelected = m_TreeCtrl.GetSelectedItem();
ASSERT(hSelected!=NULL);
// aditional check
INDEX iNodeIndex = 0;
if(hSelected!=NULL) {
iNodeIndex = m_TreeCtrl.GetItemData(hSelected);
}
return theApp.aNodeInfo[iNodeIndex];
}
// chose control group to show
void CDlgBarTreeView::ShowControlGroup(INDEX iGroup)
{
CDialog *pLastVisibleDlg = pdlgCurrent;
switch(iGroup)
{
case GR_PARENT:
pdlgCurrent = &m_dlgParent;
break;
case GR_ANIMSET:
pdlgCurrent = &m_dlgAnimSet;
break;
case GR_COLISION:
pdlgCurrent = &m_dlgColision;
break;
case GR_ALLFRAMES_BBOX:
pdlgCurrent = &m_dlgAllFrames;
break;
case GR_LOD:
pdlgCurrent = &m_dlgLod;
break;
case GR_BONE:
pdlgCurrent = &m_dlgBone;
break;
case GR_TEXTURE:
pdlgCurrent = &m_dlgTexture;
break;
case GR_LISTOPTIONS:
pdlgCurrent = &m_dlgListOpt;
break;
case GR_SHADERS:
pdlgCurrent = &m_dlgShader;
break;
default:
pdlgCurrent = NULL;
break;
}
if(pLastVisibleDlg!=pdlgCurrent) {
if(pLastVisibleDlg!=NULL) {
// hide current dialog
pLastVisibleDlg->ShowWindow(SW_HIDE);
}
if(pdlgCurrent!=NULL) {
// show new dialog
pdlgCurrent->ShowWindow(SW_SHOW);
}
}
}
// select surface in tree view
void CDlgBarTreeView::SelectMeshSurface(HTREEITEM hItem)
{
INDEX iNodeIndex = m_TreeCtrl.GetItemData(hItem);
INDEX iIcon = 12;
NodeInfo &ni = theApp.aNodeInfo[iNodeIndex];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
// count selected mesh surfaces
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surface in array
for(INDEX isms=0;isms<ctsms;isms++)
{
INDEX &iIndex = _aiSelectedMeshSurfaces[isms];
// check if surface is allready selected
if(iIndex == iNodeIndex)
{
// surface is allready selected, return
return;
}
}
// add surface to selection array
INDEX &iIndex = _aiSelectedMeshSurfaces.Push();
iIndex = iNodeIndex;
// set new icon
m_TreeCtrl.SetItemImage(hItem,iIcon,iIcon);
}
// Seselect surface in tree view
void CDlgBarTreeView::DeselectMeshSurface(HTREEITEM hItem)
{
INDEX iNodeIndex = m_TreeCtrl.GetItemData(hItem);
INDEX iIcon = 11;
NodeInfo &ni = theApp.aNodeInfo[iNodeIndex];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
// count selected mesh surfaces
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surface in array
for(INDEX isms=0;isms<ctsms;isms++)
{
INDEX &iIndex = _aiSelectedMeshSurfaces[isms];
// check if this is clicked item
if(iIndex == iNodeIndex)
{
// remove one item
INDEX iLastIndex = _aiSelectedMeshSurfaces.Pop();
iIndex = iLastIndex;
// set new icon
m_TreeCtrl.SetItemImage(hItem,iIcon,iIcon);
return;
}
}
}
// Togle surface selection in tree view
void CDlgBarTreeView::TogleSurfaceSelection(HTREEITEM hItem)
{
INDEX iNodeIndex = m_TreeCtrl.GetItemData(hItem);
NodeInfo &ni = theApp.aNodeInfo[iNodeIndex];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
// count selected mesh surfaces
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surface in array
for(INDEX isms=0;isms<ctsms;isms++)
{
INDEX &iIndex = _aiSelectedMeshSurfaces[isms];
// check if this is clicked item
if(iIndex == iNodeIndex)
{
// deselect surface
DeselectMeshSurface(hItem);
return;
}
}
// if item was't previously selected, select it
SelectMeshSurface(hItem);
}
// Deselect all surfaces
void CDlgBarTreeView::DeSelectAllSurfaces(HTREEITEM hParent/*=NULL*/)
{
INDEX iIcon=11;
if(hParent==NULL)
{
hParent = m_TreeCtrl.GetRootItem();
_aiSelectedMeshSurfaces.PopAll();
}
HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent);
while(hChild!=NULL)
{
DeSelectAllSurfaces(hChild);
NodeInfo &ni = GetNodeInfo(hChild);
if(ni.ni_iType == NT_MESHSURFACE)
{
m_TreeCtrl.SetItemImage(hChild,iIcon,iIcon);
}
hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
// select all surfaces if item is not selected, otherwise deselect all
void CDlgBarTreeView::SelectAllSurfaces(HTREEITEM hItem)
{
INDEX iIcon = -1;
INDEX iNodeIndex = m_TreeCtrl.GetItemData(hItem);
NodeInfo &ni = theApp.aNodeInfo[iNodeIndex];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
// clicked item is allready selected, deselect all surfaces
BOOL bSelect = IsSurfaceSelected(*pmsrf);
// get parent
HTREEITEM hParent = m_TreeCtrl.GetParentItem(hItem);
INDEX iParentIndex = m_TreeCtrl.GetItemData(hParent);
NodeInfo &niParent = theApp.aNodeInfo[iParentIndex];
ASSERT(niParent.ni_iType == NT_MESHLOD);
MeshLOD *pmlod = (MeshLOD*)niParent.ni_pPtr;
// get children of mesh lod
HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent);
while(hChild!=NULL)
{
// select surface
if(!bSelect) SelectMeshSurface(hChild);
else DeselectMeshSurface(hChild);
hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
}
}
// check if surface is selected
BOOL CDlgBarTreeView::IsSurfaceSelected(MeshSurface &msrf)
{
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++)
{
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
// check if this is selected surface
if(pmsrf == &msrf) return TRUE;
}
return FALSE;
}
// change texture for all selected surfaces
void CDlgBarTreeView::ChangeTextureOnSelectedSurfaces(CTString strControlID,CTString strNewTexID)
{
// get id of texture
INDEX iTextureID = ska_GetIDFromStringTable(strNewTexID);
// get selected surfaces count
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++)
{
// get pointer to mesh surface
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
if(pmsrf->msrf_pShader==NULL) continue;
// get surface description and find witch param has same id as control that was modified
ShaderDesc shDesc;
pmsrf->msrf_pShader->GetShaderDesc(shDesc);
INDEX cttx = shDesc.sd_astrTextureNames.Count();
// for each texture in shader
for(INDEX itx=0;itx<cttx;itx++)
{
// if this surface has shader param that has text same as control that changed value
if(shDesc.sd_astrTextureNames[itx] == strControlID)
{
// change it
pmsrf->msrf_ShadingParams.sp_aiTextureIDs[itx] = iTextureID;
}
}
}
}
// change texture coord index for all selected surfaces
void CDlgBarTreeView::ChangeTextureCoordsOnSelectedSurfaces(CTString strControlID,INDEX iNewTexCoordsIndex)
{
// get selected surfaces count
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++)
{
// get pointer to mesh surface
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
if(pmsrf->msrf_pShader==NULL) continue;
// get surface description and find witch param has same id as control that was modified
ShaderDesc shDesc;
pmsrf->msrf_pShader->GetShaderDesc(shDesc);
INDEX cttxc = shDesc.sd_astrTexCoordNames.Count();
// for each texture in shader
for(INDEX itxc=0;itxc<cttxc;itxc++)
{
// if this surface has shader param that has text same as control that changed value
if(shDesc.sd_astrTexCoordNames[itxc] == strControlID)
{
// change it
pmsrf->msrf_ShadingParams.sp_aiTexCoordsIndex[itxc] = iNewTexCoordsIndex;
}
}
}
}
// change color on curently selected model instance
void CDlgBarTreeView::ChangeColorOnSelectedModel(COLOR colNewColor)
{
ASSERT(pmiSelected!=NULL);
pmiSelected->mi_colModelColor = colNewColor;
}
// change color on all selected mesh surfaces
void CDlgBarTreeView::ChangeColorOnSelectedSurfaces(CTString strControlID,COLOR colNewColor)
{
// get selected surfaces count
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++)
{
// get pointer to mesh surface
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
if(pmsrf->msrf_pShader==NULL) continue;
// get surface description and find witch param has same id as control that was modified
ShaderDesc shDesc;
pmsrf->msrf_pShader->GetShaderDesc(shDesc);
INDEX ctcl = shDesc.sd_astrColorNames.Count();
// for each color in shader
for(INDEX icl=0;icl<ctcl;icl++)
{
// if this surface has shader param that has text same as control that changed value
if(shDesc.sd_astrColorNames[icl] == strControlID)
{
// change it
pmsrf->msrf_ShadingParams.sp_acolColors[icl] = colNewColor;
}
}
}
}
// change floats on all selected mesh surfaces
void CDlgBarTreeView::ChangeFloatOnSelectedSurfaces(CTString strControlID,FLOAT fNewFloat)
{
// get selected surfaces count
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++) {
// get pointer to mesh surface
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
if(pmsrf->msrf_pShader==NULL) continue;
// get surface description and find witch param has same id as control that was modified
ShaderDesc shDesc;
pmsrf->msrf_pShader->GetShaderDesc(shDesc);
INDEX ctfl = shDesc.sd_astrFloatNames.Count();
// for each float in shader
for(INDEX ifl=0;ifl<ctfl;ifl++) {
// if this surface has shader param that has text same as control that changed value
if(shDesc.sd_astrFloatNames[ifl] == strControlID) {
// change it
pmsrf->msrf_ShadingParams.sp_afFloats[ifl] = fNewFloat;
}
}
}
}
void CDlgBarTreeView::ChangeFlagOnSelectedSurfaces(CTString strControlID, BOOL bChecked, INDEX iFlagIndex)
{
ULONG ulNewFlag = (1UL<<iFlagIndex);
// get selected surfaces count
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++) {
// get pointer to mesh surface
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
if(pmsrf->msrf_pShader==NULL) continue;
// get surface description and find witch param has same id as control that was modified
ShaderDesc shDesc;
pmsrf->msrf_pShader->GetShaderDesc(shDesc);
INDEX ctfl = shDesc.sd_astrFlagNames.Count();
// for each flag in shader
for(INDEX ifl=0;ifl<ctfl;ifl++) {
// if this surface has shader param that has text same as control that changed value
if(shDesc.sd_astrFlagNames[ifl] == strControlID) {
// if now checked
if(bChecked) {
// add this flag
pmsrf->msrf_ShadingParams.sp_ulFlags |= ulNewFlag;
// if unchecked
} else {
// remove this flag
pmsrf->msrf_ShadingParams.sp_ulFlags &= ~ulNewFlag;
}
}
}
}
}
// change shader for all surfaces that are in selection array
void CDlgBarTreeView::ChangeShaderOnSelectedSurfaces(CTString fnNewShader)
{
#pragma message(">> Remove: Warning if usage of Double sided shader")
// TEMP
if(fnNewShader.FindSubstr("DS")!=(-1)) {
theApp.ErrorMessage("Usage of double sided shader");
}
INDEX ctsms = _aiSelectedMeshSurfaces.Count();
// for each selected mesh surfaces
for(INDEX isms=0;isms<ctsms;isms++) {
NodeInfo &ni = theApp.aNodeInfo[_aiSelectedMeshSurfaces[isms]];
ASSERT(ni.ni_iType == NT_MESHSURFACE);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
ASSERT(pmsrf!=NULL);
try {
// try to change surface shader
ChangeSurfaceShader_t(*pmsrf,fnNewShader);
} catch(char *strErr) {
theApp.ErrorMessage(strErr);
}
}
}
// notification that item was clicked
void CDlgBarTreeView::OnItemClick(HTREEITEM hItem,HTREEITEM hLastSelected)
{
BOOL bControl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
ASSERT(hItem != NULL);
NodeInfo &ni = theApp.aNodeInfo[m_TreeCtrl.GetItemData(hItem)];
if(ni.ni_iType == NT_MESHSURFACE) {
if (bShift) {
if(hLastSelected!=NULL) {
NodeInfo &niLastSelected = GetNodeInfo(hLastSelected);
if(niLastSelected.ni_iType == NT_MESHSURFACE) {
HTREEITEM hParent = m_TreeCtrl.GetParentItem(hItem);
HTREEITEM hLastParent = m_TreeCtrl.GetParentItem(hLastSelected);
ASSERT(hParent!=NULL);
ASSERT(hLastParent!=NULL);
if(hParent==hLastParent) {
// deselect all items
if(!bControl) DeSelectAllSurfaces();
// get first child
HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent);
// find first item or last selected item
while((hChild!=hItem)&&(hChild!=hLastSelected)) {
hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
ASSERT(hChild!=NULL);
}
// select first item
SelectMeshSurface(hChild);
if(hItem!=hLastSelected) hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
// select all items until item or last selected item
while((hChild!=hItem)&&(hChild!=hLastSelected)) {
SelectMeshSurface(hChild);
hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
ASSERT(hChild!=NULL);
}
SelectMeshSurface(hChild);
}
return;
}
}
}
if(bControl) {
// select curent surface
TogleSurfaceSelection(hItem);
return;
}
// deselect all items
DeSelectAllSurfaces();
// select curent surface
SelectMeshSurface(hItem);
}
}
// notification that item icons was clicked
void CDlgBarTreeView::OnItemIconClick(HTREEITEM hItem)
{
NodeInfo &ni = GetNodeInfo(hItem);
if(ni.ni_iType == NT_MESHSURFACE) {
TogleSurfaceSelection(hItem);
}
}
// show shader for surface
void CDlgBarTreeView::ShowSurfaceShader(MeshSurface *pmsrf,MeshLOD *pmlod,MeshInstance *pmshi)
{
ASSERT(pmsrf!=NULL);
ASSERT(pmlod!=NULL);
ASSERT(pmshi!=NULL);
// remember vertical scroll pos
INDEX ivScroll = m_dlgShader.GetScrollPos(SB_VERT);
// set scroll to 0
m_dlgShader.SetScrollPos(SB_VERT,0);
VScrollControls(&m_dlgShader);
// clear shader dlg
RemoveDialogControls(&m_dlgShader);
CComboBox *cbShader = ((CComboBox*)m_dlgShader.GetDlgItem(IDC_CB_SHADER));
_atxcTexControls.Clear();
_atxccTexCoordControls.Clear();
_accColors.Clear();
_afcFloatControls.Clear();
_afcFlagControls.Clear();
iCustomControlID=FIRSTSHADEID;
ShaderDesc shDesc;
INDEX ctTextures = 0;
INDEX ctTexCoords = 0;
INDEX ctColors = 0;
INDEX ctFloats = 0;
INDEX ctFlags = 0;
// if surface has shader
if(pmsrf->msrf_pShader!=NULL) {
pmsrf->msrf_pShader->GetShaderDesc(shDesc);
ctTextures = shDesc.sd_astrTextureNames.Count();
ctTexCoords = shDesc.sd_astrTexCoordNames.Count();
ctColors = shDesc.sd_astrColorNames.Count();
ctFloats = shDesc.sd_astrFloatNames.Count();
ctFlags = shDesc.sd_astrFlagNames.Count();
// select shader in combo box
CTFileName fnShader = pmsrf->msrf_pShader->GetName();
CTString strShader = fnShader.FileName();
ASSERT(cbShader!=NULL);
if(cbShader->SelectString(-1,CString(strShader)) == CB_ERR) {
// error: shader is not found in list of shaders
return;
}
ShaderParams &mspParams = pmsrf->msrf_ShadingParams;
// ASSERT(pmsrf->msrf_ShadingParams.sp_acolColors.Count() == ctColors);
_atxcTexControls.New(ctTextures);
_atxccTexCoordControls.New(ctTexCoords);
_accColors.New(ctColors);
_afcFloatControls.New(ctFloats);
_afcFlagControls.New(ctFlags);
// add texture controls to shader dialog
for(INDEX itx=0;itx<ctTextures;itx++) {
CTextureControl &txc = _atxcTexControls[itx];
txc.AddControl(shDesc.sd_astrTextureNames[itx],&pmsrf->msrf_ShadingParams.sp_aiTextureIDs[itx]);
// count texture instances
INDEX ctti=pmshi->mi_tiTextures.Count();
// for each texture instances
for(INDEX iti=0;iti<ctti;iti++) {
TextureInstance &ti = pmshi->mi_tiTextures[iti];
CTString strTexName = ska_GetStringFromTable(ti.GetID());
txc.txc_Combo.AddString(CString(strTexName));
}
INDEX iSelectTexID = mspParams.sp_aiTextureIDs[itx];
CTString strSelectTexID = ska_GetStringFromTable(iSelectTexID);
int iItemIndex = txc.txc_Combo.FindStringExact(-1,CString(strSelectTexID));
if(iItemIndex!=CB_ERR) txc.txc_Combo.SetCurSel(iItemIndex);
}
// add texcoord controls to shader dialog
for(INDEX itxc=0;itxc<ctTexCoords;itxc++) {
CTexCoordControl &txcc = _atxccTexCoordControls[itxc];
txcc.AddControl(shDesc.sd_astrTexCoordNames[itxc],&pmsrf->msrf_ShadingParams.sp_aiTexCoordsIndex[itxc]);
// count uvmaps
INDEX ctuv = pmlod->mlod_aUVMaps.Count();
// for each uvmap in lod
for(INDEX iuv=0;iuv<ctuv;iuv++) {
// add uvmap name in combo box
MeshUVMap &uvm = pmlod->mlod_aUVMaps[iuv];
CTString strUVMapName = ska_GetStringFromTable(uvm.muv_iID);
txcc.txcc_Combo.AddString(CString(strUVMapName));
}
INDEX iSelectTexCoordsIndex = mspParams.sp_aiTexCoordsIndex[itxc];
txcc.txcc_Combo.SetCurSel(iSelectTexCoordsIndex);
}
// add color controls to shader dialog
for(INDEX icc=0;icc<ctColors;icc++) {
CColorControl &cc = _accColors[icc];
cc.AddControl(shDesc.sd_astrColorNames[icc],&pmsrf->msrf_ShadingParams.sp_acolColors[icc]);
}
// add float controls to shader dialog
INDEX ifc=0;
for(;ifc<ctFloats;ifc++) {
CFloatControl &fc = _afcFloatControls[ifc];
fc.AddControl(shDesc.sd_astrFloatNames[ifc],&pmsrf->msrf_ShadingParams.sp_afFloats[ifc]);
}
// add flag controls to shader dialog
for(ifc=0;ifc<ctFlags;ifc++) {
CFlagControl &fc = _afcFlagControls[ifc];
fc.AddControl(shDesc.sd_astrFlagNames[ifc],ifc,mspParams.sp_ulFlags);
}
} else {
// clear text from combo box
cbShader->SetCurSel(-1);
}
CRect rcDlg;
m_dlgShader.GetWindowRect(rcDlg);
INDEX iCtrlCount = iCustomControlID-FIRSTSHADEID;
INDEX iDlgHeight = (rcDlg.bottom-rcDlg.top-15);
if(iDlgHeight<YPOS) m_dlgShader.SetScrollRange(SB_VERT,1,YPOS-iDlgHeight);
else m_dlgShader.SetScrollRange(SB_VERT,0,0);
AddDialogControls(&m_dlgShader);
// return old vertical scroll pos
m_dlgShader.SetScrollPos(SB_VERT,ivScroll);
VScrollControls(&m_dlgShader);
//m_dlgShader.Invalidate(FALSE);
}
void CDlgBarTreeView::VScrollControls(CDialog *pDlg)
{
//pDlg->SetRedraw(FALSE);
int iPosition = pDlg->GetScrollPos(SB_VERT);
// GetScrollPos returns values from 1 to n
if(iPosition>0) iPosition--;
INDEX ctctrl = dlg_aControls.Count();
// for each control in array of contrls
for(INDEX ictrl=0;ictrl<ctctrl;ictrl++) {
Control &ctrl = dlg_aControls[ictrl];
// check if its dialog is being scrolled
if(ctrl.ct_pParentDlg == pDlg) {
// move control
CRect rcCtrl;
pDlg->GetDlgItem(ctrl.ct_iID)->GetWindowRect(rcCtrl);
pDlg->ScreenToClient(rcCtrl);
rcCtrl.top = ctrl.ct_iTop - iPosition;
rcCtrl.bottom = ctrl.ct_iBottom - iPosition;
pDlg->GetDlgItem(ctrl.ct_iID)->MoveWindow(rcCtrl);
}
}
// pDlg->SetRedraw(TRUE);
// pDlg->Invalidate(TRUE);
}
// notification that selected item has changed
void CDlgBarTreeView::SelItemChanged(HTREEITEM hSelected)
{
CSeriousSkaStudioDoc *pDoc = theApp.GetDocument();
BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
BOOL bAlt = (GetKeyState( VK_MENU)&0x8000) != 0;
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
// reset selected bone in treeview
theApp.iSelectedBoneID = -1;
// if no item selected
if(hSelected == NULL) {
pmiSelected = NULL;
ResetControls();
}
// get index in node array of selected item
INDEX iSelIndex = m_TreeCtrl.GetItemData(hSelected);
// get node info of selected item
NodeInfo &ni = theApp.aNodeInfo[iSelIndex];
// get model instance that holds selected item
pmiSelected = ni.pmi;
// if selected item is model instance set it to be selected model instance
if(ni.ni_iType == NT_MODELINSTANCE) pmiSelected = (CModelInstance*)ni.ni_pPtr;
if(pmiSelected!=NULL) {
CTString strStretch = CTString(0,"%g",pmiSelected->mi_vStretch(1));
pMainFrame->m_ctrlMIStretch.SetWindowText(CString(strStretch));
}
// get parent of selected item
HTREEITEM hParent = m_TreeCtrl.GetParentItem(hSelected);
INDEX iParent=-1;
// if parent exists get ist index
if(hParent != NULL) iParent = m_TreeCtrl.GetItemData(hParent);
// get parent model isntance of selected model instance
CModelInstance *pmiParent = pmiSelected->GetParent(pDoc->m_ModelInstance);
// if parent exisits fill combo box with parent bones
if(pmiParent != NULL) {
// fill combo box with parent bones
if(pmiParent->mi_psklSkeleton != NULL) FillBonesToComboBox(pmiParent->mi_psklSkeleton,0);
// clear combo box for parent bones
else ((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->ResetContent();
} else {
// clear combo box for parent bones
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->ResetContent();
}
// get name of parent bone
CTString strBoneName = ska_GetStringFromTable(pmiSelected->mi_iParentBoneID);
// select parent bone in combo box
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->SelectString(-1,CString(strBoneName));
// select parent model instance in combo box
CComboBox *cbParentList = ((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTMODEL));
// count items in combo box
INDEX ctpl = cbParentList->GetCount();
// for each item in combo box
for(INDEX ipl=0;ipl<ctpl;ipl++) {
CModelInstance *pmiParentInList = (CModelInstance*)cbParentList->GetItemDataPtr(ipl);
// chech if this item is parent in current selected mi
if(pmiParentInList == pmiParent) {
cbParentList->SetCurSel(ipl);
break;
}
cbParentList->SetCurSel(-1);
}
// switch type of selected item
switch(ni.ni_iType)
{
case NT_MODELINSTANCE:
{
ShowControlGroup(GR_PARENT);
CModelInstance *pmi = (CModelInstance*)ni.ni_pPtr;
m_tbMiName.SetWindowText(CString(pmi->GetName()));
}
break;
case NT_ANIMSET:
case NT_MESHLODLIST:
case NT_SKELETONLODLIST:
ShowControlGroup(GR_LISTOPTIONS);
break;
case NT_TEXINSTANCE:
{
TextureInstance *pti = (TextureInstance*)ni.ni_pPtr;
CTString strTexName = ska_GetStringFromTable(pti->GetID());
m_tbTextureName.SetWindowText(CString(strTexName));
m_tvTexView.ChangeTexture(pti->ti_toTexture.GetName());
ShowControlGroup(GR_TEXTURE);
}
break;
case NT_MESHLOD:
{
MeshLOD *pmlod = (MeshLOD*)ni.ni_pPtr;
CTString strName;
strName.PrintF("%g",pmlod->mlod_fMaxDistance);
m_tbDistance.SetWindowText(CString(strName));
// set this mesh lod as forced lod
pDoc->fCustomMeshLodDist=pmlod->mlod_fMaxDistance-0.01f;
ShowControlGroup(GR_LOD);
SetCustomTabText(L"Mesh lod");
}
break;
case NT_SKELETONLOD:
{
SkeletonLOD *pslod = (SkeletonLOD*)ni.ni_pPtr;
CTString strName = CTString(0,"%g",pslod->slod_fMaxDistance);
m_tbDistance.SetWindowText(CString(strName));
// set this skleleton lod as forced lod
pDoc->fCustomSkeletonLodDist=pslod->slod_fMaxDistance-0.01f;
ShowControlGroup(GR_LOD);
SetCustomTabText(L"Skeleton lod");
}
break;
case NT_BONE:
{
SkeletonBone *pbone = (SkeletonBone*)ni.ni_pPtr;
theApp.iSelectedBoneID = pbone->sb_iID;
ShowControlGroup(GR_BONE);
}
break;
case NT_ANIMATION:
{
Animation *pan = (Animation*)ni.ni_pPtr;
// start playing selected animation
ULONG ulAnimFlags = 0;// | AN_NORESTART;
// if looping animations
if(pDoc->bAnimLoop) {
// if shift is not presed
if(!bShift) {
// loop animations
ulAnimFlags |= AN_LOOPING;
}
// if not looping and shift pressed
} else if(bShift) {
// loop anims
ulAnimFlags |= AN_LOOPING;
}
// if control is presed
if(bCtrl) {
// Add animation
pmiSelected->AddAnimation(pan->an_iID,ulAnimFlags|AN_CLONE,1.0f,0);
// if alt is presed
} else if(bAlt) {
// do new cloned state
pmiSelected->NewClonedState(0.2f);
// Add animation
pmiSelected->RemAnimation(pan->an_iID);
} else {
// Add animation
pmiSelected->AddAnimation(pan->an_iID,ulAnimFlags|AN_CLEAR,1,0);
}
// Set timer for current document
pDoc->SetTimerForDocument();
CTString strTreshold;
CTString strSecPerFrame;
CTString strZSpeed;
CTString strLoopSec;
strTreshold.PrintF("%g",pan->an_fTreshold);
strSecPerFrame.PrintF("%g",pan->an_fSecPerFrame);
strZSpeed.PrintF("%g",pDoc->m_fSpeedZ);
strLoopSec.PrintF("%g",pDoc->m_fLoopSecends);
m_tbTreshold.SetWindowText(CString(strTreshold));
m_tbAnimSpeed.SetWindowText(CString(strSecPerFrame));
m_tbWalkSpeed.SetWindowText(CString(strZSpeed));
m_tbWalkLoopSec.SetWindowText(CString(strLoopSec));
// check compresion
((CButton*)m_dlgAnimSet.GetDlgItem(IDC_CB_COMPRESION))->SetCheck(pan->an_bCompresed);
CheckSecPerFrameCtrl(pan->an_bCustomSpeed);
ShowControlGroup(GR_ANIMSET);
SetCustomTabText(L"Animation");
}
break;
case NT_MESHSURFACE:
{
// get mesh instance
HTREEITEM hParentsParent = m_TreeCtrl.GetParentItem(hParent);
NodeInfo &niParent = GetNodeInfo(hParent);
NodeInfo &niParentsParent = GetNodeInfo(hParentsParent);
MeshSurface *pmsrf = (MeshSurface*)ni.ni_pPtr;
MeshLOD *pmlod = (MeshLOD*)niParent.ni_pPtr;
MeshInstance *pmshi = (MeshInstance*)niParentsParent.ni_pPtr;
ShowControlGroup(GR_SHADERS);
ShowSurfaceShader(pmsrf,pmlod,pmshi);
}
break;
case NT_COLISIONBOX:
{
ColisionBox *pcb = (ColisionBox*)ni.ni_pPtr;
INDEX iIndex = -1;
// get colision box count
INDEX ctcb = pmiSelected->mi_cbAABox.Count();
// for each colision box in array
for(INDEX icb=0;icb<ctcb;icb++) {
ColisionBox *pcb2 = &pmiSelected->mi_cbAABox[icb];
if(pcb == pcb2) {
iIndex = icb;
break;
}
}
if(iIndex<0) return;
// set it to be curent colision box
pmiSelected->mi_iCurentBBox = iIndex;
ShowControlGroup(GR_COLISION);
SetCustomTabText(L"Colision");
}
break;
case NT_ALLFRAMESBBOX:
{
ShowControlGroup(GR_ALLFRAMES_BBOX);
SetCustomTabText(L"All frames");
}
break;
default:
// no custom group
//iShowCustomGroup = -1;
ShowControlGroup(-1);
SetCustomTabText(L"Custom");
break;
}
// show name of selected model instance
GetDlgItem(IDC_SELECTEDMI)->SetWindowText(CString(pmiSelected->GetName()));
// show offset of model instance
FLOATmatrix3D mat;
FLOAT3D vPos = pmiSelected->mi_qvOffset.vPos;
ANGLE3D aRot;
pmiSelected->mi_qvOffset.qRot.ToMatrix(mat);
DecomposeRotationMatrix(aRot,mat);
m_tbOffPosX.SetWindowText(CString(CTString(0,"%g",vPos(1))));
m_tbOffPosY.SetWindowText(CString(CTString(0,"%g",vPos(2))));
m_tbOffPosZ.SetWindowText(CString(CTString(0,"%g",vPos(3))));
m_tbOffRotH.SetWindowText(CString(CTString(0,"%g",aRot(1))));
m_tbOffRotP.SetWindowText(CString(CTString(0,"%g",aRot(2))));
m_tbOffRotB.SetWindowText(CString(CTString(0,"%g",aRot(3))));
// show collision box values
if((pmiSelected->mi_iCurentBBox >= 0) && (pmiSelected->mi_iCurentBBox < pmiSelected->mi_cbAABox.Count()))
{
ColisionBox &cb = pmiSelected->mi_cbAABox[pmiSelected->mi_iCurentBBox];
FLOAT fWidth = (cb.Max()(1)-cb.Min()(1));
FLOAT fHeight = (cb.Max()(2)-cb.Min()(2));
FLOAT fLength = (cb.Max()(3)-cb.Min()(3));
FLOAT fPosX = (cb.Max()(1)+cb.Min()(1)) / 2;
FLOAT fPosY = (cb.Max()(2)+cb.Min()(2)) / 2;
FLOAT fPosZ = (cb.Max()(3)+cb.Min()(3)) / 2;
fPosY -= fHeight/2;
m_tbColName.SetWindowText( CString(cb.GetName()));
m_tbColWidth.SetWindowText( CString(CTString(0,"%g",fWidth)));
m_tbColHeight.SetWindowText(CString(CTString(0,"%g",fHeight)));
m_tbColLength.SetWindowText(CString(CTString(0,"%g",fLength)));
m_tbColPosX.SetWindowText( CString(CTString(0,"%g",fPosX)));
m_tbColPosY.SetWindowText( CString(CTString(0,"%g",fPosY)));
m_tbColPosZ.SetWindowText( CString(CTString(0,"%g",fPosZ)));
}
// show all frames bbox
ColisionBox &cb = pmiSelected->mi_cbAllFramesBBox;
FLOAT fWidth = (cb.Max()(1)-cb.Min()(1));
FLOAT fHeight = (cb.Max()(2)-cb.Min()(2));
FLOAT fLength = (cb.Max()(3)-cb.Min()(3));
FLOAT fPosX = (cb.Max()(1)+cb.Min()(1)) / 2;
FLOAT fPosY = (cb.Max()(2)+cb.Min()(2)) / 2;
FLOAT fPosZ = (cb.Max()(3)+cb.Min()(3)) / 2;
fPosY -= fHeight/2;
m_tbAFBBWidth.SetWindowText( CString(CTString(0,"%g",fWidth)));
m_tbAFBBHeight.SetWindowText(CString(CTString(0,"%g",fHeight)));
m_tbAFBBLength.SetWindowText(CString(CTString(0,"%g",fLength)));
m_tbAFBBPosX.SetWindowText( CString(CTString(0,"%g",fPosX)));
m_tbAFBBPosY.SetWindowText( CString(CTString(0,"%g",fPosY)));
m_tbAFBBPosZ.SetWindowText( CString(CTString(0,"%g",fPosZ)));
// change custom controls visibility
// ShowControlGroup(iVisibleGroup);
}
// calculate size of tree view
CSize CDlgBarTreeView::CalcLayout(int nLength, DWORD nMode)
{
CSize csResult;
// Return default if it is being docked or floated
if(nMode & LM_VERTDOCK)
{
csResult = m_Size;
CRect rc;
// get main frm
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
// get his child
CMDIClientWnd *pMDIClient = &pMainFrame->m_wndMDIClient;
pMDIClient->GetWindowRect(rc);
csResult.cy = rc.bottom - rc.top;
}
else if((nMode & LM_VERTDOCK) || (nMode & LM_HORZDOCK))
{
if (nMode & LM_STRETCH) // if not docked stretch to fit
{
csResult = CSize((nMode & LM_HORZ) ? 32767 : m_Size.cx,
(nMode & LM_HORZ) ? m_Size.cy : 32767);
}
else
{
csResult = m_Size;
}
}
else if (nMode & LM_MRUWIDTH)
{
csResult = m_Size;
}
// In all other cases, accept the dynamic length
else
{
if (nMode & LM_LENGTHY)
{
// Note that we don't change m_Size.cy because we disabled vertical sizing
csResult = CSize( m_Size.cx, m_Size.cy = nLength);
}
else
{
csResult = CSize( m_Size.cx = nLength, m_Size.cy);
}
}
// csResult = CSize(300,300);
return csResult;
}
// resize dialog
CSize CDlgBarTreeView::CalcDynamicLayout(int nLength, DWORD nMode)
{
// return CDlgTemplate::CalcDynamicLayout(nLength, nMode);
CSize csResult = CalcLayout(nLength,nMode);
if(theApp.IsErrorDlgVisible()) {
csResult.cy+=theApp.GetLogDlgSize().cy;
}
#define H_BORDER 20
#define V_BORDER 10
#define LINE1 15
#define LINE2 35
#define LINE3 55
#define LINE1U 5
#define LINE2U 25
#define LINE3U 45
#define LINE4U 65
#define WIT (csResult.cx-2*H_BORDER)/4
#define YOFFSET csResult.cy - V_BORDER - 140
// move tab control
GetDlgItem(IDC_MODE_SELECT_TAB)->MoveWindow(CRect(H_BORDER/2,YOFFSET-30,csResult.cx-H_BORDER/2,YOFFSET + 140));
// move dialogs
CRect rcDlg = CRect(2,6,csResult.cx-H_BORDER/2-13,165); // !!! fix
ResizeDlgWithChildren(&m_dlgParent,rcDlg);
ResizeDlgWithChildren(&m_dlgAnimSet,rcDlg);
ResizeDlgWithChildren(&m_dlgColision,rcDlg);
ResizeDlgWithChildren(&m_dlgAllFrames,rcDlg);
ResizeDlgWithChildren(&m_dlgLod,rcDlg);
ResizeDlgWithChildren(&m_dlgBone,rcDlg);
ResizeDlgWithChildren(&m_dlgTexture,rcDlg);
ResizeDlgWithChildren(&m_dlgListOpt,rcDlg);
ResizeDlgWithChildren(&m_dlgShader,rcDlg);
AdjustSplitter();
/*
if(iDockSide == AFX_IDW_DOCKBAR_LEFT)
{
GetDlgItem(IDC_SPLITER_FRAME)->MoveWindow(CRect(csResult.cx-SPLITTER_WITDH,0,csResult.cx,csResult.cy));
GetDlgItem(IDC_SPLITER_FRAME)->ShowWindow(SW_SHOW);
}
else if(iDockSide == AFX_IDW_DOCKBAR_RIGHT)
{
GetDlgItem(IDC_SPLITER_FRAME)->MoveWindow(CRect(0,0,SPLITTER_WITDH,csResult.cy));
GetDlgItem(IDC_SPLITER_FRAME)->ShowWindow(SW_SHOW);
}
else
{
GetDlgItem(IDC_SPLITER_FRAME)->ShowWindow(SW_HIDE);
}
*/
// move label that display curent selected mi
GetDlgItem(IDC_SELECTEDMI)->MoveWindow(CRect(H_BORDER ,3,csResult.cx-H_BORDER,V_BORDER + 15));
// move tree ctrl
CRect NewTreePos;
NewTreePos = CRect(H_BORDER/2, V_BORDER + 15, csResult.cx - H_BORDER/2, csResult.cy - V_BORDER - 180);
CWnd *pwndTree = GetDlgItem(IDC_TREE1);
pwndTree->MoveWindow(NewTreePos);
pwndTree->UpdateWindow();
UpdateWindow();
return csResult;
}
void CDlgBarTreeView::ResizeDlgWithChildren(CDialog *pDlg,CRect rcDlg)
{
INDEX iDlgWidth = rcDlg.right - rcDlg.left;
INDEX ctctrl = dlg_aControls.Count();
// for each control in array of contrls
for(INDEX ictrl=0;ictrl<ctctrl;ictrl++)
{
Control &ctrl = dlg_aControls[ictrl];
// check if its dialog is being resized
if(ctrl.ct_pParentDlg == pDlg)
{
// resize control
CRect rcCtrl;
rcCtrl.left = iDlgWidth * ctrl.ct_fLeft;
rcCtrl.right = iDlgWidth * ctrl.ct_fRight;
rcCtrl.top = ctrl.ct_iTop;
rcCtrl.bottom = ctrl.ct_iBottom;
pDlg->GetDlgItem(ctrl.ct_iID)->MoveWindow(rcCtrl);
}
}
// resize dialog
pDlg->MoveWindow(rcDlg);
}
// remove control form array
void CDlgBarTreeView::RemoveControlFromArray(CWnd *pChild, CDialog *pDlg)
{
// get control ID
INDEX ictrlID = pChild->GetDlgCtrlID();
// count controls in array
INDEX ctctrl = dlg_aControls.Count();
// for each control in array
for(INDEX ictrl=0;ictrl<ctctrl;ictrl++) {
Control &ctrl = dlg_aControls[ictrl];
// check if this is control to remove
if((ctrl.ct_iID == ictrlID) && (ctrl.ct_pParentDlg == pDlg)) {
// get last ctrl
Control &ctrlLast = dlg_aControls[ctctrl-1];
// copy last control insted of one that has to be removed
ctrl = ctrlLast;
// remove last control from array
dlg_aControls.Pop();
return;
}
}
}
// add control to array witch stores all controls that need to be dynamicly resized
void CDlgBarTreeView::AddControlToArray(CWnd *pChild, CDialog *pDlg)
{
CRect rcParent;
CRect rcChild;
pDlg->GetWindowRect(rcParent);
pChild->GetWindowRect(rcChild);
INDEX iParentWidth = rcParent.right - rcParent.left;
// convert to parent coords
pDlg->ScreenToClient(rcChild);
Control &ctrl = dlg_aControls.Push();
ctrl.ct_iID = pChild->GetDlgCtrlID();
ctrl.ct_pParentDlg = pDlg;
ctrl.ct_iTop = rcChild.top;
ctrl.ct_iBottom = rcChild.bottom;
ctrl.ct_fLeft = ((FLOAT)rcChild.left/(FLOAT)iParentWidth);
ctrl.ct_fRight = ((FLOAT)rcChild.right/(FLOAT)iParentWidth);
}
// remove controls from array
void CDlgBarTreeView::RemoveDialogControls(CDialog *pDlg)
{
CWnd *pChild = pDlg->GetWindow(GW_CHILD);
while(pChild!=NULL) {
RemoveControlFromArray(pChild,pDlg);
pChild = pChild->GetWindow(GW_HWNDNEXT);
}
}
// add all controls from dialog to array
void CDlgBarTreeView::AddDialogControls(CDialog *pDlg)
{
CWnd *pChild = pDlg->GetWindow(GW_CHILD);
while(pChild!=NULL) {
AddControlToArray(pChild,pDlg);
pChild = pChild->GetWindow(GW_HWNDNEXT);
}
}
// create dialog
BOOL CDlgBarTreeView::Create( CWnd* pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID)
{
CRect rectDummy(0,0,0,0);
if(!CDlgTemplate::Create(pParentWnd,nIDTemplate,nStyle,nID)) return FALSE;
m_Size = m_sizeDefault;
SetSplitterControlID(IDC_SPLITTER_TREE);
// spliter
// m_wndSpliterFrame.SubclassDlgItem(IDC_SPLITTER_TREE,this);
// m_wndSpliterFrame.SetDockingSide(AFX_IDW_DOCKBAR_FLOAT);
// tree ctrl
m_IconsImageList.Create( IDB_BITMAP1, 16, 32, CLR_NONE);
m_TreeCtrl.SubclassDlgItem(IDC_TREE1, this);
m_TreeCtrl.SetImageList( &m_IconsImageList, TVSIL_NORMAL);
// add tab control buttons
CTabCtrl *pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_MODE_SELECT_TAB);
// create dialogs
m_dlgParent.Create(IDD_PARENT,pTabCtrl);
m_dlgAnimSet.Create(IDD_ANIMSET,pTabCtrl);
m_dlgColision.Create(IDD_COLISION,pTabCtrl);
m_dlgAllFrames.Create(IDD_ALL_FRAMES_BBOX,pTabCtrl);
m_dlgLod.Create(IDD_LOD,pTabCtrl);
m_dlgBone.Create(IDD_BONE,pTabCtrl);
m_dlgTexture.Create(IDD_TEXTURE,pTabCtrl);
m_dlgListOpt.Create(IDD_LIST_OPTIONS,pTabCtrl);
m_dlgShader.Create(IDD_SHADER,pTabCtrl);
CRect rcDummy = CRect(0,0,100,20);
AddDialogControls(&m_dlgTexture);
AddDialogControls(&m_dlgListOpt);
AddDialogControls(&m_dlgParent);
AddDialogControls(&m_dlgAnimSet);
AddDialogControls(&m_dlgColision);
AddDialogControls(&m_dlgAllFrames);
AddDialogControls(&m_dlgLod);
AddDialogControls(&m_dlgBone);
AddDialogControls(&m_dlgShader);
// subclass controls in parent dialog
m_tbOffPosX.SubclassDlgItem(IDC_TB_OFFSET_POSX, &m_dlgParent);
m_tbOffPosY.SubclassDlgItem(IDC_TB_OFFSET_POSY, &m_dlgParent);
m_tbOffPosZ.SubclassDlgItem(IDC_TB_OFFSET_POSZ, &m_dlgParent);
m_tbOffRotH.SubclassDlgItem(IDC_TB_OFFSET_ROTH, &m_dlgParent);
m_tbOffRotP.SubclassDlgItem(IDC_TB_OFFSET_ROTP, &m_dlgParent);
m_tbOffRotB.SubclassDlgItem(IDC_TB_OFFSET_ROTB, &m_dlgParent);
m_tbMiName.SubclassDlgItem(IDC_TB_MI_NAME, &m_dlgParent);
// subclass controls in animset dialog
m_tbTreshold.SubclassDlgItem(IDC_EB_TRESHOLD ,&m_dlgAnimSet);
m_tbAnimSpeed.SubclassDlgItem(IDC_EB_SECPERFRAME,&m_dlgAnimSet);
m_tbWalkSpeed.SubclassDlgItem(IDC_TB_ZTRANSSPEED,&m_dlgAnimSet);
m_tbWalkLoopSec.SubclassDlgItem(IDC_TB_ZTRANSLOOP,&m_dlgAnimSet);
// subclass controls in colision dialog
m_tbColName.SubclassDlgItem(IDC_TB_COLNAME, &m_dlgColision);
m_tbColWidth.SubclassDlgItem(IDC_TB_COLWIDTH, &m_dlgColision);
m_tbColHeight.SubclassDlgItem(IDC_TB_COLHEIGHT,&m_dlgColision);
m_tbColLength.SubclassDlgItem(IDC_TB_COLLENGTH,&m_dlgColision);
m_tbColPosX.SubclassDlgItem(IDC_TB_COLPOSX, &m_dlgColision);
m_tbColPosY.SubclassDlgItem(IDC_TB_COLPOSY, &m_dlgColision);
m_tbColPosZ.SubclassDlgItem(IDC_TB_COLPOSZ, &m_dlgColision);
// subclass controls in colision dialog
m_tbAFBBWidth.SubclassDlgItem(IDC_TB_COLWIDTH, &m_dlgAllFrames);
m_tbAFBBHeight.SubclassDlgItem(IDC_TB_COLHEIGHT,&m_dlgAllFrames);
m_tbAFBBLength.SubclassDlgItem(IDC_TB_COLLENGTH,&m_dlgAllFrames);
m_tbAFBBPosX.SubclassDlgItem(IDC_TB_COLPOSX, &m_dlgAllFrames);
m_tbAFBBPosY.SubclassDlgItem(IDC_TB_COLPOSY, &m_dlgAllFrames);
m_tbAFBBPosZ.SubclassDlgItem(IDC_TB_COLPOSZ, &m_dlgAllFrames);
m_tbDistance.SubclassDlgItem(IDC_EB_DISTANCE, &m_dlgLod);
m_tbTextureName.SubclassDlgItem(IDC_EB_TEXTURENAME, &m_dlgTexture);
CWnd *pTexViewFrame = m_dlgTexture.GetDlgItem(IDC_TEXTURE_VIEW);
// CRect rc;
// pTexViewFrame->GetClientRect(&rc);
CRect rc = CRect(0,0,200,100);
m_tvTexView.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rc, pTexViewFrame,IDC_TEXTURE_VIEW);
m_tvTexView.SubclassDlgItem(IDC_TEXTURE_VIEW, &m_dlgTexture);
// set width of shader combo box
((CComboBox*)m_dlgShader.GetDlgItem(IDC_CB_SHADER))->SetDroppedWidth(200);
CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
pMainFrame->m_ctrlMIStretch.SetFont(m_dlgShader.GetFont(),FALSE);
return TRUE;
}
// add node from tree view to nodeinfo array
INDEX AddNode(INDEX iType,void *ni_pPtr,CModelInstance *pmi)
{
INDEX ctni = theApp.aNodeInfo.Count();
NodeInfo &ni = theApp.aNodeInfo.Push();
ni.ni_iType = iType;
ni.pmi = pmi;
ni.ni_pPtr = ni_pPtr;
ni.ni_bSelected = FALSE;
return ctni;
}
// add model instance to tree view
HTREEITEM CDlgBarTreeView::AddModelInst(CModelInstance &mi, CModelInstance *pmiParent, HTREEITEM hParent)
{
// insert model instance item
HTREEITEM hItem;
// expand only root model
if(hParent == TVI_ROOT) {
// add parent model instance
hItem = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE , L"", 0, 0, TVIS_EXPANDED, TVIS_EXPANDED, 0, hParent, 0 );
m_TreeCtrl.SetItemText(hItem,CString(mi.GetName()));
} else {
int iIcon = 0;
if(mi.mi_fnSourceFile != pmiParent->mi_fnSourceFile) iIcon = 8;
// add child model instance
hItem = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE , L"", iIcon, iIcon, TVIS_EXPANDED, TVIS_EXPANDED, 0, hParent, 0 );
// get parent bone name
CTString strParentBoneName = ska_GetStringFromTable(mi.mi_iParentBoneID);
CTString strText = mi.GetName() + " [" + strParentBoneName + "]";
m_TreeCtrl.SetItemText(hItem,CString(strText));
}
m_TreeCtrl.SetItemData(hItem,AddNode(NT_MODELINSTANCE,&mi,pmiParent));
// add its mesh instances
AddMeshInstances(mi,hItem);
// if skeleton exists
if(mi.mi_psklSkeleton != NULL) {
// add skeleton
AddSkeleton(mi,hItem);
}
// add animsets
AddAnimSet(mi,hItem);
// add colision boxes
AddColisionBoxes(mi,hItem);
// add all frames colision box
AddAllFramesBBox(mi,hItem);
// add model instance children
INDEX ctmi = mi.mi_cmiChildren.Count();
// for each child in model isntance
for(INDEX imi=0;imi<ctmi;imi++) {
// add child
AddModelInst(mi.mi_cmiChildren[imi],&mi,hItem);
}
return hItem;
}
// add skeleton to tree view
void CDlgBarTreeView::AddSkeleton(CModelInstance &mi, HTREEITEM hParent)
{
if(mi.mi_psklSkeleton == NULL) return;
CSkeleton &sk = *mi.mi_psklSkeleton;
// insert skeleton
HTREEITEM hItem = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 5, 5, TVIS_SELECTED, TVIF_STATE, 0, hParent, 0 );
CTString strSkeletonName;
strSkeletonName.PrintF("%s [%d]",(const char*)sk.GetName().FileName(),sk.skl_aSkeletonLODs.Count());
m_TreeCtrl.SetItemText(hItem,CString(strSkeletonName));
m_TreeCtrl.SetItemData(hItem,AddNode(NT_SKELETONLODLIST,&sk,&mi));
INDEX ctslod = sk.skl_aSkeletonLODs.Count();
for(INDEX islod=0;islod<ctslod;islod++) {
SkeletonLOD &slod = sk.skl_aSkeletonLODs[islod];
// insert skeleton lod
HTREEITEM hSlod = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 5, 5, TVIS_SELECTED, TVIF_STATE, 0, hItem, 0 );
// count bones
INDEX ctb = slod.slod_aBones.Count();
CTString strText;
CTFileName fnSlodSource = sk.skl_aSkeletonLODs[islod].slod_fnSourceFile;
fnSlodSource = fnSlodSource.FileName();
strText.PrintF("%s [%g]-[%d]",(const char*)fnSlodSource.NoExt(),sk.skl_aSkeletonLODs[islod].slod_fMaxDistance,ctb);
m_TreeCtrl.SetItemText(hSlod,CString(strText));
m_TreeCtrl.SetItemData(hSlod,AddNode(NT_SKELETONLOD,&slod,&mi));
for(INDEX ib=0;ib<ctb;ib++) {
SkeletonBone &sb = sk.skl_aSkeletonLODs[islod].slod_aBones[ib];
// insert bone
HTREEITEM hBone = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 7, 7, TVIS_SELECTED, TVIF_STATE, 0, hSlod , 0 );
m_TreeCtrl.SetItemText(hBone,CString(ska_GetStringFromTable(sb.sb_iID)));
m_TreeCtrl.SetItemData(hBone,AddNode(NT_BONE,&sb,&mi));
}
}
}
// add mesh surfaces to tree view
void CDlgBarTreeView::AddSurfaces(CModelInstance &mi,MeshLOD &mlod,HTREEITEM hParent)
{
INDEX ctsrf = mlod.mlod_aSurfaces.Count();
for(INDEX isrf=0;isrf<ctsrf;isrf++) {
MeshSurface &msrf = mlod.mlod_aSurfaces[isrf];
CShader *pShader = msrf.msrf_pShader;
CTString strShaderName;
if(pShader!=NULL) strShaderName = pShader->GetName().FileName();
HTREEITEM hItem = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 11, 11, TVIS_SELECTED, TVIF_STATE, 0, hParent, 0);
CTString strSurfName;
strSurfName.PrintF("%s [%d]-[%d]",(const char*)ska_GetStringFromTable(msrf.msrf_iSurfaceID),
msrf.msrf_ctVertices,msrf.msrf_aTriangles.Count());
m_TreeCtrl.SetItemText(hItem,CString(strSurfName));
m_TreeCtrl.SetItemData(hItem,AddNode(NT_MESHSURFACE,&msrf,&mi));
}
}
// add mesh instance to tree view
void CDlgBarTreeView::AddMeshInstances(CModelInstance &mi,HTREEITEM hParent)
{
INDEX ctmsh = mi.mi_aMeshInst.Count();
for(INDEX imsh=0;imsh<ctmsh;imsh++)
{
MeshInstance &mshi = mi.mi_aMeshInst[imsh];
HTREEITEM hItem = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 1, 1, TVIS_SELECTED, TVIF_STATE, 0, hParent, 0);
CTString strMeshName;
strMeshName.PrintF("%s [%d]",(const char*)mshi.mi_pMesh->GetName().FileName(),mshi.mi_pMesh->msh_aMeshLODs.Count());
m_TreeCtrl.SetItemText(hItem,CString(strMeshName));
m_TreeCtrl.SetItemData(hItem,AddNode(NT_MESHLODLIST,&mshi,&mi));
// add mesh lods
INDEX ctmlod = mshi.mi_pMesh->msh_aMeshLODs.Count();
for(INDEX imlod=0;imlod<ctmlod;imlod++)
{
MeshLOD &mlod = mshi.mi_pMesh->msh_aMeshLODs[imlod];
HTREEITEM hMlod = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 3, 3, TVIS_SELECTED, TVIF_STATE, 0, hItem, 0);
CTString strMeshLod;
CTFileName fnMlodSource = mlod.mlod_fnSourceFile;
fnMlodSource = fnMlodSource.FileName();
strMeshLod.PrintF("%s [%g]-[%d]",(const char*)fnMlodSource.NoExt(),mlod.mlod_fMaxDistance,mlod.mlod_aVertices.Count());
m_TreeCtrl.SetItemText(hMlod,CString(strMeshLod));
m_TreeCtrl.SetItemData(hMlod,AddNode(NT_MESHLOD,&mlod,&mi));
AddSurfaces(mi,mlod,hMlod);
}
// add textures for this mesh
INDEX cttex = mshi.mi_tiTextures.Count();
for(INDEX itex=0;itex<cttex;itex++)
{
TextureInstance &ti = mshi.mi_tiTextures[itex];
CTString strTextName = ska_GetStringFromTable(ti.GetID());
HTREEITEM hTexture = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 4, 4, TVIS_SELECTED, TVIF_STATE, 0, hItem, 0 );
m_TreeCtrl.SetItemText(hTexture,CString(strTextName));
m_TreeCtrl.SetItemData(hTexture,AddNode(NT_TEXINSTANCE,&ti,&mi));
}
}
}
// add collision boxes to tree view
void CDlgBarTreeView::AddColisionBoxes(CModelInstance &mi,HTREEITEM hParent)
{
INDEX ctcb = mi.mi_cbAABox.Count();
// for each collision box
for(INDEX icb=0;icb<ctcb;icb++)
{
// add collision box
ColisionBox &cb = mi.mi_cbAABox[icb];
HTREEITEM hColisionBox = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 2, 2, TVIS_SELECTED, TVIF_STATE, 0, hParent, 0);
m_TreeCtrl.SetItemText(hColisionBox,CString(cb.GetName()));
m_TreeCtrl.SetItemData(hColisionBox,AddNode(NT_COLISIONBOX,&cb,&mi));
}
}
void CDlgBarTreeView::AddAllFramesBBox(CModelInstance &mi,HTREEITEM hParent)
{
#pragma message(">> Remove AddAllFramesBBox")
// add all frames bounding box
ColisionBox &cb = mi.mi_cbAllFramesBBox;
HTREEITEM hAllFramesBBox = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 6, 6, TVIS_SELECTED, TVIF_STATE, 0, hParent, 0);
m_TreeCtrl.SetItemText(hAllFramesBBox,L"All frames BBox");
m_TreeCtrl.SetItemData(hAllFramesBBox,AddNode(NT_ALLFRAMESBBOX,&cb,&mi));
}
// add anim set to tree view
HTREEITEM CDlgBarTreeView::AddAnimSet(CModelInstance &mi,HTREEITEM hParent)
{
INDEX ctas = mi.mi_aAnimSet.Count();
// for each animset
for(INDEX ias=0;ias<ctas;ias++)
{
CAnimSet &as = mi.mi_aAnimSet[ias];
INDEX ctan = as.as_Anims.Count();
CTString strAnimSetName;
strAnimSetName.PrintF("%s [%d]",(const char*)(as.GetName()).FileName(),ctan);
HTREEITEM hAnimSet = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 9, 9, TVIS_SELECTED, TVIF_STATE, 0, hParent, 0);
m_TreeCtrl.SetItemText(hAnimSet,CString(strAnimSetName));
m_TreeCtrl.SetItemData(hAnimSet,AddNode(NT_ANIMSET,&as,&mi));
// for each anim
for(INDEX ian=0;ian<ctan;ian++)
{
Animation &an = as.as_Anims[ian];
CTString strAnimName;
//strAnimName.PrintF("%s [%d]",(const char*)ska_GetStringFromTable(an.an_iID),an.an_iFrames);
strAnimName.PrintF("%s [%d]",(const char*)ska_GetStringFromTable(an.an_iID),an.an_iFrames);
HTREEITEM hAnim = m_TreeCtrl.InsertItem( TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 9, 9, TVIS_SELECTED, TVIF_STATE, 0, hAnimSet, 0);
m_TreeCtrl.SetItemText(hAnim,CString(strAnimName));
m_TreeCtrl.SetItemData(hAnim,AddNode(NT_ANIMATION,&an,&mi));
INDEX ctbe=an.an_abeBones.Count();
for(INDEX ibe=0;ibe<ctbe;ibe++)
{
BoneEnvelope &be = an.an_abeBones[ibe];
CTString strBoneEnvName;
CTString strBoneName = ska_GetStringFromTable(be.be_iBoneID);
INDEX ctr = be.be_arRot.Count();
if(an.an_bCompresed) ctr = be.be_arRotOpt.Count();
strBoneEnvName.PrintF("%s [%d]-[%d]",(const char*)strBoneName,ctr,be.be_apPos.Count());
HTREEITEM hBoneEnv = m_TreeCtrl.InsertItem(TVIF_IMAGE | TVIF_SELECTEDIMAGE , L"", 9, 9, TVIS_SELECTED, TVIF_STATE, 0, hAnim, 0);
m_TreeCtrl.SetItemText(hBoneEnv,CString(strBoneEnvName));
m_TreeCtrl.SetItemData(hBoneEnv,AddNode(NT_ANIM_BONEENV,&be,&mi));
}
}
}
return 0;
}
// add all model instances to combo box
void CDlgBarTreeView::FillParentDropDown(CModelInstance *pmi)
{
if(pmi == NULL) return;
CComboBox *cbParentList = ((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTMODEL));
INDEX iItem = cbParentList->AddString(CString(pmi->GetName()));
cbParentList->SetItemDataPtr(iItem,pmi);
// add all children to combo box
INDEX ctmi = pmi->mi_cmiChildren.Count();
for(INDEX imi=0;imi<ctmi;imi++)
{
FillParentDropDown(&pmi->mi_cmiChildren[imi]);
}
}
// find out how many children from root to selected item
BOOL CDlgBarTreeView::RememberSelectedItem(HTREEITEM hParent,HTREEITEM hSelected)
{
if(hParent==NULL) return FALSE;
HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent);
INDEX ctLoops = 0;
while(hChild != NULL)
{
ctLoops++;
if(m_TreeCtrl.ItemHasChildren(hChild))
{
if(RememberSelectedItem(hChild,hSelected))
{
INDEX &iCur = _aSelectItem.Push();
iCur = ctLoops;
return TRUE;
}
}
if(hChild == hSelected)
{
INDEX &iCur = _aSelectItem.Push();
iCur = ctLoops;
return TRUE;
}
hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
}
return FALSE;
}
// use previously filed array of child depth to reach selected item
BOOL CDlgBarTreeView::ReselectItem(HTREEITEM hParent)
{
INDEX ctrec=_aSelectItem.Count();
// from last to first
HTREEITEM hChild = hParent;
// if child is NULL select his parent and return
// loop filled array of recursion depth for selected item
for(INDEX irec=ctrec-1;irec>=0;irec--)
{
HTREEITEM hRet = m_TreeCtrl.GetChildItem(hChild);
if(hRet == NULL)
{
m_TreeCtrl.SelectItem(hChild);
return FALSE;
}
else hChild = hRet;
INDEX cti=_aSelectItem[irec];
for(INDEX i=0;i<cti-1;i++)
{
HTREEITEM hRet = m_TreeCtrl.GetNextSiblingItem(hChild);
if(hRet == NULL)
{
m_TreeCtrl.SelectItem(hChild);
return FALSE;
}
else hChild = hRet;
}
}
if(hChild != NULL)
{
m_TreeCtrl.SelectItem(hChild);
}
return TRUE;
}
// update tree view containing whole hierarchy of model instance
void CDlgBarTreeView::UpdateModelInstInfo(CModelInstance *pmi)
{
m_TreeCtrl.SetRedraw(FALSE);
// ShowControlGroup(-1);
HTREEITEM htSelectedItem = m_TreeCtrl.GetSelectedItem();
HTREEITEM hRoot = m_TreeCtrl.GetRootItem();
CTString strRoot;
// if root item exists
if(hRoot!=NULL) {
// remember its name
strRoot = CStringA(m_TreeCtrl.GetItemText(hRoot));
}
// clear array for selected item
_aSelectItem.PopAll();
_aiSelectedMeshSurfaces.PopAll();
// get current selected item and fill array of depths how to reach it
RememberSelectedItem(hRoot,htSelectedItem);
theApp.iSelectedBoneID = -1;
INDEX iSelIndex=0;
NodeInfo niSelected;
if(htSelectedItem != NULL)
{
iSelIndex = m_TreeCtrl.GetItemData(htSelectedItem);
niSelected = theApp.aNodeInfo[iSelIndex];
}
m_TreeCtrl.DeleteAllItems();
theApp.aNodeInfo.PopAll();
// reset combo box
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTMODEL))->ResetContent();
if(pmi == NULL) {
m_TreeCtrl.SetRedraw(TRUE);
return;
}
// fill combo with all parents
FillParentDropDown(pmi);
// fill tree ctrl with all hierarchy
HTREEITEM hParent = AddModelInst(*pmi,NULL,TVI_ROOT);
// get name of root item
CTString strNewRoot = CStringA(m_TreeCtrl.GetItemText(hParent));
// if root item name is different then old root item name clear selection
if(strRoot != strNewRoot && strRoot.Length() > 0) _aSelectItem.PopAll();
if(_aSelectItem.Count() > 0)
{
// try to select item that was selected before reloading
ReselectItem(hParent);
}
else
{
// select hParent
m_TreeCtrl.SelectItem(hParent);
}
m_TreeCtrl.SetRedraw(TRUE);
}
// check custom seconds per frame check box
void CDlgBarTreeView::CheckSecPerFrameCtrl(BOOL bCheck)
{
((CButton*)m_dlgAnimSet.GetDlgItem(IDC_CB_SECPERFRAME))->SetCheck(bCheck);
m_dlgAnimSet.GetDlgItem(IDC_EB_SECPERFRAME)->EnableWindow(bCheck);
}
// change tab in tab control
void CDlgBarTreeView::OnSelchangeModeSelectTab(NMHDR* pNMHDR, LRESULT* pResult)
{
// CTabCtrl* pTab = (CTabCtrl*)GetDlgItem(IDC_MODE_SELECT_TAB);
// ShowControlGroup(pTab->GetCurSel());
*pResult = 0;
}
// expand all model instances in tree view
void CDlgBarTreeView::ExpandAllModelInstances(HTREEITEM hItem)
{
INDEX iIndex = m_TreeCtrl.GetItemData(hItem);
NodeInfo &ni = theApp.aNodeInfo[iIndex];
// it this item is model instance
if(ni.ni_iType == NT_MODELINSTANCE)
{
// expand it
m_TreeCtrl.Expand(hItem,TVE_EXPAND);
}
// check if current item has children
if(m_TreeCtrl.ItemHasChildren(hItem))
{
HTREEITEM hChild = m_TreeCtrl.GetChildItem(hItem);
while(TRUE)
{
// expand all model instance in this child
ExpandAllModelInstances(hChild);
// get next item
hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
if(hChild==NULL)
{
break;
}
}
}
}
// put all bones of selected skeleton in combo box
void CDlgBarTreeView::FillBonesToComboBox(CSkeleton *pskl,INDEX iSelectedIndex)
{
// delete all bones from combo box
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->ResetContent();
// if skeleton does not exist return
if(pskl == NULL) return;
// count skeleton lods
INDEX ctslod = pskl->skl_aSkeletonLODs.Count();
if(ctslod<1) return;
SkeletonLOD *pslod = &pskl->skl_aSkeletonLODs[0];
// if lod doesnt exist return;
if(pslod == NULL) return;
// count bones in skeleton lod
INDEX ctsb = pslod->slod_aBones.Count();
// for each bone in skeleton lod
for(INDEX isb=0;isb<ctsb;isb++)
{
SkeletonBone &sb = pslod->slod_aBones[isb];
// add bone to combo box
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->AddString(CString(ska_GetStringFromTable(sb.sb_iID)));
}
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->SetCurSel(iSelectedIndex);
}
// set text for 'custom' tab in tab control
void CDlgBarTreeView::SetCustomTabText(wchar_t *strText)
{
// fill tab control item
TCITEM tcitem;
memset(&tcitem,0,sizeof(tcitem));
tcitem.mask = TCIF_TEXT;
tcitem.cchTextMax = 256;
tcitem.pszText = strText;
((CTabCtrl*)GetDlgItem(IDC_MODE_SELECT_TAB))->SetItem(2,&tcitem);
}
// reset all controls on dialog
void CDlgBarTreeView::ResetControls()
{
m_TreeCtrl.DeleteAllItems();
m_TreeCtrl.hLastSelected = NULL;
GetDlgItem(IDC_SELECTEDMI)->SetWindowText(L"(none)");
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTBONE))->ResetContent();
((CComboBox*)m_dlgParent.GetDlgItem(IDC_CB_PARENTMODEL))->ResetContent();
((CButton*)m_dlgAnimSet.GetDlgItem(IDC_CB_COMPRESION))->SetCheck(FALSE);
CheckSecPerFrameCtrl(FALSE);
ShowControlGroup(-1);
m_tbOffPosX.SetWindowText(L"");
m_tbOffPosY.SetWindowText(L"");
m_tbOffPosZ.SetWindowText(L"");
m_tbOffRotH.SetWindowText(L"");
m_tbOffRotP.SetWindowText(L"");
m_tbOffRotB.SetWindowText(L"");
m_tbTreshold.SetWindowText(L"");
m_tbAnimSpeed.SetWindowText(L"");
m_tbColName.SetWindowText(L"");
m_tbColWidth.SetWindowText(L"");
m_tbColHeight.SetWindowText(L"");
m_tbColLength.SetWindowText(L"");
m_tbColPosX.SetWindowText(L"");
m_tbColPosY.SetWindowText(L"");
m_tbColPosZ.SetWindowText(L"");
m_tbDistance.SetWindowText(L"");
//GET_CTRL(IDC_CB_TEXNAME)->SetWindowText("");
}
void CDlgBarTreeView::OnSize(UINT nType, int cx, int cy)
{
/*
// if app has initialized
if(theApp.bAppInitialized) {
// adjust splitter
AdjustSplitter();
}
*/
CDlgTemplate::OnSize(nType, cx, cy);
}