summaryrefslogtreecommitdiff
path: root/hammer/prefabsdlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hammer/prefabsdlg.cpp')
-rw-r--r--hammer/prefabsdlg.cpp623
1 files changed, 623 insertions, 0 deletions
diff --git a/hammer/prefabsdlg.cpp b/hammer/prefabsdlg.cpp
new file mode 100644
index 0000000..67eceaf
--- /dev/null
+++ b/hammer/prefabsdlg.cpp
@@ -0,0 +1,623 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// PrefabsDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "hammer.h"
+#include "PrefabsDlg.h"
+#include "Prefabs.h"
+#include "Prefab3D.h"
+#include "EditPrefabDlg.h"
+#include "MapDoc.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// CPrefabsDlg dialog
+
+CPrefabsDlg::CPrefabsDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CPrefabsDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CPrefabsDlg)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+}
+
+
+void CPrefabsDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CPrefabsDlg)
+ DDX_Control(pDX, IDC_OBJECTS, m_Objects);
+ DDX_Control(pDX, IDC_OBJECTNOTES, m_ObjectNotes);
+ DDX_Control(pDX, IDC_LIBRARYNOTES, m_LibraryNotes);
+ DDX_Control(pDX, IDC_LIBRARIES, m_Libraries);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CPrefabsDlg, CDialog)
+ //{{AFX_MSG_MAP(CPrefabsDlg)
+ ON_BN_CLICKED(IDC_ADDLIBRARY, OnAddlibrary)
+ ON_BN_CLICKED(IDC_ADDOBJECT, OnAddobject)
+ ON_BN_CLICKED(IDC_EDITLIBRARY, OnEditlibrary)
+ ON_BN_CLICKED(IDC_EDITOBJECT, OnEditobject)
+ ON_BN_CLICKED(IDC_EXPORTOBJECT, OnExportobject)
+ ON_CBN_SELCHANGE(IDC_LIBRARIES, OnSelchangeLibraries)
+ ON_BN_CLICKED(IDC_REMOVELIBRARY, OnRemovelibrary)
+ ON_BN_CLICKED(IDC_REMOVEOBJECT, OnRemoveobject)
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_OBJECTS, OnItemchangedObjects)
+ ON_NOTIFY(LVN_ENDLABELEDIT, IDC_OBJECTS, OnEndlabeleditObjects)
+ ON_WM_CLOSE()
+ //}}AFX_MSG_MAP
+ ON_COMMAND_EX(id_EditObjectInfo, HandleEditObjectPopup)
+ ON_COMMAND_EX(id_EditObjectData, HandleEditObjectPopup)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CPrefabsDlg message handlers
+
+void CPrefabsDlg::OnAddobject()
+{
+ CPrefabLibrary *pLibrary = GetCurrentLibrary();
+ if(!pLibrary)
+ return; // no lib, no add
+
+ CFileDialog dlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST |
+ OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_NOCHANGEDIR,
+ "Prefab files (*.map;*.rmf;*.os)|*.map; *.rmf; *.os|"
+ "Game MAP files (*.map)|*.map|"
+ "Worldcraft RMF files (*.rmf)|*.rmf||", this);
+
+ if(dlg.DoModal() == IDCANCEL)
+ return; // aborted
+
+ // add all these files ..
+ char szDir[MAX_PATH], szFiles[2048];
+ memcpy(szFiles, dlg.m_ofn.lpstrFile, dlg.m_ofn.nMaxFile);
+ strcpy(szDir, dlg.m_ofn.lpstrFile);
+
+ BOOL bOneFile = FALSE;
+ char *p = szFiles + strlen(szDir) + 1;
+ if(!p[0])
+ {
+ bOneFile = TRUE;
+ p = szDir; // just one file
+ }
+
+ // disable caching of prefabs
+ CPrefab::EnableCaching(FALSE);
+
+ // get files
+ char szFile[MAX_PATH];
+ CString strFullPath;
+ int iItem = m_Objects.GetItemCount();
+ while(1)
+ {
+ strcpy(szFile, p);
+ if(!szFile[0])
+ break;
+ p += strlen(szFile) + 1;
+
+ if(!bOneFile)
+ strFullPath.Format("%s\\%s", szDir, szFile);
+ else
+ strFullPath = szFile;
+
+ // check file type
+ CPrefab *pPrefab = NULL;
+
+ switch(CPrefab::CheckFileType(strFullPath))
+ {
+ case CPrefab::pftUnknown:
+ {
+ continue; // no.
+ }
+
+ case CPrefab::pftRMF:
+ {
+ CPrefabRMF *pNew = new CPrefabRMF;
+ pNew->Init(strFullPath, TRUE, CPrefab::lsRMF);
+ pPrefab = (CPrefab *)pNew;
+ break;
+ }
+
+ case CPrefab::pftMAP:
+ {
+ CPrefabRMF *pNew = new CPrefabRMF;
+ pNew->Init(strFullPath, TRUE, CPrefab::lsMAP);
+ pPrefab = (CPrefab *)pNew;
+ break;
+ }
+
+ case CPrefab::pftScript:
+ {
+ Assert(0); // not supported yet
+ break;
+ }
+ }
+
+ if (!pPrefab)
+ {
+ continue;
+ }
+
+ // add to current library
+ pLibrary->Add(pPrefab);
+ // add to objects list
+ AddToObjectList(pPrefab, iItem++);
+
+ if(bOneFile)
+ break;
+ }
+
+ // now rewrite library
+ pLibrary->Sort();
+ pLibrary->Save();
+
+ CPrefab::FreeAllData(); // free memory
+ // re-enable prefab caching
+ CPrefab::EnableCaching(TRUE);
+
+ bCurLibraryModified = FALSE;
+}
+
+
+void CPrefabsDlg::AddToObjectList(CPrefab *pPrefab, int iItem, BOOL bReplace)
+{
+ if(iItem == -1)
+ iItem = m_Objects.GetItemCount();
+ if(bReplace) // replace existing item
+ {
+ m_Objects.DeleteItem(iItem);
+ }
+ iItem = m_Objects.InsertItem(iItem, pPrefab->GetName(),
+ pPrefab->GetType() == CPrefab::pftScript ? 1 : 0);
+ m_Objects.SetItemData(iItem, pPrefab->GetID());
+
+ bCurLibraryModified = TRUE;
+}
+
+BOOL CPrefabsDlg::HandleEditObjectPopup(UINT nID)
+{
+ switch(nID)
+ {
+ case id_EditObjectInfo:
+ EditObjectInfo();
+ break;
+ case id_EditObjectData:
+ EditObjectData();
+ break;
+ }
+ return TRUE;
+}
+
+static BOOL IsValidFilename(LPCTSTR pszString)
+// check for valid windows filename. no drive/dirs allowed.
+{
+ LPCTSTR p = pszString;
+ while(p[0])
+ {
+ BYTE ch = BYTE(p[0]);
+ ++p;
+ if(ch > 127 || isalpha(ch) || isdigit(ch) ||
+ strchr(" $%`-_@~'!(){}^#&", ch))
+ continue;
+ // not one of those chars - not correct
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void CPrefabsDlg::EditObjectInfo()
+{
+ int iSel;
+ CPrefab *pPrefab = GetCurrentObject(&iSel);
+
+ CEditPrefabDlg dlg;
+ dlg.m_strName = pPrefab->GetName();
+ dlg.m_strDescript = pPrefab->GetNotes();
+
+ dlg.SetRanges(500, -1);
+
+ if(dlg.DoModal() == IDCANCEL)
+ return;
+
+ pPrefab->SetName(dlg.m_strName);
+ pPrefab->SetNotes(dlg.m_strDescript);
+
+ AddToObjectList(pPrefab, iSel, TRUE);
+ bCurLibraryModified = TRUE;
+}
+
+
+void CPrefabsDlg::EditObjectData()
+{
+ // get application
+ CHammer *pApp = (CHammer*) AfxGetApp();
+
+ if(bCurLibraryModified)
+ {
+ CPrefabLibrary *pLibrary = GetCurrentLibrary();
+ if(pLibrary)
+ pLibrary->Save();
+ }
+
+ CMapDoc *pDoc = (CMapDoc*) pApp->pMapDocTemplate->OpenDocumentFile(NULL);
+ pDoc->EditPrefab3D(GetCurrentObject()->GetID());
+ EndDialog(IDOK);
+}
+
+
+void CPrefabsDlg::OnEditobject()
+{
+ if(!GetCurrentObject()) // nothing
+ return;
+
+ // two stages - name/description OR data itself
+ CMenu menu;
+ menu.CreatePopupMenu();
+ menu.AppendMenu(MF_STRING, id_EditObjectInfo, "Name and Description");
+ menu.AppendMenu(MF_STRING, id_EditObjectData, "Prefab Data");
+
+ // track menu
+ CWnd *pButton = GetDlgItem(IDC_EDITOBJECT);
+ CRect r;
+ pButton->GetWindowRect(r);
+ menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, r.left, r.bottom,
+ this, NULL);
+}
+
+void CPrefabsDlg::OnRemoveobject()
+{
+ // remove marked objectsss
+ int iIndex = m_Objects.GetNextItem(-1, LVNI_SELECTED);
+ BOOL bConfirmed = FALSE;
+ CPrefabLibrary *pLibrary = GetCurrentLibrary();
+ while(iIndex != -1)
+ {
+ CPrefab *pPrefab = CPrefab::FindID(m_Objects.GetItemData(iIndex));
+ if(pPrefab)
+ {
+ // delete it
+ if(!bConfirmed)
+ {
+ // do confirmation.
+ if(AfxMessageBox("Are you sure you want to delete these "
+ "items?", MB_YESNO) == IDNO)
+ return; // nope!
+ m_Objects.SetRedraw(FALSE); // no redraw while doing this
+ }
+
+ bConfirmed = TRUE;
+
+ // remove from lib & delete
+ pLibrary->Remove(pPrefab);
+ delete pPrefab;
+
+ // delete from list and shift index down so we keep processing
+ // correctly
+ m_Objects.DeleteItem(iIndex--);
+ }
+ // get next item
+ iIndex = m_Objects.GetNextItem(iIndex, LVNI_SELECTED);
+ }
+
+ // save library
+ pLibrary->Save();
+
+ m_Objects.SetRedraw(TRUE); // redraw objects
+ m_Objects.Invalidate();
+}
+
+void CPrefabsDlg::OnExportobject()
+{
+ int iIndex = m_Objects.GetNextItem(-1, LVNI_SELECTED);
+ while(iIndex != -1)
+ {
+ CPrefab *pPrefab = CPrefab::FindID(m_Objects.GetItemData(iIndex));
+ if(pPrefab)
+ {
+ // export it
+ CString strFilename;
+ strFilename = pPrefab->GetName();
+ CFileDialog dlg(FALSE, "map", strFilename, OFN_HIDEREADONLY |
+ OFN_OVERWRITEPROMPT, "Map files|*.map;*.rmf|", this);
+ if(dlg.DoModal() == IDCANCEL)
+ return; // nevermind
+ strFilename = dlg.GetPathName();
+
+ int iPos = strFilename.Find('.');
+ DWORD dwFlags = CPrefab::lsRMF;
+ if(iPos != -1)
+ {
+ char *p = strFilename.GetBuffer(0);
+ if(!strnicmp(p+iPos+1, "map", 3))
+ dwFlags = CPrefab::lsMAP;
+ }
+
+ pPrefab->Save(strFilename, dwFlags);
+ }
+ // get next item
+ iIndex = m_Objects.GetNextItem(iIndex, LVNI_SELECTED);
+ }
+}
+
+void CPrefabsDlg::SetCurObject(int iItem)
+{
+ iCurObject = iItem;
+
+ if(iCurObject == -1)
+ {
+ m_ObjectNotes.SetWindowText("");
+ return;
+ }
+
+ // update data..
+ CPrefab *pPrefab = CPrefab::FindID(m_Objects.GetItemData(iCurObject));
+ Assert(pPrefab);
+
+ m_ObjectNotes.SetWindowText(pPrefab->GetNotes());
+}
+
+void CPrefabsDlg::OnItemchangedObjects(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
+ *pResult = 0;
+
+ if(!(pNMListView->uChanged & LVIF_STATE))
+ return;
+
+ if(pNMListView->uNewState & LVIS_FOCUSED)
+ {
+ SetCurObject(pNMListView->iItem);
+ }
+}
+
+//
+// Library mgmt
+//
+
+CPrefabLibrary *CPrefabsDlg::GetCurrentLibrary(int *piSel)
+{
+ if(piSel)
+ piSel[0] = -1;
+
+ int iSel = m_Libraries.GetCurSel();
+ if(iSel == CB_ERR)
+ return NULL;
+ CPrefabLibrary *pLibrary = CPrefabLibrary::FindID(
+ m_Libraries.GetItemData(iSel));
+
+ if(piSel)
+ piSel[0] = iSel;
+ return pLibrary;
+}
+
+CPrefab *CPrefabsDlg::GetCurrentObject(int *piSel)
+{
+ if(piSel)
+ piSel[0] = -1;
+
+ int iSel = iCurObject;
+ if(iSel == -1)
+ return NULL;
+ CPrefab *pPrefab= CPrefab::FindID(m_Objects.GetItemData(iSel));
+
+ if(piSel)
+ piSel[0] = iSel;
+
+ return pPrefab;
+}
+
+void CPrefabsDlg::OnSelchangeLibraries()
+{
+ // get last library
+ CPrefabLibrary *pLibrary = CPrefabLibrary::FindID(
+ m_Libraries.GetItemData(iCurLibrary));
+
+ // save its index
+ if(bCurLibraryModified)
+ {
+ pLibrary->Save();
+ }
+
+ // update objects list
+ m_Objects.DeleteAllItems();
+ iCurLibrary = m_Libraries.GetCurSel();
+ bCurLibraryModified = FALSE;
+ pLibrary = GetCurrentLibrary();
+ if(!pLibrary) return;
+
+ // add objects to object list
+ m_Objects.SetRedraw(FALSE);
+ POSITION p = ENUM_START;
+ CPrefab *pPrefab = pLibrary->EnumPrefabs(p);
+ int iItem = 0;
+ while(pPrefab)
+ {
+ AddToObjectList(pPrefab, iItem++);
+ pPrefab = pLibrary->EnumPrefabs(p);
+ }
+ m_Objects.SetRedraw(TRUE);
+ m_Objects.Invalidate();
+
+ // set description window
+ m_LibraryNotes.SetWindowText(pLibrary->GetNotes());
+}
+
+static int AskAboutInvalidFilename()
+{
+ return AfxMessageBox("That's not a valid name - some of the characters aren't\n"
+ "acceptable. Try using a name with only A-Z, 0-9, space,\n"
+ "and these characters: $%`-_@~'!(){}^#&", MB_OKCANCEL);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CPrefabsDlg::OnAddlibrary()
+{
+Again:
+ CEditPrefabDlg dlg;
+ if(dlg.DoModal() == IDCANCEL)
+ return;
+
+ // check name
+ if(!IsValidFilename(dlg.m_strName))
+ {
+ if(AskAboutInvalidFilename() == IDOK)
+ goto Again;
+ return; // nevermind.
+ }
+
+ CPrefabLibraryRMF *pLibrary = new CPrefabLibraryRMF;
+
+ pLibrary->SetName(dlg.m_strName);
+ pLibrary->SetNotes(dlg.m_strDescript);
+
+ // add to list
+ int iIndex = m_Libraries.AddString(pLibrary->GetName());
+ m_Libraries.SetItemData(iIndex, pLibrary->GetID());
+
+ m_Libraries.SetCurSel(iIndex);
+ OnSelchangeLibraries(); // to redraw description window
+ bCurLibraryModified = TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CPrefabsDlg::OnEditlibrary()
+{
+ // get selection
+ int iSel;
+ CPrefabLibrary *pLibrary = GetCurrentLibrary(&iSel);
+ if(!pLibrary) return;
+
+ CEditPrefabDlg dlg;
+ dlg.m_strName = pLibrary->GetName();
+ dlg.m_strDescript = pLibrary->GetNotes();
+
+Again:
+ if(dlg.DoModal() == IDCANCEL)
+ return;
+
+ // check name
+ if(!IsValidFilename(dlg.m_strName))
+ {
+ if(AskAboutInvalidFilename() == IDOK)
+ goto Again;
+ return; // nevermind.
+ }
+
+ pLibrary->SetName(dlg.m_strName);
+ pLibrary->SetNotes(dlg.m_strDescript);
+
+ // set in list
+ m_Libraries.SetRedraw(FALSE);
+ m_Libraries.DeleteString(iSel);
+ int iIndex = m_Libraries.InsertString(iSel, pLibrary->GetName());
+ m_Libraries.SetItemData(iIndex, pLibrary->GetID());
+ m_Libraries.SetRedraw(TRUE);
+ m_Libraries.Invalidate();
+
+ m_Libraries.SetCurSel(iSel);
+ OnSelchangeLibraries(); // to redraw description window
+ bCurLibraryModified = TRUE;
+}
+
+
+void CPrefabsDlg::OnRemovelibrary()
+{
+ // get cur library
+ int iSel;
+ CPrefabLibrary *pLibrary = GetCurrentLibrary(&iSel);
+ if (pLibrary == NULL)
+ {
+ return;
+ }
+
+ if (AfxMessageBox("Are you sure you want to delete this library from your hard drive?", MB_YESNO) == IDYES)
+ {
+ pLibrary->DeleteFile();
+ delete pLibrary;
+
+ bCurLibraryModified = FALSE;
+
+ m_Libraries.DeleteString(iSel);
+ m_Libraries.SetCurSel(0);
+ OnSelchangeLibraries(); // to redraw description window
+ }
+}
+
+
+BOOL CPrefabsDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ SetCurObject(-1);
+
+ // make imagelist
+ PrefabImages.Create(IDB_PREFABS, 32, 1, RGB(0, 255, 255));
+ PrefabImages.SetBkColor(m_Objects.GetBkColor());
+ m_Objects.SetImageList(&PrefabImages, LVSIL_NORMAL);
+
+ // add libraries to list
+ POSITION p = ENUM_START;
+ CPrefabLibrary *pLibrary = CPrefabLibrary::EnumLibraries(p);
+ while(pLibrary)
+ {
+ int iIndex = m_Libraries.AddString(pLibrary->GetName());
+ m_Libraries.SetItemData(iIndex, pLibrary->GetID());
+ pLibrary = CPrefabLibrary::EnumLibraries(p);
+ }
+
+ iCurLibrary = 0;
+ bCurLibraryModified = FALSE;
+ m_Libraries.SetCurSel(0);
+ OnSelchangeLibraries();
+
+ return TRUE;
+}
+
+
+void CPrefabsDlg::OnEndlabeleditObjects(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+ LV_ITEM &item = pDispInfo->item;
+
+ *pResult = 0;
+
+ if(item.pszText == NULL)
+ return;
+
+ CPrefab *pPrefab = CPrefab::FindID(m_Objects.GetItemData(item.iItem));
+ pPrefab->SetName(item.pszText);
+ m_Objects.SetItemText(item.iItem, 0, item.pszText);
+ bCurLibraryModified = TRUE;
+}
+
+void CPrefabsDlg::OnClose()
+{
+ // get library
+ CPrefabLibrary *pLibrary = GetCurrentLibrary();
+
+ // save it
+ if(bCurLibraryModified && pLibrary)
+ {
+ pLibrary->Save();
+ }
+
+ CDialog::OnClose();
+}