/* ** 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 . */ // PresetListDialog.cpp : implementation file // #include "stdafx.h" #include "leveledit.h" #include "PresetListDialog.h" #include "presetmgr.h" #include "definition.h" #include "definitionfactory.h" #include "definitionfactorymgr.h" #include "icons.h" #include "utils.h" #include "preset.h" #include "persistfactory.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // // PresetListDialogClass // ///////////////////////////////////////////////////////////////////////////// PresetListDialogClass::PresetListDialogClass (CWnd *pParent) : m_List (NULL), m_ClassID (0), m_RootClassID (0), m_EnableTypeSel (true), CDialog(PresetListDialogClass::IDD, pParent) { //{{AFX_DATA_INIT(PresetListDialogClass) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::DoDataExchange (CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(PresetListDialogClass) DDX_Control(pDX, IDC_TYPE_COMBO, m_ComboBox); DDX_Control(pDX, IDC_PRESET_TREE, m_PresetTreeCtrl); DDX_Control(pDX, IDC_PRESET_LIST, m_PresetListCtrl); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(PresetListDialogClass, CDialog) //{{AFX_MSG_MAP(PresetListDialogClass) ON_BN_CLICKED(IDC_ADD, OnAdd) ON_BN_CLICKED(IDC_REMOVE, OnRemove) ON_NOTIFY(NM_DBLCLK, IDC_PRESET_LIST, OnDblclkPresetList) ON_NOTIFY(NM_DBLCLK, IDC_PRESET_TREE, OnDblclkPresetTree) ON_NOTIFY(LVN_ITEMCHANGED, IDC_PRESET_LIST, OnItemchangedPresetList) ON_NOTIFY(TVN_SELCHANGED, IDC_PRESET_TREE, OnSelchangedPresetTree) ON_WM_DESTROY() ON_CBN_SELENDOK(IDC_TYPE_COMBO, OnSelendokTypeCombo) ON_CBN_SELCHANGE(IDC_TYPE_COMBO, OnSelchangeTypeCombo) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // OnInitDialog // ///////////////////////////////////////////////////////////////////////////// BOOL PresetListDialogClass::OnInitDialog (void) { CDialog::OnInitDialog (); ASSERT (m_List != NULL); // // Configure the preset list control // m_PresetListCtrl.InsertColumn (0, "Name"); m_PresetListCtrl.InsertColumn (1, "Type"); // // Configure the type combobox // Generate_Type_List (); // // Add the previously selected presets to the list control // for (int index = 0; index < m_List->Count (); index ++) { // // Lookup this preset // int preset_id = (*m_List)[index]; PresetClass *preset = PresetMgrClass::Find_Preset (preset_id); // // Add the preset to the list control // Add_Preset (preset); } // // Fill in the tree control // m_PresetTreeCtrl.SetImageList (::Get_Global_Image_List (), TVSIL_NORMAL); Populate_Preset_Tree (); // // Size the columns // CRect rect; m_PresetListCtrl.GetClientRect (&rect); m_PresetListCtrl.SetColumnWidth (0, rect.Width () * 2 / 3); m_PresetListCtrl.SetColumnWidth (1, (rect.Width () / 3) - 2); Update_Button_State (); return TRUE; } //////////////////////////////////////////////////////////////////////////// // // Update_Button_State // //////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Update_Button_State (void) { bool enable_add = false; bool enable_remove = (m_PresetListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) >= 0); // // Should the add button be enabled? // HTREEITEM tree_item = m_PresetTreeCtrl.GetSelectedItem (); if (tree_item != NULL) { PresetClass *preset = (PresetClass *)m_PresetTreeCtrl.GetItemData (tree_item); if (preset != NULL) { enable_add = true; } } ::EnableWindow (::GetDlgItem (m_hWnd, IDC_ADD), enable_add); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_REMOVE), enable_remove); return ; } //////////////////////////////////////////////////////////////////////////// // // Sort_Nodes // //////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Sort_Nodes (HTREEITEM root_item, bool recursive) { for ( HTREEITEM tree_item = m_PresetTreeCtrl.GetChildItem (root_item); tree_item != NULL; tree_item = m_PresetTreeCtrl.GetNextSiblingItem (tree_item)) { // // Sort the children // m_PresetTreeCtrl.SortChildren (tree_item); // // Recurse through the hierarchy // if (recursive && m_PresetTreeCtrl.ItemHasChildren (tree_item)) { Sort_Nodes (tree_item, recursive); } } return ; } ///////////////////////////////////////////////////////////////////////////// // // Add_Preset // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Add_Preset (PresetClass *preset) { if (preset != NULL && preset->Get_Definition () != NULL) { // // Insert this preset into the list control // int list_index = m_PresetListCtrl.InsertItem (0xFFF, preset->Get_Name ()); if (list_index >= 0) { // // Set the entry's type name // int class_id = preset->Get_Definition ()->Get_Class_ID (); DefinitionFactoryClass *factory = DefinitionFactoryMgrClass::Find_Factory (class_id); if (factory != NULL) { LPCTSTR type_name = factory->Get_Name (); m_PresetListCtrl.SetItemText (list_index, 1, type_name); } // // Associate the preset ID with this list entry // m_PresetListCtrl.SetItemData (list_index, preset->Get_ID ()); } } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnOK // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnOK (void) { m_List->Delete_All (); int count = m_PresetListCtrl.GetItemCount (); for (int index = 0; index < count; index ++) { int preset_id = m_PresetListCtrl.GetItemData (index); m_List->Add (preset_id); } CDialog::OnOK (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnAdd // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnAdd (void) { HTREEITEM tree_item = m_PresetTreeCtrl.GetSelectedItem (); if (tree_item != NULL) { // // Add the preset from the currently selected tree item to the list // PresetClass *preset = (PresetClass *)m_PresetTreeCtrl.GetItemData (tree_item); if (preset != NULL) { Add_Preset (preset); } } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnRemove // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnRemove (void) { int index = m_PresetListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (index >= 0) { m_PresetListCtrl.DeleteItem (index); // // Select the previous entry in the list // int count = m_PresetListCtrl.GetItemCount (); if (count > 0) { if (index >= (count-1)) { index --; } index = max (index, 0); m_PresetListCtrl.SetItemState (index, LVNI_SELECTED, LVNI_SELECTED); } Update_Button_State (); } return ; } ///////////////////////////////////////////////////////////////////////////// // // OnDblclkPresetList // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnDblclkPresetList ( NMHDR * pNMHDR, LRESULT * pResult ) { (*pResult) = 0; OnRemove (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnDblclkPresetTree // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnDblclkPresetTree ( NMHDR * pNMHDR, LRESULT * pResult ) { (*pResult) = 0; OnAdd (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnItemchangedPresetList // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnItemchangedPresetList ( NMHDR * pNMHDR, LRESULT * pResult ) { (*pResult) = 0; Update_Button_State (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnSelchangedPresetTree // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnSelchangedPresetTree ( NMHDR * pNMHDR, LRESULT * pResult ) { (*pResult) = 0; Update_Button_State (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnDestroy // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnDestroy (void) { m_PresetTreeCtrl.SetImageList (NULL, TVSIL_NORMAL); CDialog::OnDestroy (); return ; } ///////////////////////////////////////////////////////////////////////////// // // Generate_Type_List // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Generate_Type_List (void) { // // Configure the combo-box // m_ComboBox.SetImageList (::Get_Global_Image_List ()); m_ComboBox.EnableWindow (m_EnableTypeSel); // // Build a tree of factories // FACTORY_TREE factory_tree; PresetMgrClass::Build_Factory_Tree (m_RootClassID, factory_tree); // // Default to game-objects if no other type is selected // if (m_ClassID == 0) { m_ClassID = CLASSID_GAME_OBJECTS; } // // Put these factories into the combobox // int index = 0; Add_Factories_To_Combo (factory_tree.Peek_Root (), 0, index); return ; } ///////////////////////////////////////////////////////////////////////////// // // Add_Factories_To_Combo // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Add_Factories_To_Combo ( NTreeLeafClass *leaf, int indent, int & index ) { do { uint32 class_id = leaf->Get_Value (); // // Add this factory to the combobox // COMBOBOXEXITEM item = { 0 }; item.mask = CBEIF_IMAGE | CBEIF_INDENT | CBEIF_LPARAM | CBEIF_TEXT | CBEIF_SELECTEDIMAGE; item.pszText = (char *)::Get_Factory_Name (class_id); item.iImage = FOLDER_ICON; item.iSelectedImage = FOLDER_ICON; item.iIndent = indent; item.lParam = (long)class_id; item.iItem = index ++; int item_index = m_ComboBox.InsertItem (&item); // // Is this the factory we need to select? // if (class_id == m_ClassID) { m_ComboBox.SetCurSel (item_index); } // // Recurse if necessary // NTreeLeafClass *child = leaf->Peek_Child (); if (child != NULL) { Add_Factories_To_Combo (child, indent + 1, index); } } while ((leaf = leaf->Peek_Next ()) != NULL); return ; } ///////////////////////////////////////////////////////////////////////////// // // Populate_Preset_Tree // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Populate_Preset_Tree (void) { // // Start fresh // CWaitCursor wait_cursor; m_PresetTreeCtrl.DeleteAllItems (); // // Should we add any sub-factories to the tree? // if (DefinitionFactoryMgrClass::Find_Factory (m_ClassID) == NULL) { // // Generate the tree from its sub-factories // DefinitionFactoryClass *factory = NULL; for ( factory = DefinitionFactoryMgrClass::Get_First (m_ClassID); factory != NULL; factory = DefinitionFactoryMgrClass::Get_Next (factory, m_ClassID)) { if (factory->Is_Displayed ()) { HTREEITEM folder_item = m_PresetTreeCtrl.InsertItem (factory->Get_Name (), FOLDER_ICON, FOLDER_ICON); // // Generate the tree of presets // PRESET_TREE preset_tree; PresetMgrClass::Build_Preset_Tree (factory->Get_Class_ID (), preset_tree); // // Populate the tree control // Fill_Tree (preset_tree.Peek_Root (), folder_item); } } } else { // // Generate the tree of presets // PRESET_TREE preset_tree; PresetMgrClass::Build_Preset_Tree (m_ClassID, preset_tree); // // Populate the tree control // Fill_Tree (preset_tree.Peek_Root (), TVI_ROOT); } return ; } ///////////////////////////////////////////////////////////////////////////// // // Fill_Tree // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::Fill_Tree (NTreeLeafClass *leaf, HTREEITEM parent_item) { // // Loop over all the presets // for ( ; leaf != NULL; leaf = leaf->Peek_Next ()) { PresetClass *preset = leaf->Get_Value (); ASSERT (preset != NULL); if (preset != NULL) { // // Insert the new preset into the tree // int icon = preset->Get_Icon_Index (); HTREEITEM new_item = m_PresetTreeCtrl.InsertItem (preset->Get_Name (), icon, icon, parent_item); if (new_item != NULL) { // // Associate the preset with its tree entry // m_PresetTreeCtrl.SetItemData (new_item, (LONG)preset); // // Recurse if necessary // NTreeLeafClass *child = leaf->Peek_Child (); if (child != NULL) { Fill_Tree (child, new_item); m_PresetTreeCtrl.SortChildren (parent_item); } } } } return ; } /* // // Add all the presets (by category) to the tree control // DefinitionFactoryClass *factory = NULL; for ( factory = DefinitionFactoryMgrClass::Get_First (m_ClassID); factory != NULL; factory = DefinitionFactoryMgrClass::Get_Next (factory, m_ClassID)) { // // Add this folder to the tree ctrl // HTREEITEM folder_item = m_PresetTreeCtrl.InsertItem (factory->Get_Name (), FOLDER_ICON, FOLDER_ICON); // // Add all the folder contents to the tree ctrl // PresetClass *preset = NULL; uint32 factory_id = factory->Get_Class_ID (); for ( preset = PresetMgrClass::Get_First (factory_id, PresetMgrClass::ID_CLASS); preset != NULL; preset = PresetMgrClass::Get_Next (preset, factory_id, PresetMgrClass::ID_CLASS)) { // // Add this preset to the tree ctrl // HTREEITEM preset_item = m_PresetTreeCtrl.InsertItem ( preset->Get_Name (), OBJECT_ICON, OBJECT_ICON, folder_item); m_PresetTreeCtrl.SetItemData (preset_item, (ULONG)preset); } } // // Sort the tree control // Sort_Nodes (TVI_ROOT, true); m_PresetTreeCtrl.SortChildren (TVI_ROOT); return ; }*/ ///////////////////////////////////////////////////////////////////////////// // // OnSelendokTypeCombo // ///////////////////////////////////////////////////////////////////////////// void PresetListDialogClass::OnSelendokTypeCombo (void) { } void PresetListDialogClass::OnSelchangeTypeCombo() { // // Get the currently selected type from the combobox // int cur_sel = m_ComboBox.GetCurSel (); if (cur_sel >= 0) { // // Repopulate the tree control if the type changed // uint32 new_class_id = m_ComboBox.GetItemData (cur_sel); if (new_class_id != m_ClassID) { m_ClassID = new_class_id; Populate_Preset_Tree (); } } return ; }