| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319 |
- /*
- ** 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/InstancesPage.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 5/11/01 9:25a $*
- * *
- * $Revision:: 14 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "stdafx.h"
- #include "leveledit.h"
- #include "instancespage.h"
- #include "nodemgr.h"
- #include "node.h"
- #include "utils.h"
- #include "cameramgr.h"
- #include "gotoobjectdialog.h"
- #include "sceneeditor.h"
- #include "icons.h"
- #include "nodecategories.h"
- #include "definition.h"
- #include "definitionfactory.h"
- #include "definitionfactorymgr.h"
- #include "preset.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- ///////////////////////////////////////////////////////////////////////
- // Local prototypes
- ///////////////////////////////////////////////////////////////////////
- int CALLBACK InstancesListSortCallback (LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
- #ifndef ListView_SetCheckState
- #define ListView_SetCheckState(hwndLV, i, fCheck) \
- ListView_SetItemState(hwndLV, i, \
- INDEXTOSTATEIMAGEMASK((fCheck)+1), LVIS_STATEIMAGEMASK)
- #endif
- #ifndef ListView_SetOverlay
- #define ListView_SetOverlay(hwndLV, i, overlay) \
- ListView_SetItemState(hwndLV, i, \
- INDEXTOOVERLAYMASK(overlay), LVIS_OVERLAYMASK)
- #endif
- ///////////////////////////////////////////////////////////////////////
- // Local structures
- ///////////////////////////////////////////////////////////////////////
- typedef enum
- {
- TYPE_NAVIGATOR,
- TYPE_FACTORY,
- TYPE_NODE,
- } ITEM_TYPE;
- typedef struct
- {
- ITEM_TYPE type;
- StringClass name;
- union
- {
- uint32 class_id;
- NodeClass * node;
- };
- } ITEM_DATA;
- /////////////////////////////////////////////////////////////////////////////
- // Local constants
- /////////////////////////////////////////////////////////////////////////////
- const int TOOLBAR_HEIGHT = 36;
- const int TOOLBAR_V_SPACING = 5;
- const int TOOLBAR_V_BORDER = TOOLBAR_V_SPACING * 2;
- const int TOOLBAR_H_SPACING = 5;
- const int TOOLBAR_H_BORDER = TOOLBAR_H_SPACING * 2;
- //const int COLUMN_CHECK = 0;
- //const int COLUMN_PLUS = 1;
- const int COLUMN_NAME = 0;
- /////////////////////////////////////////////////////////////////////////////
- //
- // InstancesPageClass
- //
- /////////////////////////////////////////////////////////////////////////////
- InstancesPageClass::InstancesPageClass (CWnd *parent_wnd)
- : m_ClassID (0),
- CDialog(InstancesPageClass::IDD)
- {
- //{{AFX_DATA_INIT(InstancesPageClass)
- //}}AFX_DATA_INIT
- Create (InstancesPageClass::IDD, parent_wnd);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // ~InstancesPageClass
- //
- /////////////////////////////////////////////////////////////////////////////
- InstancesPageClass::~InstancesPageClass (void)
- {
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // DoDataExchange
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::DoDataExchange (CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(InstancesPageClass)
- DDX_Control(pDX, IDC_INSTANCE_LIST, m_ListCtrl);
- //}}AFX_DATA_MAP
- return ;
- }
- BEGIN_MESSAGE_MAP(InstancesPageClass, CDialog)
- //{{AFX_MSG_MAP(InstancesPageClass)
- ON_WM_SIZE()
- ON_WM_DESTROY()
- ON_COMMAND(IDC_EDIT, OnEdit)
- ON_COMMAND(IDC_GOTO, OnGoto)
- ON_COMMAND(IDC_SHOWALL, OnShowAll)
- ON_COMMAND(IDC_SELECT, OnSelect)
- ON_COMMAND(IDC_DELETE, OnDelete)
- ON_NOTIFY(LVN_DELETEITEM, IDC_INSTANCE_LIST, OnDeleteitemInstanceList)
- ON_NOTIFY(NM_DBLCLK, IDC_INSTANCE_LIST, OnDblclkInstanceList)
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_INSTANCE_LIST, OnItemchangedInstanceList)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- #ifdef _DEBUG
- void InstancesPageClass::AssertValid() const
- {
- CDialog::AssertValid();
- }
- void InstancesPageClass::Dump(CDumpContext& dc) const
- {
- CDialog::Dump(dc);
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnSize
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnSize
- (
- UINT nType,
- int cx,
- int cy
- )
- {
- // Allow the base class to process this message
- CDialog::OnSize (nType, cx, cy);
- if (::IsWindow (m_ListCtrl) && (cx > 0) && (cy > 0)) {
- // Get the bounding rectangle of the form window
- CRect parentrect;
- GetWindowRect (&parentrect);
-
- // Get the bounding rectangle of the toolbar
- CRect toolbar_rect;
- m_Toolbar.GetWindowRect (&toolbar_rect);
- ScreenToClient (&toolbar_rect);
- // Move the toolbar so it is in its correct position
- m_Toolbar.SetWindowPos (NULL,
- TOOLBAR_H_SPACING,
- (cy - TOOLBAR_V_SPACING) - toolbar_rect.Height (),
- cx - TOOLBAR_H_BORDER,
- toolbar_rect.Height (),
- SWP_NOZORDER);
- // Get the bounding rectnagle of the list ctrl
- RECT list_rect;
- m_ListCtrl.GetWindowRect (&list_rect);
-
- CRect client_rect = list_rect;
- ScreenToClient (&client_rect);
- int list_height = ((cy - TOOLBAR_V_BORDER) - toolbar_rect.Height ()) - client_rect.top;
- // Resize the tab control to fill the entire contents of the client area
- m_ListCtrl.SetWindowPos ( NULL,
- 0,
- 0,
- cx-((list_rect.left - parentrect.left) << 1),
- list_height,
- SWP_NOZORDER | SWP_NOMOVE);
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnDestroy
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnDestroy (void)
- {
- //
- // Free the state image list we associated with the control
- //
- CImageList *imagelist = m_ListCtrl.GetImageList (LVSIL_STATE);
- m_ListCtrl.SetImageList (NULL, LVSIL_STATE);
- SAFE_DELETE (imagelist);
- //
- // Remove the main image list we associated with the control
- //
- m_ListCtrl.SetImageList (NULL, LVSIL_SMALL);
- m_ListCtrl.DeleteAllItems ();
- ::RemoveProp (m_ListCtrl, "TRANS_ACCS");
- ::RemoveProp (m_hWnd, "TRANS_ACCS");
- CDialog::OnDestroy ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnEdit
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnEdit (void)
- {
- // Show the settings dialog for the currently selected item
- NodeClass *node = Get_Item_Node (m_ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED));
- if (node != NULL) {
- node->Show_Settings_Dialog ();
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnGoto
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnGoto (void)
- {
- NodeClass *selected_node = NULL;
- //
- // Try to find the first selected node (if any)
- //
- int index = m_ListCtrl.GetNextItem (-1, LVNI_SELECTED | LVNI_ALL);
- if (index >= 0) {
- selected_node = Get_Item_Node (index);
- }
- //
- // Show the 'goto' dialog...
- //
- GotoObjectDialogClass dialog (selected_node);
- dialog.DoModal ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // OnShowAll
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnShowAll (void)
- {
- //
- // Show all the nodes
- //
- for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- node->Hide (false);
- }
- //
- // Fixup the UI
- //
- for (int index = 0; index < m_ListCtrl.GetItemCount (); index ++) {
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data != NULL && item_data->type != TYPE_NAVIGATOR) {
- ListView_SetCheckState (m_ListCtrl, index, true);
- }
- }
- //
- // Make sure the main view is updated
- //
- ::Refresh_Main_View ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // WindowProc
- //
- ////////////////////////////////////////////////////////////////////////////
- LRESULT
- InstancesPageClass::WindowProc
- (
- UINT message,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- //
- // Is this the message we are expecting?
- //
- if (message == WM_USER+102) {
- int index = (int)lParam;
- //
- // Should we toggle the checkmark for this entry?
- //
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data != NULL && item_data->type != TYPE_NAVIGATOR) {
- //
- // Either hide or show the selected nodes
- //
- bool hidden = (ListView_GetCheckState (m_ListCtrl, index) == false);
- Hide_Nodes (index, !hidden);
- ListView_SetCheckState (m_ListCtrl, index, hidden);
- }
- }
- return CDialog::WindowProc(message, wParam, lParam);
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // CheckBoxSubclassProc
- //
- ////////////////////////////////////////////////////////////////////////////
- LRESULT CALLBACK
- CheckBoxSubclassProc
- (
- HWND hwnd,
- UINT message,
- WPARAM wparam,
- LPARAM lparam
- )
- {
- WNDPROC pold_proc = (WNDPROC)::GetProp (hwnd, "OLDPROC");
-
- if (message == WM_LBUTTONUP) {
-
- //
- // Find out where the user clicked
- //
- LVHITTESTINFO hittest = { 0 };
- hittest.pt.x = LOWORD (lparam);
- hittest.pt.y = HIWORD (lparam);
- ::SendMessage (hwnd, LVM_HITTEST, 0, (LPARAM)&hittest);
-
- //
- // Did the user click one of the checkboxes?
- //
- if (hittest.flags & LVHT_ONITEMSTATEICON) {
- //
- // Notify the instances page that the user wants to toggle the checkbox
- //
- ::PostMessage (::GetParent (hwnd), WM_USER+102, 0, (LPARAM)hittest.iItem);
- }
- } else if (message == WM_DESTROY) {
- ::SetWindowLong (hwnd, GWL_WNDPROC, (LONG)pold_proc);
- ::RemoveProp (hwnd, "OLDPROC");
- }
- if (pold_proc != NULL) {
- return ::CallWindowProc (pold_proc, hwnd, message, wparam, lparam);
- } else {
- return ::DefWindowProc (hwnd, message, wparam, lparam);
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OnDblclkInstanceList
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnDblclkInstanceList
- (
- NMHDR * pNMHDR,
- LRESULT* pResult
- )
- {
- // Determine what client-coord location was double-clicked on
- DWORD mouse_pos = ::GetMessagePos ();
- POINT hit_point = { GET_X_LPARAM (mouse_pos), GET_Y_LPARAM (mouse_pos) };
- m_ListCtrl.ScreenToClient (&hit_point);
- // Goto the node that was double-clicked on (if possible)
- UINT flags = 0;
- int index = m_ListCtrl.HitTest (hit_point, &flags);
- if ((index >= 0) && ((flags & LVHT_ONITEMLABEL) || (flags & LVHT_ONITEMICON))) {
-
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data != NULL) {
-
- if (item_data->type == TYPE_NAVIGATOR) {
-
- //
- // Determine which class id we should display
- //
- int class_id = 0;
- if (m_ClassIDStack.Count () > 0) {
- class_id = m_ClassIDStack[m_ClassIDStack.Count ()-1];
- m_ClassIDStack.Delete (m_ClassIDStack.Count ()-1);
- }
- Populate_List (class_id);
- } else if (item_data->type == TYPE_FACTORY) {
-
- //
- // Fill the list with children of the given class id
- //
- m_ClassIDStack.Add (m_ClassID);
- Populate_List (item_data->class_id);
- } else {
-
- NodeClass *node = Get_Item_Node (index);
- if (node != NULL) {
-
- //
- // If this node is a terrain, then display the subojects,
- // otherwise snap the camera to the node
- //
- if (node->Get_Sub_Node_Count () > 0) {
- m_ClassIDStack.Add (m_ClassID);
- Populate_List (node);
- } else {
- ::Get_Camera_Mgr ()->Goto_Node (node);
- }
- }
- }
- }
- }
-
- (*pResult) = 0;
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OnSelect
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnSelect (void)
- {
- //
- // Clear all selected nodes
- //
- ::Get_Scene_Editor ()->Set_Selection (NULL);
- //
- // Toggle the selection state of all the nodes in the selection set
- //
- int index = -1;
- while ((index = m_ListCtrl.GetNextItem (index, LVNI_ALL | LVNI_SELECTED)) >= 0) {
- NodeClass *node = Get_Item_Node (index);
- if (node != NULL) {
- ::Get_Scene_Editor ()->Toggle_Selection (node);
- }
- }
-
- ::Refresh_Main_View ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OnDelete
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnDelete (void)
- {
- CString message = "Are you sure you wish to delete the selected node(s)?";
- CString title;
- title.LoadString (IDS_DELETE_CONFIRM_TITLE);
-
- //
- // Ask the user if they really want to delete the selected item
- //
- if (MessageBox (message, title, MB_ICONEXCLAMATION | MB_YESNO) == IDYES) {
- //
- // Build a list of all the nodes we need to delete
- //
- DynamicVectorClass<NodeClass *> delete_list;
- int index = -1;
- while ((index = m_ListCtrl.GetNextItem (index, LVNI_ALL | LVNI_SELECTED)) >= 0) {
- NodeClass *node = Get_Item_Node (index);
- if (node != NULL) {
- delete_list.Add (node);
- }
- }
- //
- // Delete all the selected nodes
- //
- for (index = 0; index < delete_list.Count (); index ++) {
- ::Get_Scene_Editor ()->Delete_Node (delete_list[index]);
- }
-
- ::Refresh_Main_View ();
- }
-
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OnInitDialog
- //
- ////////////////////////////////////////////////////////////////////////////
- BOOL
- InstancesPageClass::OnInitDialog (void)
- {
- CDialog::OnInitDialog ();
- m_Toolbar.CreateEx (this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect(0, 0, 0, 0), 101);
- m_Toolbar.SetOwner (this);
- m_Toolbar.LoadToolBar (IDR_INSTANCES_TOOLBAR);
- m_Toolbar.SetBarStyle (m_Toolbar.GetBarStyle () | CBRS_TOOLTIPS | CBRS_FLYBY);
- //
- // Configure the toolbar
- //
- CRect parentrect;
- GetWindowRect (&parentrect);
- m_Toolbar.SetWindowPos (NULL, 0, 0, parentrect.Width () - TOOLBAR_H_BORDER, TOOLBAR_HEIGHT, SWP_NOZORDER | SWP_NOMOVE);
- m_Toolbar.Enable_Button (IDC_DELETE, false);
- m_Toolbar.Enable_Button (IDC_SELECT, false);
- m_Toolbar.Enable_Button (IDC_EDIT, false);
- //
- // Configure the list control's extended styles
- //
- //m_ListCtrl.SetExtendedStyle (m_ListCtrl.GetExtendedStyle () | LVS_EX_SUBITEMIMAGES | LVS_EX_FULLROWSELECT);
- //
- // Create a state imagelist for the list control to use for checkboxes
- //
- CImageList *imagelist = new CImageList;
- imagelist->Create (MAKEINTRESOURCE (IDB_CHECKBOX_STATES1), 13, 0, RGB (255, 0, 255));
- m_ListCtrl.SetImageList (imagelist, LVSIL_STATE);
-
- //
- // Setup the columns of the list control
- //
- CRect client_rect;
- m_ListCtrl.GetClientRect (&client_rect);
- m_ListCtrl.InsertColumn (COLUMN_NAME, "Name");
- m_ListCtrl.SetColumnWidth (COLUMN_NAME, client_rect.Width () - 5);
- //
- // Pass the general use imagelist onto the list control
- //
- m_ListCtrl.SetImageList (::Get_Global_Image_List (), LVSIL_SMALL);
- //
- // Subclass the list control so we can handle the checkstates
- //
- LONG oldproc = ::SetWindowLong (m_ListCtrl, GWL_WNDPROC, (LONG)CheckBoxSubclassProc);
- ::SetProp (m_ListCtrl, "OLDPROC", (HANDLE)oldproc);
- //
- // Populate the list control
- //
- Reset_List ();
- SetProp (m_ListCtrl, "TRANS_ACCS", (HANDLE)1);
- SetProp (m_hWnd, "TRANS_ACCS", (HANDLE)1);
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Insert_Factory
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Insert_Factory (LPCTSTR name, int class_id)
- {
- //
- // Add an entry to the list control for the factory
- //
- int index = m_ListCtrl.InsertItem (0xFF, name, FOLDER_ICON);
- if (index >= 0) {
- //
- // Set the text and the icon for this entry
- //
- //m_ListCtrl.SetItem (index, COLUMN_NAME, LVIF_TEXT | LVIF_IMAGE, name, FOLDER_ICON, 0, 0, 0);
- //
- // Allocate a new wrapper if we need to
- //
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data == NULL) {
- item_data = new ITEM_DATA;
- }
- //
- // Set a flag in the wrapper so we know what kind of data
- // this list item contains.
- //
- item_data->type = TYPE_FACTORY;
- item_data->class_id = class_id;
- item_data->name = name;
- m_ListCtrl.SetItemData (index, (DWORD)item_data);
- m_ListCtrl.SetCheck (index, TRUE);
- }
-
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Insert_Node
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Insert_Node (NodeClass *node)
- {
- //
- // Add an entry to the list control for the node
- //
- int index = m_ListCtrl.InsertItem (0xFF, node->Get_Name (), node->Get_Icon_Index ());
- if (index >= 0) {
- //
- // Set the text and the icon for this entry
- //
- //m_ListCtrl.SetItem (index, COLUMN_NAME, LVIF_TEXT | LVIF_IMAGE, node->Get_Name (), node->Get_Icon_Index (), 0, 0, 0);
-
- //
- // Allocate a new wrapper if we need to
- //
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data == NULL) {
- item_data = new ITEM_DATA;
- }
- //
- // Set a flag in the wrapper so we know what kind of data
- // this list item contains.
- //
- SAFE_ADD_REF (node);
- item_data->type = TYPE_NODE;
- item_data->node = node;
- item_data->name = node->Get_Name ();
- m_ListCtrl.SetItemData (index, (DWORD)item_data);
- ListView_SetCheckState (m_ListCtrl, index, (node->Is_Hidden () == false));
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Insert_Navigator
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Insert_Navigator (void)
- {
- //
- // Add an entry to the list control for the navigator
- //
- int index = m_ListCtrl.InsertItem (0xFF, "..", NAVIGATOR_ICON);
- if (index >= 0) {
- //
- // Set the text and the icon for this entry
- //
- //m_ListCtrl.SetItem (index, COLUMN_NAME, LVIF_TEXT | LVIF_IMAGE, "..", NAVIGATOR_ICON, 0, 0, 0);
-
- //
- // Allocate a new wrapper if we need to
- //
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data == NULL) {
- item_data = new ITEM_DATA;
- }
- //
- // Set a flag in the wrapper so we know what kind of data
- // this list item contains.
- //
- item_data->type = TYPE_NAVIGATOR;
- item_data->node = NULL;
- item_data->name = "..";
- m_ListCtrl.SetItemData (index, (DWORD)item_data);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Add_Node
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Add_Node (NodeClass *node)
- {
- WWASSERT (node != NULL);
- PresetClass *preset = node->Get_Preset ();
- if (preset != NULL) {
- DefinitionClass *definition = preset->Get_Definition ();
- WWASSERT (definition != NULL);
- if (definition != NULL) {
- //
- // Should the node be inserted into the current view?
- //
- if (definition->Get_Class_ID () == m_ClassID) {
- m_ListCtrl.SetRedraw (FALSE);
- Insert_Node (node);
- m_ListCtrl.SortItems (InstancesListSortCallback, 0L);
- m_ListCtrl.SetRedraw (TRUE);
- }
- }
- }
- Update_Overlays ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Remove_Node
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Remove_Node (NodeClass *node)
- {
- WWASSERT (node != NULL);
- //
- // Attempt to find this node in the current view
- //
- for (int index = 0; index < m_ListCtrl.GetItemCount (); index ++) {
- NodeClass *curr_node = Get_Item_Node (index);
-
- //
- // If this is the node we are looking for, then remove it from
- // the view.
- //
- if (curr_node == node) {
- m_ListCtrl.DeleteItem (index);
- break;
- }
- }
- Update_Overlays ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Get_Item_Node
- //
- /////////////////////////////////////////////////////////////////////////////
- NodeClass *
- InstancesPageClass::Get_Item_Node (int index)
- {
- NodeClass *node = NULL;
- //
- // If this item represents a node, then return the node
- // pointer to the caller.
- //
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if ((item_data != NULL) && (item_data->type == TYPE_NODE)) {
- node = item_data->node;
- }
- return node;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Set_Node_Check
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Set_Node_Check
- (
- int index,
- bool onoff
- )
- {
- // First off, show/hide the node
- /*NodeClass *node = Get_Item_Node (index);
- if (node != NULL) {
- node->Hide (!onoff);
- }*/
- // Update the UI for this node
- //ListView_SetCheckState (m_ListCtrl, index, onoff);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Reset_List
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Reset_List (void)
- {
- m_ClassIDStack.Delete_All ();
- Populate_List ((uint32)0);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Populate_List
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Populate_List (uint32 class_id)
- {
- m_ListCtrl.SetRedraw (FALSE);
- m_ListCtrl.DeleteAllItems ();
- if (class_id == 0) {
-
- //
- // Add all the node categories to the list control
- //
- for (int index = 0; index < PRESET_CATEGORY_COUNT; index ++) {
- Insert_Factory (PRESET_CATEGORIES[index].name, PRESET_CATEGORIES[index].clsid);
- }
- } else {
- Insert_Navigator ();
- //
- // Fill all the node instances into the list control
- //
- for ( NodeClass *node = NodeMgrClass::Find_First (class_id);
- node != NULL;
- node = NodeMgrClass::Find_Next (node, class_id))
- {
- //
- // Add this node to the list control
- //
- Insert_Node (node);
- }
- //
- // Fill all the factory instances into the list control
- //
- for ( DefinitionFactoryClass *factory = DefinitionFactoryMgrClass::Get_First (class_id);
- factory != NULL;
- factory = DefinitionFactoryMgrClass::Get_Next (factory, class_id))
- {
- //
- // Add this node to the list control
- //
- if (factory->Get_Class_ID () != class_id) {
- Insert_Factory (factory->Get_Name (), factory->Get_Class_ID ());
- }
- }
- //
- // Sort all the items
- //
- m_ListCtrl.SortItems (InstancesListSortCallback, 0L);
- }
- m_ListCtrl.SetRedraw (TRUE);
- //
- // Save this class ID for later
- //
- m_ClassID = class_id;
-
- //
- // Make sure the toolbar is up to date
- //
- Update_Overlays ();
- Update_Button_States ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Populate_List
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Populate_List (NodeClass *node)
- {
- m_ListCtrl.SetRedraw (FALSE);
- m_ListCtrl.DeleteAllItems ();
- if (node != NULL) {
- Insert_Navigator ();
- //
- // Add all the sub-nodes to the list control
- //
- for (int index = 0; index < node->Get_Sub_Node_Count (); index ++) {
- NodeClass *sub_node = node->Get_Sub_Node (index);
- if (sub_node != NULL) {
-
- //
- // Add this node to the list control
- //
- Insert_Node (sub_node);
- }
- }
- }
- //
- // Sort all the items
- //
- m_ListCtrl.SortItems (InstancesListSortCallback, 0L);
- m_ListCtrl.SetRedraw (TRUE);
- //
- // Make sure the toolbar is up to date
- //
- Update_Overlays ();
- Update_Button_States ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OnDeleteitemInstanceList
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnDeleteitemInstanceList
- (
- NMHDR * pNMHDR,
- LRESULT * pResult
- )
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- (*pResult) = 0;
- // Get the node associated with this entry
- NodeClass *node = Get_Item_Node (pNMListView->iItem);
- MEMBER_RELEASE (node);
- // Free the item data structure associated with this entry
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (pNMListView->iItem);
- SAFE_DELETE (item_data);
- m_ListCtrl.SetItemData (pNMListView->iItem, 0L);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // InstancesListSortCallback
- //
- ////////////////////////////////////////////////////////////////////////////
- int CALLBACK
- InstancesListSortCallback
- (
- LPARAM lParam1,
- LPARAM lParam2,
- LPARAM lParamSort
- )
- {
- int retval = 0;
- ITEM_DATA *item_data1 = (ITEM_DATA *)lParam1;
- ITEM_DATA *item_data2 = (ITEM_DATA *)lParam2;
- if (item_data1 != NULL && item_data2 != NULL) {
-
- //
- // Do the types match?
- //
- if (item_data1->type == item_data2->type) {
-
- //
- // Do a simple name comparison
- //
- retval = ::lstrcmpi (item_data1->name, item_data2->name);
- } else {
- //
- // Sort based on type
- //
- retval = (item_data1->type - item_data2->type);
- }
- }
-
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // OnItemchangedInstanceList
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::OnItemchangedInstanceList
- (
- NMHDR * pNMHDR,
- LRESULT* pResult
- )
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- *pResult = 0;
- if (pNMListView->uChanged & LVIF_STATE) {
- //
- // Did the selection set change?
- //
- if (pNMListView->uNewState & LVIS_SELECTED || pNMListView->uOldState & LVIS_SELECTED) {
- Update_Button_States ();
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Update_Button_States
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Update_Button_States (void)
- {
- //
- // Determine if there are any nodes in the current selection set.
- //
- bool enable = false;
- int index = -1;
- while (!enable && (index = m_ListCtrl.GetNextItem (index, LVNI_ALL | LVNI_SELECTED)) >= 0) {
- enable |= (Get_Item_Node (index) != NULL);
- }
- //
- // Enable or disable the edit button depending on
- // whether the selected item is a category or a node
- //
- m_Toolbar.Enable_Button (IDC_DELETE, enable);
- m_Toolbar.Enable_Button (IDC_EDIT, enable);
- m_Toolbar.Enable_Button (IDC_SELECT, enable);
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Hide_Node
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Hide_Node (NodeClass *node, uint32 class_id, bool hide)
- {
- PresetClass *preset = node->Get_Preset ();
- if (preset != NULL) {
- DefinitionClass *definition = preset->Get_Definition ();
- if (definition != NULL) {
-
- //
- // Did this node come from the selected factory?
- //
- uint32 curr_class_id = definition->Get_Class_ID ();
- uint32 superclass_id = ::SuperClassID_From_ClassID (curr_class_id);
- if (curr_class_id == class_id || superclass_id == class_id) {
-
- //
- // Change this node's display state
- //
- node->Hide (hide);
- }
- }
- }
- //
- // Now, check all this nodes children
- //
- for (int index = 0; index < node->Get_Sub_Node_Count (); index ++) {
- NodeClass *sub_node = node->Get_Sub_Node (index);
- if (sub_node != NULL) {
- Hide_Node (sub_node, class_id, hide);
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////////
- //
- // Hide_Nodes
- //
- ////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Hide_Nodes (int index, bool hide)
- {
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data != NULL) {
-
- if (item_data->type == TYPE_FACTORY) {
- //
- // Loop over all the nodes in the world
- //
- for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL;
- node = NodeMgrClass::Get_Next (node))
- {
- //
- // Hide this node (if necessary)
- //
- Hide_Node (node, item_data->class_id, hide);
- }
-
- } else if (item_data->type == TYPE_NODE) {
-
- //
- // Change this node's display state
- //
- item_data->node->Hide (hide);
- }
- }
- //
- // Make sure the main view is updated
- //
- ::Refresh_Main_View ();
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Update_Overlays
- //
- /////////////////////////////////////////////////////////////////////////////
- void
- InstancesPageClass::Update_Overlays (void)
- {
- //
- // Loop over all the entries in the current view
- //
- for (int index = 0; index < m_ListCtrl.GetItemCount (); index ++) {
-
- //
- // Get information about this entry
- //
- ITEM_DATA *item_data = (ITEM_DATA *)m_ListCtrl.GetItemData (index);
- if (item_data != NULL) {
-
- bool needs_overlay = false;
- //
- // Check to see if this entry has any sub-entries
- //
- if (item_data->type == TYPE_FACTORY) {
- needs_overlay = Does_Factory_Have_Children (item_data->class_id);
- } else if (item_data->type == TYPE_NODE && (item_data->node->Get_Sub_Node_Count () > 0)) {
- needs_overlay = true;
- }
- //
- // Set the appropriate overlay
- //
- ListView_SetOverlay (m_ListCtrl, index, needs_overlay ? 1 : 0);
- }
- }
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Does_Factory_Have_Children
- //
- /////////////////////////////////////////////////////////////////////////////
- bool
- InstancesPageClass::Does_Factory_Have_Children (uint32 factory_id)
- {
- bool retval = false;
- //
- // Check to see if there are any instances of this factory
- // in the world
- //
- for ( NodeClass *node = NodeMgrClass::Get_First ();
- node != NULL && retval == false;
- node = NodeMgrClass::Get_Next (node))
- {
- PresetClass *preset = node->Get_Preset ();
- if (preset != NULL) {
- DefinitionClass *definition = preset->Get_Definition ();
- if (definition != NULL) {
-
- //
- // Did this node come from the specified factory?
- //
- uint32 class_id = definition->Get_Class_ID ();
- uint32 superclass_id = ::SuperClassID_From_ClassID (class_id);
- if (class_id == factory_id || superclass_id == factory_id) {
- retval = true;
- }
- }
- }
- }
- //
- // Check to see if this factory has any sub-factories
- //
- if (retval == false) {
- DefinitionFactoryClass *factory = DefinitionFactoryMgrClass::Get_First (factory_id);
- if (factory != NULL && factory->Get_Class_ID () != factory_id) {
- retval = true;
- }
- }
- return retval;
- }
|