/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU 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 General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see <http://www.gnu.org/licenses/>. */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : LevelEdit * * * * $Archive:: /Commando/Code/Tools/LevelEdit/NodeScriptsPropPage.cpp $Modtime:: $* * * * $Revision:: 3 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "stdafx.h" #include "leveledit.h" #include "nodescriptsproppage.h" #include "editscript.h" #include "scriptmgr.h" #include "utils.h" #include "scripteditdialog.h" #include "parameter.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // // Local Constants // ///////////////////////////////////////////////////////////////////////////// const int COL_NAME = 0; const int COL_PARAMS = 1; ///////////////////////////////////////////////////////////////////////////// // // NodeScriptsPropPage // ///////////////////////////////////////////////////////////////////////////// NodeScriptsPropPage::NodeScriptsPropPage (void) : m_ScriptList (NULL), m_ScriptListParam (NULL), DockableFormClass (NodeScriptsPropPage::IDD) { //{{AFX_DATA_INIT(NodeScriptsPropPage) //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////////////////////// // // NodeScriptsPropPage // ///////////////////////////////////////////////////////////////////////////// NodeScriptsPropPage::NodeScriptsPropPage (SCRIPT_LIST *script_list) : m_ScriptList (script_list), m_ScriptListParam (NULL), DockableFormClass (NodeScriptsPropPage::IDD) { return ; } ///////////////////////////////////////////////////////////////////////////// // // ~NodeScriptsPropPage // ///////////////////////////////////////////////////////////////////////////// NodeScriptsPropPage::~NodeScriptsPropPage (void) { return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::DoDataExchange (CDataExchange* pDX) { DockableFormClass ::DoDataExchange(pDX); //{{AFX_DATA_MAP(NodeScriptsPropPage) DDX_Control(pDX, IDC_SCRIPTLIST, m_ListCtrl); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(NodeScriptsPropPage, DockableFormClass ) //{{AFX_MSG_MAP(NodeScriptsPropPage) ON_NOTIFY(LVN_ITEMCHANGED, IDC_SCRIPTLIST, OnItemChangedScriptList) ON_BN_CLICKED(IDC_ADD, OnAdd) ON_BN_CLICKED(IDC_DELETE, OnDelete) ON_BN_CLICKED(IDC_MODIFY, OnModify) ON_NOTIFY(LVN_DELETEITEM, IDC_SCRIPTLIST, OnDeleteItemScriptList) ON_NOTIFY(NM_DBLCLK, IDC_SCRIPTLIST, OnDblclkScriptlist) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // NodeScriptsPropPage diagnostics #ifdef _DEBUG void NodeScriptsPropPage::AssertValid() const { DockableFormClass ::AssertValid(); } void NodeScriptsPropPage::Dump(CDumpContext& dc) const { DockableFormClass ::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // // Build_Script_List // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::Build_Script_List (void) { // // If we are dealing with a script list parameter, then convert // it into a list of editable scripts // if (m_ScriptListParam != NULL) { m_ScriptList = new SCRIPT_LIST; DynamicVectorClass<StringClass> &name_list = m_ScriptListParam->Get_Name_List (); DynamicVectorClass<StringClass> ¶m_list = m_ScriptListParam->Get_Param_List (); // // Loop over and create edit scripts for each string pair // for (int index = 0; index < name_list.Count (); index ++) { EditScriptClass *edit_script = new EditScriptClass; edit_script->Set_Name (name_list[index]); edit_script->Lookup_Param_Description (); edit_script->Set_Composite_Values (param_list[index]); // // Add this script to our list // m_ScriptList->Add (edit_script); } } return ; } ///////////////////////////////////////////////////////////////////////////// // // HandleInitDialog // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::HandleInitDialog (void) { ListView_SetExtendedListViewStyle (m_ListCtrl, LVS_EX_FULLROWSELECT); // // Make sure we have a script list (can be built internally in some cases) // Build_Script_List (); // Insert the 2 columns into the list oontrol m_ListCtrl.InsertColumn (COL_NAME, "Name"); m_ListCtrl.InsertColumn (COL_PARAMS, "Params"); // // Add all the scripts that we are editing to the list control // for (int index = 0; index < m_ScriptList->Count (); index ++) { EditScriptClass *script = (*m_ScriptList)[index]; if (script != NULL) { // // Put this script into the list control // int item_index = m_ListCtrl.InsertItem (index, (LPCTSTR)script->Get_Name ()); m_ListCtrl.SetItemText (item_index, COL_PARAMS, (LPCTSTR)script->Get_Composite_String ()); m_ListCtrl.SetItemData (item_index, (DWORD)script->Clone ()); } } // // Size the columns to fit their largest entry // CRect rect; m_ListCtrl.GetClientRect (&rect); m_ListCtrl.SetColumnWidth (COL_NAME, (rect.Width () / 3) - 2); m_ListCtrl.SetColumnWidth (COL_PARAMS, ((rect.Width () * 2) / 3) - 2); // Disable the 'add', 'delete' and 'modify' buttons ::EnableWindow (::GetDlgItem (m_hWnd, IDC_DELETE), FALSE); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_MODIFY), FALSE); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnItemChangedScriptList // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::OnItemChangedScriptList ( NMHDR* pNMHDR, LRESULT* pResult ) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // Did the selection state change? if ((pNMListView != NULL) && (pNMListView->uChanged & LVIF_STATE) && ((pNMListView->uNewState & LVIS_SELECTED) || (pNMListView->uOldState & LVIS_SELECTED))) { // Get the index of the currently selected property int index = m_ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (index != -1) { // Enable the 'delete' and 'modify' buttons ::EnableWindow (::GetDlgItem (m_hWnd, IDC_DELETE), TRUE); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_MODIFY), TRUE); } else { // Disable the 'delete' and 'modify' buttons ::EnableWindow (::GetDlgItem (m_hWnd, IDC_DELETE), FALSE); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_MODIFY), FALSE); } } *pResult = 0; return ; } ///////////////////////////////////////////////////////////////////////////// // // OnModify // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::OnModify (void) { // Get the index of the currently selected property int index = m_ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (index != -1) { // Get a pointer to the script EditScriptClass *script = (EditScriptClass *)m_ListCtrl.GetItemData (index); if (script != NULL) { // // Show the dialog that allows the user to edit this script's settings // ScriptEditDialogClass dialog (this); dialog.Set_Script (*script); if (dialog.DoModal () == IDOK) { // // Update the list // (*script) = dialog.Get_Script (); m_ListCtrl.SetItemText (index, COL_NAME, (LPCTSTR)script->Get_Name ()); m_ListCtrl.SetItemText (index, COL_PARAMS, (LPCTSTR)script->Get_Composite_String ()); } } } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnAdd // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::OnAdd (void) { // // Show the dialog that allows the user to edit this script's settings // ScriptEditDialogClass dialog (this); if (dialog.DoModal () == IDOK) { EditScriptClass *new_script = new EditScriptClass (dialog.Get_Script ()); // Put this script into the list control int index = m_ListCtrl.InsertItem (0xFFFF, (LPCTSTR)new_script->Get_Name ()); m_ListCtrl.SetItemText (index, COL_PARAMS, (LPCTSTR)new_script->Get_Composite_String ()); m_ListCtrl.SetItemData (index, (DWORD)new_script); } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnDelete // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::OnDelete (void) { // Get the index of the currently selected property int index = m_ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (index != -1) { // Delete the entry from the list control m_ListCtrl.DeleteItem (index); } return ; } ///////////////////////////////////////////////////////////////////////////// // // Apply_Changes // ///////////////////////////////////////////////////////////////////////////// bool NodeScriptsPropPage::Apply_Changes (void) { // // Delete all the scripts in the old list // for (int index = 0; index < m_ScriptList->Count (); index ++) { EditScriptClass *script = (*m_ScriptList)[index]; SAFE_DELETE (script); } m_ScriptList->Delete_All (); // // Loop through all the entries in the list contrl and add them // to the script list // index = -1; while ((index = m_ListCtrl.GetNextItem (index, LVNI_ALL)) != -1) { EditScriptClass *script = (EditScriptClass *)m_ListCtrl.GetItemData (index); if (script != NULL) { // // Add this script to the script list and remove it from the list control // m_ScriptList->Add (script); m_ListCtrl.SetItemData (index, NULL); } } // // Do we need to convert the script list to a script list param object? // if (m_ScriptListParam != NULL) { // // Reset the contents of the script parameter's lists // DynamicVectorClass<StringClass> &name_list = m_ScriptListParam->Get_Name_List (); DynamicVectorClass<StringClass> ¶m_list = m_ScriptListParam->Get_Param_List (); name_list.Delete_All (); param_list.Delete_All (); // // Copy the data from each script object into the string lists // for (index = 0; index < m_ScriptList->Count (); index ++) { EditScriptClass *script = (*m_ScriptList)[index]; // // Pull the values from the script object into the string lists // name_list.Add (script->Get_Name ()); param_list.Add ((LPCTSTR)script->Get_Composite_String ()); SAFE_DELETE (script); } SAFE_DELETE (m_ScriptList); } return true; } ///////////////////////////////////////////////////////////////////////////// // // OnDeleteItemPropertyList // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::OnDeleteItemScriptList ( NMHDR * pNMHDR, LRESULT * pResult ) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if (pNMListView != NULL) { // Free the associated script EditScriptClass *script = (EditScriptClass *)m_ListCtrl.GetItemData (pNMListView->iItem); SAFE_DELETE (script); // Reset the associated data for this item m_ListCtrl.SetItemData (pNMListView->iItem, NULL); } *pResult = 0; return; } ///////////////////////////////////////////////////////////////////////////// // // OnDblclkScriptlist // ///////////////////////////////////////////////////////////////////////////// void NodeScriptsPropPage::OnDblclkScriptlist ( NMHDR * pNMHDR, LRESULT * pResult ) { (*pResult) = 0; OnModify (); return ; }