//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// // RunMapExpertDlg.cpp : implementation file // #include "stdafx.h" #include "hammer.h" #include "RunMapExpertDlg.h" #include "RunMapCfgDlg.h" // memdbgon must be the last include file in a .cpp file!!! #include ///////////////////////////////////////////////////////////////////////////// // CRunMapExpertDlg dialog CRunMapExpertDlg::CRunMapExpertDlg(CWnd* pParent /*=NULL*/) : CDialog(CRunMapExpertDlg::IDD, pParent) { //{{AFX_DATA_INIT(CRunMapExpertDlg) //}}AFX_DATA_INIT m_pActiveSequence = NULL; m_bNoUpdateCmd = FALSE; m_bSwitchMode = FALSE; } void CRunMapExpertDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CRunMapExpertDlg) DDX_Control(pDX, IDC_USEPROCESSWND, m_cUseProcessWnd); DDX_Control(pDX, IDC_CONFIGURATIONS, m_cCmdSequences); DDX_Control(pDX, IDC_MOVEUP, m_cMoveUp); DDX_Control(pDX, IDC_MOVEDOWN, m_cMoveDown); DDX_Control(pDX, IDC_ENSUREFN, m_cEnsureFn); DDX_Control(pDX, IDC_ENSURECHECK, m_cEnsureCheck); DDX_Control(pDX, IDC_PARAMETERS, m_cParameters); DDX_Control(pDX, IDC_COMMAND, m_cCommand); //}}AFX_DATA_MAP DDX_Control(pDX, IDC_COMMANDLIST, m_cCommandList); } // dvs: this is duplicated in OPTBuild.cpp!! enum { id_InsertParmMapFileNoExt = 0x100, id_InsertParmMapFile, id_InsertParmMapPath, id_InsertParmBspDir, id_InsertParmExeDir, id_InsertParmGameDir, id_InsertParmEnd }; enum { id_BrExecutable = 0x150, id_BrChangeDir, id_BrCopyFile, id_BrDelFile, id_BrRenameFile, id_BrGameProgram, id_BrVISProgram, id_BrBSPProgram, id_BrLIGHTProgram, id_BrEnd }; BEGIN_MESSAGE_MAP(CRunMapExpertDlg, CDialog) //{{AFX_MSG_MAP(CRunMapExpertDlg) ON_BN_CLICKED(IDC_BROWSECOMMAND, OnBrowsecommand) ON_LBN_SELCHANGE(IDC_COMMANDLIST, OnSelchangeCommandlist) ON_BN_CLICKED(IDC_INSERTPARM, OnInsertparm) ON_BN_CLICKED(IDC_MOVEDOWN, OnMovedown) ON_BN_CLICKED(IDC_MOVEUP, OnMoveup) ON_BN_CLICKED(IDC_NEW, OnNew) ON_BN_CLICKED(IDC_NORMAL, OnNormal) ON_BN_CLICKED(IDC_REMOVE, OnRemove) ON_EN_UPDATE(IDC_COMMAND, OnUpdateCommand) ON_EN_UPDATE(IDC_PARAMETERS, OnUpdateParameters) ON_BN_CLICKED(IDC_ENSURECHECK, OnEnsurecheck) ON_EN_UPDATE(IDC_ENSUREFN, OnUpdateEnsurefn) ON_CBN_SELCHANGE(IDC_CONFIGURATIONS, OnSelchangeConfigurations) ON_BN_CLICKED(IDC_EDITCONFIGS, OnEditconfigs) ON_BN_CLICKED(IDC_USEPROCESSWND, OnUseprocesswnd) ON_COMMAND_EX_RANGE(id_InsertParmMapFileNoExt, id_InsertParmEnd, HandleInsertParm) ON_COMMAND_EX_RANGE(id_BrExecutable, id_BrEnd, HandleInsertCommand) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRunMapExpertDlg message handlers BOOL CRunMapExpertDlg::HandleInsertCommand(UINT nID) // insert a parm at the current cursor location into the parameters // edit control { PCCOMMAND pCommand = GetCommandAtIndex(NULL); if(!pCommand) return TRUE; // no command if(nID == id_BrExecutable) { CFileDialog dlg(TRUE, "exe", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Executable Files|*.exe||", this); if(dlg.DoModal() == IDCANCEL) return TRUE; m_cCommand.SetWindowText(dlg.m_ofn.lpstrFile); pCommand->iSpecialCmd = 0; } else { pCommand->iSpecialCmd = 0; switch(nID) { case id_BrCopyFile: pCommand->iSpecialCmd = CCCopyFile; break; case id_BrDelFile: pCommand->iSpecialCmd = CCDelFile; break; case id_BrRenameFile: pCommand->iSpecialCmd = CCRenameFile; break; case id_BrChangeDir: pCommand->iSpecialCmd = CCChangeDir; break; case id_BrGameProgram: m_cCommand.SetWindowText("$game_exe"); break; case id_BrVISProgram: m_cCommand.SetWindowText("$vis_exe"); break; case id_BrLIGHTProgram: m_cCommand.SetWindowText("$light_exe"); break; case id_BrBSPProgram: m_cCommand.SetWindowText("$bsp_exe"); break; } if(pCommand->iSpecialCmd) pCommand->bLongFilenames = TRUE; OnSelchangeCommandlist(); UpdateCommandWithEditFields(-1); } return TRUE; } void CRunMapExpertDlg::OnBrowsecommand(void) { CMenu menu; menu.CreatePopupMenu(); menu.AppendMenu(MF_STRING, id_BrExecutable, "Executable"); menu.AppendMenu(MF_STRING, id_BrChangeDir, "Change Directory"); menu.AppendMenu(MF_STRING, id_BrCopyFile, "Copy File"); menu.AppendMenu(MF_STRING, id_BrDelFile, "Delete File"); menu.AppendMenu(MF_STRING, id_BrRenameFile, "Rename File"); menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, id_BrBSPProgram, "BSP program"); menu.AppendMenu(MF_STRING, id_BrVISProgram, "VIS program"); menu.AppendMenu(MF_STRING, id_BrLIGHTProgram, "LIGHT program"); menu.AppendMenu(MF_STRING, id_BrGameProgram, "Game program"); // track menu CWnd *pButton = GetDlgItem(IDC_BROWSECOMMAND); CRect r; pButton->GetWindowRect(r); menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, r.left, r.bottom, this, NULL); } LPCTSTR CRunMapExpertDlg::GetCmdString(PCCOMMAND pCommand) { switch(pCommand->iSpecialCmd) { case 0: return pCommand->szRun; case CCCopyFile: return "Copy File"; case CCDelFile: return "Delete File"; case CCRenameFile: return "Rename File"; case CCChangeDir: return "Change Directory"; } return ""; } void CRunMapExpertDlg::OnSelchangeCommandlist() { int iIndex = -1; // change the selection in the command list - update the command // and parameters edit boxes PCCOMMAND pCommand = GetCommandAtIndex(&iIndex); // enable/disable controls BOOL bEnable = pCommand ? TRUE : FALSE; int iEnableCmds[] = { // edit fields: IDC_COMMAND, IDC_PARAMETERS, IDC_ENSUREFN, // checkboxes/buttons: IDC_ENSURECHECK, IDC_USEPROCESSWND, IDC_INSERTPARM, IDC_BROWSECOMMAND, -1 }; m_bNoUpdateCmd = TRUE; for(int i = 0; iEnableCmds[i] != -1; i++) { CWnd *pWnd = GetDlgItem(iEnableCmds[i]); pWnd->EnableWindow(bEnable); if(bEnable == FALSE) { // ensure fields are cleared if we're disabling them if(i < 3) pWnd->SetWindowText(""); else ((CButton*)pWnd)->SetCheck(0); } } m_bNoUpdateCmd = FALSE; if(!pCommand) return; // set moveup/movedown buttons m_cMoveUp.EnableWindow(iIndex != 0); m_cMoveDown.EnableWindow(iIndex != m_cCommandList.GetCount() - 1); m_bNoUpdateCmd = TRUE; m_cCommand.SetWindowText(GetCmdString(pCommand)); m_cParameters.SetWindowText(pCommand->szParms); m_cEnsureCheck.SetCheck(pCommand->bEnsureCheck); m_cEnsureFn.SetWindowText(pCommand->szEnsureFn); m_cUseProcessWnd.SetCheck(pCommand->bUseProcessWnd); // don't forget to call this: OnEnsurecheck(); m_bNoUpdateCmd = FALSE; } BOOL CRunMapExpertDlg::HandleInsertParm(UINT nID) // insert a parm at the current cursor location into the parameters // edit control { LPCTSTR pszInsert; switch (nID) { case id_InsertParmMapFileNoExt: pszInsert = "$file"; break; case id_InsertParmMapFile: pszInsert = "$file.$ext"; break; case id_InsertParmMapPath: pszInsert = "$path"; break; case id_InsertParmExeDir: pszInsert = "$exedir"; break; case id_InsertParmBspDir: pszInsert = "$bspdir"; break; case id_InsertParmGameDir: default: pszInsert = "$gamedir"; break; } Assert(pszInsert); if(!pszInsert) return TRUE; m_cParameters.ReplaceSel(pszInsert); return TRUE; } void CRunMapExpertDlg::OnInsertparm(void) { // two stages - name/description OR data itself CMenu menu; menu.CreatePopupMenu(); menu.AppendMenu(MF_STRING, id_InsertParmMapFileNoExt, "Map Filename (no extension)"); menu.AppendMenu(MF_STRING, id_InsertParmMapFile, "Map Filename (with extension)"); menu.AppendMenu(MF_STRING, id_InsertParmMapPath, "Map Path (no filename)"); menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING, id_InsertParmExeDir, "Game Executable Directory"); menu.AppendMenu(MF_STRING, id_InsertParmBspDir, "BSP Directory"); menu.AppendMenu(MF_STRING, id_InsertParmGameDir, "Game Directory"); // track menu CWnd *pButton = GetDlgItem(IDC_INSERTPARM); CRect r; pButton->GetWindowRect(r); menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, r.left, r.bottom, this, NULL); } void CRunMapExpertDlg::DeleteCommand(int iIndex) { // kill the command at that index (deletes the dataptr memory too) PCCOMMAND pCommand = GetCommandAtIndex(&iIndex); m_cCommandList.DeleteString(iIndex); if(iIndex >= m_cCommandList.GetCount()-1) iIndex = m_cCommandList.GetCount()-1; m_cCommandList.SetCurSel(iIndex); // selection has "changed" OnSelchangeCommandlist(); delete pCommand; } void CRunMapExpertDlg::AddCommand(int iIndex, PCCOMMAND pCommand) { // add a command to the list at the index specified in iIndex (-1 to add // at end of list.) CString str; str.Format("%s %s", GetCmdString(pCommand), pCommand->szParms); iIndex = m_cCommandList.InsertString(iIndex, str); m_cCommandList.SetItemDataPtr(iIndex, PVOID(pCommand)); } void CRunMapExpertDlg::MoveCommand(int iIndex, BOOL bUp) { PCCOMMAND pCommand = GetCommandAtIndex(&iIndex); if(!pCommand) return; // keep check state of item in listbox BOOL bChecked = m_cCommandList.GetCheck(iIndex); // don't bother with the string - that's made from the command/parms // struct that the item's dataptr points to m_cCommandList.DeleteString(iIndex); int iNewIndex = iIndex + (bUp ? -1 : +1); AddCommand(iNewIndex, pCommand); // restore check state saved above m_cCommandList.SetCheck(iNewIndex, bChecked); // selection has changed m_cCommandList.SetCurSel(iNewIndex); OnSelchangeCommandlist(); } void CRunMapExpertDlg::OnMovedown() { MoveCommand(-1, FALSE); } void CRunMapExpertDlg::OnMoveup() { MoveCommand(-1, TRUE); } void CRunMapExpertDlg::OnNew() { // add a command PCCOMMAND pCommand = new CCOMMAND; memset(pCommand, 0, sizeof(CCOMMAND)); pCommand->bUseProcessWnd = TRUE; AddCommand(-1, pCommand); m_cCommandList.SetCurSel(m_cCommandList.GetCount()-1); // sleection has changed OnSelchangeCommandlist(); } void CRunMapExpertDlg::OnNormal() { m_bSwitchMode = TRUE; SaveCommandsToSequence(); CHammer *pApp = (CHammer*) AfxGetApp(); pApp->SaveSequences(); EndDialog(IDOK); } void CRunMapExpertDlg::UpdateCommandWithEditFields(int iIndex) { PCCOMMAND pCommand = GetCommandAtIndex(&iIndex); // update command struct with edit fields: m_cCommand.GetWindowText(pCommand->szRun, MAX_PATH); m_cParameters.GetWindowText(pCommand->szParms, MAX_PATH); m_cEnsureFn.GetWindowText(pCommand->szEnsureFn, MAX_PATH); pCommand->bUseProcessWnd = m_cUseProcessWnd.GetCheck(); pCommand->bEnsureCheck = m_cEnsureCheck.GetCheck(); // save checked state.. BOOL bCmdChecked = m_cCommandList.GetCheck(iIndex); // update list by deleting/adding command m_cCommandList.SetRedraw(FALSE); m_cCommandList.DeleteString(iIndex); AddCommand(iIndex, pCommand); m_cCommandList.SetCurSel(iIndex); m_cCommandList.SetRedraw(TRUE); m_cCommandList.Invalidate(); m_cCommandList.SetCheck(iIndex, bCmdChecked); // DON'T call OnCommandlistSelchange() here } PCCOMMAND CRunMapExpertDlg::GetCommandAtIndex(int *piIndex) { // make sure we're pointing at something: int iIndex = -1; if(piIndex == NULL) piIndex = &iIndex; // return the current command structure if(piIndex[0] == -1) piIndex[0] = m_cCommandList.GetCurSel(); if(piIndex[0] == LB_ERR) return NULL; PCCOMMAND pCommand = PCCOMMAND(m_cCommandList.GetItemDataPtr(piIndex[0])); return pCommand; } void CRunMapExpertDlg::OnRemove() { // kill the current command int iIndex = m_cCommandList.GetCurSel(); if(iIndex == LB_ERR) return; DeleteCommand(iIndex); } void CRunMapExpertDlg::OnUpdateCommand() { if(!m_bNoUpdateCmd) { // make sure no special command is contained here .. // (this is only ever called when the user types // in the command edit field.) PCCOMMAND pCommand = GetCommandAtIndex(NULL); if(pCommand->iSpecialCmd) { // clear out command .. set the noupdatecmd // flag so we don't get into a stack overflow m_bNoUpdateCmd = TRUE; m_cCommand.SetWindowText(""); m_bNoUpdateCmd = FALSE; pCommand->iSpecialCmd = 0; } UpdateCommandWithEditFields(-1); } } void CRunMapExpertDlg::OnUpdateParameters() { if(!m_bNoUpdateCmd) UpdateCommandWithEditFields(-1); } void CRunMapExpertDlg::OnEnsurecheck() { if(!m_bNoUpdateCmd) UpdateCommandWithEditFields(-1); // enable/disable edit field m_cEnsureFn.EnableWindow(m_cEnsureCheck.GetCheck()); } void CRunMapExpertDlg::OnUpdateEnsurefn() { if(!m_bNoUpdateCmd) UpdateCommandWithEditFields(-1); } void CRunMapExpertDlg::OnUseprocesswnd() { // update the command here.. PCCOMMAND pCommand = GetCommandAtIndex(NULL); Assert(pCommand); pCommand->bUseProcessWnd = m_cUseProcessWnd.GetCheck() ? TRUE : FALSE; } void CRunMapExpertDlg::InitSequenceList() { // add all the information from the CHammer object into // the dialog box .. CHammer *pApp = (CHammer*) AfxGetApp(); m_cCmdSequences.ResetContent(); // add the configurations into the list .. int iSize = pApp->m_CmdSequences.GetSize(); if(iSize == 0) { // add a default configuration CCommandSequence *pSeq = new CCommandSequence; strcpy(pSeq->m_szName, "Default"); ((CHammer*)AfxGetApp())->m_CmdSequences.Add(pSeq); iSize = 1; } for(int i = 0; i < iSize; i++) { CCommandSequence *pSeq = pApp->m_CmdSequences[i]; int iIndex = m_cCmdSequences.AddString(pSeq->m_szName); m_cCmdSequences.SetItemDataPtr(iIndex, PVOID(pSeq)); } m_pActiveSequence = NULL; m_cCmdSequences.SetCurSel(0); OnSelchangeConfigurations(); } BOOL CRunMapExpertDlg::OnInitDialog() { CDialog::OnInitDialog(); int iSequence = AfxGetApp()->GetProfileInt("RunMapExpert", "LastSequence", 0); InitSequenceList(); m_cCmdSequences.SetCurSel(iSequence); OnSelchangeConfigurations(); return TRUE; } void CRunMapExpertDlg::OnOK() { SaveCommandsToSequence(); CHammer *pApp = (CHammer*) AfxGetApp(); pApp->SaveSequences(); CDialog::OnOK(); } void CRunMapExpertDlg::SaveCommandsToSequence() { if(!m_pActiveSequence) return; // nothing set yet int nCommands = m_cCommandList.GetCount(); m_pActiveSequence->m_Commands.RemoveAll(); for(int i = 0; i < nCommands; i++) { PCCOMMAND pCommand = PCCOMMAND(m_cCommandList.GetItemDataPtr(i)); pCommand->bEnable = m_cCommandList.GetCheck(i); if (!strcmp(pCommand->szRun, "$game_exe")) pCommand->bNoWait = TRUE; m_pActiveSequence->m_Commands.Add(*pCommand); // free the memory: delete pCommand; } } void CRunMapExpertDlg::OnSelchangeConfigurations() { // save the current command list back into the previously active // command sequence SaveCommandsToSequence(); int iSel = m_cCmdSequences.GetCurSel(); if(iSel == LB_ERR) // nothing there { m_pActiveSequence = NULL; return; } AfxGetApp()->WriteProfileInt("RunMapExpert", "LastSequence", iSel); CCommandSequence *pSeq = (CCommandSequence*) m_cCmdSequences.GetItemDataPtr(iSel); // delete strings from listbox (dataptrs already deleted // in SaveCommandsToSequence()) m_cCommandList.ResetContent(); m_pActiveSequence = pSeq; // add the commands from this sequence into the command listbox .. CCommandArray &Commands = pSeq->m_Commands; for(int i = 0; i < Commands.GetSize(); i++) { PCCOMMAND pCommand = new CCOMMAND(Commands[i]); AddCommand(i, pCommand); m_cCommandList.SetCheck(i, pCommand->bEnable); } // set to 0th element in list .. m_cCommandList.SetCurSel(0); OnSelchangeCommandlist(); } void CRunMapExpertDlg::OnEditconfigs() { CRunMapCfgDlg dlg; SaveCommandsToSequence(); if(dlg.DoModal() == IDOK) InitSequenceList(); } void CRunMapExpertDlg::OnCancel() { SaveCommandsToSequence(); CHammer *pApp = (CHammer*) AfxGetApp(); pApp->SaveSequences(); CDialog::OnCancel(); }