#include "stdafx.h" #include "VIControls.h" #include "ParameterDialog.h" #include "CKShader.h" #include "CUIKNotificationReceiver.h" //--- Include "GenericObjectParameterDialog.h" from CK2UI define IDDs to mak it compile #define IDD_GENOBJECTDIALOG 2011 #define IDD_BASEPARAMDIALOG 2000 #include "Parameters\GenericObjectParameterDialog.h" //--- Some constants #define MFC_NAME_OF_DIALOG "#32770" #define CHECK_MATERIAL_TIMER 57 /***********************************************/ // Parameter Dialog /***********************************************/ class CShaderParameterDialog : public CParameterDialog { enum { PARAMTYPE_SHADER = 0, PARAMTYPE_TECHNIQUE, PARAMTYPE_PASS }; // Construction public: VIComboBox m_Combo; CKShaderManager* m_ShaderManager; int m_paramType; CShaderParameterDialog* m_associatedShaderDlg; CShaderParameterDialog* m_associatedTechniqueDlg; CShaderParameterDialog* m_associatedPassDlg; CGenericObjectParameterDialog* m_associatedMaterialDlg; CString m_associatedMaterialCurStr; CShaderParameterDialog(CKParameter* Parameter,CK_CLASSID Cid=CKCID_OBJECT) : CParameterDialog(Parameter,Cid) { } virtual ~CShaderParameterDialog() { } virtual void DoDataExchange(CDataExchange* pDX); //_________________________________________ // Add Passes to Combo Box void ParsePassesToComboBox( CKShader& iShader, int iTechIndex ){ CKShader::PassInfo passInfo; const int passCount = iShader.GetPassCount( iTechIndex ); for( int c=0 ; cGetNumShaders(); for( int a=0 ; aGetShader(a); if( !shader ) continue; if( shader!=m_ShaderManager->GetDefaultShader() //&& shader!=m_ShaderManager->GetShadowShader() ){ //--- If Param is a Shader then simply add Shaders if( m_paramType == PARAMTYPE_SHADER ){ //--- Fill with all Shader names otherwise m_Combo.AddString( shader->GetName().CStr() ); continue; }; //--- Otherwise parse all Techniques in this Shader ParseTechniquesToComboBox( *shader ); } } } //__________________________________________ // Get Techniques From Associated Shader Dlg void GetTechniquesFromAssociatedShader() { CString cstr; m_associatedShaderDlg->m_Combo.GetWindowText( cstr ); if( !m_ShaderManager ) return; CKShader* shader = m_ShaderManager->GetShaderByName( (char*)(LPCTSTR)cstr ); if( shader ){ ParseTechniquesToComboBox( *shader ); } } //____________________________________________ // Get Shader from Associated Material CKMaterialShader* GetMatShaderFromAssociatedMaterial() { //--- Tries to get the material m_associatedMaterialCurStr = m_associatedMaterialDlg->m_ComboCurStr; CKMaterial* mat = (CKMaterial*)m_ShaderManager->m_Context-> GetObjectByNameAndClass( (char*)(LPCTSTR)m_associatedMaterialCurStr, CKCID_MATERIAL ); if( !mat ) return NULL; //--- Return the MaterialShader return mat->GetMaterialShader( TRUE ); } //____________________________________________ // Get Techniques From Associated Material Dlg void GetTechniquesFromAssociatedMaterial() { CKMaterialShader* matShader = GetMatShaderFromAssociatedMaterial(); if( matShader && matShader->m_Shader ){ ParseTechniquesToComboBox( *matShader->m_Shader ); } } //_________________________________________ // Get Passes From Associated Material Dlg void GetPassesFromAssociatedMaterial() { CKMaterialShader* matShader = GetMatShaderFromAssociatedMaterial(); if( matShader && matShader->m_Shader && (matShader->m_TechIndex>=0) ){ ParsePassesToComboBox( *matShader->m_Shader, matShader->m_TechIndex ); } } //_______________________________________ // Fill Combo Box void FillComboBox() { //--- Fill Combo Box m_Combo.ResetContent(); const int shaderCount = m_ShaderManager->GetNumShaders(); if( m_paramType==PARAMTYPE_PASS && m_associatedMaterialDlg ){ //--- Get Passes From Associated Material Dlg GetPassesFromAssociatedMaterial(); } else if( m_paramType==PARAMTYPE_TECHNIQUE && m_associatedShaderDlg ){ //--- Get Techniques From Associated Shader Dlg GetTechniquesFromAssociatedShader(); } else if( m_paramType==PARAMTYPE_TECHNIQUE && m_associatedMaterialDlg ){ GetTechniquesFromAssociatedMaterial(); } else { //--- Otherwise parse all Shaders (possibly to show all Techniques or Passes) m_Combo.AddString( "-- None --" ); ParseShadersToComboBox(); } } //_________________________________________ // Select Item By Name void SelectItemByName( char *name ) { //--- Select the item in combo box that matches the string int curSel = -1; if( name && name[0]!=0 ){ curSel = m_Combo.FindString( 0, name ); if( curSel<0 && m_paramType==PARAMTYPE_SHADER ) curSel=0; } m_Combo.SetCurSel( curSel ); } //_________________________________________ // Set UI from CKParameter virtual BOOL On_UpdateFromParameter(CKParameter* p){ if(!p) p = (CKParameterOut *)CKGetObject(m_EditedParameter); if(!p) return FALSE; //--- Fill Combo Box FillComboBox(); SelectItemByName( (char*)p->GetReadDataPtr() ); return TRUE; } //_________________________________________ // Set CKParameter from UI virtual BOOL On_UpdateToParameter(CKParameter* p){ if(!p) p = (CKParameterOut *)CKGetObject(m_EditedParameter); if(!p) return FALSE; CString cstr; if( m_Combo.GetCurSel()<0 ){ cstr=""; } else { if( m_paramType==PARAMTYPE_SHADER && m_Combo.GetCurSel()==0 ){ cstr=""; } m_Combo.GetWindowText(cstr); } char *str = (char*)(LPCTSTR)cstr; p->SetValue( str, cstr.GetLength()+1 ); return TRUE; } //_________________________________________ // Associated Combo Box Has Changed void AssociatedComboBoxHasChanged( CShaderParameterDialog& callerDlg ) { CKParameter* p = (CKParameterOut *)CKGetObject(m_EditedParameter); if(!p) return; FillComboBox(); SelectItemByName( (char*)p->GetReadDataPtr() ); } //_________________________________________ // Find Associated Parameter Dialogs void FindAssociatedParameterDialogs() { m_associatedShaderDlg = NULL; m_associatedTechniqueDlg = NULL; m_associatedPassDlg = NULL; m_associatedMaterialDlg = NULL; m_associatedMaterialCurStr = ""; char name[256]; CWnd* thisSubParentWindow = this->GetParent(); CWnd* bigParentWindow = thisSubParentWindow->GetParent(); for( CWnd* subParentWindow = bigParentWindow->GetWindow(GW_CHILD); subParentWindow ; subParentWindow = subParentWindow->GetWindow(GW_HWNDNEXT) ){ //--- Don't parse any further if we reached THIS parameter if( subParentWindow == thisSubParentWindow ) break; GetClassName( subParentWindow->m_hWnd, name, sizeof(name) ); if( strcmp(name,MFC_NAME_OF_DIALOG) ) continue; for( CWnd* child = subParentWindow->GetWindow(GW_CHILD) ; child ; child = child->GetWindow(GW_HWNDNEXT) ){ GetClassName( child->m_hWnd, name, sizeof(name) ); if( strcmp(name,MFC_NAME_OF_DIALOG) ) continue; //--- From this point it should be a CParameterDialog... CParameterDialog* otherParamDialog = (CParameterDialog*) (child->SendMessage( CKWM_GETPARAMDIALOG, 0, 0 )); if( !otherParamDialog ) continue; CK_CLASSID cid = otherParamDialog->m_EditedClassID; CKClassDesc* cDesc = CKGetClassDesc( cid ); CKParameterOut* otherParam = (CKParameterOut*)CKGetObject( otherParamDialog->m_EditedParameter ); if( !otherParam ) continue; switch( m_paramType ){ case PARAMTYPE_TECHNIQUE: //--- Technique Param is interested by Shader Param and Material Param if( otherParam->GetGUID() == CKPGUID_SHADER ){ m_associatedShaderDlg = (CShaderParameterDialog*)otherParamDialog; m_associatedShaderDlg->m_associatedTechniqueDlg = this; } else if( otherParam->GetGUID() == CKPGUID_MATERIAL ){ m_associatedMaterialDlg = (CGenericObjectParameterDialog*)otherParamDialog; } break; case PARAMTYPE_PASS: //--- Pass Param is only interested by Material Param if( otherParam->GetGUID() == CKPGUID_MATERIAL ){ m_associatedMaterialDlg = (CGenericObjectParameterDialog*)otherParamDialog; } break; } } } } //_________________________________________ // Initialization virtual BOOL On_Init(){ //--- Some members initialization m_paramType = PARAMTYPE_SHADER; m_FocusWindow = &m_Combo; m_ShaderManager = (CKShaderManager *) m_Context->GetManagerByGuid( ShaderManagerGUID ); CKParameter* p = (CKParameterOut *)CKGetObject( m_EditedParameter ); if( p->GetGUID() == CKPGUID_TECHNIQUE ){ //--- If it's a Technique Parameter m_paramType = PARAMTYPE_TECHNIQUE; } else if( p->GetGUID() == CKPGUID_PASS ){ //--- If it's a Pass Parameter m_paramType = PARAMTYPE_PASS; } FindAssociatedParameterDialogs(); //--- if( m_associatedMaterialDlg ){ this->SetTimer( CHECK_MATERIAL_TIMER, 100, NULL ); } return TRUE; } //_________________________________________ // WindowProc virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message){ //--- Called to check for Material's Combo Box Modifications case WM_TIMER: { //--- Ensure it is the correct Timer if( wParam != CHECK_MATERIAL_TIMER ) break; //--- Retrieve Material's Combo box info if( !m_associatedMaterialDlg ) break; //--- Check if the Material Combo Box Current Selection has Changed if( !m_associatedMaterialCurStr.Compare( m_associatedMaterialDlg->m_ComboCurStr ) ) break; //--- If combo box changed, then update associated combo boxes if( m_paramType==PARAMTYPE_TECHNIQUE || m_paramType==PARAMTYPE_PASS ){ AssociatedComboBoxHasChanged( *this ); } } break; case WM_NOTIFY: { int idCtrl = (int) wParam; LPNMHDR pnmh = (LPNMHDR) lParam; } break; case WM_COMMAND: { int hparam = (int) HIWORD(wParam); switch( hparam ){ case CBN_SELCHANGE: { int idComboBox = (int) LOWORD(wParam); // identifier of combo box if( idComboBox == IDC_COMBOSHADER ){ CString cstr; m_Combo.GetWindowText(cstr); //--- If it's a Shader notify associated Techniques Dialog if( m_paramType==PARAMTYPE_SHADER ){ if( m_associatedTechniqueDlg ){ m_associatedTechniqueDlg->AssociatedComboBoxHasChanged( *this ); } } } return 1; } break; } } } return CParameterDialog::WindowProc(message, wParam, lParam); } public: }; void CShaderParameterDialog::DoDataExchange(CDataExchange* pDX) { CParameterDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CShaderParameterDialog) DDX_Control(pDX, IDC_COMBOSHADER, m_Combo); //}}AFX_DATA_MAP } WIN_HANDLE ShaderParamUIFunc(CKParameter*param,WIN_HANDLE parent,CKRECT *rect) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CShaderParameterDialog *Dlg = new CShaderParameterDialog(param); Dlg->Create( IDD_SHADERDIALOG ); return CreateParameterDialog( (HWND)parent, Dlg, 0, PARAMETER_NOPICK, 0, PARAMETER_RESIZE ); }