/* ** 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/>. */ // EditLODDialog.cpp : implementation file // #include "stdafx.h" #include "W3DView.h" #include "EditLODDialog.h" #include "DistLod.H" #include "Utils.H" #include "RendObj.H" #include "W3DViewDoc.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_SWITCH_UP = 1; const int COL_SWITCH_DN = 2; ///////////////////////////////////////////////////////////// // // CEditLODDialog // CEditLODDialog::CEditLODDialog(CWnd* pParent /*=NULL*/) : m_spinIncrement (0.5F), CDialog(CEditLODDialog::IDD, pParent) { //{{AFX_DATA_INIT(CEditLODDialog) //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////// // // DoDataExchange // void CEditLODDialog::DoDataExchange (CDataExchange* pDX) { // Allow the base class to process this message CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CEditLODDialog) DDX_Control(pDX, IDC_SWITCH_UP_SPIN, m_switchUpSpin); DDX_Control(pDX, IDC_SWITCH_DN_SPIN, m_switchDownSpin); DDX_Control(pDX, IDC_HIERARCHY_LIST, m_hierarchyListCtrl); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(CEditLODDialog, CDialog) //{{AFX_MSG_MAP(CEditLODDialog) ON_NOTIFY(UDN_DELTAPOS, IDC_SWITCH_UP_SPIN, OnDeltaposSwitchUpSpin) ON_NOTIFY(UDN_DELTAPOS, IDC_SWITCH_DN_SPIN, OnDeltaposSwitchDnSpin) ON_NOTIFY(LVN_ITEMCHANGED, IDC_HIERARCHY_LIST, OnItemChangedHierarchyList) ON_EN_UPDATE(IDC_SWITCH_DN_EDIT, OnUpdateSwitchDnEdit) ON_EN_UPDATE(IDC_SWITCH_UP_EDIT, OnUpdateSwitchUpEdit) ON_BN_CLICKED(IDC_RECALC, OnRecalc) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////// // // OnInitDialog // BOOL CEditLODDialog::OnInitDialog (void) { // Allow the base class to process this message CDialog::OnInitDialog (); // Center the dialog around the data tree view instead // of the direct center of the screen ::CenterDialogAroundTreeView (m_hWnd); // Get a pointer to the doc CW3DViewDoc *pCDoc = ::GetCurrentDocument (); if (pCDoc) { // Get the current LOD from the doc DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject (); ASSERT (pLOD); if (pLOD) { int iSubObjects = pLOD->Get_Num_Sub_Objects (); // Add the columns to the list control m_hierarchyListCtrl.InsertColumn (COL_NAME, "Name"); m_hierarchyListCtrl.InsertColumn (COL_SWITCH_UP, "Switch Up"); m_hierarchyListCtrl.InsertColumn (COL_SWITCH_DN, "Switch Down"); RenderObjClass *pfirst_subobj = pLOD->Get_Sub_Object (0); if (pfirst_subobj != NULL) { m_spinIncrement = pfirst_subobj->Get_Bounding_Sphere ().Radius / 5.0F; MEMBER_RELEASE (pfirst_subobj); } // Loop through all the subobjects for (int iObject = 0; (iObject < iSubObjects); iObject ++) { // Get this subobject RenderObjClass *pCSubObject = pLOD->Get_Sub_Object (iObject); if (pCSubObject) { // Add this object to the list int iIndex = m_hierarchyListCtrl.InsertItem (COL_NAME, pCSubObject->Get_Name ()); CString stringTemp; stringTemp.Format ("%.2f", pLOD->Get_Switch_Up_Dist (iObject)); m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp); stringTemp.Format ("%.2f", pLOD->Get_Switch_Down_Dist (iObject)); m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp); // Free this object MEMBER_RELEASE (pCSubObject); } } m_switchUpSpin.SetRange (-20, UD_MAXVAL-20); m_switchDownSpin.SetRange (-20, UD_MAXVAL-20); // Resize the columns so they are wide enough to display the largest string m_hierarchyListCtrl.SetColumnWidth (COL_NAME, LVSCW_AUTOSIZE); m_hierarchyListCtrl.SetColumnWidth (COL_SWITCH_UP, LVSCW_AUTOSIZE_USEHEADER); m_hierarchyListCtrl.SetColumnWidth (COL_SWITCH_DN, LVSCW_AUTOSIZE_USEHEADER); // Select the first item in the list m_hierarchyListCtrl.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED); } } return TRUE; } ///////////////////////////////////////////////////////////// // // OnOK // void CEditLODDialog::OnOK (void) { // Get a pointer to the doc CW3DViewDoc *pCDoc = ::GetCurrentDocument (); if (pCDoc) { // Get the current LOD from the doc DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject (); ASSERT (pLOD); if (pLOD) { int iSubObjects = pLOD->Get_Num_Sub_Objects (); // Loop through all the subobjects and add them to the list control for (int iObject = 0; (iObject < iSubObjects); iObject ++) { // Get the switch up distance from the list control CString stringTemp = m_hierarchyListCtrl.GetItemText (iObject, COL_SWITCH_UP); // Convert the string to a float and pass this value // onto the LOD manager float switchDistance = ::atof (stringTemp); pLOD->Set_Switch_Up_Dist (iObject, switchDistance); // Get the switch down distance from the list control stringTemp = m_hierarchyListCtrl.GetItemText (iObject, COL_SWITCH_DN); // Convert the string to a float and pass this value // onto the LOD manager switchDistance = ::atof (stringTemp); pLOD->Set_Switch_Down_Dist (iObject, switchDistance); } } } // Allow the base class to process this message CDialog::OnOK (); return ; } ///////////////////////////////////////////////////////////// // // OnCancel // void CEditLODDialog::OnCancel (void) { // Allow the base class to process this message CDialog::OnCancel (); return ; } ///////////////////////////////////////////////////////////// // // OnDeltaposSwitchUpSpin // void CEditLODDialog::OnDeltaposSwitchUpSpin ( NMHDR* pNMHDR, LRESULT* pResult ) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; if (pNMUpDown) { float newVal = float(pNMUpDown->iPos) / 10.00F; // Change the switching distance in the edit control CString stringTemp; stringTemp.Format ("%.2f", newVal); SetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp); // Find the selected item in the list control int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { // Change the switching distance in the list control m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp); } } *pResult = 0; return ; } ///////////////////////////////////////////////////////////// // // OnDeltaposSwitchDnSpin // void CEditLODDialog::OnDeltaposSwitchDnSpin ( NMHDR* pNMHDR, LRESULT* pResult ) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; if (pNMUpDown) { float newVal = float(pNMUpDown->iPos) / 10.00F; // Change the switching distance in the edit control CString stringTemp; stringTemp.Format ("%.2f", newVal); SetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp); // Find the selected item in the list control int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { // Change the switching distance in the list control m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp); } } *pResult = 0; return ; } ///////////////////////////////////////////////////////////// // // OnItemChangedHierarchyList // void CEditLODDialog::OnItemChangedHierarchyList ( NMHDR* pNMHDR, LRESULT* pResult ) { // Did the 'state' of the entry change? NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; if (pNMListView && (pNMListView->uChanged & LVIF_STATE) == LVIF_STATE) { if ((pNMListView->uNewState & LVIS_SELECTED) != LVIS_SELECTED) { // Is there a selected item in the list control? if (m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) == -1) { // Disabled the edit and spin controls EnableControls (FALSE); } } else { // Enable the edit and spin controls EnableControls (TRUE); // Load the control with data for the selected item. ResetControls (pNMListView->iItem); } } *pResult = 0; return ; } ///////////////////////////////////////////////////////////// // // ResetControls // void CEditLODDialog::ResetControls (int iIndex) { // // Set the text of the group box // CString stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_NAME); // Set the text of the group box CString stringTitle; stringTitle.Format ("Settings (%s)", (LPCTSTR)stringTemp); SetDlgItemText (IDC_SETTINGS_GROUP, stringTitle); // // Reset the switch up controls // // Get the switch up distance from the list control stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_SWITCH_UP); // Set the text of the edit control to reflect the switching distance SetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp); // Set the current position of the spin control float switchDistance = ::atof (stringTemp); m_switchUpSpin.SetPos (int(switchDistance * 10.00F)); // // Reset the switch down controls // // Get the switch down distance from the list control stringTemp = m_hierarchyListCtrl.GetItemText (iIndex, COL_SWITCH_DN); // Set the text of the edit control to reflect the switching distance SetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp); // Set the current position of the spin control switchDistance = ::atof (stringTemp); m_switchDownSpin.SetPos (int(switchDistance * 10.00F)); return ; } ///////////////////////////////////////////////////////////// // // EnableControls // void CEditLODDialog::EnableControls (BOOL bEnable) { // Enable or disable the windows ::EnableWindow (::GetDlgItem (m_hWnd, IDC_SETTINGS_GROUP), bEnable); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_UP_SPIN), bEnable); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_UP_EDIT), bEnable); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_DN_SPIN), bEnable); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_SWITCH_DN_EDIT), bEnable); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_RECALC), bEnable); return ; } ///////////////////////////////////////////////////////////// // // OnUpdateSwitchDnEdit // void CEditLODDialog::OnUpdateSwitchDnEdit (void) { // Get the switching distance from the edit control CString stringTemp; GetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp); float newVal = ::atof (stringTemp); // Change the switching distance in the spin control m_switchDownSpin.SetPos (int(newVal * 10.00F)); // Find the selected item in the list control int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { // Change the switching distance in the list control m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_DN, stringTemp); } return ; } ///////////////////////////////////////////////////////////// // // OnUpdateSwitchUpEdit // void CEditLODDialog::OnUpdateSwitchUpEdit (void) { // Get the switching distance from the edit control CString stringTemp; GetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp); float newVal = ::atof (stringTemp); // Change the switching distance in the spin control m_switchUpSpin.SetPos (int(newVal * 10.00F)); // Find the selected item in the list control int iIndex = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED); if (iIndex != -1) { // Change the switching distance in the list control m_hierarchyListCtrl.SetItemText (iIndex, COL_SWITCH_UP, stringTemp); } return ; } ///////////////////////////////////////////////////////////// // // OnRecalc // void CEditLODDialog::OnRecalc (void) { // Get the up switching distance from the edit control CString stringTemp; GetDlgItemText (IDC_SWITCH_UP_EDIT, stringTemp); float switchUp = ::atof (stringTemp); // Get the down switching distance from the edit control stringTemp; GetDlgItemText (IDC_SWITCH_DN_EDIT, stringTemp); float switchDown = ::atof (stringTemp); if (switchUp < switchDown) { // Calculate the current range float switchDelta = switchDown - switchUp; float switchOverlap = switchDelta * 0.1F; // Get a pointer to the doc CW3DViewDoc *pCDoc = ::GetCurrentDocument (); if (pCDoc) { // Get the current LOD from the doc DistLODClass *pLOD = (DistLODClass *)pCDoc->GetDisplayedObject (); ASSERT (pLOD); if (pLOD) { int iSubObjects = pLOD->Get_Num_Sub_Objects (); switchUp = switchDown - switchOverlap; // Loop through all the subobjects (following the highlighted one) for (int iObject = m_hierarchyListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED) + 1; (iObject < iSubObjects); iObject ++) { // Set the text of the switch up column CString stringTemp; stringTemp.Format ("%.2f", switchUp); m_hierarchyListCtrl.SetItemText (iObject, COL_SWITCH_UP, stringTemp); // Set the text of the switch dn column stringTemp.Format ("%.2f", switchUp+switchDelta); m_hierarchyListCtrl.SetItemText (iObject, COL_SWITCH_DN, stringTemp); // Add the range to the switch up distance switchUp += switchDelta-switchOverlap; } } } } return ; }